1a9cf57cfSAxel Dörfler /* 2a9cf57cfSAxel Dörfler * Copyright 2003 Marcus Overhagen 3a9cf57cfSAxel Dörfler * Distributed under the terms of the MIT License. 4575526ffSbeveloper */ 5575526ffSbeveloper 6a9cf57cfSAxel Dörfler 7575526ffSbeveloper #include "Resampler.h" 8a9cf57cfSAxel Dörfler 9a9cf57cfSAxel Dörfler #include <MediaDefs.h> 10a9cf57cfSAxel Dörfler 11f916862cSMarcus Overhagen #include "MixerDebug.h" 12575526ffSbeveloper 13a9cf57cfSAxel Dörfler 14a9cf57cfSAxel Dörfler /*! A simple resampling class for the audio mixer. 15a9cf57cfSAxel Dörfler You pick the conversion function on object creation, 16a9cf57cfSAxel Dörfler and then call the Resample() function, specifying data pointer, 17a9cf57cfSAxel Dörfler offset (in bytes) to the next sample, and count of samples for 18a9cf57cfSAxel Dörfler both source and destination. 19a9cf57cfSAxel Dörfler */ 20a9cf57cfSAxel Dörfler 21a9cf57cfSAxel Dörfler 22f0a85f97SJérôme Duval Resampler::Resampler(uint32 src_format, uint32 dst_format) 23a9cf57cfSAxel Dörfler : 24*78341a93SJohn Scipione 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: 44a9cf57cfSAxel Dörfler ERROR("Resampler::Resampler: unknown source format 0x%x\n", 45a9cf57cfSAxel 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 71a9cf57cfSAxel Dörfler ERROR("Resampler::Resampler: source or destination format must be " 72a9cf57cfSAxel Dörfler "B_AUDIO_FLOAT\n"); 73575526ffSbeveloper } 74575526ffSbeveloper 75a9cf57cfSAxel Dörfler 76575526ffSbeveloper Resampler::~Resampler() 77575526ffSbeveloper { 78575526ffSbeveloper } 79575526ffSbeveloper 80a9cf57cfSAxel Dörfler 81575526ffSbeveloper status_t 82a9cf57cfSAxel Dörfler Resampler::InitCheck() const 83575526ffSbeveloper { 84*78341a93SJohn Scipione return fFunc != 0 ? B_OK : B_ERROR; 85575526ffSbeveloper } 86575526ffSbeveloper 87a9cf57cfSAxel Dörfler 88575526ffSbeveloper void 89a9cf57cfSAxel Dörfler Resampler::float_to_float(const void *_src, int32 srcSampleOffset, 90a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 91a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 927ca83dacSbeveloper { 937ca83dacSbeveloper register const char * src = (const char *)_src; 94a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 95a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 967ca83dacSbeveloper register float gain = _gain; 977ca83dacSbeveloper 98a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 997ca83dacSbeveloper // optimized case for no resampling 1007ca83dacSbeveloper while (count--) { 101a9cf57cfSAxel Dörfler *(float *)dest = *(const float *)src * gain; 102a9cf57cfSAxel Dörfler src += srcSampleOffset; 103a9cf57cfSAxel Dörfler dest += destSampleOffset; 1047ca83dacSbeveloper } 1057ca83dacSbeveloper return; 1067ca83dacSbeveloper } 1077ca83dacSbeveloper 108a9cf57cfSAxel 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--) { 114a9cf57cfSAxel Dörfler *(float *)dest = *(const float *)src * gain; 115a9cf57cfSAxel Dörfler dest += destSampleOffset; 1167ca83dacSbeveloper current += delta; 1176b5e1508Sbeveloper if (current >= 1.0f) { 1187ca83dacSbeveloper current -= 1.0f; 119a9cf57cfSAxel Dörfler src += srcSampleOffset; 1207ca83dacSbeveloper } 1217ca83dacSbeveloper } 1227ca83dacSbeveloper } else { 1237ca83dacSbeveloper // downsample 1247ca83dacSbeveloper while (count--) { 125a9cf57cfSAxel Dörfler *(float *)dest = *(const float *)src * gain; 126a9cf57cfSAxel Dörfler dest += destSampleOffset; 1276b5e1508Sbeveloper current += delta; 1286b5e1508Sbeveloper register int32 skipcount = (int32)current; 1296b5e1508Sbeveloper current -= skipcount; 130a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 1317ca83dacSbeveloper } 1327ca83dacSbeveloper } 1337ca83dacSbeveloper } 1347ca83dacSbeveloper 135a9cf57cfSAxel Dörfler 1367ca83dacSbeveloper void 137a9cf57cfSAxel Dörfler Resampler::int32_to_float(const void *_src, int32 srcSampleOffset, 138a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 139a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 140575526ffSbeveloper { 14188e430cbSbeveloper register const char * src = (const char *)_src; 142a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 143a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 14488e430cbSbeveloper register float gain = _gain / 2147483647.0; 14588e430cbSbeveloper 146a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 14788e430cbSbeveloper // optimized case for no resampling 14888e430cbSbeveloper while (count--) { 149a9cf57cfSAxel Dörfler *(float *)dest = *(const int32 *)src * gain; 150a9cf57cfSAxel Dörfler src += srcSampleOffset; 151a9cf57cfSAxel Dörfler dest += destSampleOffset; 15288e430cbSbeveloper } 15388e430cbSbeveloper return; 15488e430cbSbeveloper } 15588e430cbSbeveloper 156a9cf57cfSAxel 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--) { 162a9cf57cfSAxel Dörfler *(float *)dest = *(const int32 *)src * gain; 163a9cf57cfSAxel Dörfler dest += destSampleOffset; 16488e430cbSbeveloper current += delta; 1656b5e1508Sbeveloper if (current >= 1.0f) { 16688e430cbSbeveloper current -= 1.0f; 167a9cf57cfSAxel Dörfler src += srcSampleOffset; 16888e430cbSbeveloper } 16988e430cbSbeveloper } 17088e430cbSbeveloper } else { 17188e430cbSbeveloper // downsample 17288e430cbSbeveloper while (count--) { 173a9cf57cfSAxel Dörfler *(float *)dest = *(const int32 *)src * gain; 174a9cf57cfSAxel Dörfler dest += destSampleOffset; 1756b5e1508Sbeveloper current += delta; 1766b5e1508Sbeveloper register int32 skipcount = (int32)current; 1776b5e1508Sbeveloper current -= skipcount; 178a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 17988e430cbSbeveloper } 18088e430cbSbeveloper } 181575526ffSbeveloper } 182575526ffSbeveloper 183a9cf57cfSAxel Dörfler 184575526ffSbeveloper void 185a9cf57cfSAxel Dörfler Resampler::int16_to_float(const void *_src, int32 srcSampleOffset, 186a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 187a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 188575526ffSbeveloper { 18988e430cbSbeveloper register const char * src = (const char *)_src; 190a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 191a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 19288e430cbSbeveloper register float gain = _gain / 32767.0; 19388e430cbSbeveloper 194a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 19588e430cbSbeveloper // optimized case for no resampling 19688e430cbSbeveloper while (count--) { 197a9cf57cfSAxel Dörfler *(float *)dest = *(const int16 *)src * gain; 198a9cf57cfSAxel Dörfler src += srcSampleOffset; 199a9cf57cfSAxel Dörfler dest += destSampleOffset; 20088e430cbSbeveloper } 20188e430cbSbeveloper return; 20288e430cbSbeveloper } 20388e430cbSbeveloper 204a9cf57cfSAxel 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--) { 210a9cf57cfSAxel Dörfler *(float *)dest = *(const int16 *)src * gain; 211a9cf57cfSAxel Dörfler dest += destSampleOffset; 21288e430cbSbeveloper current += delta; 2136b5e1508Sbeveloper if (current >= 1.0f) { 21488e430cbSbeveloper current -= 1.0f; 215a9cf57cfSAxel Dörfler src += srcSampleOffset; 21688e430cbSbeveloper } 21788e430cbSbeveloper } 21888e430cbSbeveloper } else { 21988e430cbSbeveloper // downsample 22088e430cbSbeveloper while (count--) { 221a9cf57cfSAxel Dörfler *(float *)dest = *(const int16 *)src * gain; 222a9cf57cfSAxel Dörfler dest += destSampleOffset; 2236b5e1508Sbeveloper current += delta; 2246b5e1508Sbeveloper register int32 skipcount = (int32)current; 2256b5e1508Sbeveloper current -= skipcount; 226a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 22788e430cbSbeveloper } 22888e430cbSbeveloper } 229575526ffSbeveloper } 230575526ffSbeveloper 231a9cf57cfSAxel Dörfler 232575526ffSbeveloper void 233a9cf57cfSAxel Dörfler Resampler::int8_to_float(const void *_src, int32 srcSampleOffset, 234a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 235a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 236575526ffSbeveloper { 23788e430cbSbeveloper register const char * src = (const char *)_src; 238a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 239a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 24088e430cbSbeveloper register float gain = _gain / 127.0; 24188e430cbSbeveloper 242a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 24388e430cbSbeveloper // optimized case for no resampling 24488e430cbSbeveloper while (count--) { 245a9cf57cfSAxel Dörfler *(float *)dest = *(const int8 *)src * gain; 246a9cf57cfSAxel Dörfler src += srcSampleOffset; 247a9cf57cfSAxel Dörfler dest += destSampleOffset; 24888e430cbSbeveloper } 24988e430cbSbeveloper return; 25088e430cbSbeveloper } 25188e430cbSbeveloper 252a9cf57cfSAxel 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--) { 258a9cf57cfSAxel Dörfler *(float *)dest = *(const int8 *)src * gain; 259a9cf57cfSAxel Dörfler dest += destSampleOffset; 26088e430cbSbeveloper current += delta; 2616b5e1508Sbeveloper if (current >= 1.0f) { 26288e430cbSbeveloper current -= 1.0f; 263a9cf57cfSAxel Dörfler src += srcSampleOffset; 26488e430cbSbeveloper } 26588e430cbSbeveloper } 26688e430cbSbeveloper } else { 26788e430cbSbeveloper // downsample 26888e430cbSbeveloper while (count--) { 269a9cf57cfSAxel Dörfler *(float *)dest = *(const int8 *)src * gain; 270a9cf57cfSAxel Dörfler dest += destSampleOffset; 2716b5e1508Sbeveloper current += delta; 2726b5e1508Sbeveloper register int32 skipcount = (int32)current; 2736b5e1508Sbeveloper current -= skipcount; 274a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 27588e430cbSbeveloper } 27688e430cbSbeveloper } 277575526ffSbeveloper } 278575526ffSbeveloper 279a9cf57cfSAxel Dörfler 280575526ffSbeveloper void 281a9cf57cfSAxel Dörfler Resampler::uint8_to_float(const void *_src, int32 srcSampleOffset, 282a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 283a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 284575526ffSbeveloper { 28588e430cbSbeveloper register const char * src = (const char *)_src; 286a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 287a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 28888e430cbSbeveloper register float gain = _gain / 127.0; 28988e430cbSbeveloper 290a9cf57cfSAxel Dörfler if (srcSampleCount == destSampleCount) { 29188e430cbSbeveloper // optimized case for no resampling 29288e430cbSbeveloper while (count--) { 293a9cf57cfSAxel Dörfler *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; 294a9cf57cfSAxel Dörfler src += srcSampleOffset; 295a9cf57cfSAxel Dörfler dest += destSampleOffset; 29688e430cbSbeveloper } 29788e430cbSbeveloper return; 29888e430cbSbeveloper } 29988e430cbSbeveloper 300a9cf57cfSAxel 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--) { 306a9cf57cfSAxel Dörfler *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; 307a9cf57cfSAxel Dörfler dest += destSampleOffset; 30888e430cbSbeveloper current += delta; 3096b5e1508Sbeveloper if (current >= 1.0f) { 31088e430cbSbeveloper current -= 1.0f; 311a9cf57cfSAxel Dörfler src += srcSampleOffset; 31288e430cbSbeveloper } 31388e430cbSbeveloper } 31488e430cbSbeveloper } else { 31588e430cbSbeveloper // downsample 31688e430cbSbeveloper while (count--) { 317a9cf57cfSAxel Dörfler *(float *)dest = (((int32) *(const uint8 *)src) - 128) * gain; 318a9cf57cfSAxel Dörfler dest += destSampleOffset; 3196b5e1508Sbeveloper current += delta; 3206b5e1508Sbeveloper register int32 skipcount = (int32)current; 3216b5e1508Sbeveloper current -= skipcount; 322a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 32388e430cbSbeveloper } 32488e430cbSbeveloper } 325575526ffSbeveloper } 326575526ffSbeveloper 327a9cf57cfSAxel Dörfler 328575526ffSbeveloper void 329a9cf57cfSAxel Dörfler Resampler::float_to_int32(const void *_src, int32 srcSampleOffset, 330a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 331a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 332575526ffSbeveloper { 3339b875fbaSbeveloper register const char * src = (const char *)_src; 334a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 335a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 3369b875fbaSbeveloper register float gain = _gain * 2147483647.0; 3379b875fbaSbeveloper 338a9cf57cfSAxel 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) 343a9cf57cfSAxel Dörfler *(int32 *)dest = 2147483647L; 3449b875fbaSbeveloper else if (sample < -2147483647.0f) 345a9cf57cfSAxel Dörfler *(int32 *)dest = -2147483647L; 3469b875fbaSbeveloper else 347a9cf57cfSAxel Dörfler *(int32 *)dest = (int32)sample; 348a9cf57cfSAxel Dörfler src += srcSampleOffset; 349a9cf57cfSAxel Dörfler dest += destSampleOffset; 3509b875fbaSbeveloper } 3519b875fbaSbeveloper return; 3529b875fbaSbeveloper } 3539b875fbaSbeveloper 354a9cf57cfSAxel 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) 362a9cf57cfSAxel Dörfler *(int32 *)dest = 2147483647L; 3639b875fbaSbeveloper else if (sample < -2147483647.0f) 364a9cf57cfSAxel Dörfler *(int32 *)dest = -2147483647L; 3659b875fbaSbeveloper else 366a9cf57cfSAxel Dörfler *(int32 *)dest = (int32)sample; 367a9cf57cfSAxel Dörfler dest += destSampleOffset; 3689b875fbaSbeveloper current += delta; 3696b5e1508Sbeveloper if (current >= 1.0f) { 3709b875fbaSbeveloper current -= 1.0f; 371a9cf57cfSAxel 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) 379a9cf57cfSAxel Dörfler *(int32 *)dest = 2147483647L; 3809b875fbaSbeveloper else if (sample < -2147483647.0f) 381a9cf57cfSAxel Dörfler *(int32 *)dest = -2147483647L; 3829b875fbaSbeveloper else 383a9cf57cfSAxel Dörfler *(int32 *)dest = (int32)sample; 384a9cf57cfSAxel Dörfler dest += destSampleOffset; 3856b5e1508Sbeveloper current += delta; 3866b5e1508Sbeveloper register int32 skipcount = (int32)current; 3876b5e1508Sbeveloper current -= skipcount; 388a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 3899b875fbaSbeveloper } 3909b875fbaSbeveloper } 391575526ffSbeveloper } 392575526ffSbeveloper 393ff14d245SJérôme Duval 394ff14d245SJérôme Duval void 395a9cf57cfSAxel Dörfler Resampler::float_to_int16(const void *_src, int32 srcSampleOffset, 396a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 397a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 398575526ffSbeveloper { 3999b875fbaSbeveloper register const char * src = (const char *)_src; 400a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 401a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 4029b875fbaSbeveloper register float gain = _gain * 32767.0; 4039b875fbaSbeveloper 404a9cf57cfSAxel 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) 409a9cf57cfSAxel Dörfler *(int16 *)dest = 32767; 4109b875fbaSbeveloper else if (sample < -32767.0f) 411a9cf57cfSAxel Dörfler *(int16 *)dest = -32767; 4129b875fbaSbeveloper else 413a9cf57cfSAxel Dörfler *(int16 *)dest = (int16)sample; 414a9cf57cfSAxel Dörfler src += srcSampleOffset; 415a9cf57cfSAxel Dörfler dest += destSampleOffset; 4169b875fbaSbeveloper } 4179b875fbaSbeveloper return; 4189b875fbaSbeveloper } 4199b875fbaSbeveloper 420a9cf57cfSAxel 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) 428a9cf57cfSAxel Dörfler *(int16 *)dest = 32767; 4299b875fbaSbeveloper else if (sample < -32767.0f) 430a9cf57cfSAxel Dörfler *(int16 *)dest = -32767; 4319b875fbaSbeveloper else 432a9cf57cfSAxel Dörfler *(int16 *)dest = (int16)sample; 433a9cf57cfSAxel Dörfler dest += destSampleOffset; 4349b875fbaSbeveloper current += delta; 4356b5e1508Sbeveloper if (current >= 1.0f) { 4369b875fbaSbeveloper current -= 1.0f; 437a9cf57cfSAxel 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) 445a9cf57cfSAxel Dörfler *(int16 *)dest = 32767; 4469b875fbaSbeveloper else if (sample < -32767.0f) 447a9cf57cfSAxel Dörfler *(int16 *)dest = -32767; 4489b875fbaSbeveloper else 449a9cf57cfSAxel Dörfler *(int16 *)dest = (int16)sample; 450a9cf57cfSAxel Dörfler dest += destSampleOffset; 4516b5e1508Sbeveloper current += delta; 4526b5e1508Sbeveloper register int32 skipcount = (int32)current; 4536b5e1508Sbeveloper current -= skipcount; 454a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 4559b875fbaSbeveloper } 4569b875fbaSbeveloper } 457575526ffSbeveloper } 458575526ffSbeveloper 459a9cf57cfSAxel Dörfler 460575526ffSbeveloper void 461a9cf57cfSAxel Dörfler Resampler::float_to_int8(const void *_src, int32 srcSampleOffset, 462a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 463a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 464575526ffSbeveloper { 4659b875fbaSbeveloper register const char * src = (const char *)_src; 466a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 467a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 4689b875fbaSbeveloper register float gain = _gain * 127.0; 4699b875fbaSbeveloper 470a9cf57cfSAxel 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) 475a9cf57cfSAxel Dörfler *(int8 *)dest = 127; 4769b875fbaSbeveloper else if (sample < -127.0f) 477a9cf57cfSAxel Dörfler *(int8 *)dest = -127; 4789b875fbaSbeveloper else 479a9cf57cfSAxel Dörfler *(int8 *)dest = (int8)sample; 480a9cf57cfSAxel Dörfler src += srcSampleOffset; 481a9cf57cfSAxel Dörfler dest += destSampleOffset; 4829b875fbaSbeveloper } 4839b875fbaSbeveloper return; 4849b875fbaSbeveloper } 4859b875fbaSbeveloper 486a9cf57cfSAxel 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) 494a9cf57cfSAxel Dörfler *(int8 *)dest = 127; 4959b875fbaSbeveloper else if (sample < -127.0f) 496a9cf57cfSAxel Dörfler *(int8 *)dest = -127; 4979b875fbaSbeveloper else 498a9cf57cfSAxel Dörfler *(int8 *)dest = (int8)sample; 499a9cf57cfSAxel Dörfler dest += destSampleOffset; 5009b875fbaSbeveloper current += delta; 5016b5e1508Sbeveloper if (current >= 1.0f) { 5029b875fbaSbeveloper current -= 1.0f; 503a9cf57cfSAxel 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) 511a9cf57cfSAxel Dörfler *(int8 *)dest = 127; 5129b875fbaSbeveloper else if (sample < -127.0f) 513a9cf57cfSAxel Dörfler *(int8 *)dest = -127; 5149b875fbaSbeveloper else 515a9cf57cfSAxel Dörfler *(int8 *)dest = (int8)sample; 516a9cf57cfSAxel Dörfler dest += destSampleOffset; 5176b5e1508Sbeveloper current += delta; 5186b5e1508Sbeveloper register int32 skipcount = (int32)current; 5196b5e1508Sbeveloper current -= skipcount; 520a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 5219b875fbaSbeveloper } 5229b875fbaSbeveloper } 523575526ffSbeveloper } 524575526ffSbeveloper 525a9cf57cfSAxel Dörfler 526575526ffSbeveloper void 527a9cf57cfSAxel Dörfler Resampler::float_to_uint8(const void *_src, int32 srcSampleOffset, 528a9cf57cfSAxel Dörfler int32 srcSampleCount, void *_dest, int32 destSampleOffset, 529a9cf57cfSAxel Dörfler int32 destSampleCount, float _gain) 530575526ffSbeveloper { 5319b875fbaSbeveloper register const char * src = (const char *)_src; 532a9cf57cfSAxel Dörfler register char * dest = (char *)_dest; 533a9cf57cfSAxel Dörfler register int32 count = destSampleCount; 5349b875fbaSbeveloper register float gain = _gain * 127.0; 5359b875fbaSbeveloper 536a9cf57cfSAxel 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) 541a9cf57cfSAxel Dörfler *(uint8 *)dest = 255; 5429b875fbaSbeveloper else if (sample < 1.0f) 543a9cf57cfSAxel Dörfler *(uint8 *)dest = 1; 5449b875fbaSbeveloper else 545a9cf57cfSAxel Dörfler *(uint8 *)dest = (uint8)sample; 546a9cf57cfSAxel Dörfler src += srcSampleOffset; 547a9cf57cfSAxel Dörfler dest += destSampleOffset; 548575526ffSbeveloper } 5499b875fbaSbeveloper return; 5509b875fbaSbeveloper } 5519b875fbaSbeveloper 552a9cf57cfSAxel 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) 560a9cf57cfSAxel Dörfler *(uint8 *)dest = 255; 5619b875fbaSbeveloper else if (sample < 1.0f) 562a9cf57cfSAxel Dörfler *(uint8 *)dest = 1; 5639b875fbaSbeveloper else 564a9cf57cfSAxel Dörfler *(uint8 *)dest = (uint8)sample; 565a9cf57cfSAxel Dörfler dest += destSampleOffset; 5669b875fbaSbeveloper current += delta; 5676b5e1508Sbeveloper if (current >= 1.0f) { 5689b875fbaSbeveloper current -= 1.0f; 569a9cf57cfSAxel 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) 577a9cf57cfSAxel Dörfler *(uint8 *)dest = 255; 5789b875fbaSbeveloper else if (sample < 1.0f) 579a9cf57cfSAxel Dörfler *(uint8 *)dest = 1; 5809b875fbaSbeveloper else 581a9cf57cfSAxel Dörfler *(uint8 *)dest = (uint8)sample; 582a9cf57cfSAxel Dörfler dest += destSampleOffset; 5836b5e1508Sbeveloper current += delta; 5846b5e1508Sbeveloper register int32 skipcount = (int32)current; 5856b5e1508Sbeveloper current -= skipcount; 586a9cf57cfSAxel Dörfler src += skipcount * srcSampleOffset; 5879b875fbaSbeveloper } 5889b875fbaSbeveloper } 5899b875fbaSbeveloper } 590