#ifndef __AUDIO_BUFFER_TOOLS_H__
#define __AUDIO_BUFFER_TOOLS_H__
#include <ByteOrder.h>
#include <Debug.h>
inline void convert_sample(float& in, float& out) {
out = in;
}
inline void convert_sample(uchar& in, float& out) {
out = (float)(in - 128) / 127.0;
}
inline void convert_sample(short& in, float& out) {
out = (float)in / 32767.0;
}
inline void convert_sample(int32& in, float& out) {
out = (float)in / (float)0x7fffffff;
}
inline void convert_sample(float& in, uchar& out) {
out = (uchar)(in * 127.0);
}
inline void convert_sample(float& in, short& out) {
out = (short)(in * 32767.0);
}
inline void convert_sample(float& in, int32& out) {
out = (int32)(in * 0x7fffffff);
}
inline void swap_convert_sample(float& in, float& out) {
out = B_SWAP_FLOAT(in);
}
inline void swap_convert_sample(uchar& in, float& out) {
out = (float)(in - 128) / 127.0;
}
inline void swap_convert_sample(short& in, float& out) {
out = (float)(int16)(B_SWAP_INT16(in)) / 32767.0;
}
inline void swap_convert_sample(int32& in, float& out) {
out = (float)(int32)(B_SWAP_INT32(in)) / (float)0x7fffffff;
}
inline void swap_convert_sample(float& in, uchar& out) {
out = (uchar)((B_SWAP_FLOAT(in)) * 127.0);
}
inline void swap_convert_sample(float& in, short& out) {
out = (short)((B_SWAP_FLOAT(in)) * 32767.0);
}
inline void swap_convert_sample(float& in, int32& out) {
out = (int32)((B_SWAP_FLOAT(in)) * 0x7fffffff);
}
template<class to_sample_t>
inline void convert_sample(void* pIn, to_sample_t& out, int32 in_audio_format) {
switch(in_audio_format) {
case media_raw_audio_format::B_AUDIO_UCHAR:
convert_sample(*(uchar*)pIn, out);
break;
case media_raw_audio_format::B_AUDIO_SHORT:
convert_sample(*(short*)pIn, out);
break;
case media_raw_audio_format::B_AUDIO_FLOAT:
convert_sample(*(float*)pIn, out);
break;
case media_raw_audio_format::B_AUDIO_INT:
convert_sample(*(int32*)pIn, out);
break;
default:
ASSERT(!"convert_sample(): bad raw_audio_format value");
}
}
template<class from_sample_t>
inline void convert_sample(from_sample_t in, void* pOut, int32 out_audio_format) {
switch(out_audio_format) {
case media_raw_audio_format::B_AUDIO_UCHAR:
convert_sample(in, *(uchar*)pOut);
break;
case media_raw_audio_format::B_AUDIO_SHORT:
convert_sample(in, *(short*)pOut);
break;
case media_raw_audio_format::B_AUDIO_FLOAT:
convert_sample(in, *(float*)pOut);
break;
case media_raw_audio_format::B_AUDIO_INT:
convert_sample(in, *(int32*)pOut);
break;
default:
ASSERT(!"convert_sample(): bad raw_audio_format value");
}
}
inline void convert_sample(void* pIn, void* pOut,
int32 in_audio_format, int32 out_audio_format) {
if(in_audio_format == out_audio_format)
return;
if(in_audio_format == media_raw_audio_format::B_AUDIO_FLOAT)
convert_sample(*(float*)pIn, pOut, out_audio_format);
else if(out_audio_format == media_raw_audio_format::B_AUDIO_FLOAT)
convert_sample(pOut, *(float*)pIn, in_audio_format);
else {
float fTemp = 0;
convert_sample(pIn, fTemp, in_audio_format);
convert_sample(fTemp, pOut, out_audio_format);
}
}
template<class from_sample_t, class to_sample_t>
inline size_t copy_linear_to_circular(
from_sample_t* pFrom,
to_sample_t* pTo,
size_t samples, size_t toOffset, size_t toLength) {
ASSERT(pFrom != 0);
ASSERT(pTo != 0);
ASSERT(samples > 0);
ASSERT(toLength > 0);
ASSERT(toOffset < toLength);
size_t n = toOffset;
for(; samples; samples--) {
pTo[n] = (to_sample_t)*pFrom++;
if(++n >= toLength)
n = 0;
}
return n;
}
template<class from_sample_t, class to_sample_t>
inline size_t copy_linear_to_circular_convert(
from_sample_t* pFrom,
to_sample_t* pTo,
size_t samples, size_t toOffset, size_t toLength) {
ASSERT(pFrom != 0);
ASSERT(pTo != 0);
ASSERT(samples > 0);
ASSERT(toLength > 0);
ASSERT(toOffset < toLength);
size_t n = toOffset;
for(; samples; samples--) {
convert_sample(*pFrom++, pTo[n]);
if(++n >= toLength)
n = 0;
}
return n;
}
template<class from_sample_t, class to_sample_t>
inline size_t copy_circular_to_linear(
from_sample_t* pFrom,
to_sample_t* pTo,
size_t samples, size_t fromOffset, size_t fromLength) {
ASSERT(pFrom != 0);
ASSERT(pTo != 0);
ASSERT(samples > 0);
ASSERT(fromLength > 0);
ASSERT(fromOffset < fromLength);
size_t n = fromOffset;
for(; samples; samples--) {
*pTo++ = (to_sample_t)pFrom[n];
if(++n >= fromLength)
n = 0;
}
return n;
}
template<class from_sample_t, class to_sample_t>
inline size_t copy_circular_to_linear_convert(
from_sample_t* pFrom,
to_sample_t* pTo,
size_t samples, size_t fromOffset, size_t fromLength) {
ASSERT(pFrom != 0);
ASSERT(pTo != 0);
ASSERT(samples > 0);
ASSERT(fromLength > 0);
ASSERT(fromOffset < fromLength);
size_t n = fromOffset;
for(; samples; samples--) {
convert_sample(pFrom[n], *pTo++);
if(++n >= fromLength)
n = 0;
}
return n;
}
template<class from_sample_t, class to_sample_t>
inline size_t mix_linear_to_circular(
from_sample_t* pFrom,
to_sample_t* pTo,
uint32 samples,
uint32 toOffset,
uint32 toLength,
float fSourceGain,
float fFeedback) {
size_t n, nLength;
if(fFeedback == 0.0)
for(n = toOffset, nLength = samples;
nLength;
n = (n+1 == toLength) ? 0 : n+1, nLength--) { pTo[n] = 0.0; }
else if(fFeedback != 1.0)
for(n = toOffset, nLength = samples;
nLength;
n = (n+1 == toLength) ? 0 : n+1, nLength--) { pTo[n] *= fFeedback; }
if(pFrom && fSourceGain != 0.0) {
if(fSourceGain == 1.0)
for(n = toOffset, nLength = samples;
nLength;
n = (n+1 == toLength) ? 0 : n+1, nLength--) {
pTo[n] += (to_sample_t)*pFrom++;
}
else
for(n = toOffset, nLength = samples;
nLength;
n = (n+1 == toLength) ? 0 : n+1, nLength--) {
pTo[n] += (to_sample_t)*pFrom++ * fSourceGain;
}
}
toOffset += samples;
if(toOffset >= toLength)
toOffset -= toLength;
return toOffset;
}
template<class from_sample_t, class to_sample_t>
inline size_t mix_linear_to_circular_convert(
from_sample_t* pFrom,
to_sample_t* pTo,
size_t samples,
size_t toOffset,
size_t toLength,
float fSourceGain,
float fFeedback) {
size_t n, nLength;
if(fFeedback == 0.0)
for(n = toOffset, nLength = samples;
nLength;
n = (n+1 == toLength) ? 0 : n+1, nLength--) { pTo[n] = 0.0; }
else if(fFeedback != 1.0)
for(n = toOffset, nLength = samples;
nLength;
n = (n+1 == toLength) ? 0 : n+1, nLength--) { pTo[n] *= fFeedback; }
if(pFrom && fSourceGain != 0.0) {
if(fSourceGain == 1.0)
for(n = toOffset, nLength = samples;
nLength;
n = (n+1 == toLength) ? 0 : n+1, nLength--) {
to_sample_t from;
convert_sample(*pFrom++, from);
pTo[n] += from;
}
else
for(n = toOffset, nLength = samples;
nLength;
n = (n+1 == toLength) ? 0 : n+1, nLength--) {
to_sample_t from;
convert_sample(*pFrom++, from);
pTo[n] += from * fSourceGain;
}
}
toOffset += samples;
if(toOffset >= toLength)
toOffset -= toLength;
return toOffset;
}
#endif