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\
|
LameLibEncoder.h\
|
||||||
VorbisLibEncoder.cpp\
|
VorbisLibEncoder.cpp\
|
||||||
VorbisLibEncoder.h\
|
VorbisLibEncoder.h\
|
||||||
|
aflibDebug.h\
|
||||||
|
aflibDebug.cc\
|
||||||
aflibConverter.h\
|
aflibConverter.h\
|
||||||
aflibConverter.cc\
|
aflibConverter.cc\
|
||||||
aflibConverterLargeFilter.h\
|
aflibConverterLargeFilter.h\
|
||||||
|
|
|
@ -18,10 +18,13 @@
|
||||||
* Julius O. Smith jos@ccrma.stanford.edu
|
* 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
|
into a C++ class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -32,6 +35,7 @@
|
||||||
#include "aflibConverterLargeFilter.h"
|
#include "aflibConverterLargeFilter.h"
|
||||||
#include "aflibConverterSmallFilter.h"
|
#include "aflibConverterSmallFilter.h"
|
||||||
|
|
||||||
|
#include "aflibDebug.h"
|
||||||
|
|
||||||
#if (!defined(TRUE) || !defined(FALSE))
|
#if (!defined(TRUE) || !defined(FALSE))
|
||||||
# define TRUE 1
|
# define TRUE 1
|
||||||
|
@ -112,12 +116,16 @@ aflibConverter::aflibConverter(
|
||||||
bool linear_interpolation,
|
bool linear_interpolation,
|
||||||
bool filter_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;
|
interpFilt = filter_interpolation;
|
||||||
largeFilter = high_quality;
|
largeFilter = high_quality;
|
||||||
linearInterp = linear_interpolation;
|
linearInterp = linear_interpolation;
|
||||||
|
|
||||||
X = NULL;
|
_X = NULL;
|
||||||
Y = NULL;
|
_Y = NULL;
|
||||||
|
_vol = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
aflibConverter::~aflibConverter()
|
aflibConverter::~aflibConverter()
|
||||||
|
@ -131,65 +139,65 @@ aflibConverter::deleteMemory()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
// Delete memory for the input and output arrays
|
// 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];
|
delete [] _X[i];
|
||||||
X[i] = NULL;
|
_X[i] = NULL;
|
||||||
delete [] Y[i];
|
delete [] _Y[i];
|
||||||
Y[i] = NULL;
|
_Y[i] = NULL;
|
||||||
}
|
}
|
||||||
delete [] X;
|
delete [] _X;
|
||||||
X = NULL;
|
_X = NULL;
|
||||||
delete [] Y;
|
delete [] _Y;
|
||||||
Y = NULL;
|
_Y = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
aflibConverter::initialize(
|
aflibConverter::initialize(
|
||||||
double fac,
|
double fac,
|
||||||
int channels)
|
int channels,
|
||||||
|
double volume)
|
||||||
{
|
{
|
||||||
// This function will allow one to stream data. When a new data stream is to
|
// 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
|
// 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
|
// 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;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
// Delete all previous allocated input and output buffer memory
|
// Delete all previous allocated input and output buffer memory
|
||||||
deleteMemory();
|
deleteMemory();
|
||||||
|
|
||||||
factor = fac;
|
_factor = fac;
|
||||||
nChans = channels;
|
_nChans = channels;
|
||||||
initial = TRUE;
|
_initial = TRUE;
|
||||||
|
_vol = volume;
|
||||||
|
|
||||||
// Allocate all new memory
|
// Allocate all new memory
|
||||||
X = new HWORD * [nChans];
|
_X = new short * [_nChans];
|
||||||
Y = new HWORD * [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)
|
// Add extra to allow of offset of input data (Xoff in main routine)
|
||||||
X[i] = new HWORD[IBUFFSIZE + 256];
|
_X[i] = new short[IBUFFSIZE + 256];
|
||||||
Y[i] = new HWORD[(int)(((double)IBUFFSIZE)*factor)];
|
_Y[i] = new short[(int)(((double)IBUFFSIZE)*_factor)];
|
||||||
memset(X[i], 0, sizeof(HWORD) * (IBUFFSIZE + 256));
|
memset(_X[i], 0, sizeof(short) * (IBUFFSIZE + 256));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
aflibConverter::resample( /* number of output samples returned */
|
aflibConverter::resample( /* number of output samples returned */
|
||||||
int& inCount, /* number of input samples to convert */
|
int& inCount, /* number of input samples to convert */
|
||||||
int outCount, /* number of output samples to compute */
|
int outCount, /* number of output samples to compute */
|
||||||
HWORD inArray[], /* input data */
|
short inArray[], /* input data */
|
||||||
HWORD outArray[]) /* output data */
|
short outArray[]) /* output data */
|
||||||
{
|
{
|
||||||
int Ycount;
|
int Ycount;
|
||||||
|
|
||||||
|
@ -200,40 +208,42 @@ aflibConverter::resample( /* number of output samples returned */
|
||||||
// Use small filtering. Good qulaity
|
// Use small filtering. Good qulaity
|
||||||
else if (largeFilter == FALSE)
|
else if (largeFilter == FALSE)
|
||||||
Ycount = resampleWithFilter(inCount,outCount,inArray,outArray,
|
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);
|
SMALL_FILTER_NMULT, SMALL_FILTER_NWING);
|
||||||
// Use large filtering Great quality
|
// Use large filtering Great quality
|
||||||
else
|
else
|
||||||
Ycount = resampleWithFilter(inCount,outCount,inArray,outArray,
|
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);
|
LARGE_FILTER_NMULT, LARGE_FILTER_NWING);
|
||||||
|
|
||||||
initial = FALSE;
|
_initial = FALSE;
|
||||||
|
|
||||||
return (Ycount);
|
return (Ycount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
aflibConverter::err_ret(char *s)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
aflibConverter::readData(
|
aflibConverter::readData(
|
||||||
int inCount, /* _total_ number of frames in input file */
|
int inCount, /* _total_ number of frames in input file */
|
||||||
HWORD inArray[], /* input data */
|
short inArray[], /* input data */
|
||||||
HWORD *outPtr[], /* array receiving chan samps */
|
short *outPtr[], /* array receiving chan samps */
|
||||||
int dataArraySize, /* size of these arrays */
|
int dataArraySize, /* size of these arrays */
|
||||||
int Xoff, /* read into input array starting at this index */
|
int Xoff, /* read into input array starting at this index */
|
||||||
bool init_count)
|
bool init_count)
|
||||||
{
|
{
|
||||||
int i, Nsamps, c;
|
int i, Nsamps, c;
|
||||||
static unsigned int framecount; /* frames previously read */
|
static unsigned int framecount; /* frames previously read */
|
||||||
HWORD *ptr;
|
short *ptr;
|
||||||
|
|
||||||
if (init_count == TRUE)
|
if (init_count == TRUE)
|
||||||
framecount = 0; /* init this too */
|
framecount = 0; /* init this too */
|
||||||
|
@ -246,13 +256,13 @@ aflibConverter::readData(
|
||||||
Nsamps = inCount - framecount;
|
Nsamps = inCount - framecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 0; c < nChans; c++)
|
for (c = 0; c < _nChans; c++)
|
||||||
{
|
{
|
||||||
ptr = outPtr[c];
|
ptr = outPtr[c];
|
||||||
ptr += Xoff; /* Start at designated sample number */
|
ptr += Xoff; /* Start at designated sample number */
|
||||||
|
|
||||||
for (i = 0; i < Nsamps; i++)
|
for (i = 0; i < Nsamps; i++)
|
||||||
*ptr++ = (HWORD) inArray[c * inCount + i + framecount];
|
*ptr++ = (short) inArray[c * inCount + i + framecount];
|
||||||
}
|
}
|
||||||
|
|
||||||
framecount += Nsamps;
|
framecount += Nsamps;
|
||||||
|
@ -263,32 +273,37 @@ aflibConverter::readData(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
aflibConverter::SrcLinear(
|
aflibConverter::SrcLinear(
|
||||||
HWORD X[],
|
short X[],
|
||||||
HWORD Y[],
|
short Y[],
|
||||||
double factor,
|
double factor,
|
||||||
UWORD *Time,
|
unsigned int *Time,
|
||||||
UHWORD& Nx,
|
unsigned short& Nx,
|
||||||
UHWORD Nout)
|
unsigned short Nout)
|
||||||
{
|
{
|
||||||
HWORD iconst;
|
short iconst;
|
||||||
HWORD *Xp, *Ystart;
|
short *Xp, *Ystart;
|
||||||
WORD v,x1,x2;
|
int v,x1,x2;
|
||||||
|
|
||||||
double dt; /* Step through input signal */
|
double dt; /* Step through input signal */
|
||||||
UWORD dtb; /* Fixed-point version of Dt */
|
unsigned int dtb; /* Fixed-point version of Dt */
|
||||||
UWORD endTime; /* When Time reaches EndTime, return to user */
|
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
||||||
UWORD start_sample, end_sample;
|
unsigned int start_sample, end_sample;
|
||||||
|
|
||||||
dt = 1.0/factor; /* Output sampling period */
|
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;
|
start_sample = (*Time)>>Np;
|
||||||
Ystart = Y;
|
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 (Y - Ystart != Nout)
|
||||||
|
// while (*Time < endTime)
|
||||||
{
|
{
|
||||||
iconst = (*Time) & Pmask;
|
iconst = (*Time) & Pmask;
|
||||||
Xp = &X[(*Time)>>Np]; /* Ptr to current input sample */
|
Xp = &X[(*Time)>>Np]; /* Ptr to current input sample */
|
||||||
|
@ -308,40 +323,46 @@ aflibConverter::SrcLinear(
|
||||||
|
|
||||||
int
|
int
|
||||||
aflibConverter::SrcUp(
|
aflibConverter::SrcUp(
|
||||||
HWORD X[],
|
short X[],
|
||||||
HWORD Y[],
|
short Y[],
|
||||||
double factor,
|
double factor,
|
||||||
UWORD *Time,
|
unsigned int *Time,
|
||||||
UHWORD& Nx,
|
unsigned short& Nx,
|
||||||
UHWORD Nout,
|
unsigned short Nout,
|
||||||
UHWORD Nwing,
|
unsigned short Nwing,
|
||||||
UHWORD LpScl,
|
unsigned short LpScl,
|
||||||
HWORD Imp[],
|
short Imp[],
|
||||||
HWORD ImpD[],
|
short ImpD[],
|
||||||
BOOL Interp)
|
bool Interp)
|
||||||
{
|
{
|
||||||
HWORD *Xp, *Ystart;
|
short *Xp, *Ystart;
|
||||||
WORD v;
|
int v;
|
||||||
|
|
||||||
double dt; /* Step through input signal */
|
double dt; /* Step through input signal */
|
||||||
UWORD dtb; /* Fixed-point version of Dt */
|
unsigned int dtb; /* Fixed-point version of Dt */
|
||||||
UWORD endTime; /* When Time reaches EndTime, return to user */
|
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
||||||
UWORD start_sample, end_sample;
|
unsigned int start_sample, end_sample;
|
||||||
|
|
||||||
dt = 1.0/factor; /* Output sampling period */
|
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;
|
start_sample = (*Time)>>Np;
|
||||||
Ystart = Y;
|
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 (Y - Ystart != Nout)
|
||||||
|
// while (*Time < endTime)
|
||||||
{
|
{
|
||||||
Xp = &X[*Time>>Np]; /* Ptr to current input sample */
|
Xp = &X[*Time>>Np]; /* Ptr to current input sample */
|
||||||
/* Perform left-wing inner product */
|
/* 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 */
|
/* Perform right-wing inner product */
|
||||||
v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1,
|
v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1,
|
||||||
(HWORD)((-*Time)&Pmask),1);
|
(short)((((*Time)^Pmask)+1)&Pmask), 1);
|
||||||
v >>= Nhg; /* Make guard bits */
|
v >>= Nhg; /* Make guard bits */
|
||||||
v *= LpScl; /* Normalize for unity filter gain */
|
v *= LpScl; /* Normalize for unity filter gain */
|
||||||
*Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */
|
*Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */
|
||||||
|
@ -356,48 +377,55 @@ aflibConverter::SrcUp(
|
||||||
|
|
||||||
int
|
int
|
||||||
aflibConverter::SrcUD(
|
aflibConverter::SrcUD(
|
||||||
HWORD X[],
|
short X[],
|
||||||
HWORD Y[],
|
short Y[],
|
||||||
double factor,
|
double factor,
|
||||||
UWORD *Time,
|
unsigned int *Time,
|
||||||
UHWORD& Nx,
|
unsigned short& Nx,
|
||||||
UHWORD Nout,
|
unsigned short Nout,
|
||||||
UHWORD Nwing,
|
unsigned short Nwing,
|
||||||
UHWORD LpScl,
|
unsigned short LpScl,
|
||||||
HWORD Imp[],
|
short Imp[],
|
||||||
HWORD ImpD[],
|
short ImpD[],
|
||||||
BOOL Interp)
|
bool Interp)
|
||||||
{
|
{
|
||||||
HWORD *Xp, *Ystart;
|
short *Xp, *Ystart;
|
||||||
WORD v;
|
int v;
|
||||||
|
|
||||||
double dh; /* Step through filter impulse response */
|
double dh; /* Step through filter impulse response */
|
||||||
double dt; /* Step through input signal */
|
double dt; /* Step through input signal */
|
||||||
UWORD endTime; /* When Time reaches EndTime, return to user */
|
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
||||||
UWORD dhb, dtb; /* Fixed-point versions of Dh,Dt */
|
unsigned int dhb, dtb; /* Fixed-point versions of Dh,Dt */
|
||||||
UWORD start_sample, end_sample;
|
unsigned int start_sample, end_sample;
|
||||||
|
|
||||||
dt = 1.0/factor; /* Output sampling period */
|
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 */
|
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;
|
start_sample = (*Time)>>Np;
|
||||||
Ystart = Y;
|
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 (Y - Ystart != Nout)
|
||||||
|
// while (*Time < endTime)
|
||||||
{
|
{
|
||||||
Xp = &X[*Time>>Np]; /* Ptr to current input sample */
|
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 */
|
-1, dhb); /* Perform left-wing inner product */
|
||||||
v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1, (HWORD)((-*Time)&Pmask),
|
v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1,
|
||||||
1, dhb); /* Perform right-wing inner product */
|
(short)((((*Time)^Pmask)+1)&Pmask), 1, dhb); /* Perform right-wing inner product */
|
||||||
v >>= Nhg; /* Make guard bits */
|
v >>= Nhg; /* Make guard bits */
|
||||||
v *= LpScl; /* Normalize for unity filter gain */
|
v *= LpScl; /* Normalize for unity filter gain */
|
||||||
*Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */
|
*Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */
|
||||||
*Time += dtb; /* Move to next sample by time increment */
|
*Time += dtb; /* Move to next sample by time increment */
|
||||||
}
|
}
|
||||||
|
|
||||||
end_sample = (*Time)>>Np;
|
end_sample = (*Time)>>Np;
|
||||||
Nx = end_sample - start_sample;
|
Nx = end_sample - start_sample;
|
||||||
return (Y - Ystart); /* Return the number of output samples */
|
return (Y - Ystart); /* Return the number of output samples */
|
||||||
|
@ -408,17 +436,17 @@ int
|
||||||
aflibConverter::resampleFast( /* number of output samples returned */
|
aflibConverter::resampleFast( /* number of output samples returned */
|
||||||
int& inCount, /* number of input samples to convert */
|
int& inCount, /* number of input samples to convert */
|
||||||
int outCount, /* number of output samples to compute */
|
int outCount, /* number of output samples to compute */
|
||||||
HWORD inArray[], /* input data */
|
short inArray[], /* input data */
|
||||||
HWORD outArray[]) /* output data */
|
short outArray[]) /* output data */
|
||||||
{
|
{
|
||||||
UWORD Time2; /* Current time/pos in input sample */
|
unsigned int Time2; /* Current time/pos in input sample */
|
||||||
#if 0
|
#if 0
|
||||||
UHWORD Ncreep;
|
unsigned short Ncreep;
|
||||||
#endif
|
#endif
|
||||||
UHWORD Xp, Xoff, Xread;
|
unsigned short Xp, Xoff, Xread;
|
||||||
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*factor);
|
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor);
|
||||||
UHWORD Nout = 0, Nx;
|
unsigned short Nout = 0, Nx, orig_Nx;
|
||||||
UHWORD maxOutput;
|
unsigned short maxOutput;
|
||||||
int total_inCount = 0;
|
int total_inCount = 0;
|
||||||
int c, i, Ycount, last;
|
int c, i, Ycount, last;
|
||||||
bool first_pass = TRUE;
|
bool first_pass = TRUE;
|
||||||
|
@ -433,13 +461,14 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
||||||
Xp = Xoff; /* Current "now"-sample pointer for input */
|
Xp = Xoff; /* Current "now"-sample pointer for input */
|
||||||
Xread = Xoff; /* Position in input array to read into */
|
Xread = Xoff; /* Position in input array to read into */
|
||||||
|
|
||||||
if (initial == TRUE)
|
if (_initial == TRUE)
|
||||||
Time = (Xoff<<Np); /* Current-time pointer for converter */
|
_Time = (Xoff<<Np); /* Current-time pointer for converter */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!last) /* If haven't read last sample yet */
|
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;
|
first_pass = FALSE;
|
||||||
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
||||||
Nx = last-Xoff; /* ...calc last sample affected by filter */
|
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)) )
|
if ((outCount-Ycount) > (OBUFFSIZE - (2*Xoff*_factor)) )
|
||||||
maxOutput = OBUFFSIZE - (UHWORD)(2*Xoff*factor);
|
maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor);
|
||||||
else
|
else
|
||||||
maxOutput = outCount-Ycount;
|
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 */
|
/* 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 */
|
Xp += Nx; /* Advance by number of samples processed */
|
||||||
#if 0
|
#if 0
|
||||||
Ncreep = (Time>>Np) - Xoff; /* Calc time accumulation in Time */
|
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 */
|
Xp += Ncreep; /* and add it to read pointer */
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
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... */
|
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 */
|
if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */
|
||||||
return err_ret("Output array overflow");
|
return err_ret("Output array overflow");
|
||||||
|
|
||||||
for (c = 0; c < nChans; c++)
|
for (c = 0; c < _nChans; c++)
|
||||||
for (i = 0; i < Nout; i++)
|
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;
|
total_inCount += Nx;
|
||||||
|
|
||||||
|
@ -511,30 +542,30 @@ int
|
||||||
aflibConverter::resampleWithFilter( /* number of output samples returned */
|
aflibConverter::resampleWithFilter( /* number of output samples returned */
|
||||||
int& inCount, /* number of input samples to convert */
|
int& inCount, /* number of input samples to convert */
|
||||||
int outCount, /* number of output samples to compute */
|
int outCount, /* number of output samples to compute */
|
||||||
HWORD inArray[], /* input data */
|
short inArray[], /* input data */
|
||||||
HWORD outArray[], /* output data */
|
short outArray[], /* output data */
|
||||||
HWORD Imp[], HWORD ImpD[],
|
short Imp[], short ImpD[],
|
||||||
UHWORD LpScl, UHWORD Nmult, UHWORD Nwing)
|
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
|
#if 0
|
||||||
UHWORD Ncreep;
|
unsigned short Ncreep;
|
||||||
#endif
|
#endif
|
||||||
UHWORD Xp, Xoff, Xread;
|
unsigned short Xp, Xoff, Xread;
|
||||||
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*factor);
|
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor);
|
||||||
UHWORD Nout = 0, Nx;
|
unsigned short Nout = 0, Nx, orig_Nx;
|
||||||
UHWORD maxOutput;
|
unsigned short maxOutput;
|
||||||
int total_inCount = 0;
|
int total_inCount = 0;
|
||||||
int c, i, Ycount, last;
|
int c, i, Ycount, last;
|
||||||
bool first_pass = TRUE;
|
bool first_pass = TRUE;
|
||||||
|
|
||||||
|
|
||||||
/* Account for increased filter gain when using factors less than 1 */
|
/* Account for increased filter gain when using factors less than 1 */
|
||||||
if (factor < 1)
|
if (_factor < 1)
|
||||||
LpScl = (UHWORD)(LpScl*factor + 0.5);
|
LpScl = (unsigned short)(LpScl*_factor + 0.5);
|
||||||
|
|
||||||
/* Calc reach of LP filter wing & give some creeping room */
|
/* 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 */
|
if (IBUFFSIZE < 2*Xoff) /* Check input buffer size */
|
||||||
return err_ret("IBUFFSIZE (or factor) is too small");
|
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 */
|
Xp = Xoff; /* Current "now"-sample pointer for input */
|
||||||
Xread = Xoff; /* Position in input array to read into */
|
Xread = Xoff; /* Position in input array to read into */
|
||||||
|
|
||||||
if (initial == TRUE)
|
if (_initial == TRUE)
|
||||||
Time = (Xoff<<Np); /* Current-time pointer for converter */
|
_Time = (Xoff<<Np); /* Current-time pointer for converter */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!last) /* If haven't read last sample yet */
|
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;
|
first_pass = FALSE;
|
||||||
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
||||||
Nx = last-Xoff; /* ...calc last sample affected by filter */
|
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)) )
|
if ( (outCount-Ycount) > (OBUFFSIZE - (2*Xoff*_factor)) )
|
||||||
maxOutput = OBUFFSIZE - (UHWORD)(2*Xoff*factor);
|
maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor);
|
||||||
else
|
else
|
||||||
maxOutput = outCount-Ycount;
|
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 */
|
/* Resample stuff in input buffer */
|
||||||
if (factor >= 1) { /* SrcUp() is faster if we can use it */
|
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);
|
Nout=SrcUp(_X[c],_Y[c],_factor,
|
||||||
|
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
||||||
}
|
}
|
||||||
else {
|
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 */
|
Xp += Nx; /* Advance by number of samples processed */
|
||||||
#if 0
|
#if 0
|
||||||
Ncreep = (Time>>Np) - Xoff; /* Calc time accumulation in Time */
|
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 */
|
if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */
|
||||||
return err_ret("Output array overflow");
|
return err_ret("Output array overflow");
|
||||||
|
|
||||||
for (c = 0; c < nChans; c++)
|
for (c = 0; c < _nChans; c++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < Nout; i++)
|
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;
|
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 */
|
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 */
|
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 */
|
return(Ycount); /* Return # of samples in output file */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
WORD
|
aflibConverter::FilterUp(
|
||||||
aflibConverter::FilterUp(HWORD Imp[], HWORD ImpD[],
|
short Imp[],
|
||||||
UHWORD Nwing, BOOL Interp,
|
short ImpD[],
|
||||||
HWORD *Xp, HWORD Ph, HWORD Inc)
|
unsigned short Nwing,
|
||||||
|
bool Interp,
|
||||||
|
short *Xp,
|
||||||
|
short Ph,
|
||||||
|
short Inc)
|
||||||
{
|
{
|
||||||
HWORD *Hp, *Hdp = NULL, *End;
|
short *Hp, *Hdp = NULL, *End;
|
||||||
HWORD a = 0;
|
short a = 0;
|
||||||
WORD v, t;
|
int v, t;
|
||||||
|
|
||||||
v=0;
|
v=0;
|
||||||
Hp = &Imp[Ph>>Na];
|
Hp = &Imp[Ph>>Na];
|
||||||
End = &Imp[Nwing];
|
End = &Imp[Nwing];
|
||||||
if (Interp) {
|
|
||||||
|
if (Interp)
|
||||||
|
{
|
||||||
Hdp = &ImpD[Ph>>Na];
|
Hdp = &ImpD[Ph>>Na];
|
||||||
a = Ph & Amask;
|
a = Ph & Amask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Inc == 1) /* If doing right wing... */
|
if (Inc == 1) /* If doing right wing... */
|
||||||
{ /* ...drop extra coeff, so when Ph is */
|
{ /* ...drop extra coeff, so when Ph is */
|
||||||
End--; /* 0.5, we don't do too many mult's */
|
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[] */
|
Hdp += Npc; /* skip ahead in Imp[] and ImpD[] */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Interp)
|
if (Interp)
|
||||||
while (Hp < End) {
|
{
|
||||||
|
while (Hp < End)
|
||||||
|
{
|
||||||
t = *Hp; /* Get filter coeff */
|
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 */
|
Hdp += Npc; /* Filter coeff differences step */
|
||||||
t *= *Xp; /* Mult coeff by input sample */
|
t *= *Xp; /* Mult coeff by input sample */
|
||||||
if (t & (1<<(Nhxn-1))) /* Round, if needed */
|
if (t & (1<<(Nhxn-1))) /* Round, if needed */
|
||||||
|
@ -670,8 +715,11 @@ aflibConverter::FilterUp(HWORD Imp[], HWORD ImpD[],
|
||||||
Hp += Npc; /* Filter coeff step */
|
Hp += Npc; /* Filter coeff step */
|
||||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
while (Hp < End) {
|
{
|
||||||
|
while (Hp < End)
|
||||||
|
{
|
||||||
t = *Hp; /* Get filter coeff */
|
t = *Hp; /* Get filter coeff */
|
||||||
t *= *Xp; /* Mult coeff by input sample */
|
t *= *Xp; /* Mult coeff by input sample */
|
||||||
if (t & (1<<(Nhxn-1))) /* Round, if needed */
|
if (t & (1<<(Nhxn-1))) /* Round, if needed */
|
||||||
|
@ -681,22 +729,29 @@ aflibConverter::FilterUp(HWORD Imp[], HWORD ImpD[],
|
||||||
Hp += Npc; /* Filter coeff step */
|
Hp += Npc; /* Filter coeff step */
|
||||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return(v);
|
return(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WORD
|
int
|
||||||
aflibConverter::FilterUD( HWORD Imp[], HWORD ImpD[],
|
aflibConverter::FilterUD(
|
||||||
UHWORD Nwing, BOOL Interp,
|
short Imp[],
|
||||||
HWORD *Xp, HWORD Ph, HWORD Inc, UHWORD dhb)
|
short ImpD[],
|
||||||
|
unsigned short Nwing,
|
||||||
|
bool Interp,
|
||||||
|
short *Xp,
|
||||||
|
short Ph,
|
||||||
|
short Inc,
|
||||||
|
unsigned short dhb)
|
||||||
{
|
{
|
||||||
HWORD a;
|
short a;
|
||||||
HWORD *Hp, *Hdp, *End;
|
short *Hp, *Hdp, *End;
|
||||||
WORD v, t;
|
int v, t;
|
||||||
UWORD Ho;
|
unsigned int Ho;
|
||||||
|
|
||||||
v=0;
|
v=0;
|
||||||
Ho = (Ph*(UWORD)dhb)>>Np;
|
Ho = (Ph*(unsigned int)dhb)>>Np;
|
||||||
End = &Imp[Nwing];
|
End = &Imp[Nwing];
|
||||||
if (Inc == 1) /* If doing right wing... */
|
if (Inc == 1) /* If doing right wing... */
|
||||||
{ /* ...drop extra coeff, so when Ph is */
|
{ /* ...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 */
|
Ho += dhb; /* ...then we've already skipped the */
|
||||||
} /* first sample, so we must also */
|
} /* first sample, so we must also */
|
||||||
/* skip ahead in Imp[] and ImpD[] */
|
/* skip ahead in Imp[] and ImpD[] */
|
||||||
|
|
||||||
if (Interp)
|
if (Interp)
|
||||||
while ((Hp = &Imp[Ho>>Na]) < End) {
|
{
|
||||||
|
while ((Hp = &Imp[Ho>>Na]) < End)
|
||||||
|
{
|
||||||
t = *Hp; /* Get IR sample */
|
t = *Hp; /* Get IR sample */
|
||||||
Hdp = &ImpD[Ho>>Na]; /* get interp (lower Na) bits from diff table*/
|
Hdp = &ImpD[Ho>>Na]; /* get interp (lower Na) bits from diff table*/
|
||||||
a = Ho & Amask; /* a is logically between 0 and 1 */
|
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 */
|
t *= *Xp; /* Mult coeff by input sample */
|
||||||
if (t & 1<<(Nhxn-1)) /* Round, if needed */
|
if (t & 1<<(Nhxn-1)) /* Round, if needed */
|
||||||
t += 1<<(Nhxn-1);
|
t += 1<<(Nhxn-1);
|
||||||
|
@ -719,8 +777,11 @@ aflibConverter::FilterUD( HWORD Imp[], HWORD ImpD[],
|
||||||
Ho += dhb; /* IR step */
|
Ho += dhb; /* IR step */
|
||||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
while ((Hp = &Imp[Ho>>Na]) < End) {
|
{
|
||||||
|
while ((Hp = &Imp[Ho>>Na]) < End)
|
||||||
|
{
|
||||||
t = *Hp; /* Get IR sample */
|
t = *Hp; /* Get IR sample */
|
||||||
t *= *Xp; /* Mult coeff by input sample */
|
t *= *Xp; /* Mult coeff by input sample */
|
||||||
if (t & 1<<(Nhxn-1)) /* Round, if needed */
|
if (t & 1<<(Nhxn-1)) /* Round, if needed */
|
||||||
|
@ -730,6 +791,7 @@ aflibConverter::FilterUD( HWORD Imp[], HWORD ImpD[],
|
||||||
Ho += dhb; /* IR step */
|
Ho += dhb; /* IR step */
|
||||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return(v);
|
return(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* Julius O. Smith jos@ccrma.stanford.edu
|
* 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
|
into a C++ class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -26,6 +26,10 @@
|
||||||
#ifndef _AFLIBCONVERTER_H_
|
#ifndef _AFLIBCONVERTER_H_
|
||||||
#define _AFLIBCONVERTER_H_
|
#define _AFLIBCONVERTER_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(x,y) ((x)>(y) ?(x):(y))
|
#define MAX(x,y) ((x)>(y) ?(x):(y))
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,11 +40,6 @@
|
||||||
#define MAX_HWORD (32767)
|
#define MAX_HWORD (32767)
|
||||||
#define MIN_HWORD (-32768)
|
#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 */
|
#define IBUFFSIZE 4096 /* Input buffer size */
|
||||||
|
|
||||||
/*! \class aflibConverter
|
/*! \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.
|
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
|
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
|
initialize should be called to initialize everything. This initialize function will set
|
||||||
number of channels. Once everything is specified then resample should be called as many
|
the conversion factor as well as a multiplecation factor for volume. The volume only
|
||||||
times as is necessary to process all the data. The value inCount will be returned
|
applies to the small and large filter. Since this filter uses a history of the audio data
|
||||||
indicating how many inArray samples were actually used to produce the output. This
|
it is possible for it to vary in amplitude. This allows users to scale the data. This
|
||||||
value can be used to indicate where the next block of inArray data should start. The
|
class will work on any number of channels. Once everything is specified then resample
|
||||||
resample function is driven by the outCount value specified. The inArray should
|
should be called as many times as is necessary to process all the data. The value
|
||||||
contain at least:
|
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.
|
outCount / factor + extra_samples.
|
||||||
extra_samples depends on the type of filtering done. As a rule of thumb 50 should be
|
extra_samples depends on the type of filtering done. As a rule of thumb 50 should be
|
||||||
adequate for any type of filter.
|
adequate for any type of filter.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
class aflibData;
|
||||||
|
|
||||||
class aflibConverter {
|
class aflibConverter {
|
||||||
|
|
||||||
|
@ -86,14 +89,15 @@ public:
|
||||||
void
|
void
|
||||||
initialize(
|
initialize(
|
||||||
double factor, /* factor = Sndout/Sndin */
|
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
|
int
|
||||||
resample( /* number of output samples returned */
|
resample( /* number of output samples returned */
|
||||||
int& inCount, /* number of input samples to convert */
|
int& inCount, /* number of input samples to convert */
|
||||||
int outCount, /* number of output samples to compute */
|
int outCount, /* number of output samples to compute */
|
||||||
HWORD inArray[], /* input array data (length inCount * nChans) */
|
short inArray[], /* input array data (length inCount * nChans) */
|
||||||
HWORD outArray[]);/* output array data (length outCount * nChans) */
|
short outArray[]);/* output array data (length outCount * nChans) */
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -114,130 +118,117 @@ private:
|
||||||
int
|
int
|
||||||
readData(
|
readData(
|
||||||
int inCount, /* _total_ number of frames in input file */
|
int inCount, /* _total_ number of frames in input file */
|
||||||
HWORD inArray[], /* input data */
|
short inArray[], /* input data */
|
||||||
HWORD *outPtr[], /* array receiving chan samps */
|
short *outPtr[], /* array receiving chan samps */
|
||||||
int dataArraySize, /* size of these arrays */
|
int dataArraySize, /* size of these arrays */
|
||||||
int Xoff, /* read into input array starting at this index */
|
int Xoff, /* read into input array starting at this index */
|
||||||
bool init_count);
|
bool init_count);
|
||||||
|
|
||||||
|
|
||||||
inline HWORD
|
inline short
|
||||||
WordToHword(WORD v, int scl)
|
WordToHword(int v, int scl)
|
||||||
{
|
{
|
||||||
HWORD out;
|
short out;
|
||||||
WORD llsb = (1<<(scl-1));
|
int llsb = (1<<(scl-1));
|
||||||
v += llsb; /* round */
|
v += llsb; /* round */
|
||||||
v >>= scl;
|
v >>= scl;
|
||||||
if (v>MAX_HWORD) {
|
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;
|
v = MAX_HWORD;
|
||||||
} else if (v < MIN_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;
|
v = MIN_HWORD;
|
||||||
}
|
}
|
||||||
out = (HWORD) v;
|
out = (short) v;
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
SrcLinear(
|
SrcLinear(
|
||||||
HWORD X[],
|
short X[],
|
||||||
HWORD Y[],
|
short Y[],
|
||||||
double factor,
|
double factor,
|
||||||
UWORD *Time,
|
unsigned int *Time,
|
||||||
UHWORD& Nx,
|
unsigned short& Nx,
|
||||||
UHWORD Nout);
|
unsigned short Nout);
|
||||||
|
|
||||||
int
|
int
|
||||||
SrcUp(
|
SrcUp(
|
||||||
HWORD X[],
|
short X[],
|
||||||
HWORD Y[],
|
short Y[],
|
||||||
double factor,
|
double factor,
|
||||||
UWORD *Time,
|
unsigned int *Time,
|
||||||
UHWORD& Nx,
|
unsigned short& Nx,
|
||||||
UHWORD Nout,
|
unsigned short Nout,
|
||||||
UHWORD Nwing,
|
unsigned short Nwing,
|
||||||
UHWORD LpScl,
|
unsigned short LpScl,
|
||||||
HWORD Imp[],
|
short Imp[],
|
||||||
HWORD ImpD[],
|
short ImpD[],
|
||||||
BOOL Interp);
|
bool Interp);
|
||||||
|
|
||||||
int
|
int
|
||||||
SrcUD(
|
SrcUD(
|
||||||
HWORD X[],
|
short X[],
|
||||||
HWORD Y[],
|
short Y[],
|
||||||
double factor,
|
double factor,
|
||||||
UWORD *Time,
|
unsigned int *Time,
|
||||||
UHWORD& Nx,
|
unsigned short& Nx,
|
||||||
UHWORD Nout,
|
unsigned short Nout,
|
||||||
UHWORD Nwing,
|
unsigned short Nwing,
|
||||||
UHWORD LpScl,
|
unsigned short LpScl,
|
||||||
HWORD Imp[],
|
short Imp[],
|
||||||
HWORD ImpD[],
|
short ImpD[],
|
||||||
BOOL Interp);
|
bool Interp);
|
||||||
|
|
||||||
WORD
|
int
|
||||||
FilterUp(
|
FilterUp(
|
||||||
HWORD Imp[],
|
short Imp[],
|
||||||
HWORD ImpD[],
|
short ImpD[],
|
||||||
UHWORD Nwing,
|
unsigned short Nwing,
|
||||||
BOOL Interp,
|
bool Interp,
|
||||||
HWORD *Xp,
|
short *Xp,
|
||||||
HWORD Ph,
|
short Ph,
|
||||||
HWORD Inc);
|
short Inc);
|
||||||
|
|
||||||
WORD
|
int
|
||||||
FilterUD(
|
FilterUD(
|
||||||
HWORD Imp[],
|
short Imp[],
|
||||||
HWORD ImpD[],
|
short ImpD[],
|
||||||
UHWORD Nwing,
|
unsigned short Nwing,
|
||||||
BOOL Interp,
|
bool Interp,
|
||||||
HWORD *Xp,
|
short *Xp,
|
||||||
HWORD Ph,
|
short Ph,
|
||||||
HWORD Inc,
|
short Inc,
|
||||||
UHWORD dhb);
|
unsigned short dhb);
|
||||||
|
|
||||||
int
|
int
|
||||||
resampleFast( /* number of output samples returned */
|
resampleFast( /* number of output samples returned */
|
||||||
int& inCount, /* number of input samples to convert */
|
int& inCount, /* number of input samples to convert */
|
||||||
int outCount, /* number of output samples to compute */
|
int outCount, /* number of output samples to compute */
|
||||||
HWORD inArray[], /* input array data (length inCount * nChans) */
|
short inArray[], /* input array data (length inCount * nChans) */
|
||||||
HWORD outArray[]);/* output array data (length outCount * nChans) */
|
short outArray[]);/* output array data (length outCount * nChans) */
|
||||||
|
|
||||||
int
|
int
|
||||||
resampleWithFilter( /* number of output samples returned */
|
resampleWithFilter( /* number of output samples returned */
|
||||||
int& inCount, /* number of input samples to convert */
|
int& inCount, /* number of input samples to convert */
|
||||||
int outCount, /* number of output samples to compute */
|
int outCount, /* number of output samples to compute */
|
||||||
HWORD inArray[], /* input array data (length inCount * nChans) */
|
short inArray[], /* input array data (length inCount * nChans) */
|
||||||
HWORD outArray[], /* output array data (length outCount * nChans) */
|
short outArray[], /* output array data (length outCount * nChans) */
|
||||||
HWORD Imp[], HWORD ImpD[],
|
short Imp[], short ImpD[],
|
||||||
UHWORD LpScl, UHWORD Nmult, UHWORD Nwing);
|
unsigned short LpScl, unsigned short Nmult, unsigned short Nwing);
|
||||||
|
|
||||||
|
|
||||||
static HWORD SMALL_FILTER_IMP[];
|
static short SMALL_FILTER_IMP[];
|
||||||
static HWORD LARGE_FILTER_IMP[];
|
static short LARGE_FILTER_IMP[];
|
||||||
|
|
||||||
bool interpFilt;
|
bool interpFilt;
|
||||||
bool largeFilter;
|
bool largeFilter;
|
||||||
bool linearInterp;
|
bool linearInterp;
|
||||||
HWORD ** X;
|
short ** _X;
|
||||||
HWORD ** Y;
|
short ** _Y;
|
||||||
UWORD Time;
|
unsigned int _Time;
|
||||||
double factor;
|
double _factor;
|
||||||
int nChans;
|
int _nChans;
|
||||||
bool initial;
|
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_SCALE 14746 /* Unity-gain scale factor */
|
||||||
#define LARGE_FILTER_NWING 8192 /* Filter table length */
|
#define LARGE_FILTER_NWING 8192 /* Filter table length */
|
||||||
|
|
||||||
HWORD aflibConverter::LARGE_FILTER_IMP[] /* Impulse response */ = {
|
short aflibConverter::LARGE_FILTER_IMP[] /* Impulse response */ = {
|
||||||
32767,
|
32767,
|
||||||
32766,
|
32766,
|
||||||
32764,
|
32764,
|
||||||
|
@ -8232,7 +8237,7 @@ HWORD aflibConverter::LARGE_FILTER_IMP[] /* Impulse response */ = {
|
||||||
0,
|
0,
|
||||||
0};
|
0};
|
||||||
|
|
||||||
static HWORD LARGE_FILTER_IMPD[] /* Impulse response differences */ = {
|
static short LARGE_FILTER_IMPD[] /* Impulse response differences */ = {
|
||||||
-1,
|
-1,
|
||||||
-2,
|
-2,
|
||||||
-3,
|
-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_SCALE 13128 /* Unity-gain scale factor */
|
||||||
#define SMALL_FILTER_NWING 1536 /* Filter table length */
|
#define SMALL_FILTER_NWING 1536 /* Filter table length */
|
||||||
|
|
||||||
HWORD aflibConverter::SMALL_FILTER_IMP[] /* Impulse response */ = {
|
short aflibConverter::SMALL_FILTER_IMP[] /* Impulse response */ = {
|
||||||
32767,
|
32767,
|
||||||
32766,
|
32766,
|
||||||
32764,
|
32764,
|
||||||
|
@ -1562,7 +1567,7 @@ HWORD aflibConverter::SMALL_FILTER_IMP[] /* Impulse response */ = {
|
||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
static HWORD SMALL_FILTER_IMPD[] = {
|
static short SMALL_FILTER_IMPD[] = {
|
||||||
-1,
|
-1,
|
||||||
-2,
|
-2,
|
||||||
-4,
|
-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