| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "Audio/BsAudioUtility.h"
- namespace bs
- {
- void convertToMono8(const INT8* input, UINT8* output, UINT32 numSamples, UINT32 numChannels)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT16 sum = 0;
- for (UINT32 j = 0; j < numChannels; j++)
- {
- sum += *input;
- ++input;
- }
- *output = sum / numChannels;
- ++output;
- }
- }
- void convertToMono16(const INT16* input, INT16* output, UINT32 numSamples, UINT32 numChannels)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT32 sum = 0;
- for (UINT32 j = 0; j < numChannels; j++)
- {
- sum += *input;
- ++input;
- }
- *output = sum / numChannels;
- ++output;
- }
- }
- void convert32To24Bits(const INT32 input, UINT8* output)
- {
- UINT32 valToEncode = *(UINT32*)&input;
- output[0] = (valToEncode >> 8) & 0x000000FF;
- output[1] = (valToEncode >> 16) & 0x000000FF;
- output[2] = (valToEncode >> 24) & 0x000000FF;
- }
- void convertToMono24(const UINT8* input, UINT8* output, UINT32 numSamples, UINT32 numChannels)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT64 sum = 0;
- for (UINT32 j = 0; j < numChannels; j++)
- {
- sum += AudioUtility::convert24To32Bits(input);
- input += 3;
- }
- INT32 avg = (INT32)(sum / numChannels);
- convert32To24Bits(avg, output);
- output += 3;
- }
- }
- void convertToMono32(const INT32* input, INT32* output, UINT32 numSamples, UINT32 numChannels)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT64 sum = 0;
- for (UINT32 j = 0; j < numChannels; j++)
- {
- sum += *input;
- ++input;
- }
- *output = (INT32)(sum / numChannels);
- ++output;
- }
- }
- void convert8To32Bits(const INT8* input, INT32* output, UINT32 numSamples)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT8 val = input[i];
- output[i] = val << 24;
- }
- }
- void convert16To32Bits(const INT16* input, INT32* output, UINT32 numSamples)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- output[i] = input[i] << 16;
- }
- void convert24To32Bits(const UINT8* input, INT32* output, UINT32 numSamples)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- output[i] = AudioUtility::convert24To32Bits(input);
- input += 3;
- }
- }
- void convert32To8Bits(const INT32* input, UINT8* output, UINT32 numSamples)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- output[i] = (INT8)(input[i] >> 24);
- }
- void convert32To16Bits(const INT32* input, INT16* output, UINT32 numSamples)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- output[i] = (INT16)(input[i] >> 16);
- }
- void convert32To24Bits(const INT32* input, UINT8* output, UINT32 numSamples)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- convert32To24Bits(input[i], output);
- output += 3;
- }
- }
- void AudioUtility::convertToMono(const UINT8* input, UINT8* output, UINT32 bitDepth, UINT32 numSamples, UINT32 numChannels)
- {
- switch (bitDepth)
- {
- case 8:
- convertToMono8((INT8*)input, output, numSamples, numChannels);
- break;
- case 16:
- convertToMono16((INT16*)input, (INT16*)output, numSamples, numChannels);
- break;
- case 24:
- convertToMono24(input, output, numSamples, numChannels);
- break;
- case 32:
- convertToMono32((INT32*)input, (INT32*)output, numSamples, numChannels);
- break;
- default:
- assert(false);
- break;
- }
- }
- void AudioUtility::convertBitDepth(const UINT8* input, UINT32 inBitDepth, UINT8* output, UINT32 outBitDepth, UINT32 numSamples)
- {
- INT32* srcBuffer = nullptr;
- bool needTempBuffer = inBitDepth != 32;
- if (needTempBuffer)
- srcBuffer = (INT32*)bs_stack_alloc(numSamples * sizeof(INT32));
- else
- srcBuffer = (INT32*)input;
- // Note: I convert to a temporary 32-bit buffer and then use that to convert to actual requested bit depth.
- // It would be more efficient to convert directly from source to requested depth without a temporary buffer,
- // at the cost of additional complexity. If this method ever becomes a performance issue consider that.
- switch (inBitDepth)
- {
- case 8:
- convert8To32Bits((INT8*)input, srcBuffer, numSamples);
- break;
- case 16:
- convert16To32Bits((INT16*)input, srcBuffer, numSamples);
- break;
- case 24:
- bs::convert24To32Bits(input, srcBuffer, numSamples);
- break;
- case 32:
- // Do nothing
- break;
- default:
- assert(false);
- break;
- }
- switch (outBitDepth)
- {
- case 8:
- convert32To8Bits(srcBuffer, output, numSamples);
- break;
- case 16:
- convert32To16Bits(srcBuffer, (INT16*)output, numSamples);
- break;
- case 24:
- convert32To24Bits(srcBuffer, output, numSamples);
- break;
- case 32:
- memcpy(output, srcBuffer, numSamples * sizeof(INT32));
- break;
- default:
- assert(false);
- break;
- }
- if (needTempBuffer)
- {
- bs_stack_free(srcBuffer);
- srcBuffer = nullptr;
- }
- }
- void AudioUtility::convertToFloat(const UINT8* input, UINT32 inBitDepth, float* output, UINT32 numSamples)
- {
- if (inBitDepth == 8)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT8 sample = *(INT8*)input;
- output[i] = sample / 127.0f;
- input++;
- }
- }
- else if (inBitDepth == 16)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT16 sample = *(INT16*)input;
- output[i] = sample / 32767.0f;
- input += 2;
- }
- }
- else if (inBitDepth == 24)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT32 sample = convert24To32Bits(input);
- output[i] = sample / 2147483647.0f;
- input += 3;
- }
- }
- else if (inBitDepth == 32)
- {
- for (UINT32 i = 0; i < numSamples; i++)
- {
- INT32 sample = *(INT32*)input;
- output[i] = sample / 2147483647.0f;
- input += 4;
- }
- }
- else
- assert(false);
- }
- INT32 AudioUtility::convert24To32Bits(const UINT8* input)
- {
- return (input[2] << 24) | (input[1] << 16) | (input[0] << 8);
- }
- }
|