view filter_templates.h @ 356:ea5c61aeb891

Updated.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 07 Jun 2002 13:31:39 +0000
parents 7b9a0f3f030e
children c7f73428deaf
line wrap: on
line source

/*
   Extended Audio Converter for SDL (Simple DirectMedia Layer)
   Copyright (C) 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
   ranostaj@stud.uni-frankfurt.de

(This code blatantly abducted for SDL_sound. Thanks, Frank! --ryan.)

*/

#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 & Sound_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  2*length + 4*border;
}

//---------------------------------------------------------------------------
short Suffix(filterHalfBand)( short* inp )
{
   static const int fsize = _fsize;
   int out = 32770*inp[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 & Sound_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+2*fsize)] = buffer[CH(i)];
       }
       border = fsize;
       finp = inbuffer + CH( (3*fsize)/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(2*i) );
   }
   for(; i < length-fsize; i++)
   {
       buffer[CH(i+border)] = Suffix(filterHalfBand)( buffer+CH(2*i) );
   }
   for(; i < length+border; i++)
   {
       buffer[CH(i+border)] = Suffix(filterHalfBand)( linp+CH(2*i) );
   }
   return length + 2*border;
}

//---------------------------------------------------------------------------
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 & Sound_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+2*fsize)] = buffer[CH(i)];
       }
       border = fsize;
       finp = inbuffer + CH( (3*fsize)/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 + 2*border;
}
//---------------------------------------------------------------------------
#undef CH
#endif /* Suffix */