chore(fmod): add files from Chensne/DragonNest

This commit is contained in:
phaneron 2025-08-19 10:12:56 -04:00
commit 50fb3c6b1c
544 changed files with 315778 additions and 0 deletions

6
lib/neural_thx/Brev_Table.c Executable file
View file

@ -0,0 +1,6 @@
#include "Neural_THX_Encoders.h"
unsigned char * GetBrevTable(){
return (unsigned char*)BRev;
}

72
lib/neural_thx/Delay.c Executable file
View file

@ -0,0 +1,72 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio *//
//* File : Delay.h *//
//* Description : Fixed delay *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <stdlib.h>
//***************************************************************************//
//* Delay_INIT(...) *//
//***************************************************************************//
int Delay_INIT(unsigned int DelayAmount,
Delay_Struct * pPtr)
{
int n;
if(DelayAmount != NEURAL_FRAMESIZE) return UNSUPPORTED_FRAMESIZE;
pPtr->Pntr = 0;
pPtr->DelayAmount = DelayAmount;
for(n = 0; n < NEURAL_FRAMESIZE+1; n++){
pPtr->Buffer[n] = 0;
}
return NRLSUR_OK;
}
//***************************************************************************//
//* Delay(...) *//
//***************************************************************************//
int Delay(float * PtrIn,
float * PtrOut,
unsigned int Framesize,
Delay_Struct * pPtr)
{
int n, Pntr, DelayAmount;
float * Buffer;
if(Framesize != NEURAL_FRAMESIZE) return UNSUPPORTED_FRAMESIZE;
Buffer = pPtr->Buffer;
Pntr = pPtr->Pntr;
DelayAmount = pPtr->DelayAmount;
for(n = 0; n < NEURAL_FRAMESIZE; n++){
Buffer[Pntr] = PtrIn[n];
Pntr = ( (Pntr+1) >= (DelayAmount+1) ) ? 0 : (Pntr+1);
PtrOut[n] = Buffer[Pntr];
}
pPtr->Pntr = Pntr;
return NRLSUR_OK;
}

197
lib/neural_thx/FFT_Overlapped.c Executable file
View file

@ -0,0 +1,197 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Surround *//
//* File : FFT_Overlapped.c *//
//* Description : A windowed and overlapped FFT and IFFT *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <stdlib.h>
#include <math.h>
//***************************************************************************//
//* FFT_Overlapped_INIT(...) *//
//***************************************************************************//
int FFT_Overlapped_INIT(FFT_Overlapped_Struct * pPersistent,
float * pTempBuffer0, //Size must be 2*Framesize
float * pTempBuffer1, //Size must be 2*Framesize
unsigned int Framesize)
{
int n, j;
size_t memNeeded;
if(Framesize != HALFFFTSIZE) return UNSUPPORTED_FRAMESIZE;
pPersistent->pSineWin = (float*)GetSineWindow();
pPersistent->pReal = pTempBuffer0;
pPersistent->pImag = pTempBuffer1;
for(n = 0; n < HALFFFTSIZE; n++){
pPersistent->pOverlappedBuffer[n] = 0;
}
// Let's do something that will speed everything up
memNeeded = FFT_MEM_CHUNK;
pPersistent->state = THX_kiss_fft_alloc(FFTSIZE,0,fft_buff,&memNeeded);
// Lets make some memory for our buffers
for(j = 0; j < FFTSIZE; j++)
{
pPersistent->pIn[j].r = 0.0f;
pPersistent->pIn[j].i = 0.0f;
pPersistent->pOut[j].r = 0.0f;
pPersistent->pOut[j].i = 0.0f;
}
return NRLSUR_OK;
}
//***************************************************************************//
//* FFT_Overlapped(...) *//
//***************************************************************************//
int FFT_Overlapped(float * PtrIn,
float * PtrOutReal,
float * PtrOutImag,
unsigned int Framesize,
FFT_Overlapped_Struct * pPersistent)
{
unsigned int n;
float Win;
if(Framesize != HALFFFTSIZE) return UNSUPPORTED_FRAMESIZE;
// Put input values into every index as "real" data
for(n = 0; n < HALFFFTSIZE; n++){
Win = pPersistent->pSineWin[n];
pPersistent->pIn[n ].r = Win * pPersistent->pOverlappedBuffer[n];
pPersistent->pIn[n ].i = 0.0f;
pPersistent->pIn[FFTSIZE-n-1].r = Win * PtrIn[HALFFFTSIZE-n-1];
pPersistent->pIn[FFTSIZE-n-1].i = 0.0f;
//Store in pOverlappedBuffer for next call
pPersistent->pOverlappedBuffer[n] = PtrIn[n];
}
// FFT call
THX_kiss_fft(pPersistent->state,
pPersistent->pIn,
pPersistent->pOut);
// Now parse through the complex output to separate the input signal
for(n = 0; n < HALFFFTSIZE; n++){
PtrOutReal[n] = pPersistent->pOut[n].r; // Real output
PtrOutImag[n] = pPersistent->pOut[n].i; // Imag output
}
return NRLSUR_OK;
}
//***************************************************************************//
//* IFFT_Overlapped_INIT(...) *//
//***************************************************************************//
int IFFT_Overlapped_INIT(IFFT_Overlapped_Struct * pPersistent,
float * pTempBuffer0, //Size must be 2*Framesize
float * pTempBuffer1, //Size must be 2*Framesize
unsigned int Framesize)
{
int n, j;
size_t memNeeded;
if(Framesize != HALFFFTSIZE) return UNSUPPORTED_FRAMESIZE;
pPersistent->pSineWin = (float*)GetSineWindow();
pPersistent->pReal = pTempBuffer0;
pPersistent->pImag = pTempBuffer1;
for(n = 0; n < HALFFFTSIZE; n++){
pPersistent->pOverlappedBuffer[n] = 0;
}
// Let's do something that will speed everything up
memNeeded = FFT_MEM_CHUNK;
pPersistent->state = THX_kiss_fft_alloc(FFTSIZE,0,fft_buff,&memNeeded);
// Lets make some memory for our buffers
for(j = 0; j < FFTSIZE; j++)
{
pPersistent->pIn[j].r = 0.0f;
pPersistent->pIn[j].i = 0.0f;
pPersistent->pOut[j].r = 0.0f;
pPersistent->pOut[j].i = 0.0f;
}
return NRLSUR_OK;
}
//***************************************************************************//
//* IFFT_Overlapped(...) *//
//***************************************************************************//
int IFFT_Overlapped(float * PtrInReal,
float * PtrInImag,
float * PtrOut,
unsigned int Framesize,
IFFT_Overlapped_Struct * pPersistent)
{
unsigned int n;
float Win;
float coeff;
if(Framesize != HALFFFTSIZE) return UNSUPPORTED_FRAMESIZE;
for(n = 0; n < HALFFFTSIZE; n++){
pPersistent->pIn[n].r = PtrInReal[n]; //Real
pPersistent->pIn[n].i = PtrInImag[n]; //Imag
}
//Use the input buffers as temporary buffers
pPersistent->pIn[HALFFFTSIZE].r = 0;
pPersistent->pIn[HALFFFTSIZE].i = 0;
for(n = 0; n < HALFFFTSIZE-1; n++){
pPersistent->pIn[FFTSIZE-n-1].r = pPersistent->pIn[n+1].r;
pPersistent->pIn[FFTSIZE-n-1].i = -pPersistent->pIn[n+1].i;
}
// IFFT call
coeff=(float)FFTSIZE;
coeff=1/coeff;
for(n=0;n<FFTSIZE;n++)
{
pPersistent->pIn[n].i = -pPersistent->pIn[n].i;
}
THX_kiss_fft(pPersistent->state,
pPersistent->pIn,
pPersistent->pOut);
for(n=0;n < (unsigned int)FFTSIZE;n++)
{
pPersistent->pIn[n].i = -coeff*pPersistent->pIn[n].i;
pPersistent->pIn[n].r = coeff*pPersistent->pIn[n].r;
}
// Store all even indexes to output 0 and all odd indexes to output 1
for(n = 0; n < HALFFFTSIZE; n++){
Win = pPersistent->pSineWin[n];
PtrOut[n] = Win * pPersistent->pIn[n].r + pPersistent->pOverlappedBuffer[n]; // Real output
}
for(n = 0; n < HALFFFTSIZE; n++){
Win = pPersistent->pSineWin[n];
pPersistent->pOverlappedBuffer[HALFFFTSIZE-n-1] = Win * pPersistent->pIn[FFTSIZE-n-1].r;
}
return NRLSUR_OK;
}

View file

@ -0,0 +1,209 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Surround *//
//* File : FFT_Overlapped_Stereo.c *//
//* Description : A windowed and overlapped FFT and IFFT *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <stdlib.h>
#include <math.h>
//***************************************************************************//
//* FFT_Overlapped_Stereo_INIT(...) *//
//***************************************************************************//
int FFT_Overlapped_Stereo_INIT(FFT_Overlapped_Stereo_Struct * pPersistent,
float * pTempBuffer0, //Size must be 2*Framesize
float * pTempBuffer1, //Size must be 2*Framesize
unsigned int Framesize)
{
int n, j;
size_t memNeeded;
if(Framesize != HALFFFTSIZE) return UNSUPPORTED_FRAMESIZE;
pPersistent->pSineWin = (float*)GetSineWindow();
pPersistent->pReal = pTempBuffer0;
pPersistent->pImag = pTempBuffer1;
for(n = 0; n < HALFFFTSIZE; n++){
pPersistent->pOverlappedBuffer0[n] = 0;
pPersistent->pOverlappedBuffer1[n] = 0;
}
// Let's do something that will speed everything up
memNeeded = FFT_MEM_CHUNK;
pPersistent->state = THX_kiss_fft_alloc(FFTSIZE,0,fft_buff,&memNeeded);
// Lets make some memory for our buffers
for(j = 0; j < FFTSIZE; j++)
{
pPersistent->pIn[j].r = 0.0f;
pPersistent->pIn[j].i = 0.0f;
pPersistent->pOut[j].r = 0.0f;
pPersistent->pOut[j].i = 0.0f;
}
return NRLSUR_OK;
}
//***************************************************************************//
//* FFT_Overlapped_Stereo(...) *//
//***************************************************************************//
int FFT_Overlapped_Stereo(float * PtrIn0,
float * PtrOutReal0,
float * PtrOutImag0,
float * PtrIn1,
float * PtrOutReal1,
float * PtrOutImag1,
unsigned int Framesize,
FFT_Overlapped_Stereo_Struct * pPersistent)
{
unsigned int n;
float Win;
if(Framesize != HALFFFTSIZE) return UNSUPPORTED_FRAMESIZE;
// Put input0 values into every even index as "real" data and input1 values into every odd index as "imag" data
for(n = 0; n < HALFFFTSIZE; n++){
Win = pPersistent->pSineWin[n];
pPersistent->pIn[n ].r = Win * pPersistent->pOverlappedBuffer0[n];
pPersistent->pIn[n ].i = Win * pPersistent->pOverlappedBuffer1[n];
pPersistent->pIn[FFTSIZE-n-1].r = Win * PtrIn0[HALFFFTSIZE-n-1];
pPersistent->pIn[FFTSIZE-n-1].i = Win * PtrIn1[HALFFFTSIZE-n-1];
//Store in pOverlappedBuffer for next call
pPersistent->pOverlappedBuffer0[n] = PtrIn0[n];
pPersistent->pOverlappedBuffer1[n] = PtrIn1[n];
}
// FFT call
THX_kiss_fft(pPersistent->state,
pPersistent->pIn,
pPersistent->pOut);
// Pull the information out ...
// Now parse through the complex output to separate the two input signals
PtrOutReal0[0] = pPersistent->pOut[0].r; //Real value of DC coefficient
PtrOutImag0[0] = 0;
PtrOutReal1[0] = pPersistent->pOut[0].i; //Imag value of DC coefficient
PtrOutImag1[0] = 0;
for(n = 1; n < HALFFFTSIZE; n++){
PtrOutReal0[n] = (float)0.5 * ( pPersistent->pOut[n].r + pPersistent->pOut[FFTSIZE-n].r); // Real output
PtrOutImag0[n] = (float)0.5 * ( pPersistent->pOut[n].i - pPersistent->pOut[FFTSIZE-n].i); // Imag output
PtrOutReal1[n] = (float)0.5 * ( pPersistent->pOut[n].i + pPersistent->pOut[FFTSIZE-n].i); // Real output
PtrOutImag1[n] = (float)0.5 * (-pPersistent->pOut[n].r + pPersistent->pOut[FFTSIZE-n].r); // Imag output
}
return NRLSUR_OK;
}
//***************************************************************************//
//* IFFT_Overlapped_Stereo_INIT(...) *//
//***************************************************************************//
int IFFT_Overlapped_Stereo_INIT(IFFT_Overlapped_Stereo_Struct * pPersistent,
float * pTempBuffer0, //Size must be 2*Framesize
float * pTempBuffer1, //Size must be 2*Framesize
unsigned int Framesize)
{
int n, j;
size_t memNeeded;
if(Framesize != HALFFFTSIZE) return UNSUPPORTED_FRAMESIZE;
pPersistent->pSineWin = (float*)GetSineWindow();
pPersistent->pReal = pTempBuffer0;
pPersistent->pImag = pTempBuffer1;
for(n = 0; n < HALFFFTSIZE; n++){
pPersistent->pOverlappedBuffer0[n] = 0;
pPersistent->pOverlappedBuffer1[n] = 0;
}
// Let's do something that will speed everything up
memNeeded = FFT_MEM_CHUNK;
pPersistent->state = THX_kiss_fft_alloc(FFTSIZE,0,fft_buff,&memNeeded);
// Lets make some memory for our buffers
for(j = 0; j < FFTSIZE; j++)
{
pPersistent->pIn[j].r = 0.0f;
pPersistent->pIn[j].i = 0.0f;
pPersistent->pOut[j].r = 0.0f;
pPersistent->pOut[j].i = 0.0f;
}
return NRLSUR_OK;
}
//***************************************************************************//
//* IFFT_Overlapped_Stereo(...) *//
//***************************************************************************//
int IFFT_Overlapped_Stereo(float * PtrInReal0,
float * PtrInImag0,
float * PtrOut0,
float * PtrInReal1,
float * PtrInImag1,
float * PtrOut1,
unsigned int Framesize,
IFFT_Overlapped_Stereo_Struct * pPersistent)
{
unsigned int n;
float Win;
float coeff;
if(Framesize != HALFFFTSIZE) return UNSUPPORTED_FRAMESIZE;
//Sum X1 + j*X2
for(n = 0; n < HALFFFTSIZE; n++){
pPersistent->pIn[n].r = PtrInReal0[n] - PtrInImag1[n]; //Real
pPersistent->pIn[n].i = -(PtrInImag0[n] + PtrInReal1[n]); //Imag
}
//Use the input buffers as temporary buffers
pPersistent->pReal[HALFFFTSIZE] = 0;
pPersistent->pImag[HALFFFTSIZE] = 0;
for(n = 0; n < HALFFFTSIZE-1; n++){
pPersistent->pIn[FFTSIZE-n-1].r = PtrInReal0[n+1] + PtrInImag1[n+1];
pPersistent->pIn[FFTSIZE-n-1].i = -(-PtrInImag0[n+1] + PtrInReal1[n+1]);
}
// FFT call
THX_kiss_fft(pPersistent->state,
pPersistent->pIn,
pPersistent->pOut);
coeff = (float)FFTSIZE;
coeff = 1/coeff;
for(n = 0; n < FFTSIZE; n++)
{
pPersistent->pOut[n].i = -coeff * pPersistent->pOut[n].i;
pPersistent->pOut[n].r = coeff * pPersistent->pOut[n].r;
}
for(n = 0; n < HALFFFTSIZE; n++){
Win = pPersistent->pSineWin[n];
PtrOut0[n] = Win * pPersistent->pOut[n].r + pPersistent->pOverlappedBuffer0[n]; // Real output
PtrOut1[n] = Win * pPersistent->pOut[n].i + pPersistent->pOverlappedBuffer1[n]; // Real output
}
for(n = 0; n < HALFFFTSIZE; n++){
Win = pPersistent->pSineWin[n];
pPersistent->pOverlappedBuffer0[HALFFFTSIZE-n-1] = Win * pPersistent->pOut[FFTSIZE-n-1].r;
pPersistent->pOverlappedBuffer1[HALFFFTSIZE-n-1] = Win * pPersistent->pOut[FFTSIZE-n-1].i;
}
return NRLSUR_OK;
}

882
lib/neural_thx/FastMathApprox.c Executable file
View file

@ -0,0 +1,882 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio *//
//* File : FastMathApprox.c *//
//* Description : Fast math approximations *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <math.h>
#include <float.h>
#include "fmod_types.h"
//***************************************************************************//
//* FastMag(...) *//
//***************************************************************************//
#ifdef USE_MAG_APPROX
float FastMag(float r, float i)
{
return FastSqrt(r*r + i*i);
}
#else
float FastMag(float r, float i)
{
return (float)sqrtf(r*r + i*i);
}
#endif
//***************************************************************************//
//* FastMag_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_MAG_APPROX
void FastMag_ARRAY(float * PtrInRe,
float * PtrInIm,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = PtrInRe[n]*PtrInRe[n] + PtrInIm[n]*PtrInIm[n];
}
FastSqrt_ARRAY(PtrOut,PtrOut,Framesize);
}
#else
void FastMag_ARRAY(float * PtrInRe,
float * PtrInIm,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)sqrtf(PtrInRe[n]*PtrInRe[n] + PtrInIm[n]*PtrInIm[n]);
}
}
#endif
//***************************************************************************//
//* FastPhase_INIT(...) *//
//***************************************************************************//
void FastPhase_INIT(FastPhase_Struct * pParams,
float * TempBuffer0,
float * TempBuffer1,
float * TempBuffer2)
{
pParams->Quadrant = TempBuffer0;
pParams->Numerator = TempBuffer1;
pParams->Denominator = TempBuffer2;
}
//***************************************************************************//
//* FastPhase(...) *//
//***************************************************************************//
#ifdef USE_PHASE_APPROX
float FastPhase(float r, float i)
{
float temp, phase;
float Quadrant = 0, Numerator = 0, Denominator = 0;
//Shift by 0 degrees
Quadrant = 0;
Numerator = i;
Denominator = r;
if(i > r && i > -r){
//Shift by 90 degrees
Quadrant = 1;
Numerator = -r;
Denominator = i;
}
if(r <= i && r <= -i){
//Shift by 180 degrees
Quadrant = 2;
Numerator = i;
Denominator = r;
}
if(i <= r && i <= -r){
//Shift by 270 degrees
Quadrant = 3;
Numerator = -r;
Denominator = i;
}
if((float)fabs(Denominator) < (float)FLT_EPSILON)
Denominator = (float)FLT_EPSILON;
Denominator = 1.0f / Denominator;
Numerator *= Denominator;
temp = Numerator * Numerator;
phase = 0.0208351f;
phase *= temp;
phase -= 0.085133f;
phase *= temp;
phase += 0.180141f;
phase *= temp;
phase -= 0.3302995f;
phase *= temp;
phase += 0.999866f;
phase *= Numerator;
if(Quadrant == 1){
phase += 0.5f * (float)PI;
}
if(Quadrant == 2){
phase += (float)PI;
}
if(Quadrant == 3){
phase -= 0.5f * (float)PI;
}
if(phase > (float)PI)
phase -= 2.0f * (float)PI;
return phase;
}
#else
float FastPhase(float r, float i)
{
float phase, temp;
//Take the reciprocal of the real part
temp = r;
if(temp <= (float)FLT_EPSILON && temp >= -(float)FLT_EPSILON)
temp = (float)FLT_EPSILON;
temp = 1.0f / temp;
//Now take the arctan of the imag / real
temp = i * temp;
phase = (float)atanf(temp); //2 quadrant arctan
//Make into a 4 quadrant arctan
if(r < 0 && i >= 0){
phase += (float)PI;
}
if(r < 0 && i < 0){
phase -= (float)PI;
}
return phase;
}
#endif
//***************************************************************************//
//* FastPhase_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_PHASE_APPROX
void FastPhase_ARRAY(float * PtrInRe,
float * PtrInIm,
float * PtrOutPhase,
unsigned int Framesize,
FastPhase_Struct * pParams)
{
int n;
float temp;
for(n = 0; n < (int)Framesize; n++){
//Shift by 0 degrees
pParams->Quadrant[n] = 0;
pParams->Numerator[n] = PtrInIm[n];
pParams->Denominator[n] = PtrInRe[n];
if(PtrInIm[n] > PtrInRe[n] && PtrInIm[n] > -PtrInRe[n]){
//Shift by 90 degrees
pParams->Quadrant[n] = 1;
pParams->Numerator[n] = -PtrInRe[n];
pParams->Denominator[n] = PtrInIm[n];
}
if(PtrInRe[n] <= PtrInIm[n] && PtrInRe[n] <= -PtrInIm[n]){
//Shift by 180 degrees
pParams->Quadrant[n] = 2;
pParams->Numerator[n] = PtrInIm[n];
pParams->Denominator[n] = PtrInRe[n];
}
if(PtrInIm[n] <= PtrInRe[n] && PtrInIm[n] <= -PtrInRe[n]){
//Shift by 270 degrees
pParams->Quadrant[n] = 3;
pParams->Numerator[n] = -PtrInRe[n];
pParams->Denominator[n] = PtrInIm[n];
}
}
for(n = 0; n < (int)Framesize; n++){
if((float)fabs(pParams->Denominator[n]) < (float)FLT_EPSILON)
pParams->Denominator[n] = (float)FLT_EPSILON;
}
#ifdef PC_BUILD
for(n = 0; n < (int)Framesize; n++){
pParams->Denominator[n] = 1.0f / pParams->Denominator[n];
}
#endif
#ifdef DSP_BUILD
DSPF_sp_vecrecip(pParams->Denominator, pParams->Denominator, Framesize);
#endif
for(n = 0; n < (int)Framesize; n++){
pParams->Numerator[n] *= pParams->Denominator[n];
}
for(n = 0; n < (int)Framesize; n++){
temp = pParams->Numerator[n] * pParams->Numerator[n];
PtrOutPhase[n] = 0.0208351f;
PtrOutPhase[n] *= temp;
PtrOutPhase[n] -= 0.085133f;
PtrOutPhase[n] *= temp;
PtrOutPhase[n] += 0.180141f;
PtrOutPhase[n] *= temp;
PtrOutPhase[n] -= 0.3302995f;
PtrOutPhase[n] *= temp;
PtrOutPhase[n] += 0.999866f;
PtrOutPhase[n] *= pParams->Numerator[n];
}
for(n = 0; n < (int)Framesize; n++){
if(pParams->Quadrant[n] == 1){
PtrOutPhase[n] += 0.5f * (float)PI;
}
if(pParams->Quadrant[n] == 2){
PtrOutPhase[n] += (float)PI;
}
if(pParams->Quadrant[n] == 3){
PtrOutPhase[n] -= 0.5f * (float)PI;
}
}
for(n = 0; n < (int)Framesize; n++){
if(PtrOutPhase[n] > (float)PI)
PtrOutPhase[n] -= 2.0f * (float)PI;
}
}
#else
void FastPhase_ARRAY(float * PtrInRe,
float * PtrInIm,
float * PtrOutPhase,
unsigned int Framesize,
FastPhase_Struct * pParams)
{
int n;
float temp;
//Do the hard part first: the PHASE
//Take the reciprocal of the real part
for(n = 0; n < (int)Framesize; n++){
PtrOutPhase[n] = PtrInRe[n];
if(PtrOutPhase[n] <= (float)FLT_EPSILON && PtrOutPhase[n] >= -(float)FLT_EPSILON){
PtrOutPhase[n] = (float)FLT_EPSILON;
}
PtrOutPhase[n] = 1.0f / PtrOutPhase[n];
}
//Now take the arctan of the imag / real
for(n = 0; n < (int)Framesize; n++){
temp = PtrInIm[n] * PtrOutPhase[n];
PtrOutPhase[n] = atanf(temp); //2 quadrant arctan
}
for(n = 0; n < (int)Framesize; n++){
//Make into a 4 quadrant arctan
if(PtrInRe[n] < 0 && PtrInIm[n] >= 0){
PtrOutPhase[n] += (float)PI;
}
if(PtrInRe[n] < 0 && PtrInIm[n] < 0){
PtrOutPhase[n] -= (float)PI;
}
}
}
#endif
//***************************************************************************//
//* FastSqrt(...) *//
//***************************************************************************//
#ifdef USE_SQRT_APPROX
float FastSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits back to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
x = 2.0f*xhalf*x; // convert InvSqrt into Sqrt
return x;
}
#else
float FastSqrt(float x)
{
return (float)sqrtf(x);
}
#endif
//***************************************************************************//
//* FastSqrt_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_SQRT_APPROX
void FastSqrt_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
float x, xhalf;
int n, i;
static float Temp[NEURAL_FRAMESIZE];
for(n = 0; n < (int)Framesize; n++){
x = PtrIn[n];
i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i>>1); // gives initial guess y0
Temp[n] = *(float*)&i; // convert bits back to float
}
for(n = 0; n < (int)Framesize; n++){
x = Temp[n];
xhalf = 0.5f*PtrIn[n];
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
x = 2.0f*xhalf*x; // convert InvSqrt into Sqrt
PtrOut[n] = x;
}
/*
for(n = 0; n < (int)Framesize; n++){
x = LocalPtrIn[n];
xhalf = 0.5f*x;
i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits back to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
x = 2.0f*xhalf*x; // convert InvSqrt into Sqrt
LocalPtrOut[n] = x;
}
*/
}
#else
void FastSqrt_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)sqrtf(PtrIn[n]);
}
}
#endif
//***************************************************************************//
//* FastLog2(...) *//
//***************************************************************************//
#ifdef USE_LOG_APPROX
float FastLog2(float x)
{
ieee754_float32_t log2val, partial;
union {
ieee754_float32_t f;
int i;
} fi;
int mantisse;
ieee754_float32_t * LocalLogTable = (ieee754_float32_t *)LogTable;
if((1<<LOG2_SIZE_L2) != LOG2_SIZE)
return 0.0f;
fi.f = x;
mantisse = fi.i & 0x7fffff;
log2val = (ieee754_float32_t)(((fi.i>>23) & 0xFF)-0x7f);
partial = (ieee754_float32_t)((mantisse & ((1<<(23-LOG2_SIZE_L2))-1)));
partial *= 0.00006103515625f; //1.0f/((1<<(23-LOG2_SIZE_L2)));
mantisse >>= (23-LOG2_SIZE_L2);
// log2val += log_table[mantisse]; without interpolation the results are not good //
log2val += LocalLogTable[mantisse]*(1.0f-partial) + LocalLogTable[mantisse+1]*partial;
return log2val;
}
#else
float FastLog2(float x)
{
return 1.44269504088896f * logf(x);
}
#endif
//***************************************************************************//
//* FastLog2_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_LOG_APPROX
void FastLog2_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
ieee754_float32_t log2val, partial;
union {
ieee754_float32_t f;
int i;
} fi;
int mantisse;
int n;
ieee754_float32_t * LocalLogTable = (ieee754_float32_t *)LogTable;
if((1<<LOG2_SIZE_L2) != LOG2_SIZE)
return;
for(n = 0; n < (int)Framesize; n++){
fi.f = PtrIn[n];
mantisse = fi.i & 0x7fffff;
log2val = (ieee754_float32_t)(((fi.i>>23) & 0xFF)-0x7f);
partial = (ieee754_float32_t)((mantisse & ((1<<(23-LOG2_SIZE_L2))-1)));
partial *= 0.00006103515625f; //1.0f/((1<<(23-LOG2_SIZE_L2)));
mantisse >>= (23-LOG2_SIZE_L2);
// log2val += log_table[mantisse]; without interpolation the results are not good //
log2val += LocalLogTable[mantisse]*(1.0f-partial) + LocalLogTable[mantisse+1]*partial;
PtrOut[n] = log2val;
}
}
#else
void FastLog2_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
float norm = 1.44269504088896f;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = norm * logf(PtrIn[n]);
}
}
#endif
//***************************************************************************//
//* FastLog10(...) *//
//***************************************************************************//
#ifdef USE_LOG_APPROX
float FastLog10(float x)
{
float y = FastLog2(x);
y *= LOG2OVERLOG10;
return y;
}
#else
float FastLog10(float x)
{
return (float)log10f(x);
}
#endif
//***************************************************************************//
//* FastLog10_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_LOG_APPROX
void FastLog10_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
FastLog2_ARRAY(PtrIn,PtrOut,Framesize);
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] *= LOG2OVERLOG10;
}
}
#else
void FastLog10_ARRAY(float * restrict PtrIn,
float * restrict PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)log10f(PtrIn[n]);
}
}
#endif
//***************************************************************************//
//* FastLogln(...) *//
//***************************************************************************//
#ifdef USE_LOG_APPROX
float FastLogln(float x)
{
float y = FastLog2(x);
y *= LOG2;
return y;
}
#else
float FastLogln(float x)
{
return (float)logf(x);
}
#endif
//***************************************************************************//
//* FastLogln_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_LOG_APPROX
void FastLogln_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
FastLog2_ARRAY(PtrIn,PtrOut,Framesize);
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] *= LOG2;
}
}
#else
void FastLogln_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)logf(PtrIn[n]);
}
}
#endif
//***************************************************************************//
//* FastPow(...) *//
//***************************************************************************//
#ifdef USE_POW_APPROX
float FastPow(float x, float y)
{
return FastPow2(y*FastLog2(x));
}
#else
float FastPow(float x, float y)
{
return (float)FMOD_POW(x,y);
}
#endif
//***************************************************************************//
//* FastPow_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_POW_APPROX
void FastPow_ARRAY(float * PtrIn0,
float * PtrIn1,
float * PtrOut,
unsigned int Framesize)
{
int n;
FastLog2_ARRAY(PtrIn0,PtrOut,Framesize);
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] *= PtrIn1[n];
}
FastPow2_ARRAY(PtrOut,PtrOut,Framesize);
//for(n = 0; n < (int)Framesize; n++){
// PtrOut[n] = FastPow2(PtrIn1[n]*FastLog2(PtrIn0[n]));
//}
}
#else
void FastPow_ARRAY(float * PtrIn0,
float * PtrIn1,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)FMOD_POW(PtrIn0[n],PtrIn1[n]);
}
}
#endif
//***************************************************************************//
//* FastPow2(...) *//
//***************************************************************************//
#ifdef USE_POW_APPROX
float FastPow2(float i)
{
float shift23=(1<<23);
float PowBodge=0.33971f;
float x;
float y=i-FMOD_FLOOR(i);
y=(y-y*y)*PowBodge;
x=i+127-y;
x*= shift23; //pow(2,23);
*(int*)&x=(int)x;
return x;
}
#else
float FastPow2(float x)
{
return (float)FMOD_POW(2.0f,x);
}
#endif
//***************************************************************************//
//* FastPow2_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_POW_APPROX
void FastPow2_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
float shift23=(1<<23);
float i, PowBodge, x, y;
for(n = 0; n < (int)Framesize; n++){
i = PtrIn[n];
PowBodge=0.33971f;
x=(float)((i>0.0f)?(int)i:(int)(i-1.0f));
y=i-x; //floorf(i);
y=(y-y*y)*PowBodge;
PtrOut[n]=i+127-y;
}
for(n = 0; n < (int)Framesize; n++){
x=PtrOut[n];
x*=shift23; //pow(2,23);
*(int*)&x=(int)x;
PtrOut[n] = x;
}
}
#else
void FastPow2_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)FMOD_POW(2.0f,PtrIn[n]);
}
}
#endif
//***************************************************************************//
//* FastPow10(...) *//
//***************************************************************************//
#ifdef USE_POW_APPROX
float FastPow10(float x)
{
return FastPow2(x * 3.32192809488736f);
}
#else
float FastPow10(float x)
{
return (float)FMOD_POW(10.0f,x);
}
#endif
//***************************************************************************//
//* FastPow10_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_POW_APPROX
void FastPow10_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = PtrIn[n] * 3.32192809488736f;
}
FastPow2_ARRAY(PtrOut,PtrOut,Framesize);
}
#else
void FastPow10_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)FMOD_POW(10.0f,PtrIn[n]);
}
}
#endif
//***************************************************************************//
//* FastExp(...) *//
//***************************************************************************//
#ifdef USE_POW_APPROX
float FastExp(float x)
{
return FastPow2(x * 1.44269504064533f);
}
#else
float FastExp(float x)
{
return (float)expf(x);
}
#endif
//***************************************************************************//
//* FastExp_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_POW_APPROX
void FastExp_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = PtrIn[n] * 1.44269504064533f;
}
FastPow2_ARRAY(PtrOut,PtrOut,Framesize);
}
#else
void FastExp_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)expf(PtrIn[n]);
}
}
#endif
//***************************************************************************//
//* FastSin(...) *//
//***************************************************************************//
#ifdef USE_SIN_APPROX
float FastSin(float x)
{
float ASqr = x*x;
float Result = (float)-2.39e-08;
Result *= ASqr;
Result += (float)2.7526e-06;
Result *= ASqr;
Result -= (float)1.98409e-04;
Result *= ASqr;
Result += (float)8.3333315e-03;
Result *= ASqr;
Result -= (float)1.666666664e-01;
Result *= ASqr;
Result += (float)1.0;
Result *= x;
return Result;
}
#else
float FastSin(float x)
{
return (float)sin(x);
}
#endif
//***************************************************************************//
//* FastSin_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_SIN_APPROX
void FastSin_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
float ASqr, Result;
for(n = 0; n < (int)Framesize; n++){
ASqr = PtrIn[n]*PtrIn[n];
Result = (float)-2.39e-08;
Result *= ASqr;
Result += (float)2.7526e-06;
Result *= ASqr;
Result -= (float)1.98409e-04;
Result *= ASqr;
Result += (float)8.3333315e-03;
Result *= ASqr;
Result -= (float)1.666666664e-01;
Result *= ASqr;
Result += (float)1.0;
Result *= PtrIn[n];
PtrOut[n] = Result;
}
}
#else
void FastSin_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)sin(PtrIn[n]);
}
}
#endif
//***************************************************************************//
//* FastCos(...) *//
//***************************************************************************//
#ifdef USE_COS_APPROX
float FastCos(float x)
{
float ASqr = x*x;
float Result = (float)-2.605e-07;
Result *= ASqr;
Result += (float)2.47609e-05;
Result *= ASqr;
Result -= (float)1.3888397e-03;
Result *= ASqr;
Result += (float)4.16666418e-02;
Result *= ASqr;
Result -= (float)4.999999963e-01;
Result *= ASqr;
Result += (float)1.0;
return Result;
}
#else
float FastCos(float x)
{
return (float)cos(x);
}
#endif
//***************************************************************************//
//* FastCos_ARRAY(...) *//
//***************************************************************************//
#ifdef USE_COS_APPROX
void FastCos_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
float ASqr, Result;
for(n = 0; n < (int)Framesize; n++){
ASqr = PtrIn[n]*PtrIn[n];
Result = (float)-2.605e-07;
Result *= ASqr;
Result += (float)2.47609e-05;
Result *= ASqr;
Result -= (float)1.3888397e-03;
Result *= ASqr;
Result += (float)4.16666418e-02;
Result *= ASqr;
Result -= (float)4.999999963e-01;
Result *= ASqr;
Result += (float)1.0;
PtrOut[n] = Result;
}
}
#else
void FastCos_ARRAY(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
int n;
for(n = 0; n < (int)Framesize; n++){
PtrOut[n] = (float)cos(PtrIn[n]);
}
}
#endif

View file

@ -0,0 +1,112 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio *//
//* File : FreqDomain_PhaseShift.c *//
//* Description : Shift a frequency domain signal in phase *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <stdlib.h>
#include <math.h>
#include "fmod_types.h"
//***************************************************************************//
//* FreqDomain_PhaseShift_INIT(...) *//
//***************************************************************************//
//-----
//Phase shift by -90 degrees causes the output to lag the input by 90 degrees (similar to Hilbert Transform)
//Phase shift by +90 degrees causes the output to lead the input by 90 degrees
//-----
int FreqDomain_PhaseShift_INIT(float PhaseShift_Degrees, //Amount of phase shift (-90 degrees < x < 90 degrees)
unsigned int Framesize,
FreqDomain_PhaseShift_Struct * pPtr)
{
float PhaseShift_Radians;
pPtr->Prev_PhaseShift_Degrees = PhaseShift_Degrees;
if(PhaseShift_Degrees < -90.0f) PhaseShift_Degrees = -90.0f;
if(PhaseShift_Degrees > 90.0f) PhaseShift_Degrees = 90.0f;
PhaseShift_Radians = (float)PI * PhaseShift_Degrees / 180.0f;
pPtr->ShiftScalar_PositiveFreqs_Real = (float)FMOD_COS( PhaseShift_Radians );
pPtr->ShiftScalar_PositiveFreqs_Imag = (float)FMOD_SIN( PhaseShift_Radians );
return NRLSUR_OK;
}
//***************************************************************************//
//* FreqDomain_PhaseShift(...) *//
//***************************************************************************//
int FreqDomain_PhaseShift(float * PtrInReal,
float * PtrInImag,
float * PtrOutReal,
float * PtrOutImag,
float PhaseShift_Degrees, //Amount of phase shift (-90 degrees < x < 90 degrees)
unsigned int Framesize,
unsigned int SampleRate,
FreqDomain_PhaseShift_Struct * pPtr)
{
int n;
float PhaseShift_Radians, RealTemp, ImagTemp, RealShiftTemp, ImagShiftTemp;
const float *LowFreqSynthApFactors;
if(Framesize < NUMLOWFREQBINS) return UNSUPPORTED_FRAMESIZE;
//Use the tables appropriate with the samplerate
switch(SampleRate){
case SAMPLERATE_32_0:
LowFreqSynthApFactors = LowFreqSynthApFactors_32k;
break;
case SAMPLERATE_44_1:
LowFreqSynthApFactors = LowFreqSynthApFactors_44k;
break;
case SAMPLERATE_48_0:
LowFreqSynthApFactors = LowFreqSynthApFactors_48k;
break;
default:
return UNSUPPORTED_PARAMETER;
}
//If the amount of phase shift changes, re-calculate scaling constants
if(PhaseShift_Degrees != pPtr->Prev_PhaseShift_Degrees){
pPtr->Prev_PhaseShift_Degrees = PhaseShift_Degrees;
if(PhaseShift_Degrees < -90.0f) PhaseShift_Degrees = -90.0f;
if(PhaseShift_Degrees > 90.0f) PhaseShift_Degrees = 90.0f;
PhaseShift_Radians = (float)PI * PhaseShift_Degrees / 180.0f;
pPtr->ShiftScalar_PositiveFreqs_Real = (float)FMOD_COS( PhaseShift_Radians );
pPtr->ShiftScalar_PositiveFreqs_Imag = (float)FMOD_SIN( PhaseShift_Radians );
}
//Perform the phase shift which is a complex multiplication with pre-computed scalars
for(n = 0; n < NUMLOWFREQBINS; n++){ //Special handling of the low frequency bins since an ideal Hilbert transform is not possible
RealTemp = PtrInReal[n];
ImagTemp = PtrInImag[n];
RealShiftTemp = 1.0f * (1.0f - LowFreqSynthApFactors[n]) + pPtr->ShiftScalar_PositiveFreqs_Real * LowFreqSynthApFactors[n];
ImagShiftTemp = 0.0f * (1.0f - LowFreqSynthApFactors[n]) + pPtr->ShiftScalar_PositiveFreqs_Imag * LowFreqSynthApFactors[n];
PtrOutReal[n] = RealTemp * RealShiftTemp - ImagTemp * ImagShiftTemp;
PtrOutImag[n] = RealTemp * ImagShiftTemp + ImagTemp * RealShiftTemp;
}
for(n = NUMLOWFREQBINS; n < (int)Framesize; n++){
RealTemp = PtrInReal[n];
ImagTemp = PtrInImag[n];
PtrOutReal[n] = RealTemp * pPtr->ShiftScalar_PositiveFreqs_Real - ImagTemp * pPtr->ShiftScalar_PositiveFreqs_Imag;
PtrOutImag[n] = RealTemp * pPtr->ShiftScalar_PositiveFreqs_Imag + ImagTemp * pPtr->ShiftScalar_PositiveFreqs_Real;
}
return NRLSUR_OK;
}

102
lib/neural_thx/LR4_LP.c Executable file
View file

@ -0,0 +1,102 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio *//
//* File : LR4_LP.c *//
//* Description : Linkwitz-Riley 4th order Low-Pass filter *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2005 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <math.h>
#include "fmod_types.h"
//***************************************************************************//
//* LR4_LP_INIT(...) *//
//***************************************************************************//
void LR4_LP_INIT(LR4_LP_Struct * pPtr)
{
pPtr->PrevCutOff = -1.0f;
pPtr->PrevStage00 = 0.0f;
pPtr->PrevStage01 = 0.0f;
pPtr->PrevStage10 = 0.0f;
pPtr->PrevStage11 = 0.0f;
pPtr->b0 = 0.0f;
pPtr->b1 = 0.0f;
pPtr->b2 = 0.0f;
pPtr->a0 = 0.0f;
pPtr->a1 = 0.0f;
pPtr->PrevSampleRate = -1.0f;
}
//***************************************************************************//
//* LR4_LP(...) *//
//***************************************************************************//
void LR4_LP(float * PtrIn,
float * PtrOut,
float Cutoff, //in Hertz
unsigned int Framesize,
unsigned int SampleRate,
LR4_LP_Struct * pPtr)
{
int n;
float midStage = 0.0f; // Local buffer
//----- Note that this only works for fourth order LR filters -----//
//----- Calculate the filter coefficients -----//
if( Cutoff != pPtr->PrevCutOff || (float)SampleRate != pPtr->PrevSampleRate ){
//----- Pre-warp the digital cutoff frequency to an analog equivalent -----//
float omegac = (float)2.0 * FMOD_TAN( (float)PI*(Cutoff) / (float)SampleRate );
float norm = (float)4.0 + omegac*(float)TWOPOWTHREEHALVES + omegac*omegac;
norm = (float)1.0 / norm;
pPtr->b0 = (omegac*omegac) * norm;
pPtr->b1 = (float)2.0*pPtr->b0;
pPtr->b2 = pPtr->b0;
pPtr->a0 = ((float)2.0*omegac*omegac - (float)8.0) * norm;
pPtr->a1 = ((float)4.0 - omegac*(float)TWOPOWTHREEHALVES + omegac*omegac) * norm;
pPtr->PrevCutOff = Cutoff;
pPtr->PrevSampleRate = (float)SampleRate;
}
//------------------------------------------------------------------//
// Perform the filtering through a cascade of second order stages //
//------------------------------------------------------------------//
// Stage 1
for(n = 0; n < (int)Framesize; n++){
midStage = PtrIn[n]
- pPtr->PrevStage00 * pPtr->a0
- pPtr->PrevStage01 * pPtr->a1;
PtrOut[n] = midStage * pPtr->b0
+ pPtr->PrevStage00 * pPtr->b1
+ pPtr->PrevStage01 * pPtr->b2;
pPtr->PrevStage01 = pPtr->PrevStage00;
pPtr->PrevStage00 = midStage;
}
// Stage 2
for(n = 0; n < (int)Framesize; n++){
midStage = PtrOut[n]
- pPtr->PrevStage10 * pPtr->a0
- pPtr->PrevStage11 * pPtr->a1;
PtrOut[n] = midStage * pPtr->b0
+ pPtr->PrevStage10 * pPtr->b1
+ pPtr->PrevStage11 * pPtr->b2;
pPtr->PrevStage11 = pPtr->PrevStage10;
pPtr->PrevStage10 = midStage;
}
}

110
lib/neural_thx/Limiter.c Executable file
View file

@ -0,0 +1,110 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio *//
//* File : Limiter.c *//
//* Description : Limiter *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include "fmod_types.h"
//***************************************************************************//
//* Limiter_INIT(...) *//
//***************************************************************************//
int Limiter_INIT(float * TempBuffer,
Limiter_Struct * pPtr)
{
pPtr->TempBuffer = TempBuffer;
PeakConverter_INIT(0.0f,0.0f,0.0f,0.0f,0,&pPtr->EnvSmoother);
return NRLSUR_OK;
}
//***************************************************************************//
//* Compressor(...) *//
//***************************************************************************//
int Limiter(float * AudioIn,
float * AudioOut,
float MaxAudioValue,
float Knee, //in dB referenced to zero dB
float Ceiling, //in dB referenced to zero dB
float RiseTime, //in msec
float FallTime, //in msec
unsigned int Framesize,
unsigned int SampleRate,
Limiter_Struct * pPtr)
{
int n;
float fTemp;
if(Knee > Ceiling) Knee = Ceiling;
CopyArray(AudioIn,pPtr->TempBuffer,Framesize);
//First normalize audio
if(MaxAudioValue < (float)FLT_EPSILON)
MaxAudioValue = (float)FLT_EPSILON;
fTemp = 1.0f / MaxAudioValue;
ScaleArray(pPtr->TempBuffer,fTemp,Framesize);
//First convert the audio to the dB domain
AbsValue(pPtr->TempBuffer,Framesize);
MinClip(pPtr->TempBuffer,(float)FLT_EPSILON,Framesize);
MaxClip(pPtr->TempBuffer,1.0f,Framesize);
FastLog10_ARRAY(pPtr->TempBuffer,pPtr->TempBuffer,Framesize);
ScaleArray(pPtr->TempBuffer,20.0f,Framesize);
//Smooth the envelope
PeakConverter(pPtr->TempBuffer,
pPtr->TempBuffer,
RiseTime, //in msec
FallTime, //in msec
-60.0f,
0.0f,
Framesize,
SampleRate,
&pPtr->EnvSmoother);
//Apply the knee and ceiling parameters
for(n = 0; n < (int)Framesize; n++){
fTemp = pPtr->TempBuffer[n];
pPtr->TempBuffer[n] = 0.0f;
if(fTemp > Knee){
pPtr->TempBuffer[n] = 0.5f * (Knee - fTemp);
fTemp = fTemp + pPtr->TempBuffer[n];
}
if(fTemp > Ceiling){
pPtr->TempBuffer[n] += Ceiling - fTemp;
fTemp = fTemp + pPtr->TempBuffer[n];
}
}
//Convert back to linear domain
MaxClip(pPtr->TempBuffer,0.0f,Framesize);
ScaleArray(pPtr->TempBuffer,0.05f,Framesize);
FastPow10_ARRAY(pPtr->TempBuffer,pPtr->TempBuffer,Framesize);
//Limit the audio signal
Multiply2(AudioIn,pPtr->TempBuffer,AudioOut,Framesize);
Ceiling = FMOD_POW(10.0f,0.05f*Ceiling) * MaxAudioValue;
SaturateArray(AudioOut,Ceiling,Framesize);
return NRLSUR_OK;
}

View file

@ -0,0 +1,189 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio - THX *//
//* File : Neural_THX_522_Encode.c *//
//* Description : Neural Surround Downmix implementation *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <stdlib.h>
//***************************************************************************//
//* Neural_THX_522_Encode_INIT(...) *//
//***************************************************************************//
int Neural_THX_522_Encode_INIT(unsigned int Framesize,
unsigned int ChanConfig,
unsigned int SampleRate,
Neural_THX_522_Encode_Struct * pParams)
{
//Forward and inverse overlapped FFT's
FFT_Overlapped_Stereo_INIT(&pParams->FFTSourceLR,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
FFT_Overlapped_INIT(&pParams->FFTSourceC,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
FFT_Overlapped_Stereo_INIT(&pParams->FFTSourceLsRs,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
IFFT_Overlapped_Stereo_INIT(&pParams->InvFFTDownmixLR,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
//Initialize phase shifts
FreqDomain_PhaseShift_INIT(-22.5f,NEURAL_FRAMESIZE,&pParams->PhaseShift_L);
FreqDomain_PhaseShift_INIT(+22.5f,NEURAL_FRAMESIZE,&pParams->PhaseShift_R);
FreqDomain_PhaseShift_INIT(-90.0f,NEURAL_FRAMESIZE,&pParams->PhaseShift_Ls);
FreqDomain_PhaseShift_INIT(+90.0f,NEURAL_FRAMESIZE,&pParams->PhaseShift_Rs);
LR4_LP_INIT(&pParams->LFE_LP);
//Init final limiters
Limiter_INIT(pParams->TempBuffer0,&pParams->FinalLimiterL);
Limiter_INIT(pParams->TempBuffer0,&pParams->FinalLimiterR);
return NRLSUR_OK;
}
//***************************************************************************//
//* Neural_THX_522_Encode(...) *//
//***************************************************************************//
int Neural_THX_522_Encode(float * PtrInL,
float * PtrInR,
float * PtrInC,
float * PtrInLFE,
float * PtrInLs,
float * PtrInRs,
float * PtrOutL,
float * PtrOutR,
THX_bool UseFinalLimiting,
float LFE_Cutoff,
unsigned int Framesize,
unsigned int ChanConfig,
unsigned int SampleRate,
Neural_THX_522_Encode_Struct * pParams)
{
//Neural Surround Downmix
//***********************************************************
//***** Low-pass filter the LFE channel (if selected) *****
//***********************************************************
if(LFE_Cutoff > 40.0f && LFE_Cutoff < 200.0f){
LR4_LP(PtrInLFE,PtrInLFE,LFE_Cutoff,NEURAL_FRAMESIZE,SampleRate,&pParams->LFE_LP);
}
//First sum LFE channel into Center channel
Add2(PtrInC,PtrInLFE,PtrInC,NEURAL_FRAMESIZE);
//****************************************************************************************************
//***** Begin downmix by transforming all signals to frequency domain and performing phase shift *****
//****************************************************************************************************
//Convert all input channels to freq domain
//L-R channels
FFT_Overlapped_Stereo(PtrInL,pParams->Input_RealL,pParams->Input_ImagL,
PtrInR,pParams->Input_RealR,pParams->Input_ImagR,
NEURAL_FRAMESIZE,&pParams->FFTSourceLR);
//C channel
FFT_Overlapped(PtrInC,pParams->Input_RealC,pParams->Input_ImagC,
NEURAL_FRAMESIZE,&pParams->FFTSourceC);
//Ls-Rs channels
FFT_Overlapped_Stereo(PtrInLs,pParams->Input_RealLs,pParams->Input_ImagLs,
PtrInRs,pParams->Input_RealRs,pParams->Input_ImagRs,
NEURAL_FRAMESIZE,&pParams->FFTSourceLsRs);
//Phase shift L channel
FreqDomain_PhaseShift(pParams->Input_RealL,pParams->Input_ImagL,
pParams->Input_RealL,pParams->Input_ImagL,
-22.5f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_L);
//Phase shift R channel
FreqDomain_PhaseShift(pParams->Input_RealR,pParams->Input_ImagR,
pParams->Input_RealR,pParams->Input_ImagR,
+22.5f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_R);
//Phase shift Ls channel
FreqDomain_PhaseShift(pParams->Input_RealLs,pParams->Input_ImagLs,
pParams->Input_RealLs,pParams->Input_ImagLs,
-90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Ls);
//Phase shift Rs channel
FreqDomain_PhaseShift(pParams->Input_RealRs,pParams->Input_ImagRs,
pParams->Input_RealRs,pParams->Input_ImagRs,
+90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Rs);
//Scale center and lfe channels by -3dB
ScaleArray(pParams->Input_RealC,(float)MINUS_3DB,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_ImagC,(float)MINUS_3DB,NEURAL_FRAMESIZE);
//Add center and lfe channels to left/right phase shifted channels
//L channel
Add2(pParams->Input_RealL,pParams->Input_RealC,pParams->Downmix_RealL,NEURAL_FRAMESIZE);
Add2(pParams->Input_ImagL,pParams->Input_ImagC,pParams->Downmix_ImagL,NEURAL_FRAMESIZE);
//R channel
Add2(pParams->Input_RealR,pParams->Input_RealC,pParams->Downmix_RealR,NEURAL_FRAMESIZE);
Add2(pParams->Input_ImagR,pParams->Input_ImagC,pParams->Downmix_ImagR,NEURAL_FRAMESIZE);
//***********************************************************
//***** Combine the front channels with the surrounds *****
//***********************************************************
ScaleArray(pParams->Input_RealLs,(float)CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_ImagLs,(float)CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_RealRs,(float)CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_ImagRs,(float)CROSSSHARENORM,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_RealL,pParams->Input_RealLs,pParams->Downmix_RealL,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_ImagL,pParams->Input_ImagLs,pParams->Downmix_ImagL,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_RealR,pParams->Input_RealRs,pParams->Downmix_RealR,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_ImagR,pParams->Input_ImagRs,pParams->Downmix_ImagR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_RealLs,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_RealR,pParams->TempBuffer0,pParams->Downmix_RealR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_ImagLs,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_ImagR,pParams->TempBuffer0,pParams->Downmix_ImagR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_RealRs,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_RealL,pParams->TempBuffer0,pParams->Downmix_RealL,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_ImagRs,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_ImagL,pParams->TempBuffer0,pParams->Downmix_ImagL,NEURAL_FRAMESIZE);
//***********************************************************
//***** Inverse filterbank back to time signals *****
//***********************************************************
IFFT_Overlapped_Stereo(pParams->Downmix_RealL,pParams->Downmix_ImagL,PtrOutL,
pParams->Downmix_RealR,pParams->Downmix_ImagR,PtrOutR,
NEURAL_FRAMESIZE,&pParams->InvFFTDownmixLR);
if(UseFinalLimiting){
//Perform final limiting on the output signals
Limiter(PtrOutL,PtrOutL,
(float)AUDIO_VAL_MAX,
-6.0f,-0.1f,
0.0f,500.0f,
NEURAL_FRAMESIZE,SampleRate,&pParams->FinalLimiterL);
Limiter(PtrOutR,PtrOutR,
(float)AUDIO_VAL_MAX,
-6.0f,-0.1f,
0.0f,500.0f,
NEURAL_FRAMESIZE,SampleRate,&pParams->FinalLimiterR);
}
//That's all folks
SaturateArray(PtrOutL,(float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
SaturateArray(PtrOutR,(float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
return NRLSUR_OK;
}

View file

@ -0,0 +1,233 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio - THX *//
//* File : Neural_THX_722_Encode.c *//
//* Description : Neural Surround Downmix implementation *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <stdlib.h>
//***************************************************************************//
//* Neural_THX_722_Encode_INIT(...) *//
//***************************************************************************//
int Neural_THX_722_Encode_INIT(unsigned int Framesize,
unsigned int ChanConfig,
unsigned int SampleRate,
Neural_THX_722_Encode_Struct * pParams)
{
//Forward and inverse overlapped FFT's
FFT_Overlapped_Stereo_INIT(&pParams->FFTSourceLR,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
FFT_Overlapped_INIT(&pParams->FFTSourceC,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
FFT_Overlapped_Stereo_INIT(&pParams->FFTSourceLsRs,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
FFT_Overlapped_Stereo_INIT(&pParams->FFTSourceLbRb,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
IFFT_Overlapped_Stereo_INIT(&pParams->InvFFTDownmixLR,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
//Initialize phase shifts
FreqDomain_PhaseShift_INIT(-22.5f,NEURAL_FRAMESIZE,&pParams->PhaseShift_L);
FreqDomain_PhaseShift_INIT(+22.5f,NEURAL_FRAMESIZE,&pParams->PhaseShift_R);
FreqDomain_PhaseShift_INIT(-90.0f,NEURAL_FRAMESIZE,&pParams->PhaseShift_Ls);
FreqDomain_PhaseShift_INIT(+90.0f,NEURAL_FRAMESIZE,&pParams->PhaseShift_Rs);
LR4_LP_INIT(&pParams->LFE_LP);
//Init final limiters
Limiter_INIT(pParams->TempBuffer0,&pParams->FinalLimiterL);
Limiter_INIT(pParams->TempBuffer0,&pParams->FinalLimiterR);
return NRLSUR_OK;
}
//***************************************************************************//
//* Neural_THX_722_Encode(...) *//
//***************************************************************************//
int Neural_THX_722_Encode(float * PtrInL,
float * PtrInR,
float * PtrInC,
float * PtrInLFE,
float * PtrInLs,
float * PtrInRs,
float * PtrInLb,
float * PtrInRb,
float * PtrOutL,
float * PtrOutR,
THX_bool UseFinalLimiting,
float LFE_Cutoff,
unsigned int Framesize,
unsigned int ChanConfig,
unsigned int SampleRate,
Neural_THX_722_Encode_Struct * pParams)
{
//Neural Surround Downmix
//***********************************************************
//***** Low-pass filter the LFE channel (if selected) *****
//***********************************************************
if(LFE_Cutoff > 40.0f && LFE_Cutoff < 200.0f){
LR4_LP(PtrInLFE,PtrInLFE,LFE_Cutoff,NEURAL_FRAMESIZE,SampleRate,&pParams->LFE_LP);
}
//First sum LFE channel into Center channel
Add2(PtrInC,PtrInLFE,PtrInC,NEURAL_FRAMESIZE);
//****************************************************************************************************
//***** Begin downmix by transforming all signals to frequency domain and performing phase shift *****
//****************************************************************************************************
//Convert all input channels to freq domain
//L-R channels
FFT_Overlapped_Stereo(PtrInL,pParams->Input_RealL,pParams->Input_ImagL,
PtrInR,pParams->Input_RealR,pParams->Input_ImagR,
NEURAL_FRAMESIZE,&pParams->FFTSourceLR);
//C channel
FFT_Overlapped(PtrInC,pParams->Input_RealC,pParams->Input_ImagC,
NEURAL_FRAMESIZE,&pParams->FFTSourceC);
//Ls-Rs channels
FFT_Overlapped_Stereo(PtrInLs,pParams->Input_RealLs,pParams->Input_ImagLs,
PtrInRs,pParams->Input_RealRs,pParams->Input_ImagRs,
NEURAL_FRAMESIZE,&pParams->FFTSourceLsRs);
//Lb-Rb channels
FFT_Overlapped_Stereo(PtrInLb,pParams->Input_RealLb,pParams->Input_ImagLb,
PtrInRb,pParams->Input_RealRb,pParams->Input_ImagRb,
NEURAL_FRAMESIZE,&pParams->FFTSourceLbRb);
//Phase shift L channel
FreqDomain_PhaseShift(pParams->Input_RealL,pParams->Input_ImagL,
pParams->Input_RealL,pParams->Input_ImagL,
-22.5f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_L);
//Phase shift R channel
FreqDomain_PhaseShift(pParams->Input_RealR,pParams->Input_ImagR,
pParams->Input_RealR,pParams->Input_ImagR,
+22.5f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_R);
//Phase shift Ls channel
FreqDomain_PhaseShift(pParams->Input_RealLs,pParams->Input_ImagLs,
pParams->Input_RealLs,pParams->Input_ImagLs,
-90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Ls);
//Phase shift Rs channel
FreqDomain_PhaseShift(pParams->Input_RealRs,pParams->Input_ImagRs,
pParams->Input_RealRs,pParams->Input_ImagRs,
+90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Rs);
//Phase shift Lb channel
FreqDomain_PhaseShift(pParams->Input_RealLb,pParams->Input_ImagLb,
pParams->Input_RealLb,pParams->Input_ImagLb,
-90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Ls);
//Phase shift Rb channel
FreqDomain_PhaseShift(pParams->Input_RealRb,pParams->Input_ImagRb,
pParams->Input_RealRb,pParams->Input_ImagRb,
+90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Rs);
//Scale center and lfe channels by -3dB
ScaleArray(pParams->Input_RealC,(float)MINUS_3DB,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_ImagC,(float)MINUS_3DB,NEURAL_FRAMESIZE);
//Add center and lfe channels to left/right phase shifted channels
//L channel
Add2(pParams->Input_RealL,pParams->Input_RealC,pParams->Downmix_RealL,NEURAL_FRAMESIZE);
Add2(pParams->Input_ImagL,pParams->Input_ImagC,pParams->Downmix_ImagL,NEURAL_FRAMESIZE);
//R channel
Add2(pParams->Input_RealR,pParams->Input_RealC,pParams->Downmix_RealR,NEURAL_FRAMESIZE);
Add2(pParams->Input_ImagR,pParams->Input_ImagC,pParams->Downmix_ImagR,NEURAL_FRAMESIZE);
//***********************************************************
//***** Combine the front channels with the surrounds *****
//***********************************************************
ScaleArray(pParams->Input_RealLs,(float)SUR_CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_ImagLs,(float)SUR_CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_RealRs,(float)SUR_CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_ImagRs,(float)SUR_CROSSSHARENORM,NEURAL_FRAMESIZE);
//----- Back channels -----
ScaleArray(pParams->Input_RealLb,(float)BACK_CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_ImagLb,(float)BACK_CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_RealRb,(float)BACK_CROSSSHARENORM,NEURAL_FRAMESIZE);
ScaleArray(pParams->Input_ImagRb,(float)BACK_CROSSSHARENORM,NEURAL_FRAMESIZE);
//----- Surround channels -----
Add2(pParams->Downmix_RealL,pParams->Input_RealLs,pParams->Downmix_RealL,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_ImagL,pParams->Input_ImagLs,pParams->Downmix_ImagL,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_RealR,pParams->Input_RealRs,pParams->Downmix_RealR,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_ImagR,pParams->Input_ImagRs,pParams->Downmix_ImagR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_RealLs,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-SUR_CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_RealR,pParams->TempBuffer0,pParams->Downmix_RealR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_ImagLs,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-SUR_CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_ImagR,pParams->TempBuffer0,pParams->Downmix_ImagR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_RealRs,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-SUR_CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_RealL,pParams->TempBuffer0,pParams->Downmix_RealL,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_ImagRs,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-SUR_CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_ImagL,pParams->TempBuffer0,pParams->Downmix_ImagL,NEURAL_FRAMESIZE);
//----- Back channels -----
Add2(pParams->Downmix_RealL,pParams->Input_RealLb,pParams->Downmix_RealL,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_ImagL,pParams->Input_ImagLb,pParams->Downmix_ImagL,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_RealR,pParams->Input_RealRb,pParams->Downmix_RealR,NEURAL_FRAMESIZE);
Add2(pParams->Downmix_ImagR,pParams->Input_ImagRb,pParams->Downmix_ImagR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_RealLb,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-BACK_CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_RealR,pParams->TempBuffer0,pParams->Downmix_RealR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_ImagLb,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-BACK_CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_ImagR,pParams->TempBuffer0,pParams->Downmix_ImagR,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_RealRb,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-BACK_CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_RealL,pParams->TempBuffer0,pParams->Downmix_RealL,NEURAL_FRAMESIZE);
CopyArray(pParams->Input_ImagRb,pParams->TempBuffer0,NEURAL_FRAMESIZE);
ScaleArray(pParams->TempBuffer0,-BACK_CROSSSHARECONSTANT,Framesize);
Add2(pParams->Downmix_ImagL,pParams->TempBuffer0,pParams->Downmix_ImagL,NEURAL_FRAMESIZE);
//***********************************************************
//***** Inverse filterbank back to time signals *****
//***********************************************************
IFFT_Overlapped_Stereo(pParams->Downmix_RealL,pParams->Downmix_ImagL,PtrOutL,
pParams->Downmix_RealR,pParams->Downmix_ImagR,PtrOutR,
NEURAL_FRAMESIZE,&pParams->InvFFTDownmixLR);
if(UseFinalLimiting){
//Perform final limiting on the output signals
Limiter(PtrOutL,PtrOutL,
(float)AUDIO_VAL_MAX,
-6.0f,-0.1f,
0.0f,500.0f,
NEURAL_FRAMESIZE,SampleRate,&pParams->FinalLimiterL);
Limiter(PtrOutR,PtrOutR,
(float)AUDIO_VAL_MAX,
-6.0f,-0.1f,
0.0f,500.0f,
NEURAL_FRAMESIZE,SampleRate,&pParams->FinalLimiterR);
}
//That's all folks
SaturateArray(PtrOutL,(float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
SaturateArray(PtrOutR,(float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
return NRLSUR_OK;
}

View file

@ -0,0 +1,207 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio - THX *//
//* File : Neural_THX_725_Encode.c *//
//* Description : Downmixer for Neural - THX gaming mode from 7.1 to 5.1 *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <stdlib.h>
#include <math.h>
//***************************************************************************//
//* Neural_THX_725_Encode_INIT(...) *//
//***************************************************************************//
int Neural_THX_725_Encode_INIT(unsigned int Framesize,
unsigned int ChanConfig,
unsigned int SampleRate,
Neural_THX_725_Encode_Struct * pParams)
{
//Initialize the FFT transforms
FFT_Overlapped_Stereo_INIT(&pParams->Transform_LsRs,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
FFT_Overlapped_Stereo_INIT(&pParams->Transform_LbRb,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
IFFT_Overlapped_Stereo_INIT(&pParams->InvTransform_LsRs,pParams->TempBuffer0,pParams->TempBuffer1,NEURAL_FRAMESIZE);
//Initialize phase shifts
FreqDomain_PhaseShift_INIT(+90.0f,NEURAL_FRAMESIZE,&pParams->PhaseShift_Pos);
FreqDomain_PhaseShift_INIT(-90.0f,NEURAL_FRAMESIZE,&pParams->PhaseShift_Neg);
#ifdef COMPENSATION_FRONT_DELAY
//Initialize delays
if(Delay_INIT(NEURAL_FRAMESIZE,&pParams->DelayChanL) < 0) return INIT_ERROR;
if(Delay_INIT(NEURAL_FRAMESIZE,&pParams->DelayChanR) < 0) return INIT_ERROR;
if(Delay_INIT(NEURAL_FRAMESIZE,&pParams->DelayChanC) < 0) return INIT_ERROR;
if(Delay_INIT(NEURAL_FRAMESIZE,&pParams->DelayChanLFE) < 0) return INIT_ERROR;
#endif
//Init final limiters
Limiter_INIT(pParams->TempBuffer0,&pParams->FinalLimiterLs);
Limiter_INIT(pParams->TempBuffer0,&pParams->FinalLimiterRs);
return NRLSUR_OK;
}
//***************************************************************************//
//* Neural_THX_725_Encode(...) *//
//***************************************************************************//
int Neural_THX_725_Encode(float * PtrInL, //7.1 In
float * PtrInR,
float * PtrInC,
float * PtrInLFE,
float * PtrInLs,
float * PtrInRs,
float * PtrInLb,
float * PtrInRb,
float * PtrOutL, //5.1 Out
float * PtrOutR,
float * PtrOutC,
float * PtrOutLFE,
float * PtrOutLs,
float * PtrOutRs,
THX_bool UseFinalLimiting,
unsigned int Framesize,
unsigned int ChanConfig,
unsigned int SampleRate,
Neural_THX_725_Encode_Struct * pParams)
{
//Neural Audio - THX Gaming Downmix
//Downmix 7.1 format to 5.1 format
float * PhaseShift_RealLb_Pos = &pParams->TempBuffer0[0*NEURAL_FRAMESIZE];
float * PhaseShift_ImagLb_Pos = &pParams->TempBuffer0[1*NEURAL_FRAMESIZE];
float * PhaseShift_RealRb_Pos = &pParams->TempBuffer0[2*NEURAL_FRAMESIZE];
float * PhaseShift_ImagRb_Pos = &pParams->TempBuffer0[3*NEURAL_FRAMESIZE];
float * PhaseShift_RealLb_Neg = &pParams->TempBuffer1[0*NEURAL_FRAMESIZE];
float * PhaseShift_ImagLb_Neg = &pParams->TempBuffer1[1*NEURAL_FRAMESIZE];
float * PhaseShift_RealRb_Neg = &pParams->TempBuffer1[2*NEURAL_FRAMESIZE];
float * PhaseShift_ImagRb_Neg = &pParams->TempBuffer1[3*NEURAL_FRAMESIZE];
//***********************************************************
//***** Surround channel downmixing *****
//***********************************************************
//Convert all input channels to freq domain
FFT_Overlapped_Stereo(PtrInLs,pParams->Input_RealLs,pParams->Input_ImagLs,
PtrInRs,pParams->Input_RealRs,pParams->Input_ImagRs,
NEURAL_FRAMESIZE,&pParams->Transform_LsRs);
FFT_Overlapped_Stereo(PtrInLb,pParams->Input_RealLb,pParams->Input_ImagLb,
PtrInRb,pParams->Input_RealRb,pParams->Input_ImagRb,
NEURAL_FRAMESIZE,&pParams->Transform_LbRb);
//Phase shift Lb channel
FreqDomain_PhaseShift(pParams->Input_RealLb,pParams->Input_ImagLb,
PhaseShift_RealLb_Pos,PhaseShift_ImagLb_Pos,
+90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Pos);
FreqDomain_PhaseShift(pParams->Input_RealLb,pParams->Input_ImagLb,
PhaseShift_RealLb_Neg,PhaseShift_ImagLb_Neg,
-90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Neg);
//Phase shift Rb channel
FreqDomain_PhaseShift(pParams->Input_RealRb,pParams->Input_ImagRb,
PhaseShift_RealRb_Pos,PhaseShift_ImagRb_Pos,
+90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Pos);
FreqDomain_PhaseShift(pParams->Input_RealRb,pParams->Input_ImagRb,
PhaseShift_RealRb_Neg,PhaseShift_ImagRb_Neg,
-90.0f,NEURAL_FRAMESIZE,SampleRate,&pParams->PhaseShift_Neg);
//-----
//Generate Left Surround
//-----
//Real
Add2(pParams->Input_RealLs,PhaseShift_RealLb_Pos,pParams->Dmix_RealLs,NEURAL_FRAMESIZE);
ScaleArray(PhaseShift_RealRb_Pos,BACK_CROSS_SHARE,NEURAL_FRAMESIZE);
Add2(pParams->Dmix_RealLs,PhaseShift_RealRb_Pos,pParams->Dmix_RealLs,NEURAL_FRAMESIZE);
//Imag
Add2(pParams->Input_ImagLs,PhaseShift_ImagLb_Pos,pParams->Dmix_ImagLs,NEURAL_FRAMESIZE);
ScaleArray(PhaseShift_ImagRb_Pos,BACK_CROSS_SHARE,NEURAL_FRAMESIZE);
Add2(pParams->Dmix_ImagLs,PhaseShift_ImagRb_Pos,pParams->Dmix_ImagLs,NEURAL_FRAMESIZE);
//-----
//Generate Right Surround
//-----
//Real
Add2(pParams->Input_RealRs,PhaseShift_RealRb_Neg,pParams->Dmix_RealRs,NEURAL_FRAMESIZE);
ScaleArray(PhaseShift_RealLb_Neg,BACK_CROSS_SHARE,NEURAL_FRAMESIZE);
Add2(pParams->Dmix_RealRs,PhaseShift_RealLb_Neg,pParams->Dmix_RealRs,NEURAL_FRAMESIZE);
//Imag
Add2(pParams->Input_ImagRs,PhaseShift_ImagRb_Neg,pParams->Dmix_ImagRs,NEURAL_FRAMESIZE);
ScaleArray(PhaseShift_ImagLb_Neg,BACK_CROSS_SHARE,NEURAL_FRAMESIZE);
Add2(pParams->Dmix_ImagRs,PhaseShift_ImagLb_Neg,pParams->Dmix_ImagRs,NEURAL_FRAMESIZE);
//***********************************************************
//***** Convert downmixed channels back to time domain *****
//***********************************************************
IFFT_Overlapped_Stereo(pParams->Dmix_RealLs,pParams->Dmix_ImagLs,PtrOutLs,
pParams->Dmix_RealRs,pParams->Dmix_ImagRs,PtrOutRs,
NEURAL_FRAMESIZE,&pParams->InvTransform_LsRs);
if(UseFinalLimiting){
//Perform final limiting on the output signals
Limiter(PtrOutLs,PtrOutLs,
(float)AUDIO_VAL_MAX,
-6.0f,-0.1f,
0.0f,500.0f,
NEURAL_FRAMESIZE,SampleRate,&pParams->FinalLimiterLs);
Limiter(PtrOutRs,PtrOutRs,
(float)AUDIO_VAL_MAX,
-6.0f,-0.1f,
0.0f,500.0f,
NEURAL_FRAMESIZE,SampleRate,&pParams->FinalLimiterRs);
}
#ifdef COMPENSATION_FRONT_DELAY
//***********************************************************
//***** Front channel handling *****
//***********************************************************
//Delay Front channels to compensate for Surround downmixing
//-----
//Left Front
//-----
Delay(PtrInL, PtrOutL,NEURAL_FRAMESIZE,&pParams->DelayChanL);
//-----
//Right Front
//-----
Delay(PtrInR, PtrOutR,NEURAL_FRAMESIZE,&pParams->DelayChanR);
//-----
//Center
//-----
Delay(PtrInC, PtrOutC,NEURAL_FRAMESIZE,&pParams->DelayChanC);
//-----
//LFE
//-----
Delay(PtrInLFE, PtrOutLFE,NEURAL_FRAMESIZE,&pParams->DelayChanLFE);
#else
//Else just copy the input buffer to output buffers with no delay
CopyArray(PtrInL, PtrOutL, NEURAL_FRAMESIZE);
CopyArray(PtrInR, PtrOutR, NEURAL_FRAMESIZE);
CopyArray(PtrInC, PtrOutC, NEURAL_FRAMESIZE);
CopyArray(PtrInLFE,PtrOutLFE,NEURAL_FRAMESIZE);
#endif
//***********************************************************
//***** That's all folks! *****
//***********************************************************
SaturateArray(PtrOutL, (float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
SaturateArray(PtrOutR, (float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
SaturateArray(PtrOutC, (float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
SaturateArray(PtrOutLFE,(float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
SaturateArray(PtrOutLs, (float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
SaturateArray(PtrOutRs, (float)AUDIO_VAL_MAX,NEURAL_FRAMESIZE);
return NRLSUR_OK;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,311 @@
//////////////////////////////////////////////////////////////////////
// ___________________ //
// | //
// | | | \ / //
// | | | \ / //
// | |----| / //
// | | | / \ //
// | | | / \ //
// ___________________ //
// //
// Neural-THX (R) Surround Technology //
// //
// Copyright (c) 2008 THX Ltd. //
// //
// THX is a trademark of THX Ltd., which may be registered //
// in some jurisdictions. //
// All Rights Reserved. //
// //
// THX Confidential Information //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Neural_THX_Global.h
//
// Author(s) : Mark Gugler (mgugler@thx.com)
//
// Created On : 08/20/2007
//
// Last Modified : 03/03/2008
//
// Version : 1.61
//
// References :
//
// Description : Encapsulates any enumerations, structures, and
// defines needed by the Neural-THX API
//
// Revision History : 08/20/2007 Build basic framework and add in new
// structs for the encoder
// 08/21/2007 Add in more comments and update some values
// based on what was received from Neural
// 08/22/2007 Add in a new structure to encapsulate
// parameter structures into one interface
// 08/23/2007 Finish adding functions to the new struct
// Add 522 parameters to settings struct
// 08/31/2007 Updating comments for clearly outlining
// what values represent
// 09/04/2007 Update comments and prepare for 722
// encoder integration
// 02/15/2008 Got 722 encoder so integrating and testing
// 02/26/2008 Added some defines and stripped out any
// remaining memory allocation from the API
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __NEURAL_THX_GLOBAL__
#define __NEURAL_THX_GLOBAL__
#include "Neural_THX_Encoders.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Global Defines
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE:: Only comment out the encoders you won't use over the course of the game
// This was implemented to not have any memory allocation
// throughout the entire API.
#define USING_725
#define USING_722
// #define USING_522
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Neural_THX_Encoder_Params
//
// Created On : 08/22/2007
//
// Last Modified : 02/28/2008
//
// Description : Parameter structure encapsulating all other param structs
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct Neural_THX_Encoder_Params
{
#ifdef USING_725
Neural_THX_725_Encode_Struct t725;
#endif
#ifdef USING_522
Neural_THX_522_Encode_Struct t522;
#endif
#ifdef USING_722
Neural_THX_722_Encode_Struct t722;
#endif
void * pParams;
Neural_THX_Encoder_Params()
{
pParams = NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Init
//
// Params : int - Channel Configuration to know which structure to use
//
// Return : void
//
// Purpose : Initialize the pointer needed by this encoder :)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Init(int nChanConfig)
{
// see which configuration we have :)
if(nChanConfig == NEURAL_THX_7_5_GAMING)
{
#ifdef USING_725
pParams = &t725;
#endif
}
else if(nChanConfig == NEURAL_THX_5_2_GAMING)
{
#ifdef USING_522
pParams = &t522;
#endif
}
else if(nChanConfig == NEURAL_THX_7_2_GAMING)
{
#ifdef USING_722
pParams = &t722;
#endif
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Release
//
// Params : void
//
// Return : void
//
// Purpose : Releases memory if any has been allocated through the init
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Release(void)
{
pParams = NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : ValidStruct
//
// Params : void
//
// Return : bool - whether any of the pointers are valid or not
//
// Purpose : Checks to see if the init was successful
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ValidStruct(void)
{
if(pParams == NULL)
{
return false;
}
// return yes
return true;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Neural_THX_Encoder_Settings
//
// Created On : 08/20/2007
//
// Last Modified : 02/28/2008
//
// Description : Settings structure for the Neural-THX encoder
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct Neural_THX_Encoder_Settings
{
// The Number of audio samples in each mono channel buffers passed to the
// encoder
// NOTE: The encoder currently only supports an audio frame size of NEURAL_FRAMESIZE
unsigned int nFramesize;
// A configuration value indicating that the encoder is to perform a Neural-THX
// compatible encoding.
unsigned int nChanConfig;
// The sample rate of the input/output audio.
// NOTE: The encoder currently supports sample rates of 32 kHz, 44.1 kHz, and
// 48 kHz.
unsigned int nSampleRate;
// Whether to use Final Limiting or not
// NOTE: Used in 522 & 722 encoder
THX_bool bUseFinalLimiting;
// LFE Cutoff when converting to 2 channels
// NOTE: Used in 522 & 722 encoder
float fLFECutOff;
// Default Constructor Set to defaults
Neural_THX_Encoder_Settings()
{
nFramesize = NEURAL_FRAMESIZE;
nChanConfig = NEURAL_THX_7_5_GAMING;
nSampleRate = SAMPLERATE_44_1;
bUseFinalLimiting = true;
fLFECutOff = 0.0f;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Neural_THX_Channel_Format
//
// Created On : 08/20/2007
//
// Last Modified : 02/28/2008
//
// Description : Surround Setup structure
//
// m_fL[n] equals 1 Sample point for the channel
// while variable_name[n] =s a sample frame
// NOTE: The encoder uses 32 bit max for sample points
// which requires the user to compensate based on
// the bytes each sample point takes
// (i.e. bitsPerSample / 8 = nBytesPerSample rounded up)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct Neural_THX_Channel_Format // double check if we need to support the framesize
{
// Front
float m_fL[NEURAL_FRAMESIZE];
float m_fC[NEURAL_FRAMESIZE];
float m_fR[NEURAL_FRAMESIZE];
// Sides/Surround & LFE
float m_fLs[NEURAL_FRAMESIZE];
float m_fRs[NEURAL_FRAMESIZE];
float m_fLFE[NEURAL_FRAMESIZE];
// Back
float m_fLb[NEURAL_FRAMESIZE];
float m_fRb[NEURAL_FRAMESIZE];
// Constructor set everything to NULL
Neural_THX_Channel_Format()
{
// Fill with silence
// CPS - FMOD_memset(this->m_fL,0,sizeof(float) * NEURAL_FRAMESIZE);
// CPS - FMOD_memset(this->m_fC,0,sizeof(float) * NEURAL_FRAMESIZE);
// CPS - FMOD_memset(this->m_fR,0,sizeof(float) * NEURAL_FRAMESIZE);
// CPS - FMOD_memset(this->m_fLs,0,sizeof(float) * NEURAL_FRAMESIZE);
// CPS - FMOD_memset(this->m_fRs,0,sizeof(float) * NEURAL_FRAMESIZE);
// CPS - FMOD_memset(this->m_fLFE,0,sizeof(float) * NEURAL_FRAMESIZE);
// CPS - FMOD_memset(this->m_fLb,0,sizeof(float) * NEURAL_FRAMESIZE);
// CPS - FMOD_memset(this->m_fRb,0,sizeof(float) * NEURAL_FRAMESIZE);
//ZeroMemory(this->m_fL, sizeof(float) * NEURAL_FRAMESIZE);
//ZeroMemory(this->m_fC, sizeof(float) * NEURAL_FRAMESIZE);
//ZeroMemory(this->m_fR, sizeof(float) * NEURAL_FRAMESIZE);
//ZeroMemory(this->m_fLs, sizeof(float) * NEURAL_FRAMESIZE);
//ZeroMemory(this->m_fRs, sizeof(float) * NEURAL_FRAMESIZE);
//ZeroMemory(this->m_fLFE,sizeof(float) * NEURAL_FRAMESIZE);
//ZeroMemory(this->m_fLb, sizeof(float) * NEURAL_FRAMESIZE);
//ZeroMemory(this->m_fRb, sizeof(float) * NEURAL_FRAMESIZE);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Name : Convert
////
//// Params : void * - Source of channels
////
//// Return : void
////
//// Purpose : Used to provide conversion support on any platform
//// * converts any source into this format for use by
//// the Neural-THX encoder
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//void Convert(void *pSource)
//{
// // TODO : Use this function to transfer your channels into this
// // structure which will later be passed into the encoder
//}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Initialize
//
// Params : void * - Source of channels
//
// Return : void
//
// Purpose : Used to set all channels in one easy to use function
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//void Initialize(float *fL = NULL,
// float *fC = NULL,
// float *fR = NULL,
// float *fLs = NULL,
// float *fRs = NULL,
// float *fLFE = NULL,
// float *fLb = NULL,
// float *fRb = NULL)
//{
// // Copy over the information into the structure's variables
// if(fL)
// FMOD_memcpy(this->m_fL,fL,sizeof(float) * NEURAL_FRAMESIZE);
// if(fC)
// FMOD_memcpy(this->m_fC,fC,sizeof(float) * NEURAL_FRAMESIZE);
// if(fR)
// FMOD_memcpy(this->m_fR,fR,sizeof(float) * NEURAL_FRAMESIZE);
// if(fLs)
// FMOD_memcpy(this->m_fLs,fLs,sizeof(float) * NEURAL_FRAMESIZE);
// if(fRs)
// FMOD_memcpy(this->m_fRs,fRs,sizeof(float) * NEURAL_FRAMESIZE);
// if(fLFE)
// FMOD_memcpy(this->m_fLFE,fLFE,sizeof(float) * NEURAL_FRAMESIZE);
// if(fLb)
// FMOD_memcpy(this->m_fLb,fLb,sizeof(float) * NEURAL_FRAMESIZE);
// if(fRb)
// FMOD_memcpy(this->m_fRb,fRb,sizeof(float) * NEURAL_FRAMESIZE);
//}
};
#endif // __NEURAL_THX_GLOBAL__

View file

@ -0,0 +1,261 @@
#include "Neural_THX_Interface.h"
NEURAL_THX_ENCODER::NEURAL_THX_ENCODER(void)
{
}
NEURAL_THX_ENCODER::~NEURAL_THX_ENCODER(void)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Init
//
// Params : Neural_THX_Encoder_Settings - settings structure defining
// global settings of encoder
//
// Return : int - Neural-THX error code
//
// Purpose : Used to set all channels in one easy to use function
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
int NEURAL_THX_ENCODER::Init( Neural_THX_Encoder_Settings &tSettings, Neural_THX_Encoder_Params &tParams )
{
// Get prepared to catch errors
int nErrorHandle = NRLTHX_OK;
// Make sure the settings they passed us are valid
// Check Configuration
if( tSettings.nChanConfig != NEURAL_THX_7_5_GAMING &&
tSettings.nChanConfig != NEURAL_THX_6_5_GAMING &&
tSettings.nChanConfig != NEURAL_THX_7_2_GAMING &&
tSettings.nChanConfig != NEURAL_THX_5_2_GAMING)
{
return UNSUPPORTED_CHANCONFIG;
}
// Check Samplerate
if( tSettings.nSampleRate != SAMPLERATE_32_0 &&
tSettings.nSampleRate != SAMPLERATE_44_1 &&
tSettings.nSampleRate != SAMPLERATE_48_0 )
{
return UNSUPPORTED_SAMPLERATE;
}
// Check Framesize
if( tSettings.nFramesize != NEURAL_FRAMESIZE)
{
return UNSUPPORTED_FRAMESIZE;
}
// Double check if we have a valid structure now
if(!tParams.ValidStruct())
{
return UNSUPPORTED_PARAMETER;
}
// Branch for Initialization of encoder that the user wants
switch(tSettings.nChanConfig)
{
case NEURAL_THX_7_5_GAMING:
{
// The 7 to 5 Encoder Init
nErrorHandle = Neural_THX_725_Encode_INIT( tSettings.nFramesize,
tSettings.nChanConfig,
tSettings.nSampleRate,
(Neural_THX_725_Encode_Struct *)(tParams.pParams));
}
break;
case NEURAL_THX_5_2_GAMING:
{
// The 5 To 2 Encoder Init
nErrorHandle = Neural_THX_522_Encode_INIT( tSettings.nFramesize,
tSettings.nChanConfig,
tSettings.nSampleRate,
(Neural_THX_522_Encode_Struct *)(tParams.pParams));
}
break;
case NEURAL_THX_6_5_GAMING: // !Supported Yet
{
// Temporary until it gets supported
return UNSUPPORTED_CHANCONFIG;
}
break;
case NEURAL_THX_7_2_GAMING: // !Supported Yet
{
nErrorHandle = Neural_THX_722_Encode_INIT( tSettings.nFramesize,
tSettings.nChanConfig,
tSettings.nSampleRate,
(Neural_THX_722_Encode_Struct *)(tParams.pParams));
}
break;
default:
{
return UNKNOWN_ERROR;// should never reach this ... should :)
}
break;
};
// Double check if there was an error :) hopefully not
NRLTHX_ERRORCHECK(nErrorHandle);
// return the success (if it reaches here things went well most likely)
return nErrorHandle;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Encode
//
// Params : Neural_THX_Channel_Format - Channels in to down mix
// Neural_THX_Channel_Format - Channels out (results)
// Neural_THX_Encoder_Settings - settings structure defining
// global settings of encoder
//
// Return : int - Neural-THX error code
//
// Purpose : Used to pass the information to the right encoder
// packaged in the library
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
int NEURAL_THX_ENCODER::Encode( Neural_THX_Channel_Format &tChannelsIn,
Neural_THX_Channel_Format &tChannelsOut,
Neural_THX_Encoder_Settings &tSettings,
Neural_THX_Encoder_Params &tParams)
{
// Get prepared to catch errors
int nErrorHandle = NRLTHX_OK;
// Make sure the settings they passed us are valid
// Check Configuration
if( tSettings.nChanConfig != NEURAL_THX_7_5_GAMING &&
tSettings.nChanConfig != NEURAL_THX_6_5_GAMING &&
tSettings.nChanConfig != NEURAL_THX_7_2_GAMING &&
tSettings.nChanConfig != NEURAL_THX_5_2_GAMING)
{
return UNSUPPORTED_CHANCONFIG;
}
// Check Samplerate
if( tSettings.nSampleRate != SAMPLERATE_32_0 &&
tSettings.nSampleRate != SAMPLERATE_44_1 &&
tSettings.nSampleRate != SAMPLERATE_48_0 )
{
return UNSUPPORTED_SAMPLERATE;
}
// Check Framesize
if( tSettings.nFramesize != NEURAL_FRAMESIZE)
{
return UNSUPPORTED_FRAMESIZE;
}
// Check to see if we have a valid buffer
if(!tParams.ValidStruct())
{
return UNSUPPORTED_PARAMETER;
}
// Prepare the channels to be sent to the corresponding encoder
// NOTE: This section will be used if we support interleaved buffers
// Branch - figure out which encoder the user wants by the settings struct
// Send off the information to the right encoder and let it
// spit back out the results the user wants
switch(tSettings.nChanConfig)
{
case NEURAL_THX_7_5_GAMING:
{
// The 7 To 5 Encoder
nErrorHandle = Neural_THX_725_Encode( tChannelsIn.m_fL,
tChannelsIn.m_fR,
tChannelsIn.m_fC,
tChannelsIn.m_fLFE,
tChannelsIn.m_fLs,
tChannelsIn.m_fRs,
tChannelsIn.m_fLb,
tChannelsIn.m_fRb,
tChannelsOut.m_fL,
tChannelsOut.m_fR,
tChannelsOut.m_fC,
tChannelsOut.m_fLFE,
tChannelsOut.m_fLs,
tChannelsOut.m_fRs,
tSettings.bUseFinalLimiting,
tSettings.nFramesize,
tSettings.nChanConfig,
tSettings.nSampleRate,
(Neural_THX_725_Encode_Struct *)(tParams.pParams));
}
break;
case NEURAL_THX_5_2_GAMING:
{
// The 5 To 2 Encoder :)
nErrorHandle = Neural_THX_522_Encode( tChannelsIn.m_fL,
tChannelsIn.m_fR,
tChannelsIn.m_fC,
tChannelsIn.m_fLFE,
tChannelsIn.m_fLs,
tChannelsIn.m_fRs,
tChannelsOut.m_fL,
tChannelsOut.m_fR,
tSettings.bUseFinalLimiting,
tSettings.fLFECutOff,
tSettings.nFramesize,
tSettings.nChanConfig,
tSettings.nSampleRate,
(Neural_THX_522_Encode_Struct *)(tParams.pParams));
}
break;
case NEURAL_THX_6_5_GAMING: // !Supported Yet
{
// Temporary until it gets supported
return UNSUPPORTED_CHANCONFIG;
}
break;
case NEURAL_THX_7_2_GAMING: // !Supported Yet
{
nErrorHandle = Neural_THX_722_Encode( tChannelsIn.m_fL,
tChannelsIn.m_fR,
tChannelsIn.m_fC,
tChannelsIn.m_fLFE,
tChannelsIn.m_fLs,
tChannelsIn.m_fRs,
tChannelsIn.m_fLb,
tChannelsIn.m_fRb,
tChannelsOut.m_fL,
tChannelsOut.m_fR,
tSettings.bUseFinalLimiting,
tSettings.fLFECutOff,
tSettings.nFramesize,
tSettings.nChanConfig,
tSettings.nSampleRate,
(Neural_THX_722_Encode_Struct *)(tParams.pParams));
}
break;
default:
{
return UNKNOWN_ERROR;// should never reach this ... should :)
}
break;
};
// Double check if there was an error :) hopefully not
NRLTHX_ERRORCHECK(nErrorHandle);
// return the errors
return nErrorHandle;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Shutdown
//
// Params : void
//
// Return : int - Neural-THX error code
//
// Purpose : Used to unitialize structures and release any memory needed
// by the encoder
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
int NEURAL_THX_ENCODER::Shutdown(void)
{
// Get prepared to catch errors
int nErrorHandle = NRLTHX_OK;
// Return the errors
return nErrorHandle;
}

View file

@ -0,0 +1,128 @@
//////////////////////////////////////////////////////////////////////
// ___________________ //
// | //
// | | | \ / //
// | | | \ / //
// | |----| / //
// | | | / \ //
// | | | / \ //
// ___________________ //
// //
// Neural-THX (R) Surround Technology //
// //
// Copyright (c) 2008 THX Ltd. //
// //
// THX is a trademark of THX Ltd., which may be registered //
// in some jurisdictions. //
// All Rights Reserved. //
// //
// THX Confidential Information //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Neural_THX_Interface.h
//
// Author(s) : Mark Gugler (mgugler@thx.com)
//
// Created On : 08/20/2007
//
// Last Modified : 03/03/2008
//
// Version : 1.61
//
// References : Linked to Neural_THX_Encoder.h & .lib
//
// Description : Interfaces the Encoder packaged in the library
//
// Revision History : 08/20/2007 Build basic framework and comment
// tasks as best as possible
// 08/21/2007 More comments and changes of format
// 08/22/2007 Library attempts to fix linking
// 08/23/2007 Skipping libray for now, filling in
// functionality of the functions below.
// Also added in a shutdown to release memory
// 08/28/2007 Adapt the structure of allocating memory
// to developer's feedback
// 09/04/2007 Update comments and prepare for 722
// encoder integration
// 02/15/2008 Got 722 encoder so integrating and testing
// 02/26/2008 Making interface compatible with new param
// structure as we stripped out memory allocations
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __NEURAL_THX_ENCODER__
#define __NEURAL_THX_ENCODER__
#include "Neural_THX_Encoders.h"
#include "Neural_THX_Global.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Macros
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define NRLTHX_FAILED(error) (error == NRLTHX_OK || error == NRLSUR_OK ? false : true)
#define NRLTHX_ERRORCHECK(error) if(NRLTHX_FAILED(error)){return error;}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : NEURAL_THX_ENCODER
//
// Created On : 08/20/2007
//
// Last Modified : 08/23/2007
//
// Description : Interface class used to encapsulate all the
// Neural-THX encoders into one object
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
class NEURAL_THX_ENCODER
{
public:
NEURAL_THX_ENCODER(void);
virtual ~NEURAL_THX_ENCODER(void);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Init
//
// Params : Neural_THX_Encoder_Settings - settings structure defining
// global settings of encoder
// Neural_THX_Encoder_Params - Parameters structure used by
// the encoder
//
// Return : int - Neural-THX error code
//
// Purpose : Used to initialize any needs by the encoder
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Init(Neural_THX_Encoder_Settings &tSettings,Neural_THX_Encoder_Params &tParams);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Encode
//
// Params : Neural_THX_Channel_Format - Channels in to down mix
// Neural_THX_Channel_Format - Channels out (results)
// Neural_THX_Encoder_Settings - settings structure defining
// global settings of encoder
// Neural_THX_Encoder_Params - Parameters structure used by
// the encoder
//
// Return : int - Neural-THX error code
//
// Purpose : Used to pass the information to the right encoder
// packaged in the library
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Encode( Neural_THX_Channel_Format &tChannelsIn,
Neural_THX_Channel_Format &tChannelsOut,
Neural_THX_Encoder_Settings &tSettings,
Neural_THX_Encoder_Params &tParams);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name : Shutdown
//
// Params : void
//
// Return : int - Neural-THX error code
//
// Purpose : Used to unitialize structures and release any memory needed
// by the encoder
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Shutdown(void);
};
#endif //__NEURAL_THX_ENCODER__

114
lib/neural_thx/PeakConverter.c Executable file
View file

@ -0,0 +1,114 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Audio *//
//* File : PeakConverter.c *//
//* Description : Peak converter with rise time / fall time *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2008 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <math.h>
//***************************************************************************//
//* PeakConverter_INIT *//
//***************************************************************************//
int PeakConverter_INIT(float RiseTime, //in msec
float FallTime, //in msec
float MinValue,
float MaxValue,
unsigned int SampleRate,
PeakConverter_Struct * pParams)
{
if(SampleRate == 0)
return UNSUPPORTED_SAMPLERATE;
if(MaxValue-MinValue <= 0.0f)
return UNSUPPORTED_PARAMETER;
if(RiseTime > 0)
pParams->RiseSlew = (MaxValue-MinValue) / (RiseTime * 0.001f * (float)SampleRate);
else
pParams->RiseSlew = (MaxValue-MinValue);
pParams->RiseTime = RiseTime;
if(FallTime > 0)
pParams->FallSlew = -(MaxValue-MinValue) / (FallTime * 0.001f * (float)SampleRate);
else
pParams->FallSlew = -(MaxValue-MinValue);
pParams->FallTime = FallTime;
pParams->MinValue = MinValue;
pParams->MaxValue = MaxValue;
pParams->PrevValue = 0.0f;
pParams->SampleRate = SampleRate;
return NRLSUR_OK;
}
//***************************************************************************//
//* PeakConverter(...) *//
//***************************************************************************//
int PeakConverter(float * PtrIn,
float * PtrOut,
float RiseTime, //in msec
float FallTime, //in msec
float MinValue,
float MaxValue,
unsigned int Framesize,
unsigned int SampleRate,
PeakConverter_Struct * pParams)
{
int n;
int RetVal;
float fTemp;
if(SampleRate == 0)
return UNSUPPORTED_SAMPLERATE;
if(RiseTime < 0.0f)
RiseTime = 0.0f;
if(RiseTime > 5000.0f)
RiseTime = 5000.0f;
if(FallTime < 0.0f)
FallTime = 0.0f;
if(FallTime > 5000.0f)
FallTime = 5000.0f;
//If parameters have changed, then re-initialize
if( RiseTime != pParams->RiseTime ||
FallTime != pParams->FallTime ||
MinValue != pParams->MinValue ||
MaxValue != pParams->MaxValue ||
SampleRate != pParams->SampleRate ) {
RetVal = PeakConverter_INIT(RiseTime,FallTime,MinValue,MaxValue,SampleRate,pParams);
if(RetVal != NRLSUR_OK)
return RetVal;
}
//-----------------------------------------------------------//
// Perform peak converter processing //
//-----------------------------------------------------------//
for(n = 0; n < (int)Framesize; n++){
fTemp = PtrIn[n] - pParams->PrevValue;
if(fTemp > pParams->RiseSlew)
fTemp = pParams->RiseSlew;
if(fTemp < pParams->FallSlew)
fTemp = pParams->FallSlew;
PtrOut[n] = pParams->PrevValue + fTemp;
pParams->PrevValue = PtrOut[n];
}
return NRLSUR_OK;
}

5
lib/neural_thx/SineWin_512.c Executable file
View file

@ -0,0 +1,5 @@
#include "Neural_THX_Encoders.h"
float * GetSineWindow(){
return (float*)SineWindow;
}

View file

@ -0,0 +1,150 @@
/*
Copyright (c) 2003-2004, Mark Borgerding
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* kiss_fft.h
defines kiss_fft_scalar as either short or a float type
and defines
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
#include "THX_kiss_fft.h"
#include <limits.h>
#define MAXFACTORS 32
/* e.g. an fft of length 128 has 4 factors
as far as kissfft is concerned
4*4*4*2
*/
struct THX_kiss_fft_state{
int nfft;
int inverse;
int factors[2*MAXFACTORS];
THX_kiss_fft_cpx twiddles[1];
};
/*
Explanation of macros dealing with complex math:
C_MUL(m,a,b) : m = a*b
C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
C_SUB( res, a,b) : res = a - b
C_SUBFROM( res , a) : res -= a
C_ADDTO( res , a) : res += a
* */
#ifdef FIXED_POINT
#if (FIXED_POINT==32)
# define FRACBITS 31
# define SAMPPROD int64_t
#define SAMP_MAX 2147483647
#else
# define FRACBITS 15
# define SAMPPROD int32_t
#define SAMP_MAX 32767
#endif
#define SAMP_MIN -SAMP_MAX
#if defined(CHECK_OVERFLOW)
# define CHECK_OVERFLOW_OP(a,op,b) \
if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); }
#endif
# define smul(a,b) ( (SAMPPROD)(a)*(b) )
# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
# define S_MUL(a,b) sround( smul(a,b) )
# define C_MUL(m,a,b) \
do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
(m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
# define DIVSCALAR(x,k) \
(x) = sround( smul( x, SAMP_MAX/k ) )
# define C_FIXDIV(c,div) \
do { DIVSCALAR( (c).r , div); \
DIVSCALAR( (c).i , div); }while (0)
# define C_MULBYSCALAR( c, s ) \
do{ (c).r = sround( smul( (c).r , s ) ) ;\
(c).i = sround( smul( (c).i , s ) ) ; }while(0)
#else /* not FIXED_POINT*/
# define S_MUL(a,b) ( (a)*(b) )
#define C_MUL(m,a,b) \
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
# define C_FIXDIV(c,div) /* NOOP */
# define C_MULBYSCALAR( c, s ) \
do{ (c).r *= (s);\
(c).i *= (s); }while(0)
#endif
#ifndef CHECK_OVERFLOW_OP
# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
#endif
#define C_ADD( res, a,b)\
do { \
CHECK_OVERFLOW_OP((a).r,+,(b).r)\
CHECK_OVERFLOW_OP((a).i,+,(b).i)\
(res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
}while(0)
#define C_SUB( res, a,b)\
do { \
CHECK_OVERFLOW_OP((a).r,-,(b).r)\
CHECK_OVERFLOW_OP((a).i,-,(b).i)\
(res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
}while(0)
#define C_ADDTO( res , a)\
do { \
CHECK_OVERFLOW_OP((res).r,+,(a).r)\
CHECK_OVERFLOW_OP((res).i,+,(a).i)\
(res).r += (a).r; (res).i += (a).i;\
}while(0)
#define C_SUBFROM( res , a)\
do {\
CHECK_OVERFLOW_OP((res).r,-,(a).r)\
CHECK_OVERFLOW_OP((res).i,-,(a).i)\
(res).r -= (a).r; (res).i -= (a).i; \
}while(0)
#ifdef FIXED_POINT
# define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase))
# define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase))
# define HALF_OF(x) ((x)>>1)
#elif defined(USE_SIMD)
# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
# define HALF_OF(x) ((x)*_mm_set1_ps(.5))
#else
# define KISS_FFT_COS(phase) (THX_kiss_fft_scalar) cos(phase)
# define KISS_FFT_SIN(phase) (THX_kiss_fft_scalar) sin(phase)
# define HALF_OF(x) ((x)*.5)
#endif
#define kf_cexp(x,phase) \
do{ \
(x)->r = KISS_FFT_COS(phase);\
(x)->i = KISS_FFT_SIN(phase);\
}while(0)
/* a debugging function */
#define pcpx(c)\
fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )

401
lib/neural_thx/THX_kiss_fft.c Executable file
View file

@ -0,0 +1,401 @@
/*
Copyright (c) 2003-2004, Mark Borgerding
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "THX__kiss_fft_guts.h"
/* The guts header contains all the multiplication and addition macros that are defined for
fixed or floating point complex numbers. It also delares the kf_ internal functions.
*/
//static THX_kiss_fft_cpx *scratchbuf=NULL;
//static size_t nscratchbuf=0;
static THX_kiss_fft_cpx scratchbuf[4];
static size_t nscratchbuf=4;
//static THX_kiss_fft_cpx *tmpbuf=NULL;
//static size_t ntmpbuf=0;
//#define CHECKBUF(buf,nbuf,n) \
// do { \
// if ( nbuf < (size_t)(n) ) {\
// free(buf); \
// buf = (THX_kiss_fft_cpx*)THX_KISS_FFT_MALLOC(sizeof(THX_kiss_fft_cpx)*(n)); \
// nbuf = (size_t)(n); \
// } \
// }while(0)
static void THX_kf_bfly2(
THX_kiss_fft_cpx * Fout,
const size_t fstride,
const THX_kiss_fft_cfg st,
int m
)
{
THX_kiss_fft_cpx * Fout2;
THX_kiss_fft_cpx * tw1 = st->twiddles;
THX_kiss_fft_cpx t;
Fout2 = Fout + m;
do{
C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
C_MUL (t, *Fout2 , *tw1);
tw1 += fstride;
C_SUB( *Fout2 , *Fout , t );
C_ADDTO( *Fout , t );
++Fout2;
++Fout;
}while (--m);
}
static void THX_kf_bfly4(
THX_kiss_fft_cpx * Fout,
const size_t fstride,
const THX_kiss_fft_cfg st,
const size_t m
)
{
THX_kiss_fft_cpx *tw1,*tw2,*tw3;
THX_kiss_fft_cpx scratch[6];
size_t k=m;
const size_t m2=2*m;
const size_t m3=3*m;
tw3 = tw2 = tw1 = st->twiddles;
do {
C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
C_MUL(scratch[0],Fout[m] , *tw1 );
C_MUL(scratch[1],Fout[m2] , *tw2 );
C_MUL(scratch[2],Fout[m3] , *tw3 );
C_SUB( scratch[5] , *Fout, scratch[1] );
C_ADDTO(*Fout, scratch[1]);
C_ADD( scratch[3] , scratch[0] , scratch[2] );
C_SUB( scratch[4] , scratch[0] , scratch[2] );
C_SUB( Fout[m2], *Fout, scratch[3] );
tw1 += fstride;
tw2 += fstride*2;
tw3 += fstride*3;
C_ADDTO( *Fout , scratch[3] );
if(st->inverse) {
Fout[m].r = scratch[5].r - scratch[4].i;
Fout[m].i = scratch[5].i + scratch[4].r;
Fout[m3].r = scratch[5].r + scratch[4].i;
Fout[m3].i = scratch[5].i - scratch[4].r;
}else{
Fout[m].r = scratch[5].r + scratch[4].i;
Fout[m].i = scratch[5].i - scratch[4].r;
Fout[m3].r = scratch[5].r - scratch[4].i;
Fout[m3].i = scratch[5].i + scratch[4].r;
}
++Fout;
}while(--k);
}
static void THX_kf_bfly3(
THX_kiss_fft_cpx * Fout,
const size_t fstride,
const THX_kiss_fft_cfg st,
size_t m
)
{
size_t k=m;
const size_t m2 = 2*m;
THX_kiss_fft_cpx *tw1,*tw2;
THX_kiss_fft_cpx scratch[5];
THX_kiss_fft_cpx epi3;
epi3 = st->twiddles[fstride*m];
tw1=tw2=st->twiddles;
do{
C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
C_MUL(scratch[1],Fout[m] , *tw1);
C_MUL(scratch[2],Fout[m2] , *tw2);
C_ADD(scratch[3],scratch[1],scratch[2]);
C_SUB(scratch[0],scratch[1],scratch[2]);
tw1 += fstride;
tw2 += fstride*2;
Fout[m].r = (float)(Fout->r - HALF_OF(scratch[3].r));
Fout[m].i = (float)(Fout->i - HALF_OF(scratch[3].i));
C_MULBYSCALAR( scratch[0] , epi3.i );
C_ADDTO(*Fout,scratch[3]);
Fout[m2].r = Fout[m].r + scratch[0].i;
Fout[m2].i = Fout[m].i - scratch[0].r;
Fout[m].r -= scratch[0].i;
Fout[m].i += scratch[0].r;
++Fout;
}while(--k);
}
static void THX_kf_bfly5(
THX_kiss_fft_cpx * Fout,
const size_t fstride,
const THX_kiss_fft_cfg st,
int m
)
{
THX_kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
int u;
THX_kiss_fft_cpx scratch[13];
THX_kiss_fft_cpx * twiddles = st->twiddles;
THX_kiss_fft_cpx *tw;
THX_kiss_fft_cpx ya,yb;
ya = twiddles[fstride*m];
yb = twiddles[fstride*2*m];
Fout0=Fout;
Fout1=Fout0+m;
Fout2=Fout0+2*m;
Fout3=Fout0+3*m;
Fout4=Fout0+4*m;
tw=st->twiddles;
for ( u=0; u<m; ++u ) {
C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
scratch[0] = *Fout0;
C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
C_ADD( scratch[7],scratch[1],scratch[4]);
C_SUB( scratch[10],scratch[1],scratch[4]);
C_ADD( scratch[8],scratch[2],scratch[3]);
C_SUB( scratch[9],scratch[2],scratch[3]);
Fout0->r += scratch[7].r + scratch[8].r;
Fout0->i += scratch[7].i + scratch[8].i;
scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
C_SUB(*Fout1,scratch[5],scratch[6]);
C_ADD(*Fout4,scratch[5],scratch[6]);
scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
C_ADD(*Fout2,scratch[11],scratch[12]);
C_SUB(*Fout3,scratch[11],scratch[12]);
++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
}
}
/* perform the butterfly for one stage of a mixed radix FFT */
static void THX_kf_bfly_generic(
THX_kiss_fft_cpx * Fout,
const size_t fstride,
const THX_kiss_fft_cfg st,
int m,
int p
)
{
int u,k,q1,q;
THX_kiss_fft_cpx * twiddles = st->twiddles;
THX_kiss_fft_cpx t;
int Norig = st->nfft;
//CHECKBUF(scratchbuf,nscratchbuf,p);
for ( u=0; u<m; ++u ) {
k=u;
for ( q1=0 ; q1<p ; ++q1 ) {
scratchbuf[q1] = Fout[ k ];
C_FIXDIV(scratchbuf[q1],p);
k += m;
}
k=u;
for ( q1=0 ; q1<p ; ++q1 ) {
int twidx=0;
Fout[ k ] = scratchbuf[0];
for (q=1;q<p;++q ) {
twidx += fstride * k;
if (twidx>=Norig) twidx-=Norig;
C_MUL(t,scratchbuf[q] , twiddles[twidx] );
C_ADDTO( Fout[ k ] ,t);
}
k += m;
}
}
}
static
void THX_kf_work(
THX_kiss_fft_cpx * Fout,
const THX_kiss_fft_cpx * f,
const size_t fstride,
int in_stride,
int * factors,
const THX_kiss_fft_cfg st
)
{
THX_kiss_fft_cpx * Fout_beg=Fout;
const int p=*factors++; /* the radix */
const int m=*factors++; /* stage's fft length/p */
const THX_kiss_fft_cpx * Fout_end = Fout + p*m;
if (m==1) {
do{
*Fout = *f;
f += fstride*in_stride;
}while(++Fout != Fout_end );
}else{
do{
THX_kf_work( Fout , f, fstride*p, in_stride, factors,st);
f += fstride*in_stride;
}while( (Fout += m) != Fout_end );
}
Fout=Fout_beg;
switch (p) {
case 2: THX_kf_bfly2(Fout,fstride,st,m); break;
case 3: THX_kf_bfly3(Fout,fstride,st,m); break;
case 4: THX_kf_bfly4(Fout,fstride,st,m); break;
case 5: THX_kf_bfly5(Fout,fstride,st,m); break;
default: THX_kf_bfly_generic(Fout,fstride,st,m,p); break;
}
}
/* facbuf is populated by p1,m1,p2,m2, ...
where
p[i] * m[i] = m[i-1]
m0 = n */
static
void THX_kf_factor(int n,int * facbuf)
{
int p=4;
double floor_sqrt;
floor_sqrt = floor( sqrt((double)n) );
/*factor out powers of 4, powers of 2, then any remaining primes */
do {
while (n % p) {
switch (p) {
case 4: p = 2; break;
case 2: p = 3; break;
default: p += 2; break;
}
if (p > floor_sqrt)
p = n; /* no more factors, skip to end */
}
n /= p;
*facbuf++ = p;
*facbuf++ = n;
} while (n > 1);
}
/*
*
* User-callable function to allocate all necessary storage space for the fft.
*
* The return value is a contiguous block of memory, allocated with malloc. As such,
* It can be freed with free(), rather than a kiss_fft-specific function.
* */
THX_kiss_fft_cfg THX_kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
{
THX_kiss_fft_cfg st=NULL;
size_t memneeded = sizeof(struct THX_kiss_fft_state)
+ sizeof(THX_kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
//if ( lenmem==NULL ) {
// st = ( THX_kiss_fft_cfg)THX_KISS_FFT_MALLOC( memneeded );
//}else{
if (mem != NULL && *lenmem >= memneeded)
st = (THX_kiss_fft_cfg)mem;
*lenmem = memneeded;
//}
if (st) {
int i;
st->nfft=nfft;
st->inverse = inverse_fft;
for (i=0;i<nfft;++i) {
const double pi=3.141592653589793238462643383279502884197169399375105820974944;
double phase = -2*pi*i / nfft;
if (st->inverse)
phase *= -1;
kf_cexp(st->twiddles+i, phase );
}
THX_kf_factor(nfft,st->factors);
}
return st;
}
void THX_kiss_fft_stride(THX_kiss_fft_cfg st,const THX_kiss_fft_cpx *fin,THX_kiss_fft_cpx *fout,int in_stride)
{
//if (fin == fout) {
// CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
// THX_kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
// FMOD_memcpy(fout,tmpbuf,sizeof(THX_kiss_fft_cpx)*st->nfft);
//}else{
THX_kf_work( fout, fin, 1,in_stride, st->factors,st );
//}
}
void THX_kiss_fft(THX_kiss_fft_cfg cfg,const THX_kiss_fft_cpx *fin,THX_kiss_fft_cpx *fout)
{
THX_kiss_fft_stride(cfg,fin,fout,1);
}
/* not really necessary to call, but if someone is doing in-place ffts, they may want to free the
buffers from CHECKBUF
*/
void THX_kiss_fft_cleanup(void)
{
//free(scratchbuf);
//scratchbuf = NULL;
//nscratchbuf=0;
//free(tmpbuf);
//tmpbuf=NULL;
//ntmpbuf=0;
}
int THX_kiss_fft_next_fast_size(int n)
{
while(1) {
int m=n;
while ( (m%2) == 0 ) m/=2;
while ( (m%3) == 0 ) m/=3;
while ( (m%5) == 0 ) m/=5;
if (m<=1)
break; /* n is completely factorable by twos, threes, and fives */
n++;
}
return n;
}

119
lib/neural_thx/THX_kiss_fft.h Executable file
View file

@ -0,0 +1,119 @@
#ifndef THX_KISS_FFT_H
#define THX_KISS_FFT_H
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
//#include <memory.h>
//#include <malloc.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
ATTENTION!
If you would like a :
-- a utility that will handle the caching of fft objects
-- real-only (no imaginary time component ) FFT
-- a multi-dimensional FFT
-- a command-line utility to perform ffts
-- a command-line utility to perform fast-convolution filtering
Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
in the tools/ directory.
*/
//#ifdef USE_SIMD
//# include <xmmintrin.h>
//# define THX_kiss_fft_scalar __m128
//#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)
//#else
//#define THX_KISS_FFT_MALLOC malloc
//#endif
#ifdef FIXED_POINT
#include <sys/types.h>
# if (FIXED_POINT == 32)
# define kiss_fft_scalar int32_t
# else
# define kiss_fft_scalar int16_t
# endif
#else
# ifndef THX_kiss_fft_scalar
/* default is float */
# define THX_kiss_fft_scalar float
# endif
#endif
typedef struct {
THX_kiss_fft_scalar r;
THX_kiss_fft_scalar i;
}THX_kiss_fft_cpx;
typedef struct THX_kiss_fft_state* THX_kiss_fft_cfg;
/*
* kiss_fft_alloc
*
* Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
*
* typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
*
* The return value from fft_alloc is a cfg buffer used internally
* by the fft routine or NULL.
*
* If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
* The returned value should be free()d when done to avoid memory leaks.
*
* The state can be placed in a user supplied buffer 'mem':
* If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
* then the function places the cfg in mem and the size used in *lenmem
* and returns mem.
*
* If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
* then the function returns NULL and places the minimum cfg
* buffer size in *lenmem.
* */
THX_kiss_fft_cfg THX_kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
/*
* kiss_fft(cfg,in_out_buf)
*
* Perform an FFT on a complex input buffer.
* for a forward FFT,
* fin should be f[0] , f[1] , ... ,f[nfft-1]
* fout will be F[0] , F[1] , ... ,F[nfft-1]
* Note that each element is complex and can be accessed like
f[k].r and f[k].i
* */
void THX_kiss_fft(THX_kiss_fft_cfg cfg,const THX_kiss_fft_cpx *fin,THX_kiss_fft_cpx *fout);
/*
A more generic version of the above function. It reads its input from every Nth sample.
* */
void THX_kiss_fft_stride(THX_kiss_fft_cfg cfg,const THX_kiss_fft_cpx *fin,THX_kiss_fft_cpx *fout,int fin_stride);
/* If kiss_fft_alloc allocated a buffer, it is one contiguous
buffer and can be simply free()d when no longer needed*/
//#define THX_kiss_fft_free free
/*
Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
your compiler output to call this before you exit.
*/
void THX_kiss_fft_cleanup(void);
/*
* Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
*/
int THX_kiss_fft_next_fast_size(int n);
#ifdef __cplusplus
}
#endif
#endif

710
lib/neural_thx/VectorOperations.c Executable file
View file

@ -0,0 +1,710 @@
// _____________
// _________________
// _____/~\___________/\_
// ______/\_/\_________/\____
// ______/\___/\_______/\______
// _____/\_____/\_____/\_______
// ____/\_______/\___/\________
// __/\_________/\_/\________
// /\___________/~\_______
// ___________________
// _____________
//
//***************************************************************************//
//* *//
//* Project : Neural Surround *//
//* File : VectorOperations.c *//
//* Description : Basic vector (array) operations *//
//* Author(s) : Jeff Thompson *//
//* *//
//* Copyright (c) Neural Audio Corp. 2006 *//
//* *//
//***************************************************************************//
#include "Neural_THX_Encoders.h"
#include <math.h>
#include <float.h>
//***************************************************************************//
//* Add2(...) *//
//***************************************************************************//
void Add2(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] + PtrIn1[index];
}
}
//***************************************************************************//
//* Add2_x2(...) *//
//***************************************************************************//
void Add2_x2(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] + PtrIn1[index];
PtrOut1[index] = PtrIn2[index] + PtrIn3[index];
}
}
//***************************************************************************//
//* Add2_x3(...) *//
//***************************************************************************//
void Add2_x3(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
float * PtrIn4,
float * PtrIn5,
float * PtrOut2,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] + PtrIn1[index];
PtrOut1[index] = PtrIn2[index] + PtrIn3[index];
PtrOut2[index] = PtrIn4[index] + PtrIn5[index];
}
}
//***************************************************************************//
//* Add2_x4(...) *//
//***************************************************************************//
void Add2_x4(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
float * PtrIn4,
float * PtrIn5,
float * PtrOut2,
float * PtrIn6,
float * PtrIn7,
float * PtrOut3,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] + PtrIn1[index];
PtrOut1[index] = PtrIn2[index] + PtrIn3[index];
PtrOut2[index] = PtrIn4[index] + PtrIn5[index];
PtrOut3[index] = PtrIn6[index] + PtrIn7[index];
}
}
//***************************************************************************//
//* Add3(...) *//
//***************************************************************************//
void Add3(float * PtrIn0,
float * PtrIn1,
float * PtrIn2,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] + PtrIn1[index] + PtrIn2[index];
}
}
//***************************************************************************//
//* Add4(...) *//
//***************************************************************************//
void Add4(float * PtrIn0,
float * PtrIn1,
float * PtrIn2,
float * PtrIn3,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] + PtrIn1[index] + PtrIn2[index] + PtrIn3[index];
}
}
//***************************************************************************//
//* Add5(...) *//
//***************************************************************************//
void Add5(float * PtrIn0,
float * PtrIn1,
float * PtrIn2,
float * PtrIn3,
float * PtrIn4,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] + PtrIn1[index] + PtrIn2[index] + PtrIn3[index] + PtrIn4[index];
}
}
//***************************************************************************//
//* Subtract2(...) *//
//***************************************************************************//
void Subtract2(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] - PtrIn1[index];
}
}
//***************************************************************************//
//* Subtract2_x2(...) *//
//***************************************************************************//
void Subtract2_x2(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] - PtrIn1[index];
PtrOut1[index] = PtrIn2[index] - PtrIn3[index];
}
}
//***************************************************************************//
//* Subtract2_x3(...) *//
//***************************************************************************//
void Subtract2_x3(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
float * PtrIn4,
float * PtrIn5,
float * PtrOut2,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] - PtrIn1[index];
PtrOut1[index] = PtrIn2[index] - PtrIn3[index];
PtrOut2[index] = PtrIn4[index] - PtrIn5[index];
}
}
//***************************************************************************//
//* Subtract2_x4(...) *//
//***************************************************************************//
void Subtract2_x4(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
float * PtrIn4,
float * PtrIn5,
float * PtrOut2,
float * PtrIn6,
float * PtrIn7,
float * PtrOut3,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] - PtrIn1[index];
PtrOut1[index] = PtrIn2[index] - PtrIn3[index];
PtrOut2[index] = PtrIn4[index] - PtrIn5[index];
PtrOut3[index] = PtrIn6[index] - PtrIn7[index];
}
}
//***************************************************************************//
//* Multiply2(...) *//
//***************************************************************************//
void Multiply2(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] * PtrIn1[index];
}
}
//***************************************************************************//
//* Multiply2_x2(...) *//
//***************************************************************************//
void Multiply2_x2(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] * PtrIn1[index];
PtrOut1[index] = PtrIn2[index] * PtrIn3[index];
}
}
//***************************************************************************//
//* Multiply2_x3(...) *//
//***************************************************************************//
void Multiply2_x3(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
float * PtrIn4,
float * PtrIn5,
float * PtrOut2,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] * PtrIn1[index];
PtrOut1[index] = PtrIn2[index] * PtrIn3[index];
PtrOut2[index] = PtrIn4[index] * PtrIn5[index];
}
}
//***************************************************************************//
//* Multiply2_x4(...) *//
//***************************************************************************//
void Multiply2_x4(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
float * PtrIn4,
float * PtrIn5,
float * PtrOut2,
float * PtrIn6,
float * PtrIn7,
float * PtrOut3,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] * PtrIn1[index];
PtrOut1[index] = PtrIn2[index] * PtrIn3[index];
PtrOut2[index] = PtrIn4[index] * PtrIn5[index];
PtrOut3[index] = PtrIn6[index] * PtrIn7[index];
}
}
//***************************************************************************//
//* Multiply3(...) *//
//***************************************************************************//
void Multiply3(float * PtrIn0,
float * PtrIn1,
float * PtrIn2,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] * PtrIn1[index] * PtrIn2[index];
}
}
//***************************************************************************//
//* Multiply4(...) *//
//***************************************************************************//
void Multiply4(float * PtrIn0,
float * PtrIn1,
float * PtrIn2,
float * PtrIn3,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] * PtrIn1[index] * PtrIn2[index] * PtrIn3[index];
}
}
//***************************************************************************//
//* Multiply5(...) *//
//***************************************************************************//
void Multiply5(float * PtrIn0,
float * PtrIn1,
float * PtrIn2,
float * PtrIn3,
float * PtrIn4,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut0[index] = PtrIn0[index] * PtrIn1[index] * PtrIn2[index] * PtrIn3[index] * PtrIn4[index];
}
}
//***************************************************************************//
//* ComplexMultiply2(...) *//
//***************************************************************************//
void ComplexMultiply2(float * PtrInReal0,
float * PtrInImag0,
float * PtrInReal1,
float * PtrInImag1,
float * PtrOutReal,
float * PtrOutImag,
unsigned int Framesize)
{
unsigned int index;
float Real0, Real1, Imag0, Imag1;
for (index = 0; index < Framesize; index++) {
Real0 = PtrInReal0[index];
Real1 = PtrInReal1[index];
Imag0 = PtrInImag0[index];
Imag1 = PtrInImag1[index];
PtrOutReal[index] = Real0 * Real1 - Imag0 * Imag1;
PtrOutImag[index] = Real0 * Imag1 + Real1 * Imag0;
}
}
//***************************************************************************//
//* Divide2(...) *//
//***************************************************************************//
void Divide2(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
unsigned int Framesize)
{
unsigned int index;
for (index = 0; index<Framesize; index++) {
if(PtrIn1[index] == 0){
PtrIn1[index] += (float)FLT_EPSILON;
}
}
// Function to take the reciprical of the second input buffer
for(index = 0; index < Framesize; index++){
PtrOut0[index] = (float)1.0 / PtrIn1[index];
}
// Now multiply the recipricals by the first input buffer
for (index = 0; index<Framesize; index++) {
PtrOut0[index] *= PtrIn0[index];
}
}
//***************************************************************************//
//* Divide2_x2(...) *//
//***************************************************************************//
void Divide2_x2(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
unsigned int Framesize)
{
unsigned int index;
for (index = 0; index<Framesize; index++) {
if(PtrIn1[index] == 0){
PtrIn1[index] += (float)FLT_EPSILON;
}
if(PtrIn3[index] == 0){
PtrIn3[index] += (float)FLT_EPSILON;
}
}
// Function to take the reciprical of the second input buffer
for(index = 0; index < Framesize; index++){
PtrOut0[index] = (float)1.0 / PtrIn1[index];
PtrOut1[index] = (float)1.0 / PtrIn3[index];
}
// Now multiply the recipricals by the first input buffer
for (index = 0; index<Framesize; index++) {
PtrOut0[index] *= PtrIn0[index];
PtrOut1[index] *= PtrIn2[index];
}
}
//***************************************************************************//
//* Divide2_x3(...) *//
//***************************************************************************//
void Divide2_x3(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
float * PtrIn4,
float * PtrIn5,
float * PtrOut2,
unsigned int Framesize)
{
unsigned int index;
for (index = 0; index<Framesize; index++) {
if(PtrIn1[index] == 0){
PtrIn1[index] += (float)FLT_EPSILON;
}
if(PtrIn3[index] == 0){
PtrIn3[index] += (float)FLT_EPSILON;
}
if(PtrIn5[index] == 0){
PtrIn5[index] += (float)FLT_EPSILON;
}
}
// Function to take the reciprical of the second input buffer
for(index = 0; index < Framesize; index++){
PtrOut0[index] = (float)1.0 / PtrIn1[index];
PtrOut1[index] = (float)1.0 / PtrIn3[index];
PtrOut2[index] = (float)1.0 / PtrIn5[index];
}
// Now multiply the recipricals by the first input buffer
for (index = 0; index<Framesize; index++) {
PtrOut0[index] *= PtrIn0[index];
PtrOut1[index] *= PtrIn2[index];
PtrOut2[index] *= PtrIn4[index];
}
}
//***************************************************************************//
//* Divide2_x4(...) *//
//***************************************************************************//
void Divide2_x4(float * PtrIn0,
float * PtrIn1,
float * PtrOut0,
float * PtrIn2,
float * PtrIn3,
float * PtrOut1,
float * PtrIn4,
float * PtrIn5,
float * PtrOut2,
float * PtrIn6,
float * PtrIn7,
float * PtrOut3,
unsigned int Framesize)
{
unsigned int index;
for (index = 0; index<Framesize; index++) {
if(PtrIn1[index] == 0){
PtrIn1[index] += (float)FLT_EPSILON;
}
if(PtrIn3[index] == 0){
PtrIn3[index] += (float)FLT_EPSILON;
}
if(PtrIn5[index] == 0){
PtrIn5[index] += (float)FLT_EPSILON;
}
if(PtrIn7[index] == 0){
PtrIn7[index] += (float)FLT_EPSILON;
}
}
// Function to take the reciprical of the second input buffer
for(index = 0; index < Framesize; index++){
PtrOut0[index] = (float)1.0 / PtrIn1[index];
PtrOut1[index] = (float)1.0 / PtrIn3[index];
PtrOut2[index] = (float)1.0 / PtrIn5[index];
PtrOut3[index] = (float)1.0 / PtrIn7[index];
}
// Now multiply the recipricals by the first input buffer
for (index = 0; index<Framesize; index++) {
PtrOut0[index] *= PtrIn0[index];
PtrOut1[index] *= PtrIn2[index];
PtrOut2[index] *= PtrIn4[index];
PtrOut3[index] *= PtrIn6[index];
}
}
//***************************************************************************//
//* CopyArray(...) *//
//***************************************************************************//
void CopyArray(float * PtrIn,
float * PtrOut,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrOut[index] = PtrIn[index];
}
}
//***************************************************************************//
//* FillArray(...) *//
//***************************************************************************//
void FillArray(float * PtrArray,
float FillValue,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrArray[index] = FillValue;
}
}
//***************************************************************************//
//* OffsetArray(...) *//
//***************************************************************************//
void OffsetArray(float * PtrArray,
float OffsetValue,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrArray[index] += OffsetValue;
}
}
//***************************************************************************//
//* ScaleArray(...) *//
//***************************************************************************//
void ScaleArray(float * PtrArray,
float ScaleValue,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrArray[index] *= ScaleValue;
}
}
//***************************************************************************//
//* SquareArray(...) *//
//***************************************************************************//
void SquareArray(float * PtrArray,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrArray[index] *= PtrArray[index];
}
}
//***************************************************************************//
//* AbsValue(...) *//
//***************************************************************************//
void AbsValue(float * PtrArray,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
PtrArray[index] = (float)fabs(PtrArray[index]);
}
}
//***************************************************************************//
//* MaxClip(...) *//
//***************************************************************************//
void MaxClip(float * PtrArray,
float MaxValue,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
if(PtrArray[index] > MaxValue)
PtrArray[index] = MaxValue;
}
}
//***************************************************************************//
//* MinClip(...) *//
//***************************************************************************//
void MinClip(float * PtrArray,
float MinValue,
unsigned int Framesize)
{
unsigned int index;
for(index = 0; index < Framesize; index++){
if(PtrArray[index] < MinValue)
PtrArray[index] = MinValue;
}
}
//***************************************************************************//
//* SaturateArray(...) *//
//***************************************************************************//
void SaturateArray(float * PtrArray,
float SaturationValue,
unsigned int Framesize)
{
unsigned int index;
float MaxValuePos, MaxValueNeg, Value;
MaxValuePos = (float)fabs(SaturationValue);
MaxValueNeg = -MaxValuePos;
for(index = 0; index < Framesize; index++){
Value = PtrArray[index];
if(Value > MaxValuePos)
Value = MaxValuePos;
if(Value < MaxValueNeg)
Value = MaxValueNeg;
PtrArray[index] = Value;
}
}
//***************************************************************************//
//* ReverseArray(...) *//
//***************************************************************************//
void ReverseArray(float * PtrArray,
unsigned int Framesize)
{
unsigned int index;
float temp;
for(index = 0; index < (Framesize>>1); index++){
temp = PtrArray[index];
PtrArray[index] = PtrArray[Framesize-index-1];
PtrArray[Framesize-index-1] = temp;
}
}