* Copyright 2012 Jérôme Leveque
* Copyright 2012 Jérôme Duval
* Copyright 2003 Marcus Overhagen
* Distributed under the terms of the MIT License.
*/
#include "Resampler.h"
#include "MultiAudioUtility.h"
#include "debug.h"
You pick the conversion function on object creation,
and then call the Resample() function, specifying data pointer,
offset (in bytes) to the next sample, and count of samples.
*/
Resampler::Resampler(uint32 sourceFormat, uint32 destFormat)
:
fFunc(&Resampler::_Void)
{
PRINT(("Resampler() in 0x%x, out 0x%x\n", (unsigned int)sourceFormat,
(unsigned int)destFormat));
switch (sourceFormat) {
case media_raw_audio_format::B_AUDIO_FLOAT:
switch (destFormat) {
case media_raw_audio_format::B_AUDIO_FLOAT:
fFunc = &Resampler::_CopyFloat2Float;
break;
case media_raw_audio_format::B_AUDIO_DOUBLE:
fFunc = &Resampler::_CopyFloat2Double;
break;
case media_raw_audio_format::B_AUDIO_INT:
fFunc = &Resampler::_CopyFloat2Int;
break;
case media_raw_audio_format::B_AUDIO_SHORT:
fFunc = &Resampler::_CopyFloat2Short;
break;
case media_raw_audio_format::B_AUDIO_UCHAR:
fFunc = &Resampler::_CopyFloat2UChar;
break;
case media_raw_audio_format::B_AUDIO_CHAR:
fFunc = &Resampler::_CopyFloat2Char;
break;
}
break;
case media_raw_audio_format::B_AUDIO_DOUBLE:
switch (destFormat) {
case media_raw_audio_format::B_AUDIO_FLOAT:
fFunc = &Resampler::_CopyDouble2Float;
break;
case media_raw_audio_format::B_AUDIO_DOUBLE:
fFunc = &Resampler::_CopyDouble2Double;
break;
case media_raw_audio_format::B_AUDIO_INT:
fFunc = &Resampler::_CopyDouble2Int;
break;
case media_raw_audio_format::B_AUDIO_SHORT:
fFunc = &Resampler::_CopyDouble2Short;
break;
case media_raw_audio_format::B_AUDIO_UCHAR:
fFunc = &Resampler::_CopyDouble2UChar;
break;
case media_raw_audio_format::B_AUDIO_CHAR:
fFunc = &Resampler::_CopyDouble2Char;
break;
}
break;
case media_raw_audio_format::B_AUDIO_INT:
switch (destFormat) {
case media_raw_audio_format::B_AUDIO_FLOAT:
fFunc = &Resampler::_CopyInt2Float;
break;
case media_raw_audio_format::B_AUDIO_DOUBLE:
fFunc = &Resampler::_CopyInt2Double;
break;
case media_raw_audio_format::B_AUDIO_INT:
fFunc = &Resampler::_CopyInt2Int;
break;
case media_raw_audio_format::B_AUDIO_SHORT:
fFunc = &Resampler::_CopyInt2Short;
break;
case media_raw_audio_format::B_AUDIO_UCHAR:
fFunc = &Resampler::_CopyInt2UChar;
break;
case media_raw_audio_format::B_AUDIO_CHAR:
fFunc = &Resampler::_CopyInt2Char;
break;
}
break;
case media_raw_audio_format::B_AUDIO_SHORT:
switch (destFormat) {
case media_raw_audio_format::B_AUDIO_FLOAT:
fFunc = &Resampler::_CopyShort2Float;
break;
case media_raw_audio_format::B_AUDIO_DOUBLE:
fFunc = &Resampler::_CopyShort2Double;
break;
case media_raw_audio_format::B_AUDIO_INT:
fFunc = &Resampler::_CopyShort2Int;
break;
case media_raw_audio_format::B_AUDIO_SHORT:
fFunc = &Resampler::_CopyShort2Short;
break;
case media_raw_audio_format::B_AUDIO_UCHAR:
fFunc = &Resampler::_CopyShort2UChar;
break;
case media_raw_audio_format::B_AUDIO_CHAR:
fFunc = &Resampler::_CopyShort2Char;
break;
}
break;
case media_raw_audio_format::B_AUDIO_UCHAR:
switch (destFormat) {
case media_raw_audio_format::B_AUDIO_FLOAT:
fFunc = &Resampler::_CopyUChar2Float;
break;
case media_raw_audio_format::B_AUDIO_DOUBLE:
fFunc = &Resampler::_CopyUChar2Double;
break;
case media_raw_audio_format::B_AUDIO_INT:
fFunc = &Resampler::_CopyUChar2Int;
break;
case media_raw_audio_format::B_AUDIO_SHORT:
fFunc = &Resampler::_CopyUChar2Short;
break;
case media_raw_audio_format::B_AUDIO_UCHAR:
fFunc = &Resampler::_CopyUChar2UChar;
break;
case media_raw_audio_format::B_AUDIO_CHAR:
fFunc = &Resampler::_CopyUChar2Char;
break;
}
break;
case media_raw_audio_format::B_AUDIO_CHAR:
switch (destFormat) {
case media_raw_audio_format::B_AUDIO_FLOAT:
fFunc = &Resampler::_CopyChar2Float;
break;
case media_raw_audio_format::B_AUDIO_DOUBLE:
fFunc = &Resampler::_CopyChar2Double;
break;
case media_raw_audio_format::B_AUDIO_INT:
fFunc = &Resampler::_CopyChar2Int;
break;
case media_raw_audio_format::B_AUDIO_SHORT:
fFunc = &Resampler::_CopyChar2Short;
break;
case media_raw_audio_format::B_AUDIO_UCHAR:
fFunc = &Resampler::_CopyChar2UChar;
break;
case media_raw_audio_format::B_AUDIO_CHAR:
fFunc = &Resampler::_CopyChar2Char;
break;
}
break;
}
}
Resampler::~Resampler()
{
}
void
Resampler::_Void(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
}
void
Resampler::_CopyFloat2Float(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(float*)outputData = *(const float*)inputData;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyFloat2Double(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(double*)outputData = *(const float*)inputData;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyFloat2Int(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
float data = *(const float*)inputData;
if (data <= -1.0f)
*(int32*)outputData = INT32_MIN;
else if (data >= 1.0f)
*(int32*)outputData = INT32_MAX;
else
*(int32*)outputData = (int32)(data * INT32_MAX);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyFloat2Short(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int16*)outputData = (int16)(*(const float*)inputData * 32767.0f);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyFloat2UChar(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(uint8*)outputData = (uint8)(128.0f + *(const float*)inputData * 127.0f);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyFloat2Char(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int8*)outputData = (int8)(*(const float*)inputData * 127.0f);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyDouble2Float(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(float*)outputData = *(const double*)inputData;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyDouble2Double(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(double*)outputData = *(const double*)inputData;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyDouble2Int(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int32*)outputData = (int32)(*(const double*)inputData
* (double)INT32_MAX);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyDouble2Short(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int16*)outputData = (int16)(*(const double*)inputData * 32767.0f);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyDouble2UChar(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(uint8*)outputData = (uint8)(128.0f + *(const double*)inputData * 127.0f);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyDouble2Char(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int8*)outputData = (int8)(*(const double*)inputData * 127.0f);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyShort2Float(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(float*)outputData = *(const int16*)inputData / 32767.0f;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyShort2Double(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(double*)outputData = *(const int16*)inputData / 32767.0;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyShort2Int(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int32*)outputData = (int32)*(const int16*)inputData << 16;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyShort2Short(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int16*)outputData = *(const int16*)inputData;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyShort2UChar(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(uint8*)outputData = 128 + (*(const int16*)inputData >> 8);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyShort2Char(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int8*)outputData = *(const int16*)inputData >> 8;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyInt2Float(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(float*)outputData = *(const int32*)inputData / 2147483647.0f;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyInt2Double(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(double*)outputData = *(const int32*)inputData / 2147483647.0;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyInt2Int(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int32*)outputData = *(const int32*)inputData;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyInt2Short(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int16*)outputData = *(const int32*)inputData >> 16;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyInt2UChar(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(uint8*)outputData = 128 + (*(const int32*)inputData >> 24);
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyInt2Char(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(uint8*)outputData = *(const int32*)inputData >> 24;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyUChar2Float(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(float*)outputData = (*(const uint8*)inputData - 128) / 127.0f;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyUChar2Double(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(double*)outputData = (*(const uint8*)inputData - 128) / 127.0;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyUChar2Short(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int16*)outputData = (int16)(*(const uint8*)inputData - 128) << 8;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyUChar2Int(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int32*)outputData = (int32)(*(const uint8*)inputData - 128) << 24;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyUChar2UChar(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(uint8*)outputData = *(const uint8*)inputData;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyUChar2Char(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int8*)outputData = *(const uint8*)inputData - 128;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyChar2Float(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(float*)outputData = *(const int8*)inputData / 127.0f;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyChar2Double(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(double*)outputData = *(const int8*)inputData / 127.0;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyChar2Short(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int16*)outputData = ((int16)*(const int8*)inputData) << 8;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyChar2Int(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int32*)outputData = ((int16)*(const int8*)inputData) << 24;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyChar2UChar(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(uint8*)outputData = *(const int8*)inputData + 128;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}
void
Resampler::_CopyChar2Char(const void *inputData, uint32 inputStride,
void *outputData, uint32 outputStride, uint32 sampleCount)
{
while (sampleCount > 0) {
*(int8*)outputData = *(const int8*)inputData;
outputData = (void*)((uint8*)outputData + outputStride);
inputData = (void*)((uint8*)inputData + inputStride);
sampleCount--;
}
}