refactor(fmod): move all original files into fmod directory
This commit is contained in:
parent
50fb3c6b1c
commit
35569faecc
544 changed files with 0 additions and 0 deletions
6
fmod/lib/neural_thx/Brev_Table.c
Executable file
6
fmod/lib/neural_thx/Brev_Table.c
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
#include "Neural_THX_Encoders.h"
|
||||
|
||||
unsigned char * GetBrevTable(){
|
||||
return (unsigned char*)BRev;
|
||||
}
|
||||
|
||||
72
fmod/lib/neural_thx/Delay.c
Executable file
72
fmod/lib/neural_thx/Delay.c
Executable 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
fmod/lib/neural_thx/FFT_Overlapped.c
Executable file
197
fmod/lib/neural_thx/FFT_Overlapped.c
Executable 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;
|
||||
}
|
||||
209
fmod/lib/neural_thx/FFT_Overlapped_Stereo.c
Executable file
209
fmod/lib/neural_thx/FFT_Overlapped_Stereo.c
Executable 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
fmod/lib/neural_thx/FastMathApprox.c
Executable file
882
fmod/lib/neural_thx/FastMathApprox.c
Executable 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
|
||||
112
fmod/lib/neural_thx/FreqDomain_PhaseShift.c
Executable file
112
fmod/lib/neural_thx/FreqDomain_PhaseShift.c
Executable 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
fmod/lib/neural_thx/LR4_LP.c
Executable file
102
fmod/lib/neural_thx/LR4_LP.c
Executable 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
fmod/lib/neural_thx/Limiter.c
Executable file
110
fmod/lib/neural_thx/Limiter.c
Executable 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;
|
||||
}
|
||||
189
fmod/lib/neural_thx/Neural_THX_522_Encode.c
Executable file
189
fmod/lib/neural_thx/Neural_THX_522_Encode.c
Executable 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;
|
||||
}
|
||||
233
fmod/lib/neural_thx/Neural_THX_722_Encode.c
Executable file
233
fmod/lib/neural_thx/Neural_THX_722_Encode.c
Executable 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;
|
||||
}
|
||||
207
fmod/lib/neural_thx/Neural_THX_725_Encode.c
Executable file
207
fmod/lib/neural_thx/Neural_THX_725_Encode.c
Executable 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;
|
||||
}
|
||||
1115
fmod/lib/neural_thx/Neural_THX_Encoders.h
Executable file
1115
fmod/lib/neural_thx/Neural_THX_Encoders.h
Executable file
File diff suppressed because it is too large
Load diff
311
fmod/lib/neural_thx/Neural_THX_Global.h
Executable file
311
fmod/lib/neural_thx/Neural_THX_Global.h
Executable 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__
|
||||
|
||||
261
fmod/lib/neural_thx/Neural_THX_Interface.cpp
Executable file
261
fmod/lib/neural_thx/Neural_THX_Interface.cpp
Executable 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;
|
||||
}
|
||||
128
fmod/lib/neural_thx/Neural_THX_Interface.h
Executable file
128
fmod/lib/neural_thx/Neural_THX_Interface.h
Executable 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
fmod/lib/neural_thx/PeakConverter.c
Executable file
114
fmod/lib/neural_thx/PeakConverter.c
Executable 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
fmod/lib/neural_thx/SineWin_512.c
Executable file
5
fmod/lib/neural_thx/SineWin_512.c
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#include "Neural_THX_Encoders.h"
|
||||
|
||||
float * GetSineWindow(){
|
||||
return (float*)SineWindow;
|
||||
}
|
||||
150
fmod/lib/neural_thx/THX__kiss_fft_guts.h
Executable file
150
fmod/lib/neural_thx/THX__kiss_fft_guts.h
Executable 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
fmod/lib/neural_thx/THX_kiss_fft.c
Executable file
401
fmod/lib/neural_thx/THX_kiss_fft.c
Executable 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
fmod/lib/neural_thx/THX_kiss_fft.h
Executable file
119
fmod/lib/neural_thx/THX_kiss_fft.h
Executable 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
fmod/lib/neural_thx/VectorOperations.c
Executable file
710
fmod/lib/neural_thx/VectorOperations.c
Executable 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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue