pcm/PcmMix: use the SampleTraits library

This commit is contained in:
Max Kellermann 2013-12-01 20:37:30 +01:00
parent fc10bdf24d
commit 04ba40981f

View File

@ -22,40 +22,48 @@
#include "PcmVolume.hxx" #include "PcmVolume.hxx"
#include "PcmUtils.hxx" #include "PcmUtils.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "Traits.hxx"
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
template<typename T, typename U, unsigned bits> template<SampleFormat F, class Traits=SampleTraits<F>>
static T static typename Traits::value_type
PcmAddVolume(T _a, T _b, int volume1, int volume2) PcmAddVolume(typename Traits::value_type _a, typename Traits::value_type _b,
int volume1, int volume2)
{ {
U a(_a), b(_b); typename Traits::long_type a(_a), b(_b);
U c = ((a * volume1 + b * volume2) + typename Traits::value_type c = ((a * volume1 + b * volume2) +
pcm_volume_dither() + PCM_VOLUME_1 / 2) pcm_volume_dither() + PCM_VOLUME_1 / 2)
/ PCM_VOLUME_1; / PCM_VOLUME_1;
return PcmClamp<T, U, bits>(c); return PcmClamp<typename Traits::value_type,
typename Traits::long_type,
Traits::BITS>(c);
} }
template<typename T, typename U, unsigned bits> template<SampleFormat F, class Traits=SampleTraits<F>>
static void static void
PcmAddVolume(T *a, const T *b, unsigned n, int volume1, int volume2) PcmAddVolume(typename Traits::pointer_type a,
typename Traits::const_pointer_type b,
size_t n, int volume1, int volume2)
{ {
for (size_t i = 0; i != n; ++i) for (size_t i = 0; i != n; ++i)
a[i] = PcmAddVolume<T, U, bits>(a[i], b[i], volume1, volume2); a[i] = PcmAddVolume<F, Traits>(a[i], b[i], volume1, volume2);
} }
template<typename T, typename U, unsigned bits> template<SampleFormat F, class Traits=SampleTraits<F>>
static void static void
PcmAddVolumeVoid(void *a, const void *b, size_t size, int volume1, int volume2) PcmAddVolumeVoid(void *a, const void *b, size_t size, int volume1, int volume2)
{ {
constexpr size_t sample_size = sizeof(T); constexpr size_t sample_size = Traits::SAMPLE_SIZE;
assert(size % sample_size == 0); assert(size % sample_size == 0);
PcmAddVolume<T, U, bits>((T *)a, (const T *)b, size / sample_size, PcmAddVolume<F, Traits>(typename Traits::pointer_type(a),
volume1, volume2); typename Traits::const_pointer_type(b),
size / sample_size,
volume1, volume2);
} }
static void static void
@ -84,23 +92,23 @@ pcm_add_vol(void *buffer1, const void *buffer2, size_t size,
return false; return false;
case SampleFormat::S8: case SampleFormat::S8:
PcmAddVolumeVoid<int8_t, int32_t, 8>(buffer1, buffer2, size, PcmAddVolumeVoid<SampleFormat::S8>(buffer1, buffer2, size,
vol1, vol2); vol1, vol2);
return true; return true;
case SampleFormat::S16: case SampleFormat::S16:
PcmAddVolumeVoid<int16_t, int32_t, 16>(buffer1, buffer2, size, PcmAddVolumeVoid<SampleFormat::S16>(buffer1, buffer2, size,
vol1, vol2); vol1, vol2);
return true; return true;
case SampleFormat::S24_P32: case SampleFormat::S24_P32:
PcmAddVolumeVoid<int32_t, int64_t, 24>(buffer1, buffer2, size, PcmAddVolumeVoid<SampleFormat::S24_P32>(buffer1, buffer2, size,
vol1, vol2); vol1, vol2);
return true; return true;
case SampleFormat::S32: case SampleFormat::S32:
PcmAddVolumeVoid<int32_t, int64_t, 32>(buffer1, buffer2, size, PcmAddVolumeVoid<SampleFormat::S32>(buffer1, buffer2, size,
vol1, vol2); vol1, vol2);
return true; return true;
case SampleFormat::FLOAT: case SampleFormat::FLOAT: