1*a9cf57cfSAxel Dörfler /* 2*a9cf57cfSAxel Dörfler * Copyright 2003 Marcus Overhagen 3*a9cf57cfSAxel Dörfler * Distributed under the terms of the MIT License. 4575526ffSbeveloper */ 5575526ffSbeveloper 6*a9cf57cfSAxel Dörfler 7575526ffSbeveloper #include "Resampler.h" 8*a9cf57cfSAxel Dörfler 9*a9cf57cfSAxel Dörfler #include <MediaDefs.h> 10*a9cf57cfSAxel Dörfler 11f916862cSMarcus Overhagen #include "MixerDebug.h" 12575526ffSbeveloper 13*a9cf57cfSAxel Dörfler 14*a9cf57cfSAxel Dörfler /*! A simple resampling class for the audio mixer. 15*a9cf57cfSAxel Dörfler You pick the conversion function on object creation, 16*a9cf57cfSAxel Dörfler and then call the Resample() function, specifying data pointer, 17*a9cf57cfSAxel Dörfler offset (in bytes) to the next sample, and count of samples for 18*a9cf57cfSAxel Dörfler both source and destination. 19*a9cf57cfSAxel Dörfler */ 20*a9cf57cfSAxel Dörfler 21*a9cf57cfSAxel Dörfler 22f0a85f97SJérôme Duval Resampler::Resampler(uint32 src_format, uint32 dst_format) 23*a9cf57cfSAxel Dörfler : 24*a9cf57cfSAxel Dörfler fFunc(0) 25575526ffSbeveloper { 26575526ffSbeveloper if (dst_format == media_raw_audio_format::B_AUDIO_FLOAT) { 27575526ffSbeveloper switch (src_format) { 28575526ffSbeveloper case media_raw_audio_format::B_AUDIO_FLOAT: 29575526ffSbeveloper fFunc = &Resampler::float_to_float; 30575526ffSbeveloper return; 31575526ffSbeveloper case media_raw_audio_format::B_AUDIO_INT: 32575526ffSbeveloper fFunc = &Resampler::int32_to_float; 33575526ffSbeveloper return; 34575526ffSbeveloper case media_raw_audio_format::B_AUDIO_SHORT: 35575526ffSbeveloper fFunc = &Resampler::int16_to_float; 36575526ffSbeveloper return; 37575526ffSbeveloper case media_raw_audio_format::B_AUDIO_CHAR: 38575526ffSbeveloper fFunc = &Resampler::int8_to_float; 39575526ffSbeveloper return; 40575526ffSbeveloper case media_raw_audio_format::B_AUDIO_UCHAR: 41575526ffSbeveloper fFunc = &Resampler::uint8_to_float; 42575526ffSbeveloper return; 43575526ffSbeveloper default: 44*a9cf57cfSAxel Dörfler ERROR("Resampler::Resampler: unknown source format 0x%x\n", 45*a9cf57cfSAxel Dörfler src_format); 46575526ffSbeveloper return; 47575526ffSbeveloper } 48575526ffSbeveloper } 49575526ffSbeveloper 50575526ffSbeveloper if (src_format == media_raw_audio_format::B_AUDIO_FLOAT) { 51575526ffSbeveloper switch (dst_format) { 52575526ffSbeveloper // float=>float already handled above 53575526ffSbeveloper case media_raw_audio_format::B_AUDIO_INT: 54f0a85f97SJérôme Duval fFunc = &Resampler::float_to_int32; 55575526ffSbeveloper return; 56575526ffSbeveloper case media_raw_audio_format::B_AUDIO_SHORT: 57575526ffSbeveloper fFunc = &Resampler::float_to_int16; 58575526ffSbeveloper return; 59575526ffSbeveloper case media_raw_audio_format::B_AUDIO_CHAR: 60575526ffSbeveloper fFunc = &Resampler::float_to_int8; 61575526ffSbeveloper return; 62575526ffSbeveloper case media_raw_audio_format::B_AUDIO_UCHAR: 63575526ffSbeveloper fFunc = &Resampler::float_to_uint8; 64575526ffSbeveloper return; 65575526ffSbeveloper default: 66e6c7c99fSbeveloper ERROR("Resampler::Resampler: unknown destination format 0x%x\n", dst_format); 67575526ffSbeveloper return; 68575526ffSbeveloper } 69575526ffSbeveloper } 70575526ffSbeveloper 71*a9cf57cfSAxel Dörfler ERROR("Resampler::Resampler: source or destination format must be " 72*a9cf57cfSAxel Dörfler "B_AUDIO_FLOAT\n"); 73575526ffSbeveloper } 74575526ffSbeveloper 75*a9cf57cfSAxel Dörfler 76575526ffSbeveloper Resampler::~Resampler() 77575526ffSbeveloper { 78575526ffSbeveloper } 79575526ffSbeveloper 80*a9cf57cfSAxel Dörfler 81575526ffSbeveloper status_t 82*a9cf57cfSAxel Dörfler Resampler::InitCheck() const 83575526ffSbeveloper { 84*a9cf57cfSAxel Dörfler return fFunc != 0 ? B_OK : B_ERROR; 85575526ffSbeveloper } 86575526ffSbeveloper 87*a9cf57cfSAxel Dörfler 88575526ffSbeveloper void 89*a9cf57cfSAxel Dörfler Resampler::float_to_float(const void *_src, int32 srcSampleOffset, 90*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 91*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 927ca83dacSbeveloper { 937ca83dacSbeveloper register const char * src = (const char *)_src; 94*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 95*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 967ca83dacSbeveloper register float gain = _gain; 977ca83dacSbeveloper 98*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 997ca83dacSbeveloper // optimized case for no resampling 1007ca83dacSbeveloper while (count--) { 101*a9cf57cfSAxel Dörfler *(float *)dest = *(const float *)src * gain; 102*a9cf57cfSAxel Dörfler src += srcSampleOffset; 103*a9cf57cfSAxel Dörfler dest += destSampleOffset; 1047ca83dacSbeveloper } 1057ca83dacSbeveloper return; 1067ca83dacSbeveloper } 1077ca83dacSbeveloper 108*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 1097ca83dacSbeveloper register float current = 0.0f; 1107ca83dacSbeveloper 1117ca83dacSbeveloper if (delta < 1.0) { 1127ca83dacSbeveloper // upsample 1137ca83dacSbeveloper while (count--) { 114*a9cf57cfSAxel Dörfler *(float *)dest = *(const float *)src * gain; 115*a9cf57cfSAxel Dörfler dest += destSampleOffset; 1167ca83dacSbeveloper current += delta; 1176b5e1508Sbeveloper if (current >= 1.0f) { 1187ca83dacSbeveloper current -= 1.0f; 119*a9cf57cfSAxel Dörfler src += srcSampleOffset; 1207ca83dacSbeveloper } 1217ca83dacSbeveloper } 1227ca83dacSbeveloper } else { 1237ca83dacSbeveloper // downsample 1247ca83dacSbeveloper while (count--) { 125*a9cf57cfSAxel Dörfler *(float *)dest = *(const float *)src * gain; 126*a9cf57cfSAxel Dörfler dest += destSampleOffset; 1276b5e1508Sbeveloper current += delta; 1286b5e1508Sbeveloper register int32 skipcount = (int32)current; 1296b5e1508Sbeveloper current -= skipcount; 130*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 1317ca83dacSbeveloper } 1327ca83dacSbeveloper } 1337ca83dacSbeveloper } 1347ca83dacSbeveloper 135*a9cf57cfSAxel Dörfler 1367ca83dacSbeveloper void 137*a9cf57cfSAxel Dörfler Resampler::int32_to_float(const void *_src, int32 srcSampleOffset, 138*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 139*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 140575526ffSbeveloper { 14188e430cbSbeveloper register const char * src = (const char *)_src; 142*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 143*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 14488e430cbSbeveloper register float gain = _gain / 2147483647.0; 14588e430cbSbeveloper 146*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 14788e430cbSbeveloper // optimized case for no resampling 14888e430cbSbeveloper while (count--) { 149*a9cf57cfSAxel Dörfler *(float *)dest = *(const int32 *)src * gain; 150*a9cf57cfSAxel Dörfler src += srcSampleOffset; 151*a9cf57cfSAxel Dörfler dest += destSampleOffset; 15288e430cbSbeveloper } 15388e430cbSbeveloper return; 15488e430cbSbeveloper } 15588e430cbSbeveloper 156*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 15788e430cbSbeveloper register float current = 0.0f; 15888e430cbSbeveloper 15988e430cbSbeveloper if (delta < 1.0) { 16088e430cbSbeveloper // upsample 16188e430cbSbeveloper while (count--) { 162*a9cf57cfSAxel Dörfler *(float *)dest = *(const int32 *)src * gain; 163*a9cf57cfSAxel Dörfler dest += destSampleOffset; 16488e430cbSbeveloper current += delta; 1656b5e1508Sbeveloper if (current >= 1.0f) { 16688e430cbSbeveloper current -= 1.0f; 167*a9cf57cfSAxel Dörfler src += srcSampleOffset; 16888e430cbSbeveloper } 16988e430cbSbeveloper } 17088e430cbSbeveloper } else { 17188e430cbSbeveloper // downsample 17288e430cbSbeveloper while (count--) { 173*a9cf57cfSAxel Dörfler *(float *)dest = *(const int32 *)src * gain; 174*a9cf57cfSAxel Dörfler dest += destSampleOffset; 1756b5e1508Sbeveloper current += delta; 1766b5e1508Sbeveloper register int32 skipcount = (int32)current; 1776b5e1508Sbeveloper current -= skipcount; 178*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 17988e430cbSbeveloper } 18088e430cbSbeveloper } 181575526ffSbeveloper } 182575526ffSbeveloper 183*a9cf57cfSAxel Dörfler 184575526ffSbeveloper void 185*a9cf57cfSAxel Dörfler Resampler::int16_to_float(const void *_src, int32 srcSampleOffset, 186*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 187*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 188575526ffSbeveloper { 18988e430cbSbeveloper register const char * src = (const char *)_src; 190*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 191*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 19288e430cbSbeveloper register float gain = _gain / 32767.0; 19388e430cbSbeveloper 194*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 19588e430cbSbeveloper // optimized case for no resampling 19688e430cbSbeveloper while (count--) { 197*a9cf57cfSAxel Dörfler *(float *)dest = *(const int16 *)src * gain; 198*a9cf57cfSAxel Dörfler src += srcSampleOffset; 199*a9cf57cfSAxel Dörfler dest += destSampleOffset; 20088e430cbSbeveloper } 20188e430cbSbeveloper return; 20288e430cbSbeveloper } 20388e430cbSbeveloper 204*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 20588e430cbSbeveloper register float current = 0.0f; 20688e430cbSbeveloper 20788e430cbSbeveloper if (delta < 1.0) { 20888e430cbSbeveloper // upsample 20988e430cbSbeveloper while (count--) { 210*a9cf57cfSAxel Dörfler *(float *)dest = *(const int16 *)src * gain; 211*a9cf57cfSAxel Dörfler dest += destSampleOffset; 21288e430cbSbeveloper current += delta; 2136b5e1508Sbeveloper if (current >= 1.0f) { 21488e430cbSbeveloper current -= 1.0f; 215*a9cf57cfSAxel Dörfler src += srcSampleOffset; 21688e430cbSbeveloper } 21788e430cbSbeveloper } 21888e430cbSbeveloper } else { 21988e430cbSbeveloper // downsample 22088e430cbSbeveloper while (count--) { 221*a9cf57cfSAxel Dörfler *(float *)dest = *(const int16 *)src * gain; 222*a9cf57cfSAxel Dörfler dest += destSampleOffset; 2236b5e1508Sbeveloper current += delta; 2246b5e1508Sbeveloper register int32 skipcount = (int32)current; 2256b5e1508Sbeveloper current -= skipcount; 226*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 22788e430cbSbeveloper } 22888e430cbSbeveloper } 229575526ffSbeveloper } 230575526ffSbeveloper 231*a9cf57cfSAxel Dörfler 232575526ffSbeveloper void 233*a9cf57cfSAxel Dörfler Resampler::int8_to_float(const void *_src, int32 srcSampleOffset, 234*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 235*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 236575526ffSbeveloper { 23788e430cbSbeveloper register const char * src = (const char *)_src; 238*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 239*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 24088e430cbSbeveloper register float gain = _gain / 127.0; 24188e430cbSbeveloper 242*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 24388e430cbSbeveloper // optimized case for no resampling 24488e430cbSbeveloper while (count--) { 245*a9cf57cfSAxel Dörfler *(float *)dest = *(const int8 *)src * gain; 246*a9cf57cfSAxel Dörfler src += srcSampleOffset; 247*a9cf57cfSAxel Dörfler dest += destSampleOffset; 24888e430cbSbeveloper } 24988e430cbSbeveloper return; 25088e430cbSbeveloper } 25188e430cbSbeveloper 252*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 25388e430cbSbeveloper register float current = 0.0f; 25488e430cbSbeveloper 25588e430cbSbeveloper if (delta < 1.0) { 25688e430cbSbeveloper // upsample 25788e430cbSbeveloper while (count--) { 258*a9cf57cfSAxel Dörfler *(float *)dest = *(const int8 *)src * gain; 259*a9cf57cfSAxel Dörfler dest += destSampleOffset; 26088e430cbSbeveloper current += delta; 2616b5e1508Sbeveloper if (current >= 1.0f) { 26288e430cbSbeveloper current -= 1.0f; 263*a9cf57cfSAxel Dörfler src += srcSampleOffset; 26488e430cbSbeveloper } 26588e430cbSbeveloper } 26688e430cbSbeveloper } else { 26788e430cbSbeveloper // downsample 26888e430cbSbeveloper while (count--) { 269*a9cf57cfSAxel Dörfler *(float *)dest = *(const int8 *)src * gain; 270*a9cf57cfSAxel Dörfler dest += destSampleOffset; 2716b5e1508Sbeveloper current += delta; 2726b5e1508Sbeveloper register int32 skipcount = (int32)current; 2736b5e1508Sbeveloper current -= skipcount; 274*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 27588e430cbSbeveloper } 27688e430cbSbeveloper } 277575526ffSbeveloper } 278575526ffSbeveloper 279*a9cf57cfSAxel Dörfler 280575526ffSbeveloper void 281*a9cf57cfSAxel Dörfler Resampler::uint8_to_float(const void *_src, int32 srcSampleOffset, 282*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 283*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 284575526ffSbeveloper { 28588e430cbSbeveloper register const char * src = (const char *)_src; 286*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 287*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 28888e430cbSbeveloper register float gain = _gain / 127.0; 28988e430cbSbeveloper 290*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 29188e430cbSbeveloper // optimized case for no resampling 29288e430cbSbeveloper while (count--) { 293*a9cf57cfSAxel Dörfler *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; 294*a9cf57cfSAxel Dörfler src += srcSampleOffset; 295*a9cf57cfSAxel Dörfler dest += destSampleOffset; 29688e430cbSbeveloper } 29788e430cbSbeveloper return; 29888e430cbSbeveloper } 29988e430cbSbeveloper 300*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 30188e430cbSbeveloper register float current = 0.0f; 30288e430cbSbeveloper 30388e430cbSbeveloper if (delta < 1.0) { 30488e430cbSbeveloper // upsample 30588e430cbSbeveloper while (count--) { 306*a9cf57cfSAxel Dörfler *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; 307*a9cf57cfSAxel Dörfler dest += destSampleOffset; 30888e430cbSbeveloper current += delta; 3096b5e1508Sbeveloper if (current >= 1.0f) { 31088e430cbSbeveloper current -= 1.0f; 311*a9cf57cfSAxel Dörfler src += srcSampleOffset; 31288e430cbSbeveloper } 31388e430cbSbeveloper } 31488e430cbSbeveloper } else { 31588e430cbSbeveloper // downsample 31688e430cbSbeveloper while (count--) { 317*a9cf57cfSAxel Dörfler *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; 318*a9cf57cfSAxel Dörfler dest += destSampleOffset; 3196b5e1508Sbeveloper current += delta; 3206b5e1508Sbeveloper register int32 skipcount = (int32)current; 3216b5e1508Sbeveloper current -= skipcount; 322*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 32388e430cbSbeveloper } 32488e430cbSbeveloper } 325575526ffSbeveloper } 326575526ffSbeveloper 327*a9cf57cfSAxel Dörfler 328575526ffSbeveloper void 329*a9cf57cfSAxel Dörfler Resampler::float_to_int32(const void *_src, int32 srcSampleOffset, 330*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 331*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 332575526ffSbeveloper { 3339b875fbaSbeveloper register const char * src = (const char *)_src; 334*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 335*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 3369b875fbaSbeveloper register float gain = _gain * 2147483647.0; 3379b875fbaSbeveloper 338*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 3399b875fbaSbeveloper // optimized case for no resampling 3409b875fbaSbeveloper while (count--) { 3419b875fbaSbeveloper register float sample = *(const float *)src * gain; 3429b875fbaSbeveloper if (sample > 2147483647.0f) 343*a9cf57cfSAxel Dörfler *(int32 *)dest = 2147483647L; 3449b875fbaSbeveloper else if (sample < -2147483647.0f) 345*a9cf57cfSAxel Dörfler *(int32 *)dest = -2147483647L; 3469b875fbaSbeveloper else 347*a9cf57cfSAxel Dörfler *(int32 *)dest = (int32)sample; 348*a9cf57cfSAxel Dörfler src += srcSampleOffset; 349*a9cf57cfSAxel Dörfler dest += destSampleOffset; 3509b875fbaSbeveloper } 3519b875fbaSbeveloper return; 3529b875fbaSbeveloper } 3539b875fbaSbeveloper 354*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 3559b875fbaSbeveloper register float current = 0.0f; 3569b875fbaSbeveloper 3579b875fbaSbeveloper if (delta < 1.0) { 3589b875fbaSbeveloper // upsample 3599b875fbaSbeveloper while (count--) { 3609b875fbaSbeveloper register float sample = *(const float *)src * gain; 3619b875fbaSbeveloper if (sample > 2147483647.0f) 362*a9cf57cfSAxel Dörfler *(int32 *)dest = 2147483647L; 3639b875fbaSbeveloper else if (sample < -2147483647.0f) 364*a9cf57cfSAxel Dörfler *(int32 *)dest = -2147483647L; 3659b875fbaSbeveloper else 366*a9cf57cfSAxel Dörfler *(int32 *)dest = (int32)sample; 367*a9cf57cfSAxel Dörfler dest += destSampleOffset; 3689b875fbaSbeveloper current += delta; 3696b5e1508Sbeveloper if (current >= 1.0f) { 3709b875fbaSbeveloper current -= 1.0f; 371*a9cf57cfSAxel Dörfler src += srcSampleOffset; 3729b875fbaSbeveloper } 3739b875fbaSbeveloper } 3749b875fbaSbeveloper } else { 3759b875fbaSbeveloper // downsample 3769b875fbaSbeveloper while (count--) { 3779b875fbaSbeveloper register float sample = *(const float *)src * gain; 3789b875fbaSbeveloper if (sample > 2147483647.0f) 379*a9cf57cfSAxel Dörfler *(int32 *)dest = 2147483647L; 3809b875fbaSbeveloper else if (sample < -2147483647.0f) 381*a9cf57cfSAxel Dörfler *(int32 *)dest = -2147483647L; 3829b875fbaSbeveloper else 383*a9cf57cfSAxel Dörfler *(int32 *)dest = (int32)sample; 384*a9cf57cfSAxel Dörfler dest += destSampleOffset; 3856b5e1508Sbeveloper current += delta; 3866b5e1508Sbeveloper register int32 skipcount = (int32)current; 3876b5e1508Sbeveloper current -= skipcount; 388*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 3899b875fbaSbeveloper } 3909b875fbaSbeveloper } 391575526ffSbeveloper } 392575526ffSbeveloper 393ff14d245SJérôme Duval 394ff14d245SJérôme Duval void 395*a9cf57cfSAxel Dörfler Resampler::float_to_int16(const void *_src, int32 srcSampleOffset, 396*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 397*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 398575526ffSbeveloper { 3999b875fbaSbeveloper register const char * src = (const char *)_src; 400*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 401*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 4029b875fbaSbeveloper register float gain = _gain * 32767.0; 4039b875fbaSbeveloper 404*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 4059b875fbaSbeveloper // optimized case for no resampling 4069b875fbaSbeveloper while (count--) { 4079b875fbaSbeveloper register float sample = *(const float *)src * gain; 4089b875fbaSbeveloper if (sample > 32767.0f) 409*a9cf57cfSAxel Dörfler *(int16 *)dest = 32767; 4109b875fbaSbeveloper else if (sample < -32767.0f) 411*a9cf57cfSAxel Dörfler *(int16 *)dest = -32767; 4129b875fbaSbeveloper else 413*a9cf57cfSAxel Dörfler *(int16 *)dest = (int16)sample; 414*a9cf57cfSAxel Dörfler src += srcSampleOffset; 415*a9cf57cfSAxel Dörfler dest += destSampleOffset; 4169b875fbaSbeveloper } 4179b875fbaSbeveloper return; 4189b875fbaSbeveloper } 4199b875fbaSbeveloper 420*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 4219b875fbaSbeveloper register float current = 0.0f; 4229b875fbaSbeveloper 4239b875fbaSbeveloper if (delta < 1.0) { 4249b875fbaSbeveloper // upsample 4259b875fbaSbeveloper while (count--) { 4269b875fbaSbeveloper register float sample = *(const float *)src * gain; 4279b875fbaSbeveloper if (sample > 32767.0f) 428*a9cf57cfSAxel Dörfler *(int16 *)dest = 32767; 4299b875fbaSbeveloper else if (sample < -32767.0f) 430*a9cf57cfSAxel Dörfler *(int16 *)dest = -32767; 4319b875fbaSbeveloper else 432*a9cf57cfSAxel Dörfler *(int16 *)dest = (int16)sample; 433*a9cf57cfSAxel Dörfler dest += destSampleOffset; 4349b875fbaSbeveloper current += delta; 4356b5e1508Sbeveloper if (current >= 1.0f) { 4369b875fbaSbeveloper current -= 1.0f; 437*a9cf57cfSAxel Dörfler src += srcSampleOffset; 4389b875fbaSbeveloper } 4399b875fbaSbeveloper } 4409b875fbaSbeveloper } else { 4419b875fbaSbeveloper // downsample 4429b875fbaSbeveloper while (count--) { 4439b875fbaSbeveloper register float sample = *(const float *)src * gain; 4449b875fbaSbeveloper if (sample > 32767.0f) 445*a9cf57cfSAxel Dörfler *(int16 *)dest = 32767; 4469b875fbaSbeveloper else if (sample < -32767.0f) 447*a9cf57cfSAxel Dörfler *(int16 *)dest = -32767; 4489b875fbaSbeveloper else 449*a9cf57cfSAxel Dörfler *(int16 *)dest = (int16)sample; 450*a9cf57cfSAxel Dörfler dest += destSampleOffset; 4516b5e1508Sbeveloper current += delta; 4526b5e1508Sbeveloper register int32 skipcount = (int32)current; 4536b5e1508Sbeveloper current -= skipcount; 454*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 4559b875fbaSbeveloper } 4569b875fbaSbeveloper } 457575526ffSbeveloper } 458575526ffSbeveloper 459*a9cf57cfSAxel Dörfler 460575526ffSbeveloper void 461*a9cf57cfSAxel Dörfler Resampler::float_to_int8(const void *_src, int32 srcSampleOffset, 462*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 463*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 464575526ffSbeveloper { 4659b875fbaSbeveloper register const char * src = (const char *)_src; 466*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 467*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 4689b875fbaSbeveloper register float gain = _gain * 127.0; 4699b875fbaSbeveloper 470*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 4719b875fbaSbeveloper // optimized case for no resampling 4729b875fbaSbeveloper while (count--) { 4739b875fbaSbeveloper register float sample = *(const float *)src * gain; 4749b875fbaSbeveloper if (sample > 127.0f) 475*a9cf57cfSAxel Dörfler *(int8 *)dest = 127; 4769b875fbaSbeveloper else if (sample < -127.0f) 477*a9cf57cfSAxel Dörfler *(int8 *)dest = -127; 4789b875fbaSbeveloper else 479*a9cf57cfSAxel Dörfler *(int8 *)dest = (int8)sample; 480*a9cf57cfSAxel Dörfler src += srcSampleOffset; 481*a9cf57cfSAxel Dörfler dest += destSampleOffset; 4829b875fbaSbeveloper } 4839b875fbaSbeveloper return; 4849b875fbaSbeveloper } 4859b875fbaSbeveloper 486*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 4879b875fbaSbeveloper register float current = 0.0f; 4889b875fbaSbeveloper 4899b875fbaSbeveloper if (delta < 1.0) { 4909b875fbaSbeveloper // upsample 4919b875fbaSbeveloper while (count--) { 4929b875fbaSbeveloper register float sample = *(const float *)src * gain; 4939b875fbaSbeveloper if (sample > 127.0f) 494*a9cf57cfSAxel Dörfler *(int8 *)dest = 127; 4959b875fbaSbeveloper else if (sample < -127.0f) 496*a9cf57cfSAxel Dörfler *(int8 *)dest = -127; 4979b875fbaSbeveloper else 498*a9cf57cfSAxel Dörfler *(int8 *)dest = (int8)sample; 499*a9cf57cfSAxel Dörfler dest += destSampleOffset; 5009b875fbaSbeveloper current += delta; 5016b5e1508Sbeveloper if (current >= 1.0f) { 5029b875fbaSbeveloper current -= 1.0f; 503*a9cf57cfSAxel Dörfler src += srcSampleOffset; 5049b875fbaSbeveloper } 5059b875fbaSbeveloper } 5069b875fbaSbeveloper } else { 5079b875fbaSbeveloper // downsample 5089b875fbaSbeveloper while (count--) { 5099b875fbaSbeveloper register float sample = *(const float *)src * gain; 5109b875fbaSbeveloper if (sample > 127.0f) 511*a9cf57cfSAxel Dörfler *(int8 *)dest = 127; 5129b875fbaSbeveloper else if (sample < -127.0f) 513*a9cf57cfSAxel Dörfler *(int8 *)dest = -127; 5149b875fbaSbeveloper else 515*a9cf57cfSAxel Dörfler *(int8 *)dest = (int8)sample; 516*a9cf57cfSAxel Dörfler dest += destSampleOffset; 5176b5e1508Sbeveloper current += delta; 5186b5e1508Sbeveloper register int32 skipcount = (int32)current; 5196b5e1508Sbeveloper current -= skipcount; 520*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 5219b875fbaSbeveloper } 5229b875fbaSbeveloper } 523575526ffSbeveloper } 524575526ffSbeveloper 525*a9cf57cfSAxel Dörfler 526575526ffSbeveloper void 527*a9cf57cfSAxel Dörfler Resampler::float_to_uint8(const void *_src, int32 srcSampleOffset, 528*a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 529*a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 530575526ffSbeveloper { 5319b875fbaSbeveloper register const char * src = (const char *)_src; 532*a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 533*a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 5349b875fbaSbeveloper register float gain = _gain * 127.0; 5359b875fbaSbeveloper 536*a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 5379b875fbaSbeveloper // optimized case for no resampling 5389b875fbaSbeveloper while (count--) { 5399b875fbaSbeveloper register float sample = 128.0f + *(const float *)src * gain; 5409b875fbaSbeveloper if (sample > 255.0f) 541*a9cf57cfSAxel Dörfler *(uint8 *)dest = 255; 5429b875fbaSbeveloper else if (sample < 1.0f) 543*a9cf57cfSAxel Dörfler *(uint8 *)dest = 1; 5449b875fbaSbeveloper else 545*a9cf57cfSAxel Dörfler *(uint8 *)dest = (uint8)sample; 546*a9cf57cfSAxel Dörfler src += srcSampleOffset; 547*a9cf57cfSAxel Dörfler dest += destSampleOffset; 548575526ffSbeveloper } 5499b875fbaSbeveloper return; 5509b875fbaSbeveloper } 5519b875fbaSbeveloper 552*a9cf57cfSAxel Dörfler register float delta = float(srcSampleCount) / float(destSampleCount); 5539b875fbaSbeveloper register float current = 0.0f; 5549b875fbaSbeveloper 5559b875fbaSbeveloper if (delta < 1.0) { 5569b875fbaSbeveloper // upsample 5579b875fbaSbeveloper while (count--) { 5589b875fbaSbeveloper register float sample = 128.0f + *(const float *)src * gain; 5599b875fbaSbeveloper if (sample > 255.0f) 560*a9cf57cfSAxel Dörfler *(uint8 *)dest = 255; 5619b875fbaSbeveloper else if (sample < 1.0f) 562*a9cf57cfSAxel Dörfler *(uint8 *)dest = 1; 5639b875fbaSbeveloper else 564*a9cf57cfSAxel Dörfler *(uint8 *)dest = (uint8)sample; 565*a9cf57cfSAxel Dörfler dest += destSampleOffset; 5669b875fbaSbeveloper current += delta; 5676b5e1508Sbeveloper if (current >= 1.0f) { 5689b875fbaSbeveloper current -= 1.0f; 569*a9cf57cfSAxel Dörfler src += srcSampleOffset; 5709b875fbaSbeveloper } 5719b875fbaSbeveloper } 5729b875fbaSbeveloper } else { 5739b875fbaSbeveloper // downsample 5749b875fbaSbeveloper while (count--) { 5759b875fbaSbeveloper register float sample = 128.0f + *(const float *)src * gain; 5769b875fbaSbeveloper if (sample > 255.0f) 577*a9cf57cfSAxel Dörfler *(uint8 *)dest = 255; 5789b875fbaSbeveloper else if (sample < 1.0f) 579*a9cf57cfSAxel Dörfler *(uint8 *)dest = 1; 5809b875fbaSbeveloper else 581*a9cf57cfSAxel Dörfler *(uint8 *)dest = (uint8)sample; 582*a9cf57cfSAxel Dörfler dest += destSampleOffset; 5836b5e1508Sbeveloper current += delta; 5846b5e1508Sbeveloper register int32 skipcount = (int32)current; 5856b5e1508Sbeveloper current -= skipcount; 586*a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 5879b875fbaSbeveloper } 5889b875fbaSbeveloper } 5899b875fbaSbeveloper } 590