/*
Extended Audio Converter for SDL (Simple DirectMedia Layer)
Copyright © 2002 Frank Ranostaj
Institute of Applied Physik
Johann Wolfgang Goethe-Universit?t
Frankfurt am Main, Germany
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; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Frank Ranostaj
@Frank_Ranostaj
*/
#ifndef Suffix
#error include filter_template.h with defined Suffix macro!
#else
#define CH(x) (Suffix((x)*))
//---------------------------------------------------------------------------
int Suffix(_doubleRate)( short *buffer, int mode, int length )
{
const fsize = _fsize/2;
int i,di,border;
short inbuffer[_fsize];
if( mode & SDL_AI_Loop )
{
for( i = 0; i < fsize; i++ )
{
inbuffer[CH(i+fsize)] = buffer[CH(length+i)] = buffer[CH(i)];
inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
}
border = 0;
}
else
{
for( i = 0; i < fsize; i++ )
{
inbuffer[CH(i)] = buffer[CH(length+i)] = 0;
inbuffer[CH(i+fsize)] = buffer[CH(i)];
}
border = fsize/2;
}
for(i = length + border - 1; i >= -border; i–)
{
const short* const inp = i < fsize/2 ?
&inbuffer[CH(i+fsize)] : &buffer[CH(i)];
short* const outp = &buffer[CH(2*(i+border))];
int out = 0;
for( di = 1; di < 1+fsize; di+=2 )
out+= filter[di]*( inp[CH(di)/2] + inp[CH(1-di)/2] );
outp[CH(1)] = ( 32770*inp[CH(1)] + out) >> 16;
outp[CH(0)] = ( 32770*inp[CH(0)] + out) >> 16;
}
return 2length + 4border;
}
//---------------------------------------------------------------------------
short Suffix(filterHalfBand)( short* inp )
{
static const int fsize = _fsize;
int out = 32770inp[0];
int di;
for( di = 1; di < fsize/2; di+=2 )
out+= filter[di]( inp[CH(di)] + inp[CH(-di)] );
return out >> 16;
}
int Suffix(_halfRate)( short *buffer, int mode, int length )
{
static const int fsize = _fsize;
int i,border;
short inbuffer[3*_fsize];
short *finp, *linp;
if( mode & SDL_AI_Loop )
{
if( length & 1 )
{
// do something meaningful
}
for( i = 0; i < fsize; i++ )
{
inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
inbuffer[CH(i+fsize)] = buffer[CH(i)];
}
border = 0;
finp = inbuffer + CH( fsize );
linp = inbuffer + CH( fsize-length );
}
else
{
for( i = 0; i < fsize; i++ )
{
inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
inbuffer[CH(i+fsize)] = 0;
inbuffer[CH(i+2fsize)] = buffer[CH(i)];
}
border = fsize;
finp = inbuffer + CH( (3fsize)/2 + 2*border );
linp = inbuffer + CH( fsize/2 - length );
}
length = ( length + 1 ) / 2;
for(i = -border; i < fsize; i++)
{
buffer[CH(i+border)] = Suffix(filterHalfBand)( finp+CH(2i) );
}
for(; i < length-fsize; i++)
{
buffer[CH(i+border)] = Suffix(filterHalfBand)( buffer+CH(2i) );
}
for(; i < length+border; i++)
{
buffer[CH(i+border)] = Suffix(filterHalfBand)( linp+CH(2i) );
}
return length + 2border;
}
//---------------------------------------------------------------------------
short Suffix(filterVarBand)( VarFilter* filt, short** inpp, char* cpos )
{
static const int fsize = _fsize;
int di;
int out = 0;
short *inp = *inpp;
int pos = *cpos;
short *filter = filt->c[pos];
for( di = 0; di < fsize; di++ )
out+= filter[di] * (int)inp[CH(di)];
*inpp += CH(filt->incr[pos]);
*cpos = ( pos + 1 ) % filt->pos_mod;
return out >> 16;
}
int Suffix(_varRate)( short* buffer, int mode, VarFilter* filter, int
length )
{
static const int fsize = _fsize;
int i,border;
short inbuffer[CH(3*_fsize)];
short *finp, *linp, bufp;
char pos = 0;
VarFilter filterp = filter;
if( mode & SDL_AI_Loop )
{
for( i = 0; i < fsize; i++ )
{
inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
inbuffer[CH(i+fsize)] = buffer[CH(i)];
}
border = 0;
finp = inbuffer+CH(fsize);
linp = inbuffer+CH(fsize-length);
}
else
{
for( i = 0; i < fsize; i++ )
{
inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
inbuffer[CH(i+fsize)] = 0;
inbuffer[CH(i+2fsize)] = buffer[CH(i)];
}
border = fsize;
finp = inbuffer + CH( (3fsize)/2 + 2*border );
linp = inbuffer + CH( fsize/2 - length );
}
length = ( length + 1 ) / 2;
bufp = buffer;
for(i = -border; i < fsize; i++)
{
buffer[CH(i+border)] = Suffix(filterVarBand)( filterp, &finp, &pos );
}
for(; i < length-fsize; i++)
{
buffer[CH(i+border)] = Suffix(filterVarBand)( filterp, &bufp, &pos );
}
for(; i < length+border; i++)
{
buffer[CH(i+border)] = Suffix(filterVarBand)( filterp, &linp, &pos );
}
return length + 2border;
}
//---------------------------------------------------------------------------
#undef CH
#endif / Suffix */