Mercurial > SDL_sound_CoreAudio
diff alt_audio_convert.c @ 403:b1e511c879d1
More altcvt updates and fixes from Frank.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 13 Jul 2002 23:41:08 +0000 |
parents | 44ed8bdeba74 |
children | 5b8a07b5162e |
line wrap: on
line diff
--- a/alt_audio_convert.c Fri Jul 12 23:17:23 2002 +0000 +++ b/alt_audio_convert.c Sat Jul 13 23:41:08 2002 +0000 @@ -1,4 +1,4 @@ -/* +/* * Extended Audio Converter for SDL (Simple DirectMedia Layer) * Copyright (C) 2002 Frank Ranostaj * Institute of Applied Physik @@ -43,13 +43,14 @@ #endif -/* some macros for "parsing" format */ +/* 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) /*-------------------------------------------------------------------------*/ @@ -100,10 +101,17 @@ { Sint16 inbuffer[24*_fsize]; Sint16 *finp, *cinp, *linp; + int flength, clength, llength; Sint16 *buffer; - int flength, clength, llength; + VarFilter *filter; } RateConverterBuffer; +typedef struct +{ + Sint16 carry; + Sint16 pos; +} RateAux; + /* Mono (1 channel ) */ #define Suffix(x) x##1 @@ -125,13 +133,18 @@ /* Make sure there's a converter */ if( Data == NULL ) { - SDL_SetError("No converter given"); + SDL_SetError("altcvt: No converter given"); return(-1); } /* Make sure there's data to convert */ if( buffer == NULL ) { - SDL_SetError("No buffer allocated for conversion"); + SDL_SetError("altcvt: No buffer allocated for conversion"); + return(-1); + } + + if( length < 0 ) { + SDL_SetError("altcvt: Length < 0"); return(-1); } @@ -150,20 +163,18 @@ { int length; /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ - length = ConvertAudio( Data, Data->buf, Data->len, 12 ); + length = ConvertAudio( Data, Data->buf, Data->len, 0 ); Data->len_cvt = length; return length; } - /*-------------------------------------------------------------------------*/ 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 - 1; i >= 0; 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; } @@ -171,9 +182,9 @@ static int expand8BitTo16BitWrong( AdapterC Data, int length ) { int i; - Uint8* inp = Data.buffer; - Uint16* buffer = (Uint16*)Data.buffer; - for( i = length - 1; i >= 0; i--) + Uint8* inp = Data.buffer - 1; + Uint16* buffer = (Uint16*)Data.buffer - 1; + for( i = length + 1; --i; ) buffer[i] = inp[i]; return 2*length; } @@ -182,9 +193,9 @@ static int expand16BitToFloat( AdapterC Data, int length ) { int i; - Sint16* inp = (Sint16*)Data.buffer; - float* buffer = (float*)Data.buffer; - for( i = length>>1 - 1; i >= 0; 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; } @@ -202,8 +213,8 @@ int i; Uint16 a,b; - Uint16* buffer = (Uint16*) Data.buffer; - for( i = length>>1; i >= 0; i-- ) + Uint16* buffer = (Uint16*) Data.buffer - 1; + for( i = length>>1 + 1; --i; ) { a = b = buffer[i]; buffer[i] = ( a << 8 ) | ( b >> 8 ); @@ -231,27 +242,25 @@ } /*-------------------------------------------------------------------------*/ -static int cut16BitSysTo8Bit( AdapterC Data, int length ) +static int cut16BitTo8Bit( AdapterC Data, int length, int off ) { int i; - Uint16* inp = (Uint16*) Data.buffer; + Uint8* inp = Data.buffer + off; Uint8* buffer = Data.buffer; length >>= 1; - /* !!! FIXME: Get rid of the >>8 */ for( i = 0; i < length; i++ ) - buffer[i] = inp[i]>>8; + 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 ) { - int i; - Uint16* inp = (Uint16*) Data.buffer; - Uint8* buffer = Data.buffer; - length >>= 1; - for( i = 0; i < length; i++ ) - buffer[i] = inp[i]; - return length; + return cut16BitTo8Bit( Data, length, 1-SDL_MSB_POSITION_IN_SHORT ); } /*-------------------------------------------------------------------------*/ @@ -259,8 +268,8 @@ static int changeSigned( AdapterC Data, int length, Uint32 XOR ) { int i; - Uint32* buffer = (Uint32*) Data.buffer; - for( i = ( length - 1 ) >> 2; i >= 0; i-- ) + Uint32* buffer = (Uint32*) Data.buffer - 1; + for( i = ( length + 7 ) >> 2; --i; ) buffer[i] ^= XOR; return length; } @@ -329,9 +338,9 @@ static int convertMonoToStereo16Bit( AdapterC Data, int length ) { int i; - Uint16* buffer = (Uint16*) Data.buffer; + Uint16* buffer = (Uint16*)Data.buffer - 1; Uint16* dst = (Uint16*)Data.buffer + length - 2; - for( i = length>>1 - 1; i >= 0; i--, dst-=2 ) + for( i = length>>1 + 1; --i; dst-=2 ) dst[0] = dst[1] = buffer[i]; return 2*length; } @@ -339,9 +348,9 @@ static int convertMonoToStereo8Bit( AdapterC Data, int length ) { int i; - Uint8* buffer = Data.buffer; - Uint8* dst = (Uint8*)Data.buffer + length - 2; - for( i = length - 1; i >= 0; i--, dst-=2 ) + Uint8* buffer = Data.buffer - 1; + Uint8* dst = Data.buffer + length - 2; + for( i = length + 1; --i; dst-=2 ) dst[0] = dst[1] = buffer[i]; return 2*length; } @@ -351,20 +360,12 @@ { int i; Sint16* buffer = (Sint16*) Data.buffer; - for(i = length>>1 - 1; i >= 0; i-- ) - buffer[i]= (38084 * (int)buffer[i]) >> 16; + for(i = length>>1 + 1; --i; ) + buffer[i] = (38084 * (int)buffer[i]) >> 16; return length; } /*-------------------------------------------------------------------------*/ -enum RateConverterType{ - dcrsRate = -1, - incrsRate = 0, - hlfRate = 1, - dblRate = 2 -}; - - const Fraction Half = {1, 2}; const Fraction Double = {2, 1}; @@ -427,20 +428,18 @@ } static void initRateConverterBuffer( RateConverterBuffer *rcb, - AdapterC* Data, int length, enum RateConverterType typ ) + AdapterC* Data, int length, Fraction ratio ) { - int size, minsize, dir; - Fraction Ratio[] = { {0,0}, {2,1}, {1,2} }; - - Ratio[incrsRate] = Data->filter->ratio; - dir = ~typ&1; + 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[typ], dir ); + initLoopBuffer( rcb, length, ratio, dir ); else - initStraigthBuffer( rcb, length, Ratio[typ], dir ); + initStraigthBuffer( rcb, length, ratio, dir ); } static void nextRateConverterBuffer( RateConverterBuffer *rcb ) @@ -451,94 +450,88 @@ rcb->linp++; } -typedef Sint16* (*RateConverter)( Sint16*, Sint16*, int, VarFilter*, int*); -static int doRateConversion( RateConverterBuffer* rcb, - RateConverter ffp, VarFilter* filter ) +typedef Sint16* (*RateConverter)( Sint16*, Sint16*, int, + VarFilter*, RateAux* ); + +static int doRateConversion( RateConverterBuffer* rcb, RateConverter ffp ) { - int pos = 0; - Sint16 *outp; - outp = rcb->buffer; + RateAux aux = {0,0}; + Sint16 *outp = rcb->buffer; + VarFilter* filter = rcb->filter; - outp = (*ffp)( outp, rcb->finp, rcb->flength, filter, &pos ); - outp = (*ffp)( outp, rcb->cinp, rcb->clength, filter, &pos ); - outp = (*ffp)( outp, rcb->linp, rcb->llength, filter, &pos ); + 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 ); } /*-------------------------------------------------------------------------*/ - /* - * !!! FIXME !!! - * - * The doubleRate filter is half as large as the halfRate one! Frank - */ - - static int doubleRateMono( AdapterC Data, int length ) { RateConverterBuffer rcb; - initRateConverterBuffer( &rcb, &Data, length, dblRate ); - return doRateConversion( &rcb, doubleRate1, NULL ); + initRateConverterBuffer( &rcb, &Data, length, Double ); + return doRateConversion( &rcb, doubleRate1 ); } static int doubleRateStereo( AdapterC Data, int length ) { RateConverterBuffer rcb; - initRateConverterBuffer( &rcb, &Data, length, dblRate ); - doRateConversion( &rcb, doubleRate2, NULL ); + initRateConverterBuffer( &rcb, &Data, length, Double ); + doRateConversion( &rcb, doubleRate2 ); nextRateConverterBuffer( &rcb ); - return 2 + doRateConversion( &rcb, doubleRate2, NULL ); + return 2 + doRateConversion( &rcb, doubleRate2 ); } /*-------------------------------------------------------------------------*/ static int halfRateMono( AdapterC Data, int length ) { RateConverterBuffer rcb; - initRateConverterBuffer( &rcb, &Data, length, hlfRate ); - return doRateConversion( &rcb, halfRate1, NULL ); + initRateConverterBuffer( &rcb, &Data, length, Half ); + return doRateConversion( &rcb, halfRate1 ); } static int halfRateStereo( AdapterC Data, int length ) { RateConverterBuffer rcb; - initRateConverterBuffer( &rcb, &Data, length, hlfRate ); - doRateConversion( &rcb, halfRate2, NULL ); + initRateConverterBuffer( &rcb, &Data, length, Half ); + doRateConversion( &rcb, halfRate2 ); nextRateConverterBuffer( &rcb ); - return 2 + doRateConversion( &rcb, halfRate2, NULL ); + return 2 + doRateConversion( &rcb, halfRate2 ); } /*-------------------------------------------------------------------------*/ static int increaseRateMono( AdapterC Data, int length ) { RateConverterBuffer rcb; - initRateConverterBuffer( &rcb, &Data, length, incrsRate ); - return doRateConversion( &rcb, increaseRate1, Data.filter ); + initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); + return doRateConversion( &rcb, increaseRate1 ); } static int increaseRateStereo( AdapterC Data, int length ) { RateConverterBuffer rcb; - initRateConverterBuffer( &rcb, &Data, length, incrsRate ); - doRateConversion( &rcb, increaseRate2, Data.filter ); + initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); + doRateConversion( &rcb, increaseRate2 ); nextRateConverterBuffer( &rcb ); - return 2 + doRateConversion( &rcb, increaseRate2, Data.filter ); + return 2 + doRateConversion( &rcb, increaseRate2 ); } /*-------------------------------------------------------------------------*/ static int decreaseRateMono( AdapterC Data, int length ) { RateConverterBuffer rcb; - initRateConverterBuffer( &rcb, &Data, length, dcrsRate ); - return doRateConversion( &rcb, decreaseRate1, Data.filter ); + initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); + return doRateConversion( &rcb, decreaseRate1 ); } static int decreaseRateStereo( AdapterC Data, int length ) { RateConverterBuffer rcb; - initRateConverterBuffer( &rcb, &Data, length, dcrsRate ); - doRateConversion( &rcb, decreaseRate2, Data.filter ); + initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); + doRateConversion( &rcb, decreaseRate2 ); nextRateConverterBuffer( &rcb ); - return doRateConversion( &rcb, decreaseRate2, Data.filter ); + return 2 + doRateConversion( &rcb, decreaseRate2 ); } /*-------------------------------------------------------------------------*/ @@ -583,7 +576,7 @@ 9, 11, 13, 15 }; /* /16 */ - Fraction Result = {0,0}; + Fraction Result = {0,0}; int i,num,den=1; float RelErr, BestErr = 0; @@ -697,13 +690,14 @@ const Adapter decreaseRate[2] = { decreaseRateMono, decreaseRateStereo }; static void createRateConverter( Sound_AudioCVT *Data, int* fip, - int SrcRate, int DestRate, int Channel ) + int SrcRate, int DestRate, int channel ) { - Fraction f; + const int c = channel - 1; + const int size = 16 * channel * _fsize; int filter_index = *fip; int VarPos = 0; float Ratio = DestRate; - int c = Channel - 1; + Fraction f; *fip = -1; @@ -720,27 +714,27 @@ { Ratio /= 2.; Data->adapter[filter_index++] = doubleRate[c]; - adjustSize( Data, _fsize, Double ); + adjustSize( Data, size, Double ); } while( Ratio < 31./64. ) { Ratio *= 2; Data->adapter[filter_index++] = halfRate[c]; - adjustSize( Data, _fsize, Half ); + adjustSize( Data, size, Half ); } if( Ratio > 1. ) { Data->adapter[VarPos] = increaseRate[c]; f = setupVarFilter( &Data->filter, Ratio ); - adjustSize( Data, _fsize, f ); + adjustSize( Data, size, f ); } else { Data->adapter[filter_index++] = decreaseRate[c]; f = setupVarFilter( &Data->filter, Ratio ); - adjustSize( Data, _fsize, f ); + adjustSize( Data, size, f ); } *fip = filter_index; }