[plain text]
#include <libkern/OSTypes.h>
#include <IOKit/IOReturn.h>
#include <IOKit/IOLib.h>
class IOMemoryDescriptor;
#include <IOKit/usb/USB.h>
#include <IOKit/audio/IOAudioTypes.h>
#include "AppleUSBAudioClip.h"
#include "AppleUSBAudioCommon.h"
extern "C" {
typedef float Float32;
typedef double Float64;
#define FLOATLIB FALSE
#if FLOATLIB
void CoeffsFilterOrder2 (Float32 *Coeff, Float32 CutOffFreq, Float32 AttAtCutOffFreq , Float64 SamplingRate);
#else
Boolean CoeffsFilterOrder2Table (Float32 *Coeff, UInt32 samplingRate);
#endif
void MonoFilter (Float32 *in, Float32 *low, Float32 *high, UInt32 frames, UInt32 samplingRate);
void StereoFilter (Float32 *in, Float32 *low, Float32 *high, UInt32 frames, UInt32 samplingRate, PreviousValues *theValue);
UInt32 CalculateOffset (UInt64 nanoseconds, UInt32 sampleRate) {
return (UInt32)(((double)sampleRate / 1000000000.0) * nanoseconds);
}
inline static SInt16 Endian16_Swap(SInt16 inValue)
{
return (((((UInt16)inValue)<<8) & 0xFF00) | ((((UInt16)inValue)>>8) & 0x00FF));
}
inline static SInt32 Endian32_Swap(SInt32 inValue)
{
return (((((UInt32)inValue)<<24) & 0xFF000000) | ((((UInt32)inValue)<< 8) & 0x00FF0000) | ((((UInt32)inValue)>> 8) & 0x0000FF00) | ((((UInt32)inValue)>>24) & 0x000000FF));
}
#if defined(__ppc__)
static inline SInt16 SInt16BigToNativeEndian(SInt16 inValue) { return inValue; }
static inline SInt16 SInt16NativeToBigEndian(SInt16 inValue) { return inValue; }
static inline SInt16 SInt16LittleToNativeEndian(SInt16 inValue) { return Endian16_Swap(inValue); }
static inline SInt16 SInt16NativeToLittleEndian(SInt16 inValue) { return Endian16_Swap(inValue); }
static inline SInt32 SInt32BigToNativeEndian(SInt32 inValue) { return inValue; }
static inline SInt32 SInt32NativeToBigEndian(SInt32 inValue) { return inValue; }
static inline SInt32 SInt32LittleToNativeEndian(SInt32 inValue) { return Endian32_Swap(inValue); }
static inline SInt32 SInt32NativeToLittleEndian(SInt32 inValue) { return Endian32_Swap(inValue); }
#elif defined(__i386__)
static inline SInt16 SInt16BigToNativeEndian(SInt16 inValue) { return Endian16_Swap(inValue); }
static inline SInt16 SInt16NativeToBigEndian(SInt16 inValue) { return Endian16_Swap(inValue); }
static inline SInt16 SInt16LittleToNativeEndian(SInt16 inValue) { return inValue; }
static inline SInt16 SInt16NativeToLittleEndian(SInt16 inValue) { return inValue; }
static inline SInt32 SInt32BigToNativeEndian(SInt32 inValue) { return Endian32_Swap(inValue); }
static inline SInt32 SInt32NativeToBigEndian(SInt32 inValue) { return Endian32_Swap(inValue); }
static inline SInt32 SInt32LittleToNativeEndian(SInt32 inValue) { return inValue; }
static inline SInt32 SInt32NativeToLittleEndian(SInt32 inValue) { return inValue; }
#endif
inline static Float32 ClipFloat32(Float32 inSample)
{
if(inSample > 1.0) return 1.0;
if(inSample < -1.0) return -1.0;
return inSample;
}
#define kMaxSampleSInt8 ((Float32)0x7F)
static void ClipFloat32ToSInt8_4(const Float32* inInputBuffer, SInt8* outOutputBuffer, UInt32 inNumberSamples)
{
register UInt32 theLeftOvers = inNumberSamples % 4;
while(inNumberSamples > theLeftOvers)
{
register Float32 theFloat32Value1 = *(inInputBuffer + 0);
register Float32 theFloat32Value2 = *(inInputBuffer + 1);
register Float32 theFloat32Value3 = *(inInputBuffer + 2);
register Float32 theFloat32Value4 = *(inInputBuffer + 3);
inInputBuffer += 4;
theFloat32Value1 = ClipFloat32(theFloat32Value1);
theFloat32Value2 = ClipFloat32(theFloat32Value2);
theFloat32Value3 = ClipFloat32(theFloat32Value3);
theFloat32Value4 = ClipFloat32(theFloat32Value4);
*(outOutputBuffer + 0) = (SInt8)(theFloat32Value1 * kMaxSampleSInt8);
*(outOutputBuffer + 1) = (SInt8)(theFloat32Value2 * kMaxSampleSInt8);
*(outOutputBuffer + 2) = (SInt8)(theFloat32Value3 * kMaxSampleSInt8);
*(outOutputBuffer + 3) = (SInt8)(theFloat32Value4 * kMaxSampleSInt8);
outOutputBuffer += 4;
inNumberSamples -= 4;
}
while(inNumberSamples > 0)
{
register Float32 theFloat32Value = *inInputBuffer;
++inInputBuffer;
theFloat32Value = ClipFloat32(theFloat32Value);
*outOutputBuffer = (SInt8)(theFloat32Value * kMaxSampleSInt8);
++outOutputBuffer;
--inNumberSamples;
}
}
#define kMaxSampleSInt16 ((Float32)0x7FFF)
static void ClipFloat32ToSInt16LE_4(const Float32* inInputBuffer, SInt16* outOutputBuffer, UInt32 inNumberSamples)
{
register UInt32 theLeftOvers = inNumberSamples % 4;
while(inNumberSamples > theLeftOvers)
{
register Float32 theFloat32Value1 = *(inInputBuffer + 0);
register Float32 theFloat32Value2 = *(inInputBuffer + 1);
register Float32 theFloat32Value3 = *(inInputBuffer + 2);
register Float32 theFloat32Value4 = *(inInputBuffer + 3);
inInputBuffer += 4;
theFloat32Value1 = ClipFloat32(theFloat32Value1);
theFloat32Value2 = ClipFloat32(theFloat32Value2);
theFloat32Value3 = ClipFloat32(theFloat32Value3);
theFloat32Value4 = ClipFloat32(theFloat32Value4);
*(outOutputBuffer + 0) = SInt16NativeToLittleEndian((SInt16)(theFloat32Value1 * kMaxSampleSInt16));
*(outOutputBuffer + 1) = SInt16NativeToLittleEndian((SInt16)(theFloat32Value2 * kMaxSampleSInt16));
*(outOutputBuffer + 2) = SInt16NativeToLittleEndian((SInt16)(theFloat32Value3 * kMaxSampleSInt16));
*(outOutputBuffer + 3) = SInt16NativeToLittleEndian((SInt16)(theFloat32Value4 * kMaxSampleSInt16));
outOutputBuffer += 4;
inNumberSamples -= 4;
}
while(inNumberSamples > 0)
{
register Float32 theFloat32Value = *inInputBuffer;
++inInputBuffer;
theFloat32Value = ClipFloat32(theFloat32Value);
*outOutputBuffer = SInt16NativeToLittleEndian((SInt16)(theFloat32Value * kMaxSampleSInt16));
++outOutputBuffer;
--inNumberSamples;
}
}
#define kMaxSampleSInt24 ((Float32)0x7FFFFFFF)
static void ClipFloat32ToSInt24LE_4(const Float32* inInputBuffer, SInt32* outOutputBuffer, UInt32 inNumberSamples)
{
register UInt32 theLeftOvers = inNumberSamples % 4;
while(inNumberSamples > theLeftOvers)
{
register Float32 theFloat32Value1 = *(inInputBuffer + 0);
register Float32 theFloat32Value2 = *(inInputBuffer + 1);
register Float32 theFloat32Value3 = *(inInputBuffer + 2);
register Float32 theFloat32Value4 = *(inInputBuffer + 3);
inInputBuffer += 4;
theFloat32Value1 = ClipFloat32(theFloat32Value1);
theFloat32Value2 = ClipFloat32(theFloat32Value2);
theFloat32Value3 = ClipFloat32(theFloat32Value3);
theFloat32Value4 = ClipFloat32(theFloat32Value4);
#if defined(__ppc__)
register SInt32 theSInt32Value1 = (SInt32)(theFloat32Value1 * kMaxSampleSInt24);
register SInt32 theSInt32Value2 = (SInt32)(theFloat32Value2 * kMaxSampleSInt24);
register SInt32 theSInt32Value3 = (SInt32)(theFloat32Value3 * kMaxSampleSInt24);
register SInt32 theSInt32Value4 = (SInt32)(theFloat32Value4 * kMaxSampleSInt24);
register SInt32 theOutputValue1 = ((((UInt32)theSInt32Value1) << 16) & 0xFF000000) | (((UInt32)theSInt32Value1) & 0x00FF0000) | ((((UInt32)theSInt32Value1) >> 16) & 0x0000FF00) | ((((UInt32)theSInt32Value2) >> 8) & 0x000000FF);
register SInt32 theOutputValue2 = ((((UInt32)theSInt32Value2) << 8) & 0xFF000000) | ((((UInt32)theSInt32Value2) >> 8) & 0x00FF0000) | (((UInt32)theSInt32Value3) & 0x0000FF00) | ((((UInt32)theSInt32Value3) >> 16) & 0x000000FF);
register SInt32 theOutputValue3 = (((UInt32)theSInt32Value3) & 0xFF000000) | ((((UInt32)theSInt32Value4) << 8) & 0x00FF0000) | ((((UInt32)theSInt32Value4) >> 8) & 0x0000FF00) | ((((UInt32)theSInt32Value4) >> 24) & 0x000000FF);
*(outOutputBuffer + 0) = theOutputValue1;
*(outOutputBuffer + 1) = theOutputValue2;
*(outOutputBuffer + 2) = theOutputValue3;
#elif defined(__i386__)
#error this needs to be done
#endif
outOutputBuffer += 3;
inNumberSamples -= 4;
}
SInt8* theOutputBuffer = (SInt8*)outOutputBuffer;
while(inNumberSamples > 0)
{
register Float32 theFloat32Value = *inInputBuffer;
++inInputBuffer;
theFloat32Value = ClipFloat32(theFloat32Value);
#if defined(__ppc__)
register SInt32 theSInt32Value = (SInt32)(theFloat32Value * kMaxSampleSInt24);
*(theOutputBuffer + 0) = (SInt8)((((UInt32)theSInt32Value) >> 8) & 0x000000FF);
*(theOutputBuffer + 1) = (SInt8)((((UInt32)theSInt32Value) >> 16) & 0x000000FF);
*(theOutputBuffer + 2) = (SInt8)((((UInt32)theSInt32Value) >> 24) & 0x000000FF);
theOutputBuffer += 3;
#elif defined(__i386__)
#error this needs to be done
#endif
--inNumberSamples;
}
}
#define kMaxSampleSInt32 ((Float32)0x7FFFFFFF)
static void ClipFloat32ToSInt32LE_4(const Float32* inInputBuffer, SInt32* outOutputBuffer, UInt32 inNumberSamples)
{
register UInt32 theLeftOvers = inNumberSamples % 4;
while(inNumberSamples > theLeftOvers)
{
register Float32 theFloat32Value1 = *(inInputBuffer + 0);
register Float32 theFloat32Value2 = *(inInputBuffer + 1);
register Float32 theFloat32Value3 = *(inInputBuffer + 2);
register Float32 theFloat32Value4 = *(inInputBuffer + 3);
inInputBuffer += 4;
theFloat32Value1 = ClipFloat32(theFloat32Value1);
theFloat32Value2 = ClipFloat32(theFloat32Value2);
theFloat32Value3 = ClipFloat32(theFloat32Value3);
theFloat32Value4 = ClipFloat32(theFloat32Value4);
*(outOutputBuffer + 0) = SInt32NativeToLittleEndian((SInt32)(theFloat32Value1 * kMaxSampleSInt32));
*(outOutputBuffer + 1) = SInt32NativeToLittleEndian((SInt32)(theFloat32Value2 * kMaxSampleSInt32));
*(outOutputBuffer + 2) = SInt32NativeToLittleEndian((SInt32)(theFloat32Value3 * kMaxSampleSInt32));
*(outOutputBuffer + 3) = SInt32NativeToLittleEndian((SInt32)(theFloat32Value4 * kMaxSampleSInt32));
outOutputBuffer += 4;
inNumberSamples -= 4;
}
while(inNumberSamples > 0)
{
register Float32 theFloat32Value = *inInputBuffer;
++inInputBuffer;
theFloat32Value = ClipFloat32(theFloat32Value);
*outOutputBuffer = SInt32NativeToLittleEndian((SInt32)(theFloat32Value * kMaxSampleSInt32));
++outOutputBuffer;
--inNumberSamples;
}
}
IOReturn clipAppleUSBAudioToOutputStream(const void* mixBuf, void* sampleBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat)
{
if(!streamFormat)
{
return kIOReturnBadArgument;
}
UInt32 theNumberSamples = numSampleFrames * streamFormat->fNumChannels;
UInt32 theFirstSample = firstSampleFrame * streamFormat->fNumChannels;
Float32* theMixBuffer = ((Float32*)mixBuf) + theFirstSample;
switch(streamFormat->fBitWidth)
{
case 8:
{
SInt8* theOutputBufferSInt8 = ((SInt8*)sampleBuf) + theFirstSample;
ClipFloat32ToSInt8_4(theMixBuffer, theOutputBufferSInt8, theNumberSamples);
}
break;
case 16:
{
SInt16* theOutputBufferSInt16 = ((SInt16*)sampleBuf) + theFirstSample;
ClipFloat32ToSInt16LE_4(theMixBuffer, theOutputBufferSInt16, theNumberSamples);
}
break;
case 20:
case 24:
{
SInt32* theOutputBufferSInt24 = (SInt32*)(((UInt8*)sampleBuf) + (theFirstSample * 3));
ClipFloat32ToSInt24LE_4(theMixBuffer, theOutputBufferSInt24, theNumberSamples);
}
break;
case 32:
{
SInt32* theOutputBufferSInt32 = ((SInt32*)sampleBuf) + theFirstSample;
ClipFloat32ToSInt32LE_4(theMixBuffer, theOutputBufferSInt32, theNumberSamples);
}
break;
};
return kIOReturnSuccess;
}
IOReturn clipAppleUSBAudioToOutputStream_old (const void *mixBuf,
void *sampleBuf,
UInt32 firstSampleFrame,
UInt32 numSampleFrames,
const IOAudioStreamFormat *streamFormat) {
UInt32 sampleIndex,
maxSampleIndex;
float * floatMixBuf;
SInt8 * outputBuf8;
SInt16 * outputBuf16;
SInt32 * outputBuf24;
SInt32 * outputBuf32;
SInt32 sample32[1];
#ifdef DEBUGLOG
UInt32 count;
UInt32 nextStart;
#endif
if (!streamFormat) {
return kIOReturnBadArgument;
}
floatMixBuf = (float *)mixBuf;
outputBuf8 = (SInt8 *)sampleBuf;
outputBuf16 = (SInt16 *)sampleBuf;
outputBuf24 = (SInt32 *)sampleBuf;
outputBuf32 = (SInt32 *)sampleBuf;
maxSampleIndex = (firstSampleFrame + numSampleFrames) * (streamFormat->fNumChannels);
#ifdef DEBUGLOG
count = 0;
nextStart = firstSampleFrame * streamFormat->fNumChannels;
#endif
for (sampleIndex = (firstSampleFrame * streamFormat->fNumChannels); sampleIndex < maxSampleIndex; sampleIndex++) {
float inSample;
inSample = floatMixBuf[sampleIndex];
if (inSample > 1.0) {
inSample = 1.0;
} else if (inSample < -1.0) {
inSample = -1.0;
}
if (streamFormat->fBitWidth == 8) {
if (inSample >= 0) {
outputBuf8[sampleIndex] = (SInt8)(inSample * 127.0);
} else {
outputBuf8[sampleIndex] = (SInt8)(inSample * 128.0);
}
} else if (streamFormat->fBitWidth == 16) {
if (inSample >= 0) {
outputBuf16[sampleIndex] = HostToUSBWord((SInt16)(inSample * 32767.0));
#if 0
#ifdef DEBUGLOG
if (inSample == 0 && sampleIndex >= nextStart) {
count = 1;
while (floatMixBuf[sampleIndex + count] == 0.0 && (sampleIndex + count) < maxSampleIndex) {
count++;
}
if (count >= 3) {
debug5IOLog ("got %ld samples of silence back to back, sampleIndex = 0x%lX, firstSampleFrame = 0x%lX, numSampleFrames = 0x%lX\n", count, sampleIndex, firstSampleFrame, numSampleFrames);
nextStart = sampleIndex + count;
}
}
#endif
#endif
} else {
outputBuf16[sampleIndex] = HostToUSBWord((SInt16)(inSample * 32768.0));
}
} else if (streamFormat->fBitWidth == 20) {
if (inSample >= 0) {
sample32[0] = (SInt32)(inSample * 524287.0);
((UInt8 *)outputBuf24)[sampleIndex * 3 + 2] = ((UInt8 *)sample32)[0];
((UInt8 *)outputBuf24)[sampleIndex * 3 + 1] = ((UInt8 *)sample32)[1];
((UInt8 *)outputBuf24)[sampleIndex * 3] = ((UInt8 *)sample32)[2];
} else {
sample32[0] = (SInt32)(inSample * 524288.0);
((UInt8 *)outputBuf24)[sampleIndex * 3 + 2] = ((UInt8 *)sample32)[0];
((UInt8 *)outputBuf24)[sampleIndex * 3 + 1] = ((UInt8 *)sample32)[1];
((UInt8 *)outputBuf24)[sampleIndex * 3] = ((UInt8 *)sample32)[2];
}
} else if (streamFormat->fBitWidth == 24) {
if (inSample >= 0) {
sample32[0] = (SInt32)(inSample * 8388607.0);
((UInt8 *)outputBuf24)[sampleIndex * 3 + 2] = ((UInt8 *)sample32)[1];
((UInt8 *)outputBuf24)[sampleIndex * 3 + 1] = ((UInt8 *)sample32)[2];
((UInt8 *)outputBuf24)[sampleIndex * 3] = ((UInt8 *)sample32)[3];
} else {
sample32[0] = (SInt32)(inSample * 8388608.0);
((UInt8 *)outputBuf24)[sampleIndex * 3 + 2] = ((UInt8 *)sample32)[1];
((UInt8 *)outputBuf24)[sampleIndex * 3 + 1] = ((UInt8 *)sample32)[2];
((UInt8 *)outputBuf24)[sampleIndex * 3] = ((UInt8 *)sample32)[3];
}
} else if (streamFormat->fBitWidth == 32) {
if (inSample >= 0) {
sample32[0] = (SInt32)(inSample * 2147483647.0);
((UInt8 *)outputBuf32)[sampleIndex * 3 + 3] = ((UInt8 *)sample32)[0];
((UInt8 *)outputBuf32)[sampleIndex * 3 + 2] = ((UInt8 *)sample32)[1];
((UInt8 *)outputBuf32)[sampleIndex * 3 + 1] = ((UInt8 *)sample32)[2];
((UInt8 *)outputBuf32)[sampleIndex * 3] = ((UInt8 *)sample32)[3];
} else {
sample32[0] = (SInt32)(inSample * 2147483647.0);
((UInt8 *)outputBuf32)[sampleIndex * 3 + 3] = ((UInt8 *)sample32)[0];
((UInt8 *)outputBuf32)[sampleIndex * 3 + 2] = ((UInt8 *)sample32)[1];
((UInt8 *)outputBuf32)[sampleIndex * 3 + 1] = ((UInt8 *)sample32)[2];
((UInt8 *)outputBuf32)[sampleIndex * 3] = ((UInt8 *)sample32)[3];
}
}
}
return kIOReturnSuccess;
}
IOReturn clipAppleUSBAudioToOutputStreamiSub (const void *mixBuf, void *sampleBuf, PreviousValues * filterState, Float32 *low, Float32 *high, UInt32 firstSampleFrame, UInt32 numSampleFrames, UInt32 sampleRate, const IOAudioStreamFormat *streamFormat, SInt16 *iSubBufferMemory, UInt32 *loopCount, SInt32 *iSubBufferOffset, UInt32 iSubBufferLen)
{
UInt32 sampleIndex, maxSampleIndex;
float *floatMixBuf;
SInt16 *outputBuf;
float highSample;
Float32 iSubSampleFloat;
SInt16 iSubSampleInt;
floatMixBuf = (float *)mixBuf;
outputBuf = (SInt16 *)sampleBuf;
maxSampleIndex = (firstSampleFrame + numSampleFrames) * (streamFormat->fNumChannels);
if (1 == streamFormat->fNumChannels) {
MonoFilter (&floatMixBuf[firstSampleFrame * streamFormat->fNumChannels], &low[firstSampleFrame * streamFormat->fNumChannels], &high[firstSampleFrame * streamFormat->fNumChannels], numSampleFrames, sampleRate);
} else if (2 == streamFormat->fNumChannels) {
StereoFilter (&floatMixBuf[firstSampleFrame * streamFormat->fNumChannels], &low[firstSampleFrame * streamFormat->fNumChannels], &high[firstSampleFrame * streamFormat->fNumChannels], numSampleFrames, sampleRate, filterState);
}
for (sampleIndex = (firstSampleFrame * streamFormat->fNumChannels); sampleIndex < maxSampleIndex; sampleIndex++) {
highSample = high[sampleIndex];
if (highSample > 1.0) {
highSample = 1.0;
} else if (highSample < -1.0) {
highSample = -1.0;
}
if (highSample >= 0) {
outputBuf[sampleIndex] = HostToUSBWord ((SInt16)(highSample * 32767.0));
} else {
outputBuf[sampleIndex] = HostToUSBWord ((SInt16)(highSample * 32768.0));
}
iSubSampleFloat = low[sampleIndex];
if (iSubSampleFloat > 1.0) {
iSubSampleFloat = 1.0;
} else if (iSubSampleFloat < -1.0) {
iSubSampleFloat = -1.0;
}
if (iSubSampleFloat >= 0) {
iSubSampleInt = (SInt16) (iSubSampleFloat * 32767.0);
} else {
iSubSampleInt = (SInt16) (iSubSampleFloat * 32768.0);
}
if (*iSubBufferOffset >= (SInt32)iSubBufferLen) {
*iSubBufferOffset = 0;
(*loopCount)++;
}
iSubBufferMemory[(*iSubBufferOffset)++] = ((((UInt16)iSubSampleInt) << 8) & 0xFF00) | ((((UInt16)iSubSampleInt) >> 8) & 0x00FF);
}
return kIOReturnSuccess;
}
IOReturn convertFromAppleUSBAudioInputStream_NoWrap (const void *sampleBuf,
void *destBuf,
UInt32 firstSampleFrame,
UInt32 numSampleFrames,
const IOAudioStreamFormat *streamFormat) {
UInt32 numSamplesLeft;
float * floatDestBuf;
SInt16 * inputBuf;
floatDestBuf = (float *)destBuf;
inputBuf = &(((SInt16 *)sampleBuf)[firstSampleFrame * streamFormat->fNumChannels]);
numSamplesLeft = numSampleFrames * streamFormat->fNumChannels;
while (numSamplesLeft > 0) {
SInt16 inputSample;
inputSample = USBToHostWord (*inputBuf);
if (inputSample >= 0) {
*floatDestBuf = inputSample / 32767.0;
} else {
*floatDestBuf = inputSample / 32768.0;
}
++inputBuf;
++floatDestBuf;
--numSamplesLeft;
}
return kIOReturnSuccess;
}
#if FLOATLIB
void CoeffsFilterOrder2 (Float32 *Coeff, Float32 CutOffFreq, Float32 AttAtCutOffFreq , Float64 SamplingRate)
{
Float32 k, nu0, pi=3.14159, Att, norm;
nu0 = (Float32) (CutOffFreq / SamplingRate);
Att = 1 / AttAtCutOffFreq;
k = 1/(tan(pi*nu0));
norm = k*(k+Att)+1;
Coeff[0] = 1.0 / norm;
Coeff[1] = 2.0 / norm;
Coeff[2] = 1.0 / norm;
Coeff[3] = 2*(1-k*k) / norm;
Coeff[4] = (k*(k-Att)+1) / norm;
return;
}
#else
Boolean CoeffsFilterOrder2Table (Float32 *Coeff, UInt32 samplingRate)
{
Boolean success = TRUE;
switch ( samplingRate )
{
case 8000: Coeff[0] = 0.00208054389804601669;
Coeff[1] = 0.00416108779609203339;
Coeff[2] = 0.00208054389804601669;
Coeff[3] = -1.86687481403350830078;
Coeff[4] = 0.87519699335098266602;
break;
case 11025: Coeff[0] = 0.00111490569543093443;
Coeff[1] = 0.00222981139086186886;
Coeff[2] = 0.00111490569543093443;
Coeff[3] = -1.90334117412567138672;
Coeff[4] = 0.90780085325241088867;
break;
case 22050: Coeff[0] = 0.00028538206242956221;
Coeff[1] = 0.00057076412485912442;
Coeff[2] = 0.00028538206242956221;
Coeff[3] = -1.95164430141448974609;
Coeff[4] = 0.95278578996658325195;
break;
case 44100: Coeff[0] = 0.00007220284896902740;
Coeff[1] = 0.00014440569793805480;
Coeff[2] = 0.00007220284896902740;
Coeff[3] = -1.97581851482391357422;
Coeff[4] = 0.97610741853713989258;
break;
case 48000: Coeff[0] = 0.00006100598693592474;
Coeff[1] = 0.00012201197387184948;
Coeff[2] = 0.00006100598693592474;
Coeff[3] = -1.97778332233428955078;
Coeff[4] = 0.97802722454071044922;
break;
case 96000: Coeff[0] = 0.00001533597242087126;
Coeff[1] = 0.00003067194484174252;
Coeff[2] = 0.00001533597242087126;
Coeff[3] = -1.98889136314392089844;
Coeff[4] = 0.98895263671875000000;
break;
default: success = FALSE;
break;
}
return(success);
}
#endif
void MonoFilter (Float32 *in, Float32 *low, Float32 *high, UInt32 frames, UInt32 samplingRate)
{
UInt32 idx;
#if !FLOATLIB
Boolean success;
#endif
Float32 LP_Coeff[5];
Float32 x, xx, xxx, y, yy, yyy;
#if FLOATLIB
CoeffsFilterOrder2 (LP_Coeff, 120, 1/sqrt(2), 44100);
#else
success = CoeffsFilterOrder2Table (LP_Coeff, samplingRate);
if (success == FALSE) goto End;
#endif
x=xx=xxx=y=yy=yyy=0;
for ( idx = 0 ; idx < frames ; idx++ )
{
x = in[idx];
y = (LP_Coeff[0]*x + LP_Coeff[1]*xx + LP_Coeff[2]*xxx - LP_Coeff[3]*yy - LP_Coeff[4]*yyy);
xxx = xx;
xx = x;
yyy = yy;
yy = y;
low[idx] = y;
high[idx] = x-y;
}
#if !FLOATLIB
End:
#endif
return;
}
void StereoFilter (Float32 *in, Float32 *low, Float32 *high, UInt32 frames, UInt32 SamplingRate, PreviousValues *theValue)
{
UInt32 idx;
Boolean success;
Float32 LP_Coeff[5];
Float32 xl, xr, yl, yr;
success = CoeffsFilterOrder2Table (LP_Coeff, SamplingRate);
if (success == FALSE) goto End;
for ( idx = 0 ; idx < frames ; idx ++ )
{
xl = in[2*idx];
xr = in[2*idx+1];
yl = (LP_Coeff[0]*xl + LP_Coeff[1]*theValue->xl_1 + LP_Coeff[2]*theValue->xl_2 - LP_Coeff[3]*theValue->yl_1 - LP_Coeff[4]*theValue->yl_2);
yr = (LP_Coeff[0]*xr + LP_Coeff[1]*theValue->xr_1 + LP_Coeff[2]*theValue->xr_2 - LP_Coeff[3]*theValue->yr_1 - LP_Coeff[4]*theValue->yr_2);
theValue->xl_2 = theValue->xl_1;
theValue->xr_2 = theValue->xr_1;
theValue->xl_1 = xl;
theValue->xr_1 = xr;
theValue->yl_2 = theValue->yl_1;
theValue->yr_2 = theValue->yr_1;
theValue->yl_1 = yl;
theValue->yr_1 = yr;
low[2*idx] = yl;
low[2*idx+1] = yr;
high[2*idx] = xl-yl;
high[2*idx+1] = xr-yr;
}
End:
return;
}
}
Generated by GNU enscript 1.6.4.