updated imported aflib sources to OSALP 7.3
This commit is contained in:
parent
e4da2d70b8
commit
374763d680
|
@ -29,6 +29,8 @@ darkice_SOURCES = AudioEncoder.h\
|
|||
LameLibEncoder.h\
|
||||
VorbisLibEncoder.cpp\
|
||||
VorbisLibEncoder.h\
|
||||
aflibDebug.h\
|
||||
aflibDebug.cc\
|
||||
aflibConverter.h\
|
||||
aflibConverter.cc\
|
||||
aflibConverterLargeFilter.h\
|
||||
|
|
|
@ -18,10 +18,13 @@
|
|||
* Julius O. Smith jos@ccrma.stanford.edu
|
||||
*
|
||||
*/
|
||||
/* This code was modified by Bruce Forsberg (forsberg@adnc.com) to make it
|
||||
/* This code was modified by Bruce Forsberg (forsberg@tns.net) to make it
|
||||
into a C++ class
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -32,6 +35,7 @@
|
|||
#include "aflibConverterLargeFilter.h"
|
||||
#include "aflibConverterSmallFilter.h"
|
||||
|
||||
#include "aflibDebug.h"
|
||||
|
||||
#if (!defined(TRUE) || !defined(FALSE))
|
||||
# define TRUE 1
|
||||
|
@ -112,12 +116,16 @@ aflibConverter::aflibConverter(
|
|||
bool linear_interpolation,
|
||||
bool filter_interpolation)
|
||||
{
|
||||
/* TODO put all these into an enum as it only makes sense to have
|
||||
* one true at a time. - DAS
|
||||
*/
|
||||
interpFilt = filter_interpolation;
|
||||
largeFilter = high_quality;
|
||||
linearInterp = linear_interpolation;
|
||||
|
||||
X = NULL;
|
||||
Y = NULL;
|
||||
_X = NULL;
|
||||
_Y = NULL;
|
||||
_vol = 1.0;
|
||||
}
|
||||
|
||||
aflibConverter::~aflibConverter()
|
||||
|
@ -131,65 +139,65 @@ aflibConverter::deleteMemory()
|
|||
{
|
||||
int i;
|
||||
|
||||
|
||||
// Delete memory for the input and output arrays
|
||||
if (X != NULL)
|
||||
if (_X != NULL)
|
||||
{
|
||||
for (i = 0; i < nChans; i++)
|
||||
for (i = 0; i < _nChans; i++)
|
||||
{
|
||||
delete [] X[i];
|
||||
X[i] = NULL;
|
||||
delete [] Y[i];
|
||||
Y[i] = NULL;
|
||||
delete [] _X[i];
|
||||
_X[i] = NULL;
|
||||
delete [] _Y[i];
|
||||
_Y[i] = NULL;
|
||||
}
|
||||
delete [] X;
|
||||
X = NULL;
|
||||
delete [] Y;
|
||||
Y = NULL;
|
||||
delete [] _X;
|
||||
_X = NULL;
|
||||
delete [] _Y;
|
||||
_Y = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
aflibConverter::initialize(
|
||||
double fac,
|
||||
int channels)
|
||||
int channels,
|
||||
double volume)
|
||||
{
|
||||
// This function will allow one to stream data. When a new data stream is to
|
||||
// be input then this function should be called. Even if the factor and number
|
||||
// of channels don't change. Otherwise each new data block sent to resample
|
||||
// will be considered part of the previous data block.
|
||||
// will be considered part of the previous data block. This function also allows
|
||||
// one to specified a multiplication factor to adjust the final output. This
|
||||
// applies to the small and large filter.
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
// Delete all previous allocated input and output buffer memory
|
||||
deleteMemory();
|
||||
|
||||
factor = fac;
|
||||
nChans = channels;
|
||||
initial = TRUE;
|
||||
_factor = fac;
|
||||
_nChans = channels;
|
||||
_initial = TRUE;
|
||||
_vol = volume;
|
||||
|
||||
// Allocate all new memory
|
||||
X = new HWORD * [nChans];
|
||||
Y = new HWORD * [nChans];
|
||||
_X = new short * [_nChans];
|
||||
_Y = new short * [_nChans];
|
||||
|
||||
for (i = 0; i < nChans; i++)
|
||||
for (i = 0; i < _nChans; i++)
|
||||
{
|
||||
// Add extra to allow of offset of input data (Xoff in main routine)
|
||||
X[i] = new HWORD[IBUFFSIZE + 256];
|
||||
Y[i] = new HWORD[(int)(((double)IBUFFSIZE)*factor)];
|
||||
memset(X[i], 0, sizeof(HWORD) * (IBUFFSIZE + 256));
|
||||
_X[i] = new short[IBUFFSIZE + 256];
|
||||
_Y[i] = new short[(int)(((double)IBUFFSIZE)*_factor)];
|
||||
memset(_X[i], 0, sizeof(short) * (IBUFFSIZE + 256));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
aflibConverter::resample( /* number of output samples returned */
|
||||
int& inCount, /* number of input samples to convert */
|
||||
int outCount, /* number of output samples to compute */
|
||||
HWORD inArray[], /* input data */
|
||||
HWORD outArray[]) /* output data */
|
||||
short inArray[], /* input data */
|
||||
short outArray[]) /* output data */
|
||||
{
|
||||
int Ycount;
|
||||
|
||||
|
@ -200,40 +208,42 @@ aflibConverter::resample( /* number of output samples returned */
|
|||
// Use small filtering. Good qulaity
|
||||
else if (largeFilter == FALSE)
|
||||
Ycount = resampleWithFilter(inCount,outCount,inArray,outArray,
|
||||
SMALL_FILTER_IMP, SMALL_FILTER_IMPD, (UHWORD)(SMALL_FILTER_SCALE * 0.95),
|
||||
SMALL_FILTER_IMP, SMALL_FILTER_IMPD,
|
||||
(unsigned short)(SMALL_FILTER_SCALE * _vol),
|
||||
SMALL_FILTER_NMULT, SMALL_FILTER_NWING);
|
||||
// Use large filtering Great quality
|
||||
else
|
||||
Ycount = resampleWithFilter(inCount,outCount,inArray,outArray,
|
||||
LARGE_FILTER_IMP, LARGE_FILTER_IMPD, (UHWORD)(LARGE_FILTER_SCALE * 0.95),
|
||||
LARGE_FILTER_IMP, LARGE_FILTER_IMPD,
|
||||
(unsigned short)(LARGE_FILTER_SCALE * _vol),
|
||||
LARGE_FILTER_NMULT, LARGE_FILTER_NWING);
|
||||
|
||||
initial = FALSE;
|
||||
_initial = FALSE;
|
||||
|
||||
return (Ycount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
aflibConverter::err_ret(char *s)
|
||||
{
|
||||
fprintf(stderr,"resample: %s \n\n",s); /* Display error message */
|
||||
aflib_debug("resample: %s \n\n",s); /* Display error message */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
aflibConverter::readData(
|
||||
int inCount, /* _total_ number of frames in input file */
|
||||
HWORD inArray[], /* input data */
|
||||
HWORD *outPtr[], /* array receiving chan samps */
|
||||
short inArray[], /* input data */
|
||||
short *outPtr[], /* array receiving chan samps */
|
||||
int dataArraySize, /* size of these arrays */
|
||||
int Xoff, /* read into input array starting at this index */
|
||||
bool init_count)
|
||||
{
|
||||
int i, Nsamps, c;
|
||||
static unsigned int framecount; /* frames previously read */
|
||||
HWORD *ptr;
|
||||
short *ptr;
|
||||
|
||||
if (init_count == TRUE)
|
||||
framecount = 0; /* init this too */
|
||||
|
@ -246,13 +256,13 @@ aflibConverter::readData(
|
|||
Nsamps = inCount - framecount;
|
||||
}
|
||||
|
||||
for (c = 0; c < nChans; c++)
|
||||
for (c = 0; c < _nChans; c++)
|
||||
{
|
||||
ptr = outPtr[c];
|
||||
ptr += Xoff; /* Start at designated sample number */
|
||||
|
||||
for (i = 0; i < Nsamps; i++)
|
||||
*ptr++ = (HWORD) inArray[c * inCount + i + framecount];
|
||||
*ptr++ = (short) inArray[c * inCount + i + framecount];
|
||||
}
|
||||
|
||||
framecount += Nsamps;
|
||||
|
@ -263,32 +273,37 @@ aflibConverter::readData(
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
aflibConverter::SrcLinear(
|
||||
HWORD X[],
|
||||
HWORD Y[],
|
||||
short X[],
|
||||
short Y[],
|
||||
double factor,
|
||||
UWORD *Time,
|
||||
UHWORD& Nx,
|
||||
UHWORD Nout)
|
||||
unsigned int *Time,
|
||||
unsigned short& Nx,
|
||||
unsigned short Nout)
|
||||
{
|
||||
HWORD iconst;
|
||||
HWORD *Xp, *Ystart;
|
||||
WORD v,x1,x2;
|
||||
short iconst;
|
||||
short *Xp, *Ystart;
|
||||
int v,x1,x2;
|
||||
|
||||
double dt; /* Step through input signal */
|
||||
UWORD dtb; /* Fixed-point version of Dt */
|
||||
UWORD endTime; /* When Time reaches EndTime, return to user */
|
||||
UWORD start_sample, end_sample;
|
||||
unsigned int dtb; /* Fixed-point version of Dt */
|
||||
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
||||
unsigned int start_sample, end_sample;
|
||||
|
||||
dt = 1.0/factor; /* Output sampling period */
|
||||
dtb = (UWORD)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
||||
dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
||||
|
||||
start_sample = (*Time)>>Np;
|
||||
Ystart = Y;
|
||||
endTime = *Time + (1<<Np)*(WORD)Nx;
|
||||
// endTime = *Time + (1<<Np)*(int)Nx;
|
||||
/*
|
||||
* TODO
|
||||
* DAS: not sure why this was changed from *Time < endTime
|
||||
* update: *Time < endTime causes seg fault. Also adds a clicking sound.
|
||||
*/
|
||||
while (Y - Ystart != Nout)
|
||||
// while (*Time < endTime)
|
||||
{
|
||||
iconst = (*Time) & Pmask;
|
||||
Xp = &X[(*Time)>>Np]; /* Ptr to current input sample */
|
||||
|
@ -308,40 +323,46 @@ aflibConverter::SrcLinear(
|
|||
|
||||
int
|
||||
aflibConverter::SrcUp(
|
||||
HWORD X[],
|
||||
HWORD Y[],
|
||||
short X[],
|
||||
short Y[],
|
||||
double factor,
|
||||
UWORD *Time,
|
||||
UHWORD& Nx,
|
||||
UHWORD Nout,
|
||||
UHWORD Nwing,
|
||||
UHWORD LpScl,
|
||||
HWORD Imp[],
|
||||
HWORD ImpD[],
|
||||
BOOL Interp)
|
||||
unsigned int *Time,
|
||||
unsigned short& Nx,
|
||||
unsigned short Nout,
|
||||
unsigned short Nwing,
|
||||
unsigned short LpScl,
|
||||
short Imp[],
|
||||
short ImpD[],
|
||||
bool Interp)
|
||||
{
|
||||
HWORD *Xp, *Ystart;
|
||||
WORD v;
|
||||
short *Xp, *Ystart;
|
||||
int v;
|
||||
|
||||
double dt; /* Step through input signal */
|
||||
UWORD dtb; /* Fixed-point version of Dt */
|
||||
UWORD endTime; /* When Time reaches EndTime, return to user */
|
||||
UWORD start_sample, end_sample;
|
||||
unsigned int dtb; /* Fixed-point version of Dt */
|
||||
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
||||
unsigned int start_sample, end_sample;
|
||||
|
||||
dt = 1.0/factor; /* Output sampling period */
|
||||
dtb = (UWORD)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
||||
dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
||||
|
||||
start_sample = (*Time)>>Np;
|
||||
Ystart = Y;
|
||||
endTime = *Time + (1<<Np)*(WORD)Nx;
|
||||
// endTime = *Time + (1<<Np)*(int)Nx;
|
||||
/*
|
||||
* TODO
|
||||
* DAS: not sure why this was changed from *Time < endTime
|
||||
* update: *Time < endTime causes seg fault. Also adds a clicking sound.
|
||||
*/
|
||||
while (Y - Ystart != Nout)
|
||||
// while (*Time < endTime)
|
||||
{
|
||||
Xp = &X[*Time>>Np]; /* Ptr to current input sample */
|
||||
/* Perform left-wing inner product */
|
||||
v = FilterUp(Imp, ImpD, Nwing, Interp, Xp, (HWORD)(*Time&Pmask),-1);
|
||||
v = FilterUp(Imp, ImpD, Nwing, Interp, Xp, (short)(*Time&Pmask),-1);
|
||||
/* Perform right-wing inner product */
|
||||
v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1,
|
||||
(HWORD)((-*Time)&Pmask),1);
|
||||
(short)((((*Time)^Pmask)+1)&Pmask), 1);
|
||||
v >>= Nhg; /* Make guard bits */
|
||||
v *= LpScl; /* Normalize for unity filter gain */
|
||||
*Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */
|
||||
|
@ -356,48 +377,55 @@ aflibConverter::SrcUp(
|
|||
|
||||
int
|
||||
aflibConverter::SrcUD(
|
||||
HWORD X[],
|
||||
HWORD Y[],
|
||||
short X[],
|
||||
short Y[],
|
||||
double factor,
|
||||
UWORD *Time,
|
||||
UHWORD& Nx,
|
||||
UHWORD Nout,
|
||||
UHWORD Nwing,
|
||||
UHWORD LpScl,
|
||||
HWORD Imp[],
|
||||
HWORD ImpD[],
|
||||
BOOL Interp)
|
||||
unsigned int *Time,
|
||||
unsigned short& Nx,
|
||||
unsigned short Nout,
|
||||
unsigned short Nwing,
|
||||
unsigned short LpScl,
|
||||
short Imp[],
|
||||
short ImpD[],
|
||||
bool Interp)
|
||||
{
|
||||
HWORD *Xp, *Ystart;
|
||||
WORD v;
|
||||
short *Xp, *Ystart;
|
||||
int v;
|
||||
|
||||
double dh; /* Step through filter impulse response */
|
||||
double dt; /* Step through input signal */
|
||||
UWORD endTime; /* When Time reaches EndTime, return to user */
|
||||
UWORD dhb, dtb; /* Fixed-point versions of Dh,Dt */
|
||||
UWORD start_sample, end_sample;
|
||||
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
||||
unsigned int dhb, dtb; /* Fixed-point versions of Dh,Dt */
|
||||
unsigned int start_sample, end_sample;
|
||||
|
||||
dt = 1.0/factor; /* Output sampling period */
|
||||
dtb = (UWORD)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
||||
dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
||||
|
||||
dh = MIN(Npc, factor*Npc); /* Filter sampling period */
|
||||
dhb = (UWORD)(dh*(1<<Na) + 0.5); /* Fixed-point representation */
|
||||
dhb = (unsigned int)(dh*(1<<Na) + 0.5); /* Fixed-point representation */
|
||||
|
||||
start_sample = (*Time)>>Np;
|
||||
Ystart = Y;
|
||||
endTime = *Time + (1<<Np)*(WORD)Nx;
|
||||
// endTime = *Time + (1<<Np)*(int)Nx;
|
||||
/*
|
||||
* TODO
|
||||
* DAS: not sure why this was changed from *Time < endTime
|
||||
* update: *Time < endTime causes seg fault. Also adds a clicking sound.
|
||||
*/
|
||||
while (Y - Ystart != Nout)
|
||||
// while (*Time < endTime)
|
||||
{
|
||||
Xp = &X[*Time>>Np]; /* Ptr to current input sample */
|
||||
v = FilterUD(Imp, ImpD, Nwing, Interp, Xp, (HWORD)(*Time&Pmask),
|
||||
v = FilterUD(Imp, ImpD, Nwing, Interp, Xp, (short)(*Time&Pmask),
|
||||
-1, dhb); /* Perform left-wing inner product */
|
||||
v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1, (HWORD)((-*Time)&Pmask),
|
||||
1, dhb); /* Perform right-wing inner product */
|
||||
v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1,
|
||||
(short)((((*Time)^Pmask)+1)&Pmask), 1, dhb); /* Perform right-wing inner product */
|
||||
v >>= Nhg; /* Make guard bits */
|
||||
v *= LpScl; /* Normalize for unity filter gain */
|
||||
*Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */
|
||||
*Time += dtb; /* Move to next sample by time increment */
|
||||
}
|
||||
|
||||
end_sample = (*Time)>>Np;
|
||||
Nx = end_sample - start_sample;
|
||||
return (Y - Ystart); /* Return the number of output samples */
|
||||
|
@ -408,17 +436,17 @@ int
|
|||
aflibConverter::resampleFast( /* number of output samples returned */
|
||||
int& inCount, /* number of input samples to convert */
|
||||
int outCount, /* number of output samples to compute */
|
||||
HWORD inArray[], /* input data */
|
||||
HWORD outArray[]) /* output data */
|
||||
short inArray[], /* input data */
|
||||
short outArray[]) /* output data */
|
||||
{
|
||||
UWORD Time2; /* Current time/pos in input sample */
|
||||
unsigned int Time2; /* Current time/pos in input sample */
|
||||
#if 0
|
||||
UHWORD Ncreep;
|
||||
unsigned short Ncreep;
|
||||
#endif
|
||||
UHWORD Xp, Xoff, Xread;
|
||||
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*factor);
|
||||
UHWORD Nout = 0, Nx;
|
||||
UHWORD maxOutput;
|
||||
unsigned short Xp, Xoff, Xread;
|
||||
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor);
|
||||
unsigned short Nout = 0, Nx, orig_Nx;
|
||||
unsigned short maxOutput;
|
||||
int total_inCount = 0;
|
||||
int c, i, Ycount, last;
|
||||
bool first_pass = TRUE;
|
||||
|
@ -433,13 +461,14 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
|||
Xp = Xoff; /* Current "now"-sample pointer for input */
|
||||
Xread = Xoff; /* Position in input array to read into */
|
||||
|
||||
if (initial == TRUE)
|
||||
Time = (Xoff<<Np); /* Current-time pointer for converter */
|
||||
if (_initial == TRUE)
|
||||
_Time = (Xoff<<Np); /* Current-time pointer for converter */
|
||||
|
||||
do {
|
||||
if (!last) /* If haven't read last sample yet */
|
||||
{
|
||||
last = readData(inCount, inArray, X, IBUFFSIZE, (int)Xread,first_pass);
|
||||
last = readData(inCount, inArray, _X,
|
||||
IBUFFSIZE, (int)Xread,first_pass);
|
||||
first_pass = FALSE;
|
||||
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
||||
Nx = last-Xoff; /* ...calc last sample affected by filter */
|
||||
|
@ -448,20 +477,22 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
|||
}
|
||||
}
|
||||
|
||||
if ((outCount-Ycount) > (OBUFFSIZE - (2*Xoff*factor)) )
|
||||
maxOutput = OBUFFSIZE - (UHWORD)(2*Xoff*factor);
|
||||
if ((outCount-Ycount) > (OBUFFSIZE - (2*Xoff*_factor)) )
|
||||
maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor);
|
||||
else
|
||||
maxOutput = outCount-Ycount;
|
||||
|
||||
for (c = 0; c < nChans; c++)
|
||||
for (c = 0; c < _nChans; c++)
|
||||
{
|
||||
Time2 = Time;
|
||||
orig_Nx = Nx;
|
||||
Time2 = _Time;
|
||||
/* Resample stuff in input buffer */
|
||||
Nout=SrcLinear(X[c],Y[c],factor,&Time2,Nx,maxOutput);
|
||||
Nout=SrcLinear(_X[c],_Y[c],_factor,&Time2,orig_Nx,maxOutput);
|
||||
}
|
||||
Time = Time2;
|
||||
Nx = orig_Nx;
|
||||
_Time = Time2;
|
||||
|
||||
Time -= (Nx<<Np); /* Move converter Nx samples back in time */
|
||||
_Time -= (Nx<<Np); /* Move converter Nx samples back in time */
|
||||
Xp += Nx; /* Advance by number of samples processed */
|
||||
#if 0
|
||||
Ncreep = (Time>>Np) - Xoff; /* Calc time accumulation in Time */
|
||||
|
@ -470,10 +501,10 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
|||
Xp += Ncreep; /* and add it to read pointer */
|
||||
}
|
||||
#endif
|
||||
for (c = 0; c < nChans; c++)
|
||||
for (c = 0; c < _nChans; c++)
|
||||
{
|
||||
for (i=0; i<IBUFFSIZE-Xp+Xoff; i++) { /* Copy part of input signal */
|
||||
X[c][i] = X[c][i+Xp-Xoff]; /* that must be re-used */
|
||||
_X[c][i] = _X[c][i+Xp-Xoff]; /* that must be re-used */
|
||||
}
|
||||
}
|
||||
if (last) { /* If near end of sample... */
|
||||
|
@ -493,9 +524,9 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
|||
if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */
|
||||
return err_ret("Output array overflow");
|
||||
|
||||
for (c = 0; c < nChans; c++)
|
||||
for (c = 0; c < _nChans; c++)
|
||||
for (i = 0; i < Nout; i++)
|
||||
outArray[c * outCount + i + Ycount - Nout] = Y[c][i];
|
||||
outArray[c * outCount + i + Ycount - Nout] = _Y[c][i];
|
||||
|
||||
total_inCount += Nx;
|
||||
|
||||
|
@ -511,30 +542,30 @@ int
|
|||
aflibConverter::resampleWithFilter( /* number of output samples returned */
|
||||
int& inCount, /* number of input samples to convert */
|
||||
int outCount, /* number of output samples to compute */
|
||||
HWORD inArray[], /* input data */
|
||||
HWORD outArray[], /* output data */
|
||||
HWORD Imp[], HWORD ImpD[],
|
||||
UHWORD LpScl, UHWORD Nmult, UHWORD Nwing)
|
||||
short inArray[], /* input data */
|
||||
short outArray[], /* output data */
|
||||
short Imp[], short ImpD[],
|
||||
unsigned short LpScl, unsigned short Nmult, unsigned short Nwing)
|
||||
{
|
||||
UWORD Time2; /* Current time/pos in input sample */
|
||||
unsigned int Time2; /* Current time/pos in input sample */
|
||||
#if 0
|
||||
UHWORD Ncreep;
|
||||
unsigned short Ncreep;
|
||||
#endif
|
||||
UHWORD Xp, Xoff, Xread;
|
||||
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*factor);
|
||||
UHWORD Nout = 0, Nx;
|
||||
UHWORD maxOutput;
|
||||
unsigned short Xp, Xoff, Xread;
|
||||
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor);
|
||||
unsigned short Nout = 0, Nx, orig_Nx;
|
||||
unsigned short maxOutput;
|
||||
int total_inCount = 0;
|
||||
int c, i, Ycount, last;
|
||||
bool first_pass = TRUE;
|
||||
|
||||
|
||||
/* Account for increased filter gain when using factors less than 1 */
|
||||
if (factor < 1)
|
||||
LpScl = (UHWORD)(LpScl*factor + 0.5);
|
||||
if (_factor < 1)
|
||||
LpScl = (unsigned short)(LpScl*_factor + 0.5);
|
||||
|
||||
/* Calc reach of LP filter wing & give some creeping room */
|
||||
Xoff = (UHWORD)(((Nmult+1)/2.0) * MAX(1.0,1.0/factor) + 10);
|
||||
Xoff = (unsigned short)(((Nmult+1)/2.0) * MAX(1.0,1.0/_factor) + 10);
|
||||
|
||||
if (IBUFFSIZE < 2*Xoff) /* Check input buffer size */
|
||||
return err_ret("IBUFFSIZE (or factor) is too small");
|
||||
|
@ -546,13 +577,14 @@ aflibConverter::resampleWithFilter( /* number of output samples returned */
|
|||
Xp = Xoff; /* Current "now"-sample pointer for input */
|
||||
Xread = Xoff; /* Position in input array to read into */
|
||||
|
||||
if (initial == TRUE)
|
||||
Time = (Xoff<<Np); /* Current-time pointer for converter */
|
||||
if (_initial == TRUE)
|
||||
_Time = (Xoff<<Np); /* Current-time pointer for converter */
|
||||
|
||||
do {
|
||||
if (!last) /* If haven't read last sample yet */
|
||||
{
|
||||
last = readData(inCount, inArray, X, IBUFFSIZE, (int)Xread,first_pass);
|
||||
last = readData(inCount, inArray, _X,
|
||||
IBUFFSIZE, (int)Xread,first_pass);
|
||||
first_pass = FALSE;
|
||||
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
||||
Nx = last-Xoff; /* ...calc last sample affected by filter */
|
||||
|
@ -561,25 +593,28 @@ aflibConverter::resampleWithFilter( /* number of output samples returned */
|
|||
}
|
||||
}
|
||||
|
||||
if ( (outCount-Ycount) > (OBUFFSIZE - (2*Xoff*factor)) )
|
||||
maxOutput = OBUFFSIZE - (UHWORD)(2*Xoff*factor);
|
||||
if ( (outCount-Ycount) > (OBUFFSIZE - (2*Xoff*_factor)) )
|
||||
maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor);
|
||||
else
|
||||
maxOutput = outCount-Ycount;
|
||||
|
||||
for (c = 0; c < nChans; c++)
|
||||
for (c = 0; c < _nChans; c++)
|
||||
{
|
||||
Time2 = Time;
|
||||
orig_Nx = Nx;
|
||||
Time2 = _Time;
|
||||
/* Resample stuff in input buffer */
|
||||
if (factor >= 1) { /* SrcUp() is faster if we can use it */
|
||||
Nout=SrcUp(X[c],Y[c],factor,&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
||||
if (_factor >= 1) { /* SrcUp() is faster if we can use it */
|
||||
Nout=SrcUp(_X[c],_Y[c],_factor,
|
||||
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
||||
}
|
||||
else {
|
||||
Nout=SrcUD(X[c],Y[c],factor,&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
||||
Nout=SrcUD(_X[c],_Y[c],_factor,
|
||||
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
||||
}
|
||||
}
|
||||
Time = Time2;
|
||||
_Time = Time2;
|
||||
|
||||
Time -= (Nx<<Np); /* Move converter Nx samples back in time */
|
||||
_Time -= (Nx<<Np); /* Move converter Nx samples back in time */
|
||||
Xp += Nx; /* Advance by number of samples processed */
|
||||
#if 0
|
||||
Ncreep = (Time>>Np) - Xoff; /* Calc time accumulation in Time */
|
||||
|
@ -603,20 +638,20 @@ aflibConverter::resampleWithFilter( /* number of output samples returned */
|
|||
if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */
|
||||
return err_ret("Output array overflow");
|
||||
|
||||
for (c = 0; c < nChans; c++)
|
||||
for (c = 0; c < _nChans; c++)
|
||||
{
|
||||
for (i = 0; i < Nout; i++)
|
||||
{
|
||||
outArray[c * outCount + i + Ycount - Nout] = Y[c][i];
|
||||
outArray[c * outCount + i + Ycount - Nout] = _Y[c][i];
|
||||
}
|
||||
}
|
||||
|
||||
int act_incount = (int)Nx;
|
||||
|
||||
for (c = 0; c < nChans; c++)
|
||||
for (c = 0; c < _nChans; c++)
|
||||
{
|
||||
for (i=0; i<IBUFFSIZE-act_incount+Xoff; i++) { /* Copy part of input signal */
|
||||
X[c][i] = X[c][i+act_incount]; /* that must be re-used */
|
||||
_X[c][i] = _X[c][i+act_incount]; /* that must be re-used */
|
||||
}
|
||||
}
|
||||
Xread = IBUFFSIZE - Nx; /* Pos in input buff to read new data into */
|
||||
|
@ -631,23 +666,30 @@ aflibConverter::resampleWithFilter( /* number of output samples returned */
|
|||
return(Ycount); /* Return # of samples in output file */
|
||||
}
|
||||
|
||||
|
||||
WORD
|
||||
aflibConverter::FilterUp(HWORD Imp[], HWORD ImpD[],
|
||||
UHWORD Nwing, BOOL Interp,
|
||||
HWORD *Xp, HWORD Ph, HWORD Inc)
|
||||
int
|
||||
aflibConverter::FilterUp(
|
||||
short Imp[],
|
||||
short ImpD[],
|
||||
unsigned short Nwing,
|
||||
bool Interp,
|
||||
short *Xp,
|
||||
short Ph,
|
||||
short Inc)
|
||||
{
|
||||
HWORD *Hp, *Hdp = NULL, *End;
|
||||
HWORD a = 0;
|
||||
WORD v, t;
|
||||
short *Hp, *Hdp = NULL, *End;
|
||||
short a = 0;
|
||||
int v, t;
|
||||
|
||||
v=0;
|
||||
Hp = &Imp[Ph>>Na];
|
||||
End = &Imp[Nwing];
|
||||
if (Interp) {
|
||||
|
||||
if (Interp)
|
||||
{
|
||||
Hdp = &ImpD[Ph>>Na];
|
||||
a = Ph & Amask;
|
||||
}
|
||||
|
||||
if (Inc == 1) /* If doing right wing... */
|
||||
{ /* ...drop extra coeff, so when Ph is */
|
||||
End--; /* 0.5, we don't do too many mult's */
|
||||
|
@ -657,10 +699,13 @@ aflibConverter::FilterUp(HWORD Imp[], HWORD ImpD[],
|
|||
Hdp += Npc; /* skip ahead in Imp[] and ImpD[] */
|
||||
}
|
||||
}
|
||||
|
||||
if (Interp)
|
||||
while (Hp < End) {
|
||||
{
|
||||
while (Hp < End)
|
||||
{
|
||||
t = *Hp; /* Get filter coeff */
|
||||
t += (((WORD)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */
|
||||
t += (((int)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */
|
||||
Hdp += Npc; /* Filter coeff differences step */
|
||||
t *= *Xp; /* Mult coeff by input sample */
|
||||
if (t & (1<<(Nhxn-1))) /* Round, if needed */
|
||||
|
@ -670,8 +715,11 @@ aflibConverter::FilterUp(HWORD Imp[], HWORD ImpD[],
|
|||
Hp += Npc; /* Filter coeff step */
|
||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||
}
|
||||
}
|
||||
else
|
||||
while (Hp < End) {
|
||||
{
|
||||
while (Hp < End)
|
||||
{
|
||||
t = *Hp; /* Get filter coeff */
|
||||
t *= *Xp; /* Mult coeff by input sample */
|
||||
if (t & (1<<(Nhxn-1))) /* Round, if needed */
|
||||
|
@ -681,22 +729,29 @@ aflibConverter::FilterUp(HWORD Imp[], HWORD ImpD[],
|
|||
Hp += Npc; /* Filter coeff step */
|
||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||
}
|
||||
}
|
||||
return(v);
|
||||
}
|
||||
|
||||
|
||||
WORD
|
||||
aflibConverter::FilterUD( HWORD Imp[], HWORD ImpD[],
|
||||
UHWORD Nwing, BOOL Interp,
|
||||
HWORD *Xp, HWORD Ph, HWORD Inc, UHWORD dhb)
|
||||
int
|
||||
aflibConverter::FilterUD(
|
||||
short Imp[],
|
||||
short ImpD[],
|
||||
unsigned short Nwing,
|
||||
bool Interp,
|
||||
short *Xp,
|
||||
short Ph,
|
||||
short Inc,
|
||||
unsigned short dhb)
|
||||
{
|
||||
HWORD a;
|
||||
HWORD *Hp, *Hdp, *End;
|
||||
WORD v, t;
|
||||
UWORD Ho;
|
||||
short a;
|
||||
short *Hp, *Hdp, *End;
|
||||
int v, t;
|
||||
unsigned int Ho;
|
||||
|
||||
v=0;
|
||||
Ho = (Ph*(UWORD)dhb)>>Np;
|
||||
Ho = (Ph*(unsigned int)dhb)>>Np;
|
||||
End = &Imp[Nwing];
|
||||
if (Inc == 1) /* If doing right wing... */
|
||||
{ /* ...drop extra coeff, so when Ph is */
|
||||
|
@ -705,12 +760,15 @@ aflibConverter::FilterUD( HWORD Imp[], HWORD ImpD[],
|
|||
Ho += dhb; /* ...then we've already skipped the */
|
||||
} /* first sample, so we must also */
|
||||
/* skip ahead in Imp[] and ImpD[] */
|
||||
|
||||
if (Interp)
|
||||
while ((Hp = &Imp[Ho>>Na]) < End) {
|
||||
{
|
||||
while ((Hp = &Imp[Ho>>Na]) < End)
|
||||
{
|
||||
t = *Hp; /* Get IR sample */
|
||||
Hdp = &ImpD[Ho>>Na]; /* get interp (lower Na) bits from diff table*/
|
||||
a = Ho & Amask; /* a is logically between 0 and 1 */
|
||||
t += (((WORD)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */
|
||||
t += (((int)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */
|
||||
t *= *Xp; /* Mult coeff by input sample */
|
||||
if (t & 1<<(Nhxn-1)) /* Round, if needed */
|
||||
t += 1<<(Nhxn-1);
|
||||
|
@ -719,8 +777,11 @@ aflibConverter::FilterUD( HWORD Imp[], HWORD ImpD[],
|
|||
Ho += dhb; /* IR step */
|
||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||
}
|
||||
}
|
||||
else
|
||||
while ((Hp = &Imp[Ho>>Na]) < End) {
|
||||
{
|
||||
while ((Hp = &Imp[Ho>>Na]) < End)
|
||||
{
|
||||
t = *Hp; /* Get IR sample */
|
||||
t *= *Xp; /* Mult coeff by input sample */
|
||||
if (t & 1<<(Nhxn-1)) /* Round, if needed */
|
||||
|
@ -730,6 +791,7 @@ aflibConverter::FilterUD( HWORD Imp[], HWORD ImpD[],
|
|||
Ho += dhb; /* IR step */
|
||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||
}
|
||||
}
|
||||
return(v);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* Julius O. Smith jos@ccrma.stanford.edu
|
||||
*
|
||||
*/
|
||||
/* This code was modified by Bruce Forsberg (forsberg@adnc.com) to make it
|
||||
/* This code was modified by Bruce Forsberg (forsberg@tns.net) to make it
|
||||
into a C++ class
|
||||
*/
|
||||
|
||||
|
@ -26,6 +26,10 @@
|
|||
#ifndef _AFLIBCONVERTER_H_
|
||||
#define _AFLIBCONVERTER_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) ((x)>(y) ?(x):(y))
|
||||
#endif
|
||||
|
@ -36,11 +40,6 @@
|
|||
#define MAX_HWORD (32767)
|
||||
#define MIN_HWORD (-32768)
|
||||
|
||||
typedef char BOOL;
|
||||
typedef short HWORD;
|
||||
typedef unsigned short UHWORD;
|
||||
typedef int WORD;
|
||||
typedef unsigned int UWORD;
|
||||
#define IBUFFSIZE 4096 /* Input buffer size */
|
||||
|
||||
/*! \class aflibConverter
|
||||
|
@ -58,18 +57,22 @@ typedef unsigned int UWORD;
|
|||
|
||||
This class was designed to stream audio data. It also expects audio data as 16 bit values.
|
||||
Each time a new stream is started some initialization needs to be done. Thus the function
|
||||
initialize should be called to initialize everything. This class will work on any
|
||||
number of channels. Once everything is specified then resample should be called as many
|
||||
times as is necessary to process all the data. The value inCount will be returned
|
||||
indicating how many inArray samples were actually used to produce the output. This
|
||||
value can be used to indicate where the next block of inArray data should start. The
|
||||
resample function is driven by the outCount value specified. The inArray should
|
||||
contain at least:
|
||||
initialize should be called to initialize everything. This initialize function will set
|
||||
the conversion factor as well as a multiplecation factor for volume. The volume only
|
||||
applies to the small and large filter. Since this filter uses a history of the audio data
|
||||
it is possible for it to vary in amplitude. This allows users to scale the data. This
|
||||
class will work on any number of channels. Once everything is specified then resample
|
||||
should be called as many times as is necessary to process all the data. The value
|
||||
inCount will be returned indicating how many inArray samples were actually used to
|
||||
produce the output. This value can be used to indicate where the next block of
|
||||
inArray data should start. The resample function is driven by the outCount value
|
||||
specified. The inArray should contain at least:
|
||||
outCount / factor + extra_samples.
|
||||
extra_samples depends on the type of filtering done. As a rule of thumb 50 should be
|
||||
adequate for any type of filter.
|
||||
*/
|
||||
|
||||
class aflibData;
|
||||
|
||||
class aflibConverter {
|
||||
|
||||
|
@ -86,14 +89,15 @@ public:
|
|||
void
|
||||
initialize(
|
||||
double factor, /* factor = Sndout/Sndin */
|
||||
int channels);/* number of sound channels */
|
||||
int channels, /* number of sound channels */
|
||||
double volume = 1.0); /* factor to multiply amplitude */
|
||||
|
||||
int
|
||||
resample( /* number of output samples returned */
|
||||
int& inCount, /* number of input samples to convert */
|
||||
int outCount, /* number of output samples to compute */
|
||||
HWORD inArray[], /* input array data (length inCount * nChans) */
|
||||
HWORD outArray[]);/* output array data (length outCount * nChans) */
|
||||
short inArray[], /* input array data (length inCount * nChans) */
|
||||
short outArray[]);/* output array data (length outCount * nChans) */
|
||||
|
||||
|
||||
private:
|
||||
|
@ -114,130 +118,117 @@ private:
|
|||
int
|
||||
readData(
|
||||
int inCount, /* _total_ number of frames in input file */
|
||||
HWORD inArray[], /* input data */
|
||||
HWORD *outPtr[], /* array receiving chan samps */
|
||||
short inArray[], /* input data */
|
||||
short *outPtr[], /* array receiving chan samps */
|
||||
int dataArraySize, /* size of these arrays */
|
||||
int Xoff, /* read into input array starting at this index */
|
||||
bool init_count);
|
||||
|
||||
|
||||
inline HWORD
|
||||
WordToHword(WORD v, int scl)
|
||||
inline short
|
||||
WordToHword(int v, int scl)
|
||||
{
|
||||
HWORD out;
|
||||
WORD llsb = (1<<(scl-1));
|
||||
short out;
|
||||
int llsb = (1<<(scl-1));
|
||||
v += llsb; /* round */
|
||||
v >>= scl;
|
||||
if (v>MAX_HWORD) {
|
||||
#ifdef DEBUG
|
||||
if (pof == 0)
|
||||
fprintf(stderr, "*** resample: sound sample overflow\n");
|
||||
else if ((pof % 10000) == 0)
|
||||
fprintf(stderr, "*** resample: another ten thousand overflows\n");
|
||||
pof++;
|
||||
#endif
|
||||
v = MAX_HWORD;
|
||||
} else if (v < MIN_HWORD) {
|
||||
#ifdef DEBUG
|
||||
if (nof == 0)
|
||||
fprintf(stderr, "*** resample: sound sample (-) overflow\n");
|
||||
else if ((nof % 1000) == 0)
|
||||
fprintf(stderr, "*** resample: another thousand (-) overflows\n");
|
||||
nof++;
|
||||
#endif
|
||||
v = MIN_HWORD;
|
||||
}
|
||||
out = (HWORD) v;
|
||||
out = (short) v;
|
||||
return out;
|
||||
};
|
||||
|
||||
int
|
||||
SrcLinear(
|
||||
HWORD X[],
|
||||
HWORD Y[],
|
||||
short X[],
|
||||
short Y[],
|
||||
double factor,
|
||||
UWORD *Time,
|
||||
UHWORD& Nx,
|
||||
UHWORD Nout);
|
||||
unsigned int *Time,
|
||||
unsigned short& Nx,
|
||||
unsigned short Nout);
|
||||
|
||||
int
|
||||
SrcUp(
|
||||
HWORD X[],
|
||||
HWORD Y[],
|
||||
short X[],
|
||||
short Y[],
|
||||
double factor,
|
||||
UWORD *Time,
|
||||
UHWORD& Nx,
|
||||
UHWORD Nout,
|
||||
UHWORD Nwing,
|
||||
UHWORD LpScl,
|
||||
HWORD Imp[],
|
||||
HWORD ImpD[],
|
||||
BOOL Interp);
|
||||
unsigned int *Time,
|
||||
unsigned short& Nx,
|
||||
unsigned short Nout,
|
||||
unsigned short Nwing,
|
||||
unsigned short LpScl,
|
||||
short Imp[],
|
||||
short ImpD[],
|
||||
bool Interp);
|
||||
|
||||
int
|
||||
SrcUD(
|
||||
HWORD X[],
|
||||
HWORD Y[],
|
||||
short X[],
|
||||
short Y[],
|
||||
double factor,
|
||||
UWORD *Time,
|
||||
UHWORD& Nx,
|
||||
UHWORD Nout,
|
||||
UHWORD Nwing,
|
||||
UHWORD LpScl,
|
||||
HWORD Imp[],
|
||||
HWORD ImpD[],
|
||||
BOOL Interp);
|
||||
unsigned int *Time,
|
||||
unsigned short& Nx,
|
||||
unsigned short Nout,
|
||||
unsigned short Nwing,
|
||||
unsigned short LpScl,
|
||||
short Imp[],
|
||||
short ImpD[],
|
||||
bool Interp);
|
||||
|
||||
WORD
|
||||
int
|
||||
FilterUp(
|
||||
HWORD Imp[],
|
||||
HWORD ImpD[],
|
||||
UHWORD Nwing,
|
||||
BOOL Interp,
|
||||
HWORD *Xp,
|
||||
HWORD Ph,
|
||||
HWORD Inc);
|
||||
short Imp[],
|
||||
short ImpD[],
|
||||
unsigned short Nwing,
|
||||
bool Interp,
|
||||
short *Xp,
|
||||
short Ph,
|
||||
short Inc);
|
||||
|
||||
WORD
|
||||
int
|
||||
FilterUD(
|
||||
HWORD Imp[],
|
||||
HWORD ImpD[],
|
||||
UHWORD Nwing,
|
||||
BOOL Interp,
|
||||
HWORD *Xp,
|
||||
HWORD Ph,
|
||||
HWORD Inc,
|
||||
UHWORD dhb);
|
||||
short Imp[],
|
||||
short ImpD[],
|
||||
unsigned short Nwing,
|
||||
bool Interp,
|
||||
short *Xp,
|
||||
short Ph,
|
||||
short Inc,
|
||||
unsigned short dhb);
|
||||
|
||||
int
|
||||
resampleFast( /* number of output samples returned */
|
||||
int& inCount, /* number of input samples to convert */
|
||||
int outCount, /* number of output samples to compute */
|
||||
HWORD inArray[], /* input array data (length inCount * nChans) */
|
||||
HWORD outArray[]);/* output array data (length outCount * nChans) */
|
||||
short inArray[], /* input array data (length inCount * nChans) */
|
||||
short outArray[]);/* output array data (length outCount * nChans) */
|
||||
|
||||
int
|
||||
resampleWithFilter( /* number of output samples returned */
|
||||
int& inCount, /* number of input samples to convert */
|
||||
int outCount, /* number of output samples to compute */
|
||||
HWORD inArray[], /* input array data (length inCount * nChans) */
|
||||
HWORD outArray[], /* output array data (length outCount * nChans) */
|
||||
HWORD Imp[], HWORD ImpD[],
|
||||
UHWORD LpScl, UHWORD Nmult, UHWORD Nwing);
|
||||
short inArray[], /* input array data (length inCount * nChans) */
|
||||
short outArray[], /* output array data (length outCount * nChans) */
|
||||
short Imp[], short ImpD[],
|
||||
unsigned short LpScl, unsigned short Nmult, unsigned short Nwing);
|
||||
|
||||
|
||||
static HWORD SMALL_FILTER_IMP[];
|
||||
static HWORD LARGE_FILTER_IMP[];
|
||||
static short SMALL_FILTER_IMP[];
|
||||
static short LARGE_FILTER_IMP[];
|
||||
|
||||
bool interpFilt;
|
||||
bool largeFilter;
|
||||
bool linearInterp;
|
||||
HWORD ** X;
|
||||
HWORD ** Y;
|
||||
UWORD Time;
|
||||
double factor;
|
||||
int nChans;
|
||||
bool initial;
|
||||
short ** _X;
|
||||
short ** _Y;
|
||||
unsigned int _Time;
|
||||
double _factor;
|
||||
int _nChans;
|
||||
bool _initial;
|
||||
double _vol;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -34,11 +34,16 @@ well for its level of computational expense.
|
|||
|
||||
*/
|
||||
|
||||
#define LARGE_FILTER_NMULT ((HWORD)65)
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define LARGE_FILTER_NMULT ((short)65)
|
||||
#define LARGE_FILTER_SCALE 14746 /* Unity-gain scale factor */
|
||||
#define LARGE_FILTER_NWING 8192 /* Filter table length */
|
||||
|
||||
HWORD aflibConverter::LARGE_FILTER_IMP[] /* Impulse response */ = {
|
||||
short aflibConverter::LARGE_FILTER_IMP[] /* Impulse response */ = {
|
||||
32767,
|
||||
32766,
|
||||
32764,
|
||||
|
@ -8232,7 +8237,7 @@ HWORD aflibConverter::LARGE_FILTER_IMP[] /* Impulse response */ = {
|
|||
0,
|
||||
0};
|
||||
|
||||
static HWORD LARGE_FILTER_IMPD[] /* Impulse response differences */ = {
|
||||
static short LARGE_FILTER_IMPD[] /* Impulse response differences */ = {
|
||||
-1,
|
||||
-2,
|
||||
-3,
|
||||
|
|
|
@ -19,11 +19,16 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define SMALL_FILTER_NMULT ((HWORD)13)
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define SMALL_FILTER_NMULT ((short)13)
|
||||
#define SMALL_FILTER_SCALE 13128 /* Unity-gain scale factor */
|
||||
#define SMALL_FILTER_NWING 1536 /* Filter table length */
|
||||
|
||||
HWORD aflibConverter::SMALL_FILTER_IMP[] /* Impulse response */ = {
|
||||
short aflibConverter::SMALL_FILTER_IMP[] /* Impulse response */ = {
|
||||
32767,
|
||||
32766,
|
||||
32764,
|
||||
|
@ -1562,7 +1567,7 @@ HWORD aflibConverter::SMALL_FILTER_IMP[] /* Impulse response */ = {
|
|||
-1
|
||||
};
|
||||
|
||||
static HWORD SMALL_FILTER_IMPD[] = {
|
||||
static short SMALL_FILTER_IMPD[] = {
|
||||
-1,
|
||||
-2,
|
||||
-4,
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
|
||||
Copyright (C) 2000 Stefan Westerfeld
|
||||
stefan@space.twc.de
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "aflibDebug.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int aflib_debug_level = ::aflibDebug::lInfo;
|
||||
static bool aflib_debug_abort = false;
|
||||
static const char *aflib_debug_prefix = "";
|
||||
static char *messageAppName = 0;
|
||||
|
||||
|
||||
/*
|
||||
static char* status_strs[] =
|
||||
{
|
||||
"Success",
|
||||
"Error Open",
|
||||
"Unsupported",
|
||||
"AFLIB_ERROR_INITIALIZATION_FAILURE",
|
||||
"AFLIB_NOT_FOUND",
|
||||
"AFLIB_END_OF_FILE",
|
||||
"AFLIB_NO_DATA",
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static char* data_size_strs[] =
|
||||
{
|
||||
"UNDEFINED",
|
||||
"8 bit signed",
|
||||
"8 bit unsigned",
|
||||
"16 bit signed",
|
||||
"16 bit unsigned",
|
||||
"32 bit signed",
|
||||
"32 bit unsigned",
|
||||
0
|
||||
};
|
||||
|
||||
static char* data_endian_strs[] =
|
||||
{
|
||||
"UNDEFINED",
|
||||
"ENDIAN_LITTLE",
|
||||
"ENDIAN_BIG",
|
||||
0
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
* Call the graphical application to display a message, if
|
||||
* defined. Otherwise, send to standard error. Debug messages are
|
||||
* always sent to standard error because they tend to be very verbose.
|
||||
* Note that the external application is run in the background to
|
||||
* avoid blocking the sound server.
|
||||
*/
|
||||
void output_message(::aflibDebug::Level level, const char *msg) {
|
||||
char buff[1024];
|
||||
|
||||
/* default to text output if no message app is defined or if it is a debug message. */
|
||||
if (messageAppName == 0 || !strcmp(messageAppName, "") || (level == ::aflibDebug::lDebug))
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
case ::aflibDebug::lFatal:
|
||||
sprintf(buff, "%s -e \"aflib fatal error:\n\n%s\" &", messageAppName, msg);
|
||||
break;
|
||||
case ::aflibDebug::lWarning:
|
||||
sprintf(buff, "%s -w \"aflib warning message:\n\n%s\" &", messageAppName, msg);
|
||||
break;
|
||||
case ::aflibDebug::lInfo:
|
||||
sprintf(buff, "%s -i \"aflib informational message:\n\n%s\" &", messageAppName, msg);
|
||||
break;
|
||||
default:
|
||||
break; // avoid compile warning
|
||||
}
|
||||
system(buff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display a message using output_message. If the message is the same
|
||||
* as the previous one, just increment a count but don't display
|
||||
* it. This prevents flooding the user with duplicate warnings. If the
|
||||
* message is not the same as the previous one, then we report the
|
||||
* previously repeated message (if any) and reset the last message and
|
||||
* count.
|
||||
*/
|
||||
void display_message(::aflibDebug::Level level, const char *msg) {
|
||||
static char lastMsg[1024];
|
||||
static ::aflibDebug::Level lastLevel;
|
||||
static int msgCount = 0;
|
||||
|
||||
if (!strncmp(msg, lastMsg, 1024))
|
||||
{
|
||||
msgCount++;
|
||||
} else {
|
||||
if (msgCount > 0)
|
||||
{
|
||||
char buff[1024];
|
||||
sprintf(buff, "%s\n(The previous message was repeated %d times.)", lastMsg, msgCount);
|
||||
output_message(lastLevel, buff);
|
||||
}
|
||||
|
||||
strncpy(lastMsg, msg, 1024);
|
||||
lastLevel = level;
|
||||
msgCount = 0;
|
||||
output_message(level, msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class DebugInitFromEnv {
|
||||
|
||||
public:
|
||||
DebugInitFromEnv() {
|
||||
const char *env = getenv("AFLIB_DEBUG");
|
||||
if(env)
|
||||
{
|
||||
if(strcmp(env,"debug") == 0)
|
||||
aflib_debug_level = ::aflibDebug::lDebug;
|
||||
else if(strcmp(env,"info") == 0)
|
||||
aflib_debug_level = ::aflibDebug::lInfo;
|
||||
else if(strcmp(env,"warning") == 0)
|
||||
aflib_debug_level = ::aflibDebug::lWarning;
|
||||
else if(strcmp(env,"quiet") == 0)
|
||||
aflib_debug_level = ::aflibDebug::lFatal;
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"AFLIB_DEBUG must be one of debug,info,warning,quiet\n");
|
||||
}
|
||||
}
|
||||
|
||||
env = getenv("AFLIB_DEBUG_ABORT");
|
||||
if(env)
|
||||
aflib_debug_abort = true;
|
||||
}
|
||||
}
|
||||
|
||||
debugInitFromEnv;
|
||||
|
||||
|
||||
void aflibDebug::init(const char *prefix, Level level)
|
||||
{
|
||||
aflib_debug_level = level;
|
||||
aflib_debug_prefix = prefix;
|
||||
}
|
||||
|
||||
void aflibDebug::fatal(const char *fmt, ...)
|
||||
{
|
||||
char buff[1024];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buff, fmt, ap);
|
||||
va_end(ap);
|
||||
display_message(::aflibDebug::lFatal, buff);
|
||||
|
||||
if(aflib_debug_abort) abort();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void aflibDebug::warning(const char *fmt, ...)
|
||||
{
|
||||
if(lWarning >= aflib_debug_level)
|
||||
{
|
||||
char buff[1024];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buff, fmt, ap);
|
||||
va_end(ap);
|
||||
display_message(::aflibDebug::lWarning, buff);
|
||||
}
|
||||
}
|
||||
|
||||
void aflibDebug::info(const char *fmt, ...)
|
||||
{
|
||||
if(lInfo >= aflib_debug_level)
|
||||
{
|
||||
char buff[1024];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buff, fmt, ap);
|
||||
va_end(ap);
|
||||
display_message(::aflibDebug::lInfo, buff);
|
||||
}
|
||||
}
|
||||
|
||||
void aflibDebug::debug(const char *fmt, ...)
|
||||
{
|
||||
if(lDebug >= aflib_debug_level)
|
||||
{
|
||||
char buff[1024];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buff, fmt, ap);
|
||||
va_end(ap);
|
||||
display_message(::aflibDebug::lDebug, buff);
|
||||
}
|
||||
}
|
||||
|
||||
void aflibDebug::messageApp(const char *appName)
|
||||
{
|
||||
messageAppName = (char*) realloc(messageAppName, strlen(appName)+1);
|
||||
strcpy(messageAppName, appName);
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
|
||||
Copyright (C) 2000 Stefan Westerfeld
|
||||
stefan@space.twc.de
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
Some inspiration taken from glib.
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GLib Team and others 1997-1999.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _AFLIBDEBUG_H_
|
||||
#define _AFLIBDEBUG_H_
|
||||
|
||||
/*
|
||||
* BC - Status (2000-09-30): Debug.
|
||||
*
|
||||
* Collection class, no instance, no members. Thus binary compatible (will
|
||||
* be kept).
|
||||
*/
|
||||
|
||||
#define aflib_fatal ::aflibDebug::fatal
|
||||
#define aflib_warning ::aflibDebug::warning
|
||||
#define aflib_info ::aflibDebug::info
|
||||
#define aflib_debug ::aflibDebug::debug
|
||||
|
||||
/* source compatibility with older sources */
|
||||
#define aflibdebug ::aflibDebug::debug
|
||||
#define setaflibdebug(x) aflib_warning("setaflibdebug is obsolete")
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#define aflib_return_if_fail(expr) \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
aflib_warning ("file %s: line %d (%s): assertion failed: (%s)", \
|
||||
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define aflib_return_val_if_fail(expr,val) \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
aflib_warning ("file %s: line %d (%s): assertion failed: (%s)", \
|
||||
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
|
||||
return (val); \
|
||||
}
|
||||
|
||||
#define aflib_assert(expr) \
|
||||
if (!(expr)) \
|
||||
aflib_fatal ("file %s: line %d (%s): assertion failed: (%s)", \
|
||||
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
|
||||
|
||||
#else
|
||||
|
||||
#define aflib_return_if_fail(expr) \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
aflib_warning ("file %s: line %d: assertion failed: (%s)", \
|
||||
__FILE__, __LINE__, #expr); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define aflib_return_val_if_fail(expr,val) \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
aflib_warning ("file %s: line %d: assertion failed: (%s)", \
|
||||
__FILE__, __LINE__, #expr); \
|
||||
return (val); \
|
||||
}
|
||||
|
||||
#define aflib_assert(expr) \
|
||||
if (!(expr)) \
|
||||
aflib_fatal ("file %s: line %d: assertion failed: (%s)", \
|
||||
__FILE__, __LINE__, #expr); \
|
||||
|
||||
#endif
|
||||
|
||||
class aflibDebug {
|
||||
public:
|
||||
enum Level { lFatal = 3, lWarning = 2, lInfo = 1, lDebug = 0 };
|
||||
|
||||
/**
|
||||
* Initializes at which is the minimum level to react to. If you
|
||||
* call this, call this before creating the Arts::Dispatcher object.
|
||||
*/
|
||||
static void init(const char *prefix, Level level);
|
||||
|
||||
static void fatal(const char *fmt,...); // print on stderr & abort
|
||||
static void warning(const char *fmt,...); // print on stderr
|
||||
static void info(const char *fmt,...); // print on stdout
|
||||
static void debug(const char *fmt,...); // print on stdout
|
||||
|
||||
/**
|
||||
* This method sets the name of an external application to
|
||||
* display messages graphically.
|
||||
*/
|
||||
static void messageApp(const char *appName);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue