pcm_volume: implemented 32 bit support

Support 32 bit samples with software mixer.
This commit is contained in:
Max Kellermann 2009-11-19 21:00:50 +01:00
parent 5a480137d2
commit 1358428031
3 changed files with 43 additions and 0 deletions

1
NEWS
View File

@ -71,6 +71,7 @@ ver 0.16 (20??/??/??)
* database: eliminated maximum line length
* log: redirect stdout/stderr to /dev/null if syslog is used
* set the close-on-exec flag on all file descriptors
* pcm_volume: implemented 32 bit support
* obey $(sysconfdir) for default mpd.conf location
* build with large file support by default
* require GLib 2.12

View File

@ -38,4 +38,18 @@ pcm_range(int32_t sample, unsigned bits)
return sample;
}
/**
* Check if the value is within the range of the provided bit size,
* and caps it if necessary.
*/
static inline int64_t
pcm_range_64(int64_t sample, unsigned bits)
{
if (G_UNLIKELY(sample < ((int64_t)-1 << (bits - 1))))
return (int64_t)-1 << (bits - 1);
if (G_UNLIKELY(sample >= ((int64_t)1 << (bits - 1))))
return ((int64_t)1 << (bits - 1)) - 1;
return sample;
}
#endif

View File

@ -114,6 +114,29 @@ pcm_volume_change_24(int32_t *buffer, unsigned num_samples, int volume)
}
}
static void
pcm_volume_change_32(int32_t *buffer, unsigned num_samples, int volume)
{
while (num_samples > 0) {
#ifdef __i386__
/* assembly version for i386 */
int32_t sample = *buffer;
*buffer++ = pcm_volume_sample_24(sample, volume, 0);
#else
/* portable version */
int64_t sample = *buffer;
sample = (sample * volume + pcm_volume_dither() +
PCM_VOLUME_1 / 2)
/ PCM_VOLUME_1;
*buffer++ = pcm_range_64(sample, 32);
#endif
--num_samples;
}
}
bool
pcm_volume(void *buffer, int length,
const struct audio_format *format,
@ -142,6 +165,11 @@ pcm_volume(void *buffer, int length,
volume);
return true;
case 32:
pcm_volume_change_32((int32_t*)buffer, length / 4,
volume);
return true;
default:
return false;
}