# HG changeset patch # User Ryan C. Gordon # Date 1109533801 0 # Node ID 9e761a594df1493e082b77a8796418adb5f5d6d2 # Parent 9999f59cf59128f811d53cd03dfcf530cdd9c514 Removed altcvt. diff -r 9999f59cf591 -r 9e761a594df1 SDL_sound_internal.h --- a/SDL_sound_internal.h Thu Jan 06 07:35:39 2005 +0000 +++ b/SDL_sound_internal.h Sun Feb 27 19:50:01 2005 +0000 @@ -217,9 +217,6 @@ /* A structure to hold a set of audio conversion filters and buffers */ -#if (defined SOUND_USE_ALTCVT) -#include "alt_audio_convert.h" -#else typedef struct Sound_AudioCVT { int needed; /* Set to 1 if conversion possible */ @@ -234,7 +231,6 @@ void (*filters[20])(struct Sound_AudioCVT *cvt, Uint16 *format); int filter_index; /* Current audio conversion function */ } Sound_AudioCVT; -#endif extern SNDDECLSPEC int Sound_BuildAudioCVT(Sound_AudioCVT *cvt, Uint16 src_format, Uint8 src_channels, Uint32 src_rate, diff -r 9999f59cf591 -r 9e761a594df1 alt_audio_convert.c --- a/alt_audio_convert.c Thu Jan 06 07:35:39 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1057 +0,0 @@ -/* - * 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.) - */ - -#if HAVE_CONFIG_H -# include -#endif - -#if SOUND_USE_ALTCVT - -#include "alt_audio_convert.h" -#include - -/* just to make sure this is defined... */ - -#ifndef min -#define min(x, y) ( ((x) < (y)) ? (x) : (y) ) -#endif - -#ifndef max -#define max(x, y) ( ((x) > (y)) ? (x) : (y) ) -#endif - -#ifndef abs -#define abs(x) ( ((x) > (0)) ? (x) : -(x) ) -#endif - - -/* some macros for "parsing" format */ - -#define IS_8BIT(x) ((x).format & 0x0008) -#define IS_16BIT(x) ((x).format & 0x0010) -#define IS_FLOAT(x) ((x).format & 0x0020) -#define IS_SIGNED(x) ((x).format & 0x8000) -#define IS_SYSENDIAN(x) ((~AUDIO_U16SYS ^ (x).format) & 0x1000) -#define SDL_MSB_POSITION_IN_SHORT ((0x1000 & AUDIO_U16SYS)>>12) - - -/*-------------------------------------------------------------------------*/ -/* the purpose of the RateConverterBuffer is to provide a continous storage - for head and tail of the (sample)-buffer. This allows a simple and - perfomant implemantation of the sample rate converters. Depending of the - operation mode, two layouts for the RateConverterBuffer.inbuffer are - possible: - - in the Loop Mode: - ... T-4 T-3 T-2 T-1 H+0 H+1 H+2 H+3 H+4 ... - | - linp, finp - - in the Single Mode (non Loop): - ... T-4 T-3 T-2 T-1 0 0 0 ... 0 0 0 H+0 H+1 H+2 H+3 H+4 ... - | | - linp finp - - The RateConverterBuffer allows an accurate attack and decay of the - filters in the rate Converters. - - The pointer finp are actually shifted against the depicted position so - that on the first invocation of the rate converter the input of the - filter is nearly complete in the zero region, only one input value is - used. After the calculation of the first output value, the pointer are - incremented or decremented depending on down or up conversion and the - first two input value are taken into account. This procedure repeats - until the filter has processed all zeroes. The distance of the pointer - movement is stored in flength, always positive. - - Further a pointer cinp to the sample buffer itself is stored. The pointer - to the sample buffer is shifted too, so that on the first use of this - pointer the filter is complete in the sample buffer. The pointer moves - over the sample buffer until it reaches the other end. The distance of - the movement is stored in clength. - - Finally the decay of the filter is done by linp and llength like finp, - flength, but in reverse order. - - buffer denotes the start or the end of the output buffer, depending - on direction of the rate conversion. - - All pointer and length referring the buffer as Sint16. All length - are refering to the input buffer */ - -typedef struct -{ - Sint16 inbuffer[24*_fsize]; - Sint16 *finp, *cinp, *linp; - int flength, clength, llength; - Sint16 *buffer; - VarFilter *filter; -} RateConverterBuffer; - -typedef struct -{ - Sint16 carry; - Sint16 pos; -} RateAux; - - -/* Mono (1 channel ) */ -#define Suffix(x) x##1 -#include "filter_templates.h" -#undef Suffix - -/* Stereo (2 channel ) */ -#define Suffix(x) x##2 -#include "filter_templates.h" -#undef Suffix - - -/*-------------------------------------------------------------------------*/ -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("No converter given"); - return(-1); - } - - /* Make sure there's data to convert */ - if( buffer == NULL ) { - SDL_SetError("No buffer allocated for conversion"); - return(-1); - } - - if( length < 0 ) { - SDL_SetError("Lenght < 0"); - return(-1); - } - - /* Set up the conversion and go! */ - Temp.buffer = buffer; - Temp.mode = mode; - Temp.filter = &Data->filter; - - for( i = 0; Data->adapter[i] != NULL; i++ ) - length = (*Data->adapter[i])( Temp, length); - - return length; -} - -int Sound_ConvertAudio( Sound_AudioCVT *Data ) -{ - int length; - /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ - length = Sound_AltConvertAudio( Data, Data->buf, Data->len, 0 ); - Data->len_cvt = length; - return length; -} - -/*-------------------------------------------------------------------------*/ -static int expand8BitTo16BitSys( AdapterC Data, int length ) -{ - int i; - Uint8* inp = Data.buffer - 1; - Uint16* buffer = (Uint16*)Data.buffer - 1; - for( i = length + 1; --i; ) - buffer[i] = inp[i]<<8; - return 2*length; -} - -static int expand8BitTo16BitWrong( AdapterC Data, int length ) -{ - int i; - Uint8* inp = Data.buffer - 1; - Uint16* buffer = (Uint16*)Data.buffer - 1; - for( i = length + 1; --i; ) - buffer[i] = inp[i]; - return 2*length; -} - -/*-------------------------------------------------------------------------*/ -static int expand16BitToFloat( AdapterC Data, int length ) -{ - int i; - Sint16* inp = (Sint16*)Data.buffer - 1; - float* buffer = (float*)Data.buffer - 1; - for( i = length>>1 + 1; --i; ) - buffer[i] = inp[i]*(1./32767); - return 2*length; -} - -/*-------------------------------------------------------------------------*/ -static int swapBytes( AdapterC Data, int length ) -{ - /* - * !!! FIXME !!! - * - * - * Use the faster SDL-Macros to swap - * - Frank - */ - - int i; - Uint16 a,b; - Uint16* buffer = (Uint16*) Data.buffer - 1; - for( i = length>>1 + 1; --i; ) - { - a = b = buffer[i]; - buffer[i] = ( a << 8 ) | ( b >> 8 ); - } - return length; -} - -/*-------------------------------------------------------------------------*/ -static int cutFloatTo16Bit( AdapterC Data, int length ) -{ - int i; - float* inp = (float*) Data.buffer; - Sint16* buffer = (Sint16*) Data.buffer; - length>>=2; - for( i = 0; i < length; i++ ) - { - if( inp[i] > 1. ) - buffer[i] = 32767; - else if( inp[i] < -1. ) - buffer[i] = -32768; - else - buffer[i] = 32767 * inp[i]; - } - return 2*length; -} - -/*-------------------------------------------------------------------------*/ -static int cut16BitTo8Bit( AdapterC Data, int length, int off ) -{ - int i; - Uint8* inp = Data.buffer + off; - Uint8* buffer = Data.buffer; - length >>= 1; - for( i = 0; i < length; i++ ) - buffer[i] = inp[2*i]; - return length; -} - -static int cut16BitSysTo8Bit( AdapterC Data, int length ) -{ - return cut16BitTo8Bit( Data, length, SDL_MSB_POSITION_IN_SHORT ); -} - -static int cut16BitWrongTo8Bit( AdapterC Data, int length ) -{ - return cut16BitTo8Bit( Data, length, 1-SDL_MSB_POSITION_IN_SHORT ); -} - -/*-------------------------------------------------------------------------*/ -/* poor mans mmx :-) */ -static int changeSigned( AdapterC Data, int length, Uint32 XOR ) -{ - int i; - Uint32* buffer = (Uint32*) Data.buffer - 1; - for( i = ( length + 7 ) >> 2; --i; ) - buffer[i] ^= XOR; - return length; -} - -static int changeSigned16BitSys( AdapterC Data, int length ) -{ - return changeSigned( Data, length, 0x80008000 ); -} - -static int changeSigned16BitWrong( AdapterC Data, int length ) -{ - return changeSigned( Data, length, 0x00800080 ); -} - -static int changeSigned8Bit( AdapterC Data, int length ) -{ - return changeSigned( Data, length, 0x80808080 ); -} - -/*-------------------------------------------------------------------------*/ -static int convertStereoToMonoS16Bit( AdapterC Data, int length ) -{ - int i; - Sint16* buffer = (Sint16*) Data.buffer; - Sint16* src = (Sint16*) Data.buffer; - length >>= 2; - for( i = 0; i < length; i++, src+=2 ) - buffer[i] = ((int) src[0] + src[1] ) >> 1; - return 2*length; -} - -static int convertStereoToMonoU16Bit( AdapterC Data, int length ) -{ - int i; - Uint16* buffer = (Uint16*) Data.buffer; - Uint16* src = (Uint16*) Data.buffer; - length >>= 2; - for( i = 0; i < length; i++, src+=2 ) - buffer[i] = ((int) src[0] + src[1] ) >> 1; - return 2*length; -} - -static int convertStereoToMonoS8Bit( AdapterC Data, int length ) -{ - int i; - Sint8* buffer = (Sint8*) Data.buffer; - Sint8* src = (Sint8*) Data.buffer; - length >>= 1; - for( i = 0; i < length; i++, src+=2 ) - buffer[i] = ((int) src[0] + src[1] ) >> 1; - return length; -} - -static int convertStereoToMonoU8Bit( AdapterC Data, int length ) -{ - int i; - Uint8* buffer = (Uint8*) Data.buffer; - Uint8* src = (Uint8*) Data.buffer; - length >>= 1; - for( i = 0; i < length; i++, src+=2 ) - buffer[i] = ((int) src[0] + src[1] ) >> 1; - return length; -} - -/*-------------------------------------------------------------------------*/ -static int convertMonoToStereo16Bit( AdapterC Data, int length ) -{ - int i; - Uint16* buffer; - Uint16* dst; - - length >>=1; - buffer = (Uint16*)Data.buffer - 1; - dst = (Uint16*)Data.buffer + 2*length - 2; - for( i = length + 1; --i; dst-=2 ) - dst[0] = dst[1] = buffer[i]; - return 4*length; -} - -static int convertMonoToStereo8Bit( AdapterC Data, int length ) -{ - int i; - Uint8* buffer = Data.buffer - 1; - Uint8* dst = Data.buffer + 2*length - 2; - for( i = length + 1; --i; dst-=2 ) - dst[0] = dst[1] = buffer[i]; - return 2*length; -} - -/*-------------------------------------------------------------------------*/ -static int minus5dB( AdapterC Data, int length ) -{ - int i; - Sint16* buffer = (Sint16*) Data.buffer; - for(i = length>>1 + 1; --i; ) - buffer[i] = (38084 * (int)buffer[i]) >> 16; - return length; -} - -/*-------------------------------------------------------------------------*/ -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 i, size, minsize; - size = 8 * _fsize; - minsize = min( size, length ); - - for( i = 0; i < minsize; i++ ) - { - rcb->inbuffer[i] = rcb->buffer[length-size+i]; - rcb->inbuffer[i+size] = 0; - rcb->inbuffer[i+2*size] = rcb->buffer[i]; - } - for( ; i < size; i++ ) - { - rcb->inbuffer[i] = 0; - rcb->inbuffer[i+size] = 0; - rcb->inbuffer[i+2*size] = 0; - } - - length = max( length, size ); - rcb->flength = rcb->llength = size; - rcb->clength = length - size; - - if( r.numerator < r.denominator ) - { - rcb->finp = rcb->inbuffer + 5*size/2; - rcb->cinp = rcb->buffer + length - size/2; - rcb->linp = rcb->inbuffer + 3*size/2; - rcb->buffer += ( 1 + r.denominator * ( length + size ) - / r.numerator ) & -2; - } - else - { - rcb->finp = rcb->inbuffer + size/2; - rcb->cinp = rcb->buffer + size/2; - rcb->linp = rcb->inbuffer + 3*size/2; - } -} - -static void initLoopBuffer( RateConverterBuffer *rcb, - int length, Fraction r ) -{ - /* !!!FIXME: modulo length, take scale into account, - check against the Straight part -frank */ - int i, size; - size = 8 * _fsize; - for( i = 0; i < size; i++ ) - { - rcb->inbuffer[i] = rcb->buffer[length-size+i]; - rcb->inbuffer[i+size] = rcb->buffer[i]; - } - rcb->finp = rcb->linp = rcb->inbuffer + size; - if( size < 0 ) - rcb->buffer += r.numerator * ( length + 2 * size ) - / r.denominator; -} - -static void initRateConverterBuffer( RateConverterBuffer *rcb, - AdapterC* Data, int length, Fraction ratio ) -{ - length >>= 1; - rcb->buffer = (Sint16*)( Data->buffer ); - rcb->filter = Data->filter; - - if( Data->mode & SDL_SOUND_Loop ) - initLoopBuffer( rcb, length, ratio ); - else - 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 ) -{ - rcb->buffer++; - rcb->finp++; - rcb->cinp++; - rcb->linp++; -} - -typedef Sint16* (*RateConverter)( Sint16*, Sint16*, int, - VarFilter*, RateAux* ); - -static Sint16* doRateConversion( RateConverterBuffer* rcb, RateConverter rc ) -{ - RateAux aux = {0,0}; - Sint16 *outp = rcb->buffer; - VarFilter* filter = rcb->filter; - - 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, 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; - RateConverterBuffer rcb; - fprintf( stderr, "\n Buffer: %8x length: %8x\n", Data.buffer, length ); - initRateConverterBuffer( &rcb, &Data, length, Half ); - doRateConversion( &rcb, doubleRate2 ); - nextRateConverterBuffer( &rcb ); - 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, 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, Double ); - doRateConversion( &rcb, halfRate2 ); - nextRateConverterBuffer( &rcb ); - 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 ); - 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; - RateConverterBuffer rcb; - fprintf( stderr, "\n Buffer: %8x length: %8x\n", Data.buffer, length ); - initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); - doRateConversion( &rcb, increaseRate2 ); - nextRateConverterBuffer( &rcb ); - 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 ); - 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 ); - r = doRateConversion( &rcb, decreaseRate2 ); - return 2 * ( r - (Sint16*)Data.buffer ); -} - -/*-------------------------------------------------------------------------*/ -/* gives a maximal error of 3% and typical less than 0.2% */ -static Fraction findFraction( float Value ) -{ - const Sint8 frac[95]={ - 2, -1, /* /1 */ - 1, 3, -1, /* /2 */ - 2, 4, 5, -1, /* /3 */ - 3, 5, 7, -1, /* /4 */ - 3, 4, 6, 7, 8, 9, -1, /* /5 */ - 5, 7, 11, -1, /* /6 */ - 4, 5, 6, 8, 9, 10, 11, 12, 13, -1, /* /7 */ - 5, 7, 9, 11, 13, 15, -1, /* /8 */ - 5, 7, 8, 10, 11, 13, 14, 16, -1, /* /9 */ - 7, 9, 11, 13, -1, /* /10 */ - 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, -1, /* /11 */ - 7, 11, 13, -1, /* /12 */ - 7, 8, 9, 10, 11, 12, 14, 15, 16, -1, /* /13 */ - 9, 11, 13, 15, -1, /* /14 */ - 8, 11, 13, 14, 16, -1, /* /15 */ - 9, 11, 13, 15 }; /* /16 */ - - - Fraction Result = {0,0}; - int i,num,den=1; - - float RelErr, BestErr = 0; - if( Value < 31/64. || Value > 64/31. ) return Result; - - for( i = 0; i < SDL_TABLESIZE(frac); i++ ) - { - num = frac[i]; - if( num < 0 ) den++; - RelErr = Value * num / den; - RelErr = min( RelErr, 1/RelErr ); - if( RelErr > BestErr ) - { - BestErr = RelErr; - Result.denominator = den; - Result.numerator = num; - } - } - return Result; -} - -/*-------------------------------------------------------------------------*/ -static float sinc( float x ) -{ - if( x > -1e-24 && x < 1e-24 ) return 1.; - else return sin(x)/x; -} - -static float calculateVarFilter( Sint16* dst, - float Ratio, float phase, float scale ) -{ - const Uint16 KaiserWindow7[]= { - 22930, 16292, 14648, 14288, 14470, 14945, 15608, 16404, - 17304, 18289, 19347, 20467, 21644, 22872, 24145, 25460, - 26812, 28198, 29612, 31052, 32513, 33991, 35482, 36983, - 38487, 39993, 41494, 42986, 44466, 45928, 47368, 48782, - 50165, 51513, 52821, 54086, 55302, 56466, 57575, 58624, - 59610, 60529, 61379, 62156, 62858, 63483, 64027, 64490, - 64870, 65165, 65375, 65498, 65535, 65484, 65347, 65124, - 64815, 64422, 63946, 63389, 62753, 62039, 61251, 60391 }; - int i; - float w; - const float fg = -.018 + .5 * Ratio; - const float omega = 2 * M_PI * fg; - fprintf( stderr, " phase: %6g \n", phase ); - phase += 63; - for( i = 0; i < 64; i++) - { - w = scale * ( KaiserWindow7[i] * ( i + 1 )); - dst[i] = w * sinc( omega * (i-phase) ); - dst[127-i] = w * sinc( omega * (127-i-phase) ); - } - fprintf( stderr, " center: %6d %6d \n", dst[63], dst[64] ); - return fg; -} - -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; - Scale = 0.0084778; - Ratio = min( Ratio, 0.97 ); - - filter->ratio = IRatio; - n = IRatio.numerator; - d = IRatio.denominator; - rd = 1. / d; - - fprintf( stderr, "Filter:\n" ); - - for( pos = 0; pos < d; pos++ ) - { - fg = calculateVarFilter( filter->c[pos], Ratio, phase*rd, Scale ); - phase += n; - filter->incr[pos] = phase / d; - phase %= d; - } - fprintf( stderr, " fg: %6g\n\n", fg ); -/* !!!FIXME: get rid of the inversion -Frank*/ - IRatio.numerator = d; - IRatio.denominator = n; - 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) ); - Data->add = ratio * (Data->add + add); - Data->len_add = max( Data->len_add, ceil(Data->add) ); -} - -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 ) -{ - 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 int createRateConverter( Sound_AudioCVT *Data, - int SrcRate, int DestRate, int channel ) -{ - const int c = channel - 1; - const int size = 16 * channel * _fsize; - Adapter* AdapterPos; - float Ratio = DestRate; - Fraction f; - - if( SrcRate < 1 || SrcRate > 1<<18 || - DestRate < 1 || DestRate > 1<<18 ) return -1; - Ratio /= SrcRate; - - AdapterPos = addAdapter( Data, minus5dB ); - - while( Ratio > 64./31.) - { - Ratio /= 2.; - addAdapter( Data, doubleRate[c] ); - adjustSize( Data, size, Double ); - } - - while( Ratio < 31./64. ) - { - Ratio *= 2; - addAdapter( Data, halfRate[c] ); - adjustSize( Data, size, Half ); - } - - if( Ratio > 1. ) - { - *AdapterPos = increaseRate[c]; - f = setupVarFilter( Data, Ratio ); - adjustSize( Data, size, f ); - } - else - { - f = setupVarFilter( Data, Ratio ); - addAdapter( Data, decreaseRate[c]); - adjustSize( Data, size, f ); - } - - return 0; -} - -/*-------------------------------------------------------------------------*/ -static void createFormatConverter16Bit(Sound_AudioCVT *Data, - SDL_AudioSpec src, SDL_AudioSpec dst ) -{ - if( src.channels == 2 && dst.channels == 1 ) - { - if( !IS_SYSENDIAN(src) ) - addAdapter( Data, swapBytes ); - - if( IS_SIGNED(src) ) - addHAdapter( Data, convertStereoToMonoS16Bit ); - else - addHAdapter( Data, convertStereoToMonoU16Bit ); - - if( !IS_SYSENDIAN(dst) ) - addAdapter( Data, swapBytes ); - } - else if( IS_SYSENDIAN(src) != IS_SYSENDIAN(dst) ) - addAdapter( Data, swapBytes ); - - if( IS_SIGNED(src) != IS_SIGNED(dst) ) - { - if( IS_SYSENDIAN(dst) ) - addAdapter( Data, changeSigned16BitSys ); - else - addAdapter( Data, changeSigned16BitWrong ); - } - - if( src.channels == 1 && dst.channels == 2 ) - addDAdapter( Data, convertMonoToStereo16Bit ); -} - -/*-------------------------------------------------------------------------*/ -static void createFormatConverter8Bit(Sound_AudioCVT *Data, - SDL_AudioSpec src, SDL_AudioSpec dst ) -{ - if( IS_16BIT(src) ) - { - if( IS_SYSENDIAN(src) ) - addHAdapter( Data, cut16BitSysTo8Bit ); - else - addHAdapter( Data, cut16BitWrongTo8Bit ); - } - - if( src.channels == 2 && dst.channels == 1 ) - { - if( IS_SIGNED(src) ) - addHAdapter( Data, convertStereoToMonoS8Bit ); - else - addHAdapter( Data, convertStereoToMonoU8Bit ); - } - - if( IS_SIGNED(src) != IS_SIGNED(dst) ) - addDAdapter( Data, changeSigned8Bit ); - - if( src.channels == 1 && dst.channels == 2 ) - addDAdapter( Data, convertMonoToStereo8Bit ); - - if( !IS_8BIT(dst) ) - { - if( IS_SYSENDIAN(dst) ) - addDAdapter( Data, expand8BitTo16BitSys ); - else - addDAdapter( Data, expand8BitTo16BitWrong ); - } -} - -/*-------------------------------------------------------------------------*/ -static void createFormatConverter(Sound_AudioCVT *Data, - SDL_AudioSpec src, SDL_AudioSpec dst ) -{ - if( IS_FLOAT(src) ) - addHAdapter( Data, cutFloatTo16Bit ); - - if( IS_8BIT(src) || IS_8BIT(dst) ) - createFormatConverter8Bit( Data, src, dst); - else - createFormatConverter16Bit( Data, src, dst); - - if( IS_FLOAT(dst) ) - addDAdapter( Data, expand16BitToFloat ); -} - -/*-------------------------------------------------------------------------*/ -int Sound_AltBuildAudioCVT( Sound_AudioCVT *Data, - SDL_AudioSpec src, SDL_AudioSpec dst ) -{ - SDL_AudioSpec im; - - if( Data == NULL ) return -1; - - initAudioCVT( Data ); - Data->filter.ratio.denominator = 0; - 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( src.freq != dst.freq ) - { - /* 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( createRateConverter( Data, src.freq, dst.freq, im.channels ) ) - goto error_exit; - - src = im; - } - - /* Convert to final format */ - createFormatConverter( Data, src, dst ); - - /* Finalize adapter list */ - addAdapter( Data, NULL ); -/* !!! FIXME: Is it okay to assign NULL to a function pointer? - Borland says no. -frank */ - return 0; - -error_exit: -/* !!! FIXME: Is it okay to assign NULL to a function pointer? - Borland says no. -frank */ - Data->adapter[0] = NULL; - return -1; -} - -/*-------------------------------------------------------------------------*/ -static char *fmt_to_str(Uint16 fmt) -{ - switch (fmt) - { - case AUDIO_U8: return " U8"; - case AUDIO_S8: return " S8"; - case AUDIO_U16MSB: return "U16MSB"; - case AUDIO_S16MSB: return "S16MSB"; - case AUDIO_U16LSB: return "U16LSB"; - case AUDIO_S16LSB: return "S16LSB"; - } - return "??????"; -} - -#define AdapterDesc(x) { x, #x } - -static void show_AudioCVT( Sound_AudioCVT *Data ) -{ - int i,j; - const struct{ int (*adapter) ( AdapterC, int); Sint8 *name; } - AdapterDescription[] = { - AdapterDesc(expand8BitTo16BitSys), - AdapterDesc(expand8BitTo16BitWrong), - AdapterDesc(expand16BitToFloat), - AdapterDesc(swapBytes), - AdapterDesc(cut16BitSysTo8Bit), - AdapterDesc(cut16BitWrongTo8Bit), - AdapterDesc(cutFloatTo16Bit), - AdapterDesc(changeSigned16BitSys), - AdapterDesc(changeSigned16BitWrong), - AdapterDesc(changeSigned8Bit), - AdapterDesc(convertStereoToMonoS16Bit), - AdapterDesc(convertStereoToMonoU16Bit), - AdapterDesc(convertStereoToMonoS8Bit), - AdapterDesc(convertStereoToMonoU8Bit), - AdapterDesc(convertMonoToStereo16Bit), - AdapterDesc(convertMonoToStereo8Bit), - AdapterDesc(minus5dB), - AdapterDesc(doubleRateMono), - AdapterDesc(doubleRateStereo), - AdapterDesc(halfRateMono), - AdapterDesc(halfRateStereo), - AdapterDesc(increaseRateMono), - AdapterDesc(increaseRateStereo), - AdapterDesc(decreaseRateMono), - AdapterDesc(decreaseRateStereo), - { NULL, "----------NULL-----------\n" } - }; - - fprintf( stderr, "Sound_AudioCVT:\n" ); - fprintf( stderr, " needed: %8d\n", Data->needed ); - fprintf( stderr, " add: %8g\n", Data->add ); - fprintf( stderr, " len_add: %8d\n", Data->len_add ); - fprintf( stderr, " len_ratio: %8g\n", Data->len_ratio ); - fprintf( stderr, " len_mult: %8d\n", Data->len_mult ); - fprintf( stderr, " filter->mask: %#7x\n", Data->filter.mask ); - fprintf( stderr, "\n" ); - - fprintf( stderr, "Adapter List: \n" ); - for( i = 0; i < 32; i++ ) - { - for( j = 0; j < SDL_TABLESIZE(AdapterDescription); j++ ) - { - if( Data->adapter[i] == AdapterDescription[j].adapter ) - { - fprintf( stderr, " %s \n", AdapterDescription[j].name ); - if( Data->adapter[i] == NULL ) goto sucess_exit; - goto cont; - } - } - fprintf( stderr, " Error: unknown adapter\n" ); - - cont: - } - fprintf( stderr, " Error: NULL adapter missing\n" ); - sucess_exit: - if( Data->filter.ratio.denominator ) - { - fprintf( stderr, "Variable Rate Converter:\n" - " numerator: %3d\n" - " denominator: %3d\n", - Data->filter.ratio.denominator, - Data->filter.ratio.numerator ); - - fprintf( stderr, " increment sequence:\n" - " " ); - for( i = 0; i < Data->filter.ratio.denominator; i++ ) - fprintf( stderr, "%1d ", Data->filter.incr[i] ); - - fprintf( stderr, "\n" ); - } - else - { - fprintf( stderr, "No Variable Rate Converter\n" ); - } -} - - -int Sound_BuildAudioCVT(Sound_AudioCVT *Data, - Uint16 src_format, Uint8 src_channels, Uint32 src_rate, - Uint16 dst_format, Uint8 dst_channels, Uint32 dst_rate, Uint32 bufsize) -{ - SDL_AudioSpec src, dst; - int ret; - - fprintf (stderr, - "Sound_BuildAudioCVT():\n" - "-----------------------------\n" - "format: %s -> %s\n" - "channels: %6d -> %6d\n" - "rate: %6d -> %6d\n" - "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 ); - - src.format = src_format; - src.channels = src_channels; - src.freq = src_rate; - - dst.format = dst_format; - dst.channels = dst_channels; - dst.freq = dst_rate; - - ret = Sound_AltBuildAudioCVT( Data, src, dst ); - Data->needed = 1; - - show_AudioCVT( Data ); - fprintf (stderr, "\n" - "return value: %d \n\n\n", ret ); - return ret; -} - -#endif /* SOUND_USE_ALTCVT */ - -/* end of alt_audio_convert.c ... */ - diff -r 9999f59cf591 -r 9e761a594df1 alt_audio_convert.h --- a/alt_audio_convert.h Thu Jan 06 07:35:39 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * 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 _INCLUDE_AUDIO_CONVERT_H_ -#define _INCLUDE_AUDIO_CONVERT_H_ - -#include "SDL_audio.h" -#define Sound_AI_Loop 0x2 -#define _fsize 32 - -typedef struct{ - Sint16 numerator; - Sint16 denominator; -} Fraction; - -typedef struct{ - Sint16 c[16][4*_fsize]; - Uint8 incr[16]; - Fraction ratio; - int mask; -} VarFilter; - -typedef struct{ - Uint8* buffer; - int mode; - VarFilter *filter; -} AdapterC; - -typedef int (*Adapter) ( AdapterC Data, int length ); - -typedef struct{ - VarFilter filter; - int filter_index; - Adapter adapter[32]; -/* buffer must be len*len_mult(+len_add) big */ - int len_mult; - int len_add; - double add; - -/* the following elements are provided for compatibility: */ -/* the size of the output is approx len*len_ratio */ - double len_ratio; - Uint8* buf; /* input/output buffer */ - int needed; /* 0 if nothing to be done, 1 otherwise */ - int len; /* Length of the input */ - int len_cvt; /* Length of converted audio buffer */ -} Sound_AudioCVT; - -#define SDL_SOUND_Loop 0x10 - -#ifndef SNDDECLSPEC -#define SNDDECLSPEC DECLSPEC -#endif - -extern SNDDECLSPEC int Sound_AltConvertAudio( Sound_AudioCVT *Data, - Uint8* buffer, int length, int mode ); - -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_ */ - diff -r 9999f59cf591 -r 9e761a594df1 audio_convert.c --- a/audio_convert.c Thu Jan 06 07:35:39 2005 +0000 +++ b/audio_convert.c Sun Feb 27 19:50:01 2005 +0000 @@ -31,8 +31,6 @@ # include #endif -#if !SOUND_USE_ALTCVT - #include "SDL.h" #include "SDL_sound.h" @@ -733,7 +731,5 @@ return(cvt->needed); } /* Sound_BuildAudioCVT */ -#endif /* !SOUND_USE_ALTCVT */ - /* end of audio_convert.c ... */ diff -r 9999f59cf591 -r 9e761a594df1 configure.in --- a/configure.in Thu Jan 06 07:35:39 2005 +0000 +++ b/configure.in Sun Feb 27 19:50:01 2005 +0000 @@ -265,15 +265,6 @@ fi fi -dnl Check for PhysicsFS http://icculus.org/physfs/ -AC_ARG_ENABLE(altcvt, -[ --enable-altcvt enable EXPERIMENTAL audio converter [default=no]], - , enable_altcvt=no) -if test x$enable_altcvt = xyes; then - AC_DEFINE(SOUND_USE_ALTCVT) -fi - - dnl Check for efence (!!! FIXME : This doesn't work.) dnl AC_ARG_ENABLE(efence, dnl [ --enable-efence enable ElectricFence usage [default=no]],