From 27606dae3658767f5995699ada7fc8a645677ee5 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 8 Dec 2014 11:15:08 +0100 Subject: [PATCH] Mixer resampler: refactor using templates. There is no need to copypaste the resampling code which is mostly the same for all formats. However, gcc2 is confused by member function templates (I hit an internal compiler error) so the resampling code was moved to a static function instead. --- .../media/media-add-ons/mixer/Interpolate.cpp | 546 ++++------------ .../media/media-add-ons/mixer/Interpolate.h | 39 +- .../media/media-add-ons/mixer/Resampler.cpp | 581 ++---------------- .../media/media-add-ons/mixer/Resampler.h | 44 +- 4 files changed, 172 insertions(+), 1038 deletions(-) diff --git a/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp b/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp index f6af95e614..de4ab75cdd 100644 --- a/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp +++ b/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp @@ -1,6 +1,8 @@ /* - * Copyright 2010 Adrien Destugues + * Copyright 2010-2014 Haiku, inc. * Distributed under the terms of the MIT Licence. + * + * Author: Adrien Destugues */ @@ -8,453 +10,119 @@ #include +#include + +#include "MixerDebug.h" + /*! Resampling class doing linear interpolation. */ +template static void +kernel(Resampler* object, const void *_src, int32 srcSampleOffset, + int32 srcSampleCount, void *_dest, int32 destSampleOffset, + int32 destSampleCount, float _gain) +{ + register const char * src = (const char *)_src; + register char * dest = (char *)_dest; + register int32 count = destSampleCount; + register float gain = _gain * gnum / gden; + + if (srcSampleCount == destSampleCount) { + // optimized case for no resampling + while (count--) { + float tmp = *(const inType*)src * gain + offset; + if (tmp < min) tmp = min; + if (tmp > max) tmp = max; + *(outType *)dest = (outType)tmp; + src += srcSampleOffset; + dest += destSampleOffset; + } + return; + } + + register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); + register float current = 0.0f; + + #define SRC(n) *(const inType*)(src + n * srcSampleOffset) + + while (--count) { + float tmp = (gain * (SRC(0) + (SRC(1) - SRC(0)) * current) + offset); + if (tmp < min) tmp = min; + if (tmp > max) tmp = max; + *(outType *)dest = (outType)tmp; + + dest += destSampleOffset; + current += delta; + if (current >= 1.0f) { + double ipart; + current = modf(current, &ipart); + src += srcSampleOffset * (int)ipart; + } + } + + *(outType*)dest = (outType)(SRC(0) * gain + offset); +} + + Interpolate::Interpolate(uint32 src_format, uint32 dst_format) : - Resampler(src_format, dst_format) + Resampler() { -} + if (dst_format == media_raw_audio_format::B_AUDIO_FLOAT) { + switch (src_format) { + case media_raw_audio_format::B_AUDIO_FLOAT: + fFunc = &kernel; + return; + case media_raw_audio_format::B_AUDIO_INT: + fFunc = &kernel; + return; + case media_raw_audio_format::B_AUDIO_SHORT: + fFunc = &kernel; + return; + case media_raw_audio_format::B_AUDIO_CHAR: + fFunc = &kernel; + return; + case media_raw_audio_format::B_AUDIO_UCHAR: + fFunc = &kernel; + return; + default: + ERROR("Resampler::Resampler: unknown source format 0x%x\n", + src_format); + return; + } + } -Interpolate::~Interpolate() -{ + if (src_format == media_raw_audio_format::B_AUDIO_FLOAT) { + switch (dst_format) { + // float=>float already handled above + case media_raw_audio_format::B_AUDIO_INT: + fFunc = &kernel; + return; + case media_raw_audio_format::B_AUDIO_SHORT: + fFunc = &kernel; + return; + case media_raw_audio_format::B_AUDIO_CHAR: + fFunc = &kernel; + return; + case media_raw_audio_format::B_AUDIO_UCHAR: + fFunc = &kernel; + return; + default: + ERROR("Resampler::Resampler: unknown destination format 0x%x\n", + dst_format); + return; + } + } + + ERROR("Resampler::Resampler: source or destination format must be " + "B_AUDIO_FLOAT\n"); } -void -Interpolate::float_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = *(const float *)src * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - #define SRC(n) *(const float*)(src + n * srcSampleOffset) - - while (--count) { - *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - *(float*)dest = SRC(0) * gain; -} - - -void -Interpolate::int32_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain / 2147483647.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = *(const int32 *)src * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - #undef SRC - #define SRC(n) *(const int32*)(src + n * srcSampleOffset) - - while (--count) { - *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - *(float*)dest = SRC(0) * gain; -} - - -void -Interpolate::int16_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain / 32767.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = *(const int16 *)src * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - #undef SRC - #define SRC(n) *(const int16*)(src + n * srcSampleOffset) - - while (--count) { - *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current); - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - *(float*)dest = SRC(0) * gain; -} - - -void -Interpolate::int8_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain / 127.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = *(const int8 *)src * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - #undef SRC - #define SRC(n) *(const int8*)(src + n * srcSampleOffset) - - while (--count) { - *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - *(float*)dest = SRC(0) * gain; -} - - -void -Interpolate::uint8_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain / 127.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - #undef SRC - #define SRC(n) ( *(const uint8*)(src + n * srcSampleOffset) - 128) - - while (--count) { - *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current); - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - *(float*)dest = SRC(0) * gain; -} - - -void -Interpolate::float_to_int32(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain * 2147483647.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 2147483647.0f) - *(int32 *)dest = 2147483647L; - else if (sample < -2147483647.0f) - *(int32 *)dest = -2147483647L; - else - *(int32 *)dest = (int32)sample; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - #undef SRC - #define SRC(n) *(const float*)(src + n * srcSampleOffset) - - while (--count) { - register float sample = gain * (SRC(0) + (SRC(1) - SRC(0)) - * current); - if (sample > 2147483647.0f) - *(int32 *)dest = 2147483647L; - else if (sample < -2147483647.0f) - *(int32 *)dest = -2147483647L; - else - *(int32 *)dest = (int32)sample; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - register float sample = SRC(0)*gain; - if (sample > 2147483647.0f) - *(int32 *)dest = 2147483647L; - else if (sample < -2147483647.0f) - *(int32 *)dest = -2147483647L; - else - *(int32 *)dest = (int32)sample; -} - - -void -Interpolate::float_to_int16(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain * 32767.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 32767.0f) - *(int16 *)dest = 32767; - else if (sample < -32767.0f) - *(int16 *)dest = -32767; - else - *(int16 *)dest = (int16)sample; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - while (--count) { - register float sample = gain * (SRC(0) + (SRC(1) - SRC(0)) - * current); - if (sample > 32767.0f) - *(int16 *)dest = 32767; - else if (sample < -32767.0f) - *(int16 *)dest = -32767; - else - *(int16 *)dest = (int16)sample; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - register float sample = SRC(0) * gain; - if (sample > 32767.0f) - *(int16 *)dest = 32767; - else if (sample < -32767.0f) - *(int16 *)dest = -32767; - else - *(int16 *)dest = (int16)sample; -} - - -void -Interpolate::float_to_int8(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain * 127.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 127.0f) - *(int8 *)dest = 127; - else if (sample < -127.0f) - *(int8 *)dest = -127; - else - *(int8 *)dest = (int8)sample; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - while (--count) { - register float sample = gain * (SRC(0) + (SRC(1) - SRC(0)) - * current); - if (sample > 127.0f) - *(int8 *)dest = 127; - else if (sample < -127.0f) - *(int8 *)dest = -127; - else - *(int8 *)dest = (int8)sample; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - register float sample = SRC(0) * gain; - if (sample > 127.0f) - *(int8 *)dest = 127; - else if (sample < -127.0f) - *(int8 *)dest = -127; - else - *(int8 *)dest = (int8)sample; -} - - -void -Interpolate::float_to_uint8(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain * 127.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - register float sample = 128.0f + *(const float *)src * gain; - if (sample > 255.0f) - *(uint8 *)dest = 255; - else if (sample < 1.0f) - *(uint8 *)dest = 1; - else - *(uint8 *)dest = (uint8)sample; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); - register float current = 0.0f; - - while (--count) { - register float sample = gain * (SRC(0) + (SRC(1) - SRC(0)) - * current); - if (sample > 255.0f) - *(uint8 *)dest = 255; - else if (sample < 1.0f) - *(uint8 *)dest = 1; - else - *(uint8 *)dest = (uint8)sample; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - double ipart; - current = modf(current, &ipart); - src += srcSampleOffset * (int)ipart; - } - } - - register float sample = SRC(0) * gain; - if (sample > 255.0f) - *(uint8 *)dest = 255; - else if (sample < 1.0f) - *(uint8 *)dest = 1; - else - *(uint8 *)dest = (uint8)sample; -} - diff --git a/src/add-ons/media/media-add-ons/mixer/Interpolate.h b/src/add-ons/media/media-add-ons/mixer/Interpolate.h index 0ddaf0cd3c..2d08632bba 100644 --- a/src/add-ons/media/media-add-ons/mixer/Interpolate.h +++ b/src/add-ons/media/media-add-ons/mixer/Interpolate.h @@ -1,5 +1,5 @@ /* - * Copyright 2010, Adrien Destugues + * Copyright 2010-2014, Haiku, Inc. * Distributed under the terms of the MIT Licence. */ #ifndef _INTERPOLATE_H @@ -13,44 +13,7 @@ class Interpolate: public Resampler { public: Interpolate(uint32 sourceFormat, uint32 destFormat); - virtual ~Interpolate(); private: - virtual void float_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void int32_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void int16_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void int8_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void uint8_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void float_to_int32(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void float_to_int16(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void float_to_int8(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void float_to_uint8(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); }; diff --git a/src/add-ons/media/media-add-ons/mixer/Resampler.cpp b/src/add-ons/media/media-add-ons/mixer/Resampler.cpp index 1a758c23b4..0f4410dc85 100644 --- a/src/add-ons/media/media-add-ons/mixer/Resampler.cpp +++ b/src/add-ons/media/media-add-ons/mixer/Resampler.cpp @@ -19,6 +19,49 @@ */ +template static void +kernel(Resampler* object, const void *_src, int32 srcSampleOffset, + int32 srcSampleCount, void *_dest, int32 destSampleOffset, + int32 destSampleCount, float _gain) +{ + register const char * src = (const char *)_src; + register char * dest = (char *)_dest; + register int32 count = destSampleCount; + register float gain = _gain * gnum / gden; + + if (srcSampleCount == destSampleCount) { + // optimized case for no resampling + while (count--) { + float tmp = *(const inType*)src * gain + offset; + if (tmp < min) tmp = min; + if (tmp > max) tmp = max; + *(outType *)dest = (outType)tmp; + src += srcSampleOffset; + dest += destSampleOffset; + } + return; + } + + register float delta = float(srcSampleCount) / float(destSampleCount); + register float current = 0.0f; + + // downsample + while (count--) { + float tmp = *(const inType*)src * gain + offset; + if (tmp < min) tmp = min; + if (tmp > max) tmp = max; + *(outType *)dest = (outType)tmp; + + dest += destSampleOffset; + current += delta; + register int32 skipcount = (int32)current; + current -= skipcount; + src += skipcount * srcSampleOffset; + } +} + + Resampler::Resampler(uint32 src_format, uint32 dst_format) : fFunc(0) @@ -26,19 +69,19 @@ Resampler::Resampler(uint32 src_format, uint32 dst_format) if (dst_format == media_raw_audio_format::B_AUDIO_FLOAT) { switch (src_format) { case media_raw_audio_format::B_AUDIO_FLOAT: - fFunc = &Resampler::float_to_float; + fFunc = &kernel; return; case media_raw_audio_format::B_AUDIO_INT: - fFunc = &Resampler::int32_to_float; + fFunc = &kernel; return; case media_raw_audio_format::B_AUDIO_SHORT: - fFunc = &Resampler::int16_to_float; + fFunc = &kernel; return; case media_raw_audio_format::B_AUDIO_CHAR: - fFunc = &Resampler::int8_to_float; + fFunc = &kernel; return; case media_raw_audio_format::B_AUDIO_UCHAR: - fFunc = &Resampler::uint8_to_float; + fFunc = &kernel; return; default: ERROR("Resampler::Resampler: unknown source format 0x%x\n", @@ -51,19 +94,24 @@ Resampler::Resampler(uint32 src_format, uint32 dst_format) switch (dst_format) { // float=>float already handled above case media_raw_audio_format::B_AUDIO_INT: - fFunc = &Resampler::float_to_int32; + fFunc = &kernel; return; case media_raw_audio_format::B_AUDIO_SHORT: - fFunc = &Resampler::float_to_int16; + fFunc = &kernel; return; case media_raw_audio_format::B_AUDIO_CHAR: - fFunc = &Resampler::float_to_int8; + fFunc = &kernel; return; case media_raw_audio_format::B_AUDIO_UCHAR: - fFunc = &Resampler::float_to_uint8; + fFunc = &kernel; return; default: - ERROR("Resampler::Resampler: unknown destination format 0x%x\n", dst_format); + ERROR("Resampler::Resampler: unknown destination format 0x%x\n", + dst_format); return; } } @@ -73,517 +121,10 @@ Resampler::Resampler(uint32 src_format, uint32 dst_format) } -Resampler::~Resampler() +Resampler::Resampler() + : + fFunc(0) { } -status_t -Resampler::InitCheck() const -{ - return fFunc != 0 ? B_OK : B_ERROR; -} - - -void -Resampler::float_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = *(const float *)src * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - *(float *)dest = *(const float *)src * gain; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - *(float *)dest = *(const float *)src * gain; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} - - -void -Resampler::int32_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain / 2147483647.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = *(const int32 *)src * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - *(float *)dest = *(const int32 *)src * gain; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - *(float *)dest = *(const int32 *)src * gain; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} - - -void -Resampler::int16_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain / 32767.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = *(const int16 *)src * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - *(float *)dest = *(const int16 *)src * gain; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - *(float *)dest = *(const int16 *)src * gain; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} - - -void -Resampler::int8_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain / 127.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = *(const int8 *)src * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - *(float *)dest = *(const int8 *)src * gain; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - *(float *)dest = *(const int8 *)src * gain; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} - - -void -Resampler::uint8_to_float(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain / 127.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} - - -void -Resampler::float_to_int32(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain * 2147483647.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 2147483647.0f) - *(int32 *)dest = 2147483647L; - else if (sample < -2147483647.0f) - *(int32 *)dest = -2147483647L; - else - *(int32 *)dest = (int32)sample; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 2147483647.0f) - *(int32 *)dest = 2147483647L; - else if (sample < -2147483647.0f) - *(int32 *)dest = -2147483647L; - else - *(int32 *)dest = (int32)sample; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 2147483647.0f) - *(int32 *)dest = 2147483647L; - else if (sample < -2147483647.0f) - *(int32 *)dest = -2147483647L; - else - *(int32 *)dest = (int32)sample; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} - - -void -Resampler::float_to_int16(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain * 32767.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 32767.0f) - *(int16 *)dest = 32767; - else if (sample < -32767.0f) - *(int16 *)dest = -32767; - else - *(int16 *)dest = (int16)sample; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 32767.0f) - *(int16 *)dest = 32767; - else if (sample < -32767.0f) - *(int16 *)dest = -32767; - else - *(int16 *)dest = (int16)sample; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 32767.0f) - *(int16 *)dest = 32767; - else if (sample < -32767.0f) - *(int16 *)dest = -32767; - else - *(int16 *)dest = (int16)sample; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} - - -void -Resampler::float_to_int8(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain * 127.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 127.0f) - *(int8 *)dest = 127; - else if (sample < -127.0f) - *(int8 *)dest = -127; - else - *(int8 *)dest = (int8)sample; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 127.0f) - *(int8 *)dest = 127; - else if (sample < -127.0f) - *(int8 *)dest = -127; - else - *(int8 *)dest = (int8)sample; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - register float sample = *(const float *)src * gain; - if (sample > 127.0f) - *(int8 *)dest = 127; - else if (sample < -127.0f) - *(int8 *)dest = -127; - else - *(int8 *)dest = (int8)sample; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} - - -void -Resampler::float_to_uint8(const void *_src, int32 srcSampleOffset, - int32 srcSampleCount, void *_dest, int32 destSampleOffset, - int32 destSampleCount, float _gain) -{ - register const char * src = (const char *)_src; - register char * dest = (char *)_dest; - register int32 count = destSampleCount; - register float gain = _gain * 127.0; - - if (srcSampleCount == destSampleCount) { - // optimized case for no resampling - while (count--) { - register float sample = 128.0f + *(const float *)src * gain; - if (sample > 255.0f) - *(uint8 *)dest = 255; - else if (sample < 1.0f) - *(uint8 *)dest = 1; - else - *(uint8 *)dest = (uint8)sample; - src += srcSampleOffset; - dest += destSampleOffset; - } - return; - } - - register float delta = float(srcSampleCount) / float(destSampleCount); - register float current = 0.0f; - - if (delta < 1.0) { - // upsample - while (count--) { - register float sample = 128.0f + *(const float *)src * gain; - if (sample > 255.0f) - *(uint8 *)dest = 255; - else if (sample < 1.0f) - *(uint8 *)dest = 1; - else - *(uint8 *)dest = (uint8)sample; - dest += destSampleOffset; - current += delta; - if (current >= 1.0f) { - current -= 1.0f; - src += srcSampleOffset; - } - } - } else { - // downsample - while (count--) { - register float sample = 128.0f + *(const float *)src * gain; - if (sample > 255.0f) - *(uint8 *)dest = 255; - else if (sample < 1.0f) - *(uint8 *)dest = 1; - else - *(uint8 *)dest = (uint8)sample; - dest += destSampleOffset; - current += delta; - register int32 skipcount = (int32)current; - current -= skipcount; - src += skipcount * srcSampleOffset; - } - } -} diff --git a/src/add-ons/media/media-add-ons/mixer/Resampler.h b/src/add-ons/media/media-add-ons/mixer/Resampler.h index 9ad1b64b5f..f19a5798d0 100644 --- a/src/add-ons/media/media-add-ons/mixer/Resampler.h +++ b/src/add-ons/media/media-add-ons/mixer/Resampler.h @@ -13,7 +13,6 @@ class Resampler { public: Resampler(uint32 sourceFormat, uint32 destFormat); - virtual ~Resampler(); status_t InitCheck() const; @@ -23,45 +22,8 @@ public: int32 destSampleCount, float gain); protected: - virtual void float_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void int32_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void int16_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void int8_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void uint8_to_float(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void float_to_int32(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void float_to_int16(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void float_to_int8(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - virtual void float_to_uint8(const void* src, - int32 srcSampleOffset, int32 srcSampleCount, - void* dest, int32 destSampleOffset, - int32 destSampleCount, float gain); - -private: - void (Resampler::*fFunc)(const void* src, + Resampler(); + void (*fFunc)(Resampler* object, const void* src, int32 srcSampleOffset, int32 srcSampleCount, void* dest, int32 destSampleOffset, int32 destSampleCount, float gain); @@ -73,7 +35,7 @@ Resampler::Resample(const void *src, int32 srcSampleOffset, int32 srcSampleCount, void *dest, int32 destSampleOffset, int32 destSampleCount, float gain) { - (this->*fFunc)(src, srcSampleOffset, srcSampleCount, dest, destSampleOffset, + (*fFunc)(this, src, srcSampleOffset, srcSampleCount, dest, destSampleOffset, destSampleCount, gain); }