Mercurial > SDL_sound_CoreAudio
changeset 380:44ed8bdeba74
More fixes from Frank.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Wed, 03 Jul 2002 04:33:23 +0000 |
parents | 7e49f4901ceb |
children | ef30365ac717 |
files | alt_audio_convert.c alt_audio_convert.h filter_templates.h |
diffstat | 3 files changed, 122 insertions(+), 105 deletions(-) [+] |
line wrap: on
line diff
--- a/alt_audio_convert.c Wed Jul 03 03:29:44 2002 +0000 +++ b/alt_audio_convert.c Wed Jul 03 04:33:23 2002 +0000 @@ -159,10 +159,11 @@ /*-------------------------------------------------------------------------*/ static int expand8BitTo16BitSys( AdapterC Data, int length ) { +/* !!! Fixme: get rid of <<8 through pointer manipulation --frank */ int i; Uint8* inp = Data.buffer; Uint16* buffer = (Uint16*)Data.buffer; - for( i = length; i--; ) + for( i = length - 1; i >= 0; i-- ) buffer[i] = inp[i]<<8; return 2*length; } @@ -172,7 +173,7 @@ int i; Uint8* inp = Data.buffer; Uint16* buffer = (Uint16*)Data.buffer; - for( i = length; i--; ) + for( i = length - 1; i >= 0; i--) buffer[i] = inp[i]; return 2*length; } @@ -183,7 +184,7 @@ int i; Sint16* inp = (Sint16*)Data.buffer; float* buffer = (float*)Data.buffer; - for( i = length>>1; i--; ) + for( i = length>>1 - 1; i >= 0; i-- ) buffer[i] = inp[i]*(1./32767); return 2*length; } @@ -202,7 +203,7 @@ int i; Uint16 a,b; Uint16* buffer = (Uint16*) Data.buffer; - for( i = length>>1; i --; ) + for( i = length>>1; i >= 0; i-- ) { a = b = buffer[i]; buffer[i] = ( a << 8 ) | ( b >> 8 ); @@ -236,6 +237,7 @@ Uint16* inp = (Uint16*) Data.buffer; Uint8* buffer = Data.buffer; length >>= 1; + /* !!! FIXME: Get rid of the >>8 */ for( i = 0; i < length; i++ ) buffer[i] = inp[i]>>8; return length; @@ -248,7 +250,7 @@ Uint8* buffer = Data.buffer; length >>= 1; for( i = 0; i < length; i++ ) - buffer[i] = inp[i] & 0xff; + buffer[i] = inp[i]; return length; } @@ -258,10 +260,8 @@ { int i; Uint32* buffer = (Uint32*) Data.buffer; - for( i = length>>2; i--; ) + for( i = ( length - 1 ) >> 2; i >= 0; i-- ) buffer[i] ^= XOR; - for( i = 4*(length>>2); i < length; i++) - ((Uint8*)buffer)[i] ^= ((Uint8*)&XOR)[i&3]; return length; } @@ -331,7 +331,7 @@ int i; Uint16* buffer = (Uint16*) Data.buffer; Uint16* dst = (Uint16*)Data.buffer + length - 2; - for( i = length>>1; i--; dst-=2 ) + for( i = length>>1 - 1; i >= 0; i--, dst-=2 ) dst[0] = dst[1] = buffer[i]; return 2*length; } @@ -340,9 +340,9 @@ { int i; Uint8* buffer = Data.buffer; - Uint8* buffer1 = Data.buffer + 1; - for( i = length-1; i >= 0; i-- ) - buffer[2*i] = buffer1[2*i] = buffer[i]; + Uint8* dst = (Uint8*)Data.buffer + length - 2; + for( i = length - 1; i >= 0; i--, dst-=2 ) + dst[0] = dst[1] = buffer[i]; return 2*length; } @@ -351,7 +351,7 @@ { int i; Sint16* buffer = (Sint16*) Data.buffer; - for(i = length>>1; i--; ) + for(i = length>>1 - 1; i >= 0; i-- ) buffer[i]= (38084 * (int)buffer[i]) >> 16; return length; } @@ -364,68 +364,83 @@ dblRate = 2 }; + +const Fraction Half = {1, 2}; +const Fraction Double = {2, 1}; + +static void initStraigthBuffer( RateConverterBuffer *rcb, + int length, Fraction r, int dir ) +{ + 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( dir ) + { + 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; + } + 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, int dir ) +{ + /* !!!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, enum RateConverterType typ ) { int size, minsize, dir; - int den[] = { 0, 1, 2}; - int num[] = { 0, 2, 1}; - int i; + Fraction Ratio[] = { {0,0}, {2,1}, {1,2} }; - den[incrsRate] = Data->filter->denominator; - num[incrsRate] = Data->filter->numerator; - - size = 8 * _fsize; + Ratio[incrsRate] = Data->filter->ratio; dir = ~typ&1; length >>= 1; - minsize = min( length, size ); - rcb->buffer = (Sint16*)( Data->buffer ); if( Data->mode & SDL_SOUND_Loop ) - { - // !!!FIXME: modulo length, take scale into account, - // check against the 'else' part - 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 += num[typ] * ( length + 2 * size ) / den[typ]; - } + initLoopBuffer( rcb, length, Ratio[typ], dir ); else - { - 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; - } - rcb->flength = rcb->llength = size/2 + minsize/2; - rcb->clength = length - minsize; - - if( dir ) - { - rcb->finp = rcb->inbuffer + 2 * size + minsize/2; - rcb->cinp = rcb->buffer + length - minsize/2; - rcb->linp = rcb->inbuffer + size + minsize/2; - rcb->buffer += den[typ] * ( length + minsize ) / num[typ]; - } - else - { - rcb->finp = rcb->inbuffer + size/2; - rcb->cinp = rcb->buffer + size/2; - rcb->linp = rcb->inbuffer + 3*size/2; - } - } + initStraigthBuffer( rcb, length, Ratio[typ], dir ); } static void nextRateConverterBuffer( RateConverterBuffer *rcb ) @@ -536,25 +551,16 @@ if( Data.mode != SDL_SOUND_Loop ) mask = Data.filter->mask; length = mask - ( ( length - 1 ) & mask ); - zero = Data.filter->zero; - for( i = length>>2; i--; ) + for( i = 0; i < length>>2; i++ ) buffer[i] = zero; - for( i = 4*(length>>2); i < length; i++) - ((Uint8*)buffer)[i] ^= ((Uint8*)&zero)[i&3]; + for( ; i < length; i++ ) + ((Uint8*)buffer)[i] = ((Uint8*)&zero)[i&3]; return length + ((Uint8*)buffer - Data.buffer); } /*-------------------------------------------------------------------------*/ -typedef struct{ - Sint16 numerator; - Sint16 denominator; -} Fraction; - -const Fraction Half = {1, 2}; -const Fraction Double = {2, 1}; - /* gives a maximal error of 3% and typical less than 0.2% */ static Fraction findFraction( float Value ) { @@ -623,13 +629,14 @@ const float fg = -.018 + .5 * Ratio; const float omega = 2 * M_PI * fg; fprintf( stderr, " phase: %6g \n", phase ); - phase -= 63; + 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) ); + 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; } @@ -644,10 +651,9 @@ Scale = 0.0084778; Ratio = min( Ratio, 0.97 ); + filter->ratio = IRatio; n = IRatio.numerator; d = IRatio.denominator; - filter->denominator = d; - filter->numerator = n; rd = 1. / d; fprintf( stderr, "Filter:\n" ); @@ -685,14 +691,19 @@ } /*-------------------------------------------------------------------------*/ +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 ) { Fraction f; int filter_index = *fip; int VarPos = 0; - int Mono = 2 - Channel; float Ratio = DestRate; + int c = Channel - 1; *fip = -1; @@ -707,32 +718,28 @@ while( Ratio > 64./31.) { - Data->adapter[filter_index++] = - Mono ? doubleRateMono : doubleRateStereo; Ratio /= 2.; + Data->adapter[filter_index++] = doubleRate[c]; adjustSize( Data, _fsize, Double ); } while( Ratio < 31./64. ) { - Data->adapter[filter_index++] = - Mono ? halfRateMono : halfRateStereo; Ratio *= 2; + Data->adapter[filter_index++] = halfRate[c]; adjustSize( Data, _fsize, Half ); } if( Ratio > 1. ) { + Data->adapter[VarPos] = increaseRate[c]; f = setupVarFilter( &Data->filter, Ratio ); - Data->adapter[VarPos] = - Mono ? increaseRateMono : increaseRateStereo; adjustSize( Data, _fsize, f ); } else { + Data->adapter[filter_index++] = decreaseRate[c]; f = setupVarFilter( &Data->filter, Ratio ); - Data->adapter[filter_index++] = - Mono ? decreaseRateMono : decreaseRateStereo; adjustSize( Data, _fsize, f ); } *fip = filter_index; @@ -871,11 +878,15 @@ int filter_index = 0; if( Data == NULL ) return -1; + if( dst.size < 8 ) return -1; + initSize( Data ); - Data->filter.denominator = 0; + 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; @@ -996,16 +1007,17 @@ } fprintf( stderr, " Error: NULL adapter missing\n" ); sucess_exit: - if( Data->filter.denominator ) + if( Data->filter.ratio.denominator ) { fprintf( stderr, "Variable Rate Converter:\n" " numerator: %3d\n" " denominator: %3d\n", - Data->filter.denominator, Data->filter.numerator ); + Data->filter.ratio.denominator, + Data->filter.ratio.numerator ); fprintf( stderr, " increment sequence:\n" " " ); - for( i = 0; i < Data->filter.denominator; i++ ) + for( i = 0; i < Data->filter.ratio.denominator; i++ ) fprintf( stderr, "%1d ", Data->filter.incr[i] ); fprintf( stderr, "\n" ); @@ -1051,6 +1063,5 @@ show_AudioCVT( Data ); fprintf (stderr, "\n" "return value: %d \n\n\n", ret ); - return ret; }
--- a/alt_audio_convert.h Wed Jul 03 03:29:44 2002 +0000 +++ b/alt_audio_convert.h Wed Jul 03 04:33:23 2002 +0000 @@ -32,12 +32,15 @@ #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]; - int denominator; - int numerator; + Fraction ratio; Uint32 zero; int mask; } VarFilter; @@ -48,9 +51,11 @@ VarFilter *filter; } AdapterC; +typedef int (*Adapter) ( AdapterC Data, int length ); + typedef struct{ VarFilter filter; - int (*adapter[32]) ( AdapterC Data, int length ); + Adapter adapter[32]; /* buffer must be len*len_mult(+len_add) big */ int len_mult; int len_add;
--- a/filter_templates.h Wed Jul 03 03:29:44 2002 +0000 +++ b/filter_templates.h Wed Jul 03 04:33:23 2002 +0000 @@ -130,17 +130,18 @@ { out = 0; f = filter->c[pos]; - for( i = _fsize + 1; --i; inp+=CH(8), f+=4 ) + for( i = _fsize + 1; --i; inp+=CH(4), f+=4 ) { out+= f[0] * (int)inp[CH(0)]; - out+= f[1] * (int)inp[CH(2)]; - out+= f[2] * (int)inp[CH(4)]; - out+= f[3] * (int)inp[CH(6)]; + out+= f[1] * (int)inp[CH(1)]; + out+= f[2] * (int)inp[CH(2)]; + out+= f[3] * (int)inp[CH(3)]; } outp[0] = out >> 16; - pos = ( pos + filter->denominator - 1 ) % filter->denominator; - inp -= CH( 8 * _fsize ); + pos = ( pos + filter->ratio.denominator - 1 ) + % filter->ratio.denominator; + inp -= CH( 4 * _fsize ); inp -= CH( filter->incr[pos] ); outp -= CH(1); } @@ -179,7 +180,7 @@ inp -= CH( 4 * _fsize ); inp += CH( filter->incr[pos] ); outp += CH(1); - pos = ( pos + 1 ) % filter->denominator; + pos = ( pos + 1 ) % filter->ratio.denominator; } *cpos = pos;