changeset 420:5b8a07b5162e

Latest altcvt from Frank.
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 26 Sep 2002 04:34:35 +0000
parents 25a8f66112fd
children a65440b3a057
files alt_audio_convert.c alt_audio_convert.h
diffstat 2 files changed, 178 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/alt_audio_convert.c	Thu Sep 26 04:34:25 2002 +0000
+++ b/alt_audio_convert.c	Thu Sep 26 04:34:35 2002 +0000
@@ -125,26 +125,34 @@
 
 
 /*-------------------------------------------------------------------------*/
-static int ConvertAudio( Sound_AudioCVT *Data,
-                         Uint8* buffer, int length, int mode )
+int Sound_estimateBufferSize( Sound_AudioCVT *Data, int size )
+{
+    size *= Data->len_mult;
+    size += Data->len_add;
+    return ( size + 3 ) & -4; /* force Size in multipels of 4 Byte */
+}
+
+/*-------------------------------------------------------------------------*/
+int Sound_AltConvertAudio( Sound_AudioCVT *Data,
+    Uint8* buffer, int length, int mode )
 {
     AdapterC Temp;
     int i;
 
     /* Make sure there's a converter */
     if( Data == NULL ) {
-        SDL_SetError("altcvt: No converter given");
+        SDL_SetError("No converter given");
         return(-1);
     }
 
     /* Make sure there's data to convert */
     if( buffer == NULL ) {
-        SDL_SetError("altcvt: No buffer allocated for conversion");
+        SDL_SetError("No buffer allocated for conversion");
         return(-1);
     }
 
     if( length < 0 ) {
-        SDL_SetError("altcvt: Length < 0");
+        SDL_SetError("Lenght < 0");
         return(-1);
     }
 
@@ -163,7 +171,7 @@
 {
     int length;
     /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */
-    length = ConvertAudio( Data, Data->buf, Data->len, 0 );
+    length = Sound_AltConvertAudio( Data, Data->buf, Data->len, 0 );
     Data->len_cvt = length;
     return length;
 }
@@ -338,18 +346,19 @@
 static int convertMonoToStereo16Bit( AdapterC Data, int length )
 {
     int i;
+    length >>=1;
     Uint16* buffer = (Uint16*)Data.buffer - 1;
-    Uint16* dst = (Uint16*)Data.buffer + length - 2;
-    for( i = length>>1 + 1; --i; dst-=2 )
+    Uint16* dst = (Uint16*)Data.buffer + 2*length - 2;
+    for( i = length + 1; --i; dst-=2 )
          dst[0] = dst[1] = buffer[i];
-    return 2*length;
+    return 4*length;
 }
 
 static int convertMonoToStereo8Bit( AdapterC Data, int length )
 {
     int i;
     Uint8* buffer = Data.buffer - 1;
-    Uint8* dst = Data.buffer + length - 2;
+    Uint8* dst = Data.buffer + 2*length - 2;
     for( i = length + 1; --i; dst-=2 )
          dst[0] = dst[1] = buffer[i];
     return 2*length;
@@ -368,9 +377,11 @@
 /*-------------------------------------------------------------------------*/
 const Fraction Half = {1, 2};
 const Fraction Double = {2, 1};
+const Fraction One = {1, 1};
+
 
 static void initStraigthBuffer( RateConverterBuffer *rcb,
-                                int length, Fraction r, int dir )
+                                int length, Fraction r )
 {
     int i, size, minsize;
     size = 8 * _fsize;
@@ -393,13 +404,13 @@
     rcb->flength = rcb->llength = size;
     rcb->clength = length - size;
 
-    if( dir )
+    if( r.numerator < r.denominator )
     {
-        rcb->finp = rcb->inbuffer + 5 * size/2;
+        rcb->finp = rcb->inbuffer + 5*size/2;
         rcb->cinp = rcb->buffer + length - size/2;
         rcb->linp = rcb->inbuffer + 3*size/2;
-        rcb->buffer += r.denominator * ( length + size )
-                       / r.numerator;
+        rcb->buffer += ( 1 + r.denominator * ( length + size )
+                       / r.numerator ) & -2;
     }
     else
     {
@@ -410,7 +421,7 @@
 }
 
 static void initLoopBuffer( RateConverterBuffer *rcb,
-                            int length, Fraction r, int dir )
+                            int length, Fraction r )
 {
     /* !!!FIXME: modulo length, take scale into account,
                  check against the Straight part -frank */
@@ -430,16 +441,18 @@
 static void initRateConverterBuffer( RateConverterBuffer *rcb,
     AdapterC* Data, int length, Fraction ratio )
 {
-    int dir;
-    dir = ratio.numerator < ratio.denominator ? 1 : 0;
     length >>= 1;
     rcb->buffer = (Sint16*)( Data->buffer );
     rcb->filter = Data->filter;
 
     if( Data->mode & SDL_SOUND_Loop )
-        initLoopBuffer( rcb, length, ratio, dir );
+        initLoopBuffer( rcb, length, ratio );
     else
-        initStraigthBuffer( rcb, length, ratio, dir );
+        initStraigthBuffer( rcb, length, ratio );
+
+    fprintf( stderr, " finp: %8x length: %8x\n", rcb->finp, rcb->flength );
+    fprintf( stderr, " cinp: %8x length: %8x\n", rcb->cinp, rcb->clength );
+    fprintf( stderr, " linp: %8x length: %8x\n", rcb->linp, rcb->llength );
 }
 
 static void nextRateConverterBuffer( RateConverterBuffer *rcb )
@@ -453,104 +466,116 @@
 typedef Sint16* (*RateConverter)( Sint16*, Sint16*, int,
                                   VarFilter*, RateAux* );
 
-static int doRateConversion( RateConverterBuffer* rcb, RateConverter ffp )
+static Sint16* doRateConversion( RateConverterBuffer* rcb, RateConverter rc )
 {
     RateAux aux = {0,0};
     Sint16 *outp = rcb->buffer;
     VarFilter* filter = rcb->filter;
 
-    outp = (*ffp)( outp, rcb->finp, rcb->flength, filter, &aux );
-    outp = (*ffp)( outp, rcb->cinp, rcb->clength, filter, &aux );
-    outp = (*ffp)( outp, rcb->linp, rcb->llength, filter, &aux );
-    return 2 * abs( rcb->buffer - outp );
+    outp = (*rc)( outp, rcb->finp, rcb->flength, filter, &aux );
+    fprintf( stderr, " outp: %8x aux.carry: %8x\n", outp, aux.carry );
+    outp = (*rc)( outp, rcb->cinp, rcb->clength, filter, &aux );
+    fprintf( stderr, " outp: %8x aux.carry: %8x\n", outp, aux.carry );
+    outp = (*rc)( outp, rcb->linp, rcb->llength, filter, &aux );
+    fprintf( stderr, " outp: %8x aux.carry: %8x\n", outp, aux.carry );
+    return outp;
 }
 
 
 /*-------------------------------------------------------------------------*/
+static void clearSint16Buffer( Sint8* buffer, Sint16*r )
+{
+    while( r >= (Sint16*)buffer ) *r-- = 0;
+}
+
+/*-------------------------------------------------------------------------*/
 static int doubleRateMono( AdapterC Data, int length )
 {
+    Sint16* r;
     RateConverterBuffer rcb;
-    initRateConverterBuffer( &rcb, &Data, length, Double );
-    return doRateConversion( &rcb, doubleRate1 );
+    initRateConverterBuffer( &rcb, &Data, length, Half );
+    r = 1 + doRateConversion( &rcb, doubleRate1 );
+    clearSint16Buffer( Data.buffer, r );
+    return 2 * ( rcb.buffer - (Sint16*)Data.buffer + 2 );
 }
 
 static int doubleRateStereo( AdapterC Data, int length )
 {
+    Sint16* r;
+    fprintf( stderr, "\n Buffer: %8x length: %8x\n", Data.buffer, length );
     RateConverterBuffer rcb;
-    initRateConverterBuffer( &rcb, &Data, length, Double );
+    initRateConverterBuffer( &rcb, &Data, length, Half );
     doRateConversion( &rcb, doubleRate2 );
     nextRateConverterBuffer( &rcb );
-    return 2 + doRateConversion( &rcb, doubleRate2 );
+    r = 2 + doRateConversion( &rcb, doubleRate2 );
+    clearSint16Buffer( Data.buffer, r );
+    return 2 * ( rcb.buffer - (Sint16*)Data.buffer + 3 );
 }
 
 /*-------------------------------------------------------------------------*/
 static int halfRateMono( AdapterC Data, int length )
 {
+    Sint16* r;
     RateConverterBuffer rcb;
-    initRateConverterBuffer( &rcb, &Data, length, Half );
-    return doRateConversion( &rcb, halfRate1 );
+    initRateConverterBuffer( &rcb, &Data, length, Double );
+    r = doRateConversion( &rcb, halfRate1 );
+    return 2 * ( r - (Sint16*)Data.buffer );
 }
 
 static int halfRateStereo( AdapterC Data, int length )
 {
+    Sint16* r;
     RateConverterBuffer rcb;
-    initRateConverterBuffer( &rcb, &Data, length, Half );
+    initRateConverterBuffer( &rcb, &Data, length, Double );
     doRateConversion( &rcb, halfRate2 );
     nextRateConverterBuffer( &rcb );
-    return 2 + doRateConversion( &rcb, halfRate2 );
+    r = doRateConversion( &rcb, halfRate2 );
+    return 2 * ( r - (Sint16*)Data.buffer );
 }
 
 /*-------------------------------------------------------------------------*/
 static int increaseRateMono( AdapterC Data, int length )
 {
+    Sint16* r;
     RateConverterBuffer rcb;
     initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio );
-    return doRateConversion( &rcb, increaseRate1 );
+    r = doRateConversion( &rcb, increaseRate1 );
+    clearSint16Buffer( Data.buffer, r );
+    return 2 * ( rcb.buffer - (Sint16*)Data.buffer + 1 );
 }
 
 static int increaseRateStereo( AdapterC Data, int length )
 {
+    Sint16* r;
+    fprintf( stderr, "\n Buffer: %8x length: %8x\n", Data.buffer, length );
     RateConverterBuffer rcb;
     initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio );
     doRateConversion( &rcb, increaseRate2 );
     nextRateConverterBuffer( &rcb );
-    return 2 + doRateConversion( &rcb, increaseRate2 );
+    r = doRateConversion( &rcb, increaseRate2 );
+    clearSint16Buffer( Data.buffer, r );
+    return 2 * ( rcb.buffer - (Sint16*)Data.buffer + 1 );
 }
 
 /*-------------------------------------------------------------------------*/
 static int decreaseRateMono( AdapterC Data, int length )
 {
+    Sint16* r;
     RateConverterBuffer rcb;
     initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio );
-    return doRateConversion( &rcb, decreaseRate1 );
+    r = doRateConversion( &rcb, decreaseRate1 );
+    return 2 * ( r - (Sint16*)Data.buffer );
 }
 
 static int decreaseRateStereo( AdapterC Data, int length )
 {
+    Sint16* r;
     RateConverterBuffer rcb;
     initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio );
     doRateConversion( &rcb, decreaseRate2 );
     nextRateConverterBuffer( &rcb );
-    return 2 + doRateConversion( &rcb, decreaseRate2 );
-}
-
-/*-------------------------------------------------------------------------*/
-static int padSilence( AdapterC Data, int length )
-{
-    Uint32 zero, *buffer;
-    int i, mask = 0;
-
-    buffer = (Uint32*) ( Data.buffer + length );
-    if( Data.mode != SDL_SOUND_Loop )
-        mask = Data.filter->mask;
-    length = mask - ( ( length - 1 ) & mask );
-
-    for( i = 0; i < length>>2; i++ )
-         buffer[i] = zero;
-    for( ; i < length; i++ )
-        ((Uint8*)buffer)[i] = ((Uint8*)&zero)[i&3];
-
-    return length + ((Uint8*)buffer - Data.buffer);
+    r = doRateConversion( &rcb, decreaseRate2 );
+    return 2 * ( r - (Sint16*)Data.buffer );
 }
 
 /*-------------------------------------------------------------------------*/
@@ -633,11 +658,12 @@
     return fg;
 }
 
-static Fraction setupVarFilter( VarFilter* filter, float Ratio )
+static Fraction setupVarFilter( Sound_AudioCVT *Data, float Ratio )
 {
     int pos,n,d, incr, phase = 0;
     float Scale, rd, fg;
     Fraction IRatio;
+    VarFilter* filter = &Data->filter;
 
     IRatio = findFraction( Ratio );
 //    Scale = Ratio < 1. ? 0.0364733 : 0.0211952;
@@ -665,9 +691,17 @@
     return IRatio;
 }
 /*-------------------------------------------------------------------------*/
+static void initAudioCVT( Sound_AudioCVT *Data )
+{
+    Data->len_ratio = 1.;
+    Data->len_mult = 1;
+    Data->add = 0;
+    Data->len_add = 0;
+    Data->filter_index = 0;
+}
+
 static void adjustSize( Sound_AudioCVT *Data, int add, Fraction f )
 {
-
     double ratio = f.numerator / (double) f.denominator;
     Data->len_ratio *= ratio;
     Data->len_mult = max( Data->len_mult, ceil(Data->len_ratio) );
@@ -675,243 +709,194 @@
     Data->len_add = max( Data->len_add, ceil(Data->add) );
 }
 
-static void initSize( Sound_AudioCVT *Data )
+static Adapter* addAdapter( Sound_AudioCVT *Data, Adapter a )
+{
+    Data->adapter[Data->filter_index] = a;
+    return &Data->adapter[Data->filter_index++];
+}
+
+static void addHAdapter( Sound_AudioCVT *Data, Adapter a )
 {
-    Data->len_ratio = 1.;
-    Data->len_mult = 1;
-    Data->add = 0;
-    Data->len_add = 0;
+    adjustSize( Data, 0, Half );
+    addAdapter( Data, a );
 }
 
+static void addDAdapter( Sound_AudioCVT *Data, Adapter a )
+{
+    adjustSize( Data, 0, Double );
+    addAdapter( Data, a );
+}
+
+
 /*-------------------------------------------------------------------------*/
 const Adapter doubleRate[2] = { doubleRateMono, doubleRateStereo };
 const Adapter halfRate[2] = { halfRateMono, halfRateStereo };
 const Adapter increaseRate[2] = { increaseRateMono, increaseRateStereo };
 const Adapter decreaseRate[2] = { decreaseRateMono, decreaseRateStereo };
 
-static void createRateConverter( Sound_AudioCVT *Data, int* fip,
-                                 int SrcRate, int DestRate, int channel )
+static int createRateConverter( Sound_AudioCVT *Data,
+                                int SrcRate, int DestRate, int channel )
 {
     const int c = channel - 1;
     const int size = 16 * channel * _fsize;
-    int filter_index = *fip;
-    int VarPos = 0;
+    Adapter* AdapterPos;
     float Ratio = DestRate;
     Fraction f;
-    *fip = -1;
-
 
     if( SrcRate < 1 || SrcRate > 1<<18 ||
-        DestRate < 1 || DestRate > 1<<18 ) return;
+        DestRate < 1 || DestRate > 1<<18 ) return -1;
     Ratio /= SrcRate;
 
-    if( Ratio > 1.)
-        VarPos = filter_index++;
-    else
-        Data->adapter[filter_index++] = minus5dB;
+    AdapterPos = addAdapter( Data, minus5dB );
 
     while( Ratio > 64./31.)
     {
         Ratio /= 2.;
-        Data->adapter[filter_index++] = doubleRate[c];
+        addAdapter( Data, doubleRate[c] );
         adjustSize( Data, size, Double );
     }
 
     while( Ratio < 31./64. )
     {
         Ratio *= 2;
-        Data->adapter[filter_index++] = halfRate[c];
+        addAdapter( Data, halfRate[c] );
         adjustSize( Data, size, Half );
     }
 
     if( Ratio > 1. )
     {
-        Data->adapter[VarPos] = increaseRate[c];
-        f = setupVarFilter( &Data->filter, Ratio );
+        *AdapterPos = increaseRate[c];
+        f = setupVarFilter( Data, Ratio );
         adjustSize( Data, size, f );
     }
     else
     {
-        Data->adapter[filter_index++] = decreaseRate[c];
-        f = setupVarFilter( &Data->filter, Ratio );
+        f = setupVarFilter( Data, Ratio );
+        addAdapter( Data, decreaseRate[c]);
         adjustSize( Data, size, f );
     }
-    *fip = filter_index;
+
+    return 0;
 }
 
 /*-------------------------------------------------------------------------*/
-static void createFormatConverter16Bit(Sound_AudioCVT *Data, int* fip,
+static void createFormatConverter16Bit(Sound_AudioCVT *Data,
     SDL_AudioSpec src, SDL_AudioSpec dst )
 {
-    int filter_index = *fip;
-
     if( src.channels == 2 && dst.channels == 1 )
     {
-        adjustSize( Data, 0, Half );
-
         if( !IS_SYSENDIAN(src) )
-            Data->adapter[filter_index++] = swapBytes;
+            addAdapter( Data, swapBytes );
 
         if( IS_SIGNED(src) )
-            Data->adapter[filter_index++] = convertStereoToMonoS16Bit;
+            addHAdapter( Data, convertStereoToMonoS16Bit );
         else
-            Data->adapter[filter_index++] = convertStereoToMonoU16Bit;
+            addHAdapter( Data, convertStereoToMonoU16Bit );
 
         if( !IS_SYSENDIAN(dst) )
-            Data->adapter[filter_index++] = swapBytes;
+            addAdapter( Data, swapBytes );
     }
     else if( IS_SYSENDIAN(src) != IS_SYSENDIAN(dst) )
-        Data->adapter[filter_index++] = swapBytes;
+        addAdapter( Data, swapBytes );
 
     if( IS_SIGNED(src) != IS_SIGNED(dst) )
     {
         if( IS_SYSENDIAN(dst) )
-            Data->adapter[filter_index++] = changeSigned16BitSys;
+            addAdapter( Data, changeSigned16BitSys );
         else
-            Data->adapter[filter_index++] = changeSigned16BitWrong;
+            addAdapter( Data, changeSigned16BitWrong );
     }
 
     if( src.channels == 1 && dst.channels == 2 )
-    {
-        adjustSize( Data, 0, Double );
-        Data->adapter[filter_index++] = convertMonoToStereo16Bit;
-    }
-
-    *fip = filter_index;
+        addDAdapter( Data, convertMonoToStereo16Bit );
 }
 
 /*-------------------------------------------------------------------------*/
-static void createFormatConverter8Bit(Sound_AudioCVT *Data, int *fip,
+static void createFormatConverter8Bit(Sound_AudioCVT *Data,
     SDL_AudioSpec src, SDL_AudioSpec dst )
 {
-    int filter_index = *fip;
     if( IS_16BIT(src) )
     {
-        adjustSize( Data, 0, Half );
-
         if( IS_SYSENDIAN(src) )
-            Data->adapter[filter_index++] = cut16BitSysTo8Bit;
+            addHAdapter( Data, cut16BitSysTo8Bit );
         else
-            Data->adapter[filter_index++] = cut16BitWrongTo8Bit;
+            addHAdapter( Data, cut16BitWrongTo8Bit );
     }
 
     if( src.channels == 2 && dst.channels == 1 )
     {
-        adjustSize( Data, 0, Half );
-
         if( IS_SIGNED(src) )
-            Data->adapter[filter_index++] = convertStereoToMonoS8Bit;
+            addHAdapter( Data, convertStereoToMonoS8Bit );
         else
-            Data->adapter[filter_index++] = convertStereoToMonoU8Bit;
+            addHAdapter( Data, convertStereoToMonoU8Bit );
     }
 
     if( IS_SIGNED(src) != IS_SIGNED(dst) )
-        Data->adapter[filter_index++] = changeSigned8Bit;
+        addDAdapter( Data, changeSigned8Bit );
 
     if( src.channels == 1 && dst.channels == 2  )
-    {
-        adjustSize( Data, 0, Double );
-        Data->adapter[filter_index++] = convertMonoToStereo8Bit;
-    }
+        addDAdapter( Data, convertMonoToStereo8Bit );
 
     if( !IS_8BIT(dst) )
     {
-        adjustSize( Data, 0, Double );
         if( IS_SYSENDIAN(dst) )
-            Data->adapter[filter_index++] = expand8BitTo16BitSys;
+            addDAdapter( Data, expand8BitTo16BitSys );
         else
-            Data->adapter[filter_index++] = expand8BitTo16BitWrong;
+            addDAdapter( Data, expand8BitTo16BitWrong );
     }
-
-    *fip = filter_index;
 }
 
 /*-------------------------------------------------------------------------*/
-static void createFormatConverter(Sound_AudioCVT *Data, int *fip,
+static void createFormatConverter(Sound_AudioCVT *Data,
     SDL_AudioSpec src, SDL_AudioSpec dst )
 {
-    int filter_index = *fip;
-
     if( IS_FLOAT(src) )
-    {
-        Data->adapter[filter_index++] = cutFloatTo16Bit;
-        adjustSize( Data, 0, Half );
-    }
+        addHAdapter( Data, cutFloatTo16Bit );
 
     if( IS_8BIT(src) || IS_8BIT(dst) )
-         createFormatConverter8Bit( Data, &filter_index, src, dst);
+         createFormatConverter8Bit( Data, src, dst);
     else
-         createFormatConverter16Bit( Data, &filter_index, src, dst);
+         createFormatConverter16Bit( Data, src, dst);
 
     if( IS_FLOAT(dst) )
-    {
-        Data->adapter[filter_index++] = expand16BitToFloat;
-        adjustSize( Data, 0, Double );
-    }
-
-    *fip = filter_index;
+        addDAdapter( Data, expand16BitToFloat );
 }
 
 /*-------------------------------------------------------------------------*/
-Uint32 getSilenceValue( Uint16 format )
-{
-    const static float fzero[] = {0.0000001};
-    switch( format )
-    {
-    case 0x0020: return *(Uint32*) fzero;
-    default: ;
-    }
-    return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-int BuildAudioCVT( Sound_AudioCVT *Data,
+int Sound_AltBuildAudioCVT( Sound_AudioCVT *Data,
                    SDL_AudioSpec src, SDL_AudioSpec dst )
 {
-    SDL_AudioSpec intrm;
-    int filter_index = 0;
+    SDL_AudioSpec im;
 
     if( Data == NULL ) return -1;
-    if( dst.size < 8 ) return -1;
 
-    initSize( Data );
+    initAudioCVT( Data );
     Data->filter.ratio.denominator = 0;
-    Data->filter.zero = getSilenceValue( dst.format );
     Data->filter.mask = dst.size - 1;
 
-
-
     /* Check channels */
     if( src.channels < 1 || src.channels > 2 ||
         dst.channels < 1 || dst.channels > 2 ) goto error_exit;
 
-    /* If no frequency conversion is needed, go straight to dst format */
-    if( src.freq == dst.freq )
+    if( src.freq != dst.freq )
     {
-        createFormatConverter( Data, &filter_index, src, dst );
-        goto sucess_exit;
-    }
-
-    /* Convert to signed 16Bit System-Endian */
-    intrm.format = AUDIO_S16SYS;
-    intrm.channels = min( src.channels, dst.channels );
-    createFormatConverter( Data, &filter_index, src, intrm );
+    /* Convert to intermidiate format: signed 16Bit System-Endian */
+        im.format = AUDIO_S16SYS;
+        im.channels = min( src.channels, dst.channels );
+        createFormatConverter( Data, src, im );
 
     /* Do rate conversion */
-    if( src.channels == 2 && dst.channels == 2 )
-        createRateConverter( Data, &filter_index, src.freq, dst.freq, 2 );
-    else
-        createRateConverter( Data, &filter_index, src.freq, dst.freq, 1 );
-    /* propagate error */
-    if( filter_index < 0 ) goto error_exit;
+        if( createRateConverter( Data, src.freq, dst.freq, im.channels ) )
+            goto error_exit;
+
+       src = im;
+    }
 
     /* Convert to final format */
-    createFormatConverter( Data, &filter_index, intrm, dst );
+    createFormatConverter( Data, src, dst );
 
-    /* Set up the filter information */
-sucess_exit:
-    Data->adapter[filter_index++] = padSilence;
-    Data->adapter[filter_index] = NULL;
+    /* Finalize adapter list */
+    addAdapter( Data, NULL );
 /* !!! FIXME: Is it okay to assign NULL to a function pointer?
               Borland says no. -frank */
     return 0;
@@ -970,7 +955,6 @@
         AdapterDesc(increaseRateStereo),
         AdapterDesc(decreaseRateMono),
         AdapterDesc(decreaseRateStereo),
-        AdapterDesc(padSilence),
         { NULL,    "----------NULL-----------\n" }
     };
 
@@ -1025,7 +1009,7 @@
 
 int Sound_BuildAudioCVT(Sound_AudioCVT *Data,
     Uint16 src_format, Uint8 src_channels, int src_rate,
-    Uint16 dst_format, Uint8 dst_channels, int dst_rate, Uint32 dst_size )
+    Uint16 dst_format, Uint8 dst_channels, int dst_rate )
 {
     SDL_AudioSpec src, dst;
     int ret;
@@ -1039,8 +1023,7 @@
              "size:  don't care -> %#7x\n\n",
              fmt_to_str (src_format), fmt_to_str (dst_format),
              src_channels,            dst_channels,
-             src_rate,                dst_rate,
-                                      dst_size );
+             src_rate,                dst_rate );
 
     src.format = src_format;
     src.channels = src_channels;
@@ -1049,9 +1032,8 @@
     dst.format = dst_format;
     dst.channels = dst_channels;
     dst.freq = dst_rate;
-    dst.size = dst_size;
 
-    ret = BuildAudioCVT( Data, src, dst );
+    ret = Sound_AltBuildAudioCVT( Data, src, dst );
     Data->needed = 1;
 
     show_AudioCVT( Data );
--- a/alt_audio_convert.h	Thu Sep 26 04:34:25 2002 +0000
+++ b/alt_audio_convert.h	Thu Sep 26 04:34:35 2002 +0000
@@ -32,8 +32,6 @@
 #define Sound_AI_Loop 0x2
 #define _fsize 32
 
-#include "SDL_sound.h"
-
 typedef struct{
     Sint16 numerator;
     Sint16 denominator;
@@ -43,7 +41,6 @@
    Sint16 c[16][4*_fsize];
    Uint8 incr[16];
    Fraction ratio;
-   Uint32 zero;
    int mask;
 } VarFilter;
 
@@ -57,6 +54,7 @@
 
 typedef struct{
    VarFilter filter;
+   int filter_index;
    Adapter adapter[32];
 /* buffer must be len*len_mult(+len_add) big */
    int len_mult;
@@ -74,11 +72,24 @@
 
 #define SDL_SOUND_Loop 0x10
 
+#ifndef SNDDECLSPEC
+#define SNDDECLSPEC DECLSPEC
+#endif
+
 extern SNDDECLSPEC int Sound_ConvertAudio( Sound_AudioCVT *Data );
 
+extern SNDDECLSPEC int Sound_AltConvertAudio( Sound_AudioCVT *Data,
+    Uint8* buffer, int length, int mode );
+
 extern SNDDECLSPEC int Sound_BuildAudioCVT( Sound_AudioCVT *Data,
    Uint16 src_format, Uint8 src_channels, int src_rate,
-   Uint16 dst_format, Uint8 dst_channels, int dst_rate, Uint32 dst_size );
+   Uint16 dst_format, Uint8 dst_channels, int dst_rate );
+
+extern SNDDECLSPEC int Sound_AltBuildAudioCVT( Sound_AudioCVT *Data,
+   SDL_AudioSpec src, SDL_AudioSpec dst );
+
+extern SNDDECLSPEC int Sound_estimateBufferSize( Sound_AudioCVT *Data,
+   int length );
 
 #endif /* _INCLUDE_AUDIO_CONVERT_H_ */