From 432e2ecc137d4fb4d9f6ac87cbbc38830a1f3c2c Mon Sep 17 00:00:00 2001 From: Mohamed Tarek Date: Thu, 13 Aug 2009 20:38:59 +0000 Subject: Modify libatrac to use fixed-point arithmetic. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22298 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libatrac/atrac3.c | 208 ++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 120 deletions(-) (limited to 'apps/codecs/libatrac/atrac3.c') diff --git a/apps/codecs/libatrac/atrac3.c b/apps/codecs/libatrac/atrac3.c index a800511397..838bbca48a 100644 --- a/apps/codecs/libatrac/atrac3.c +++ b/apps/codecs/libatrac/atrac3.c @@ -38,7 +38,6 @@ #include "avcodec.h" #include "bitstream.h" -#include "dsputil.h" #include "bytestream.h" #include @@ -50,6 +49,10 @@ #include "../librm/rm.h" #include "atrac3data.h" +#include "atrac3data_fixed.h" +#include "fixp_math.h" +//#include "fixp_mdct.h" +#include "../lib/mdct2.h" #define JOINT_STEREO 0x12 #define STEREO 0x2 @@ -70,23 +73,23 @@ typedef struct { typedef struct { int pos; int numCoefs; - float coef[8]; + int32_t coef[8]; } tonal_component; typedef struct { int bandsCoded; int numComponents; tonal_component components[64]; - float prevFrame[1024]; + int32_t prevFrame[1024]; int gcBlkSwitch; gain_block gainBlock[2]; - DECLARE_ALIGNED_16(float, spectrum[1024]); - DECLARE_ALIGNED_16(float, IMDCT_buf[1024]); + int32_t spectrum[1024] __attribute__((aligned(16))); + int32_t IMDCT_buf[1024] __attribute__((aligned(16))); - float delayBuf1[46]; ///num_gain_data == 0) - gain1 = 1.0; + gain1 = ONE_16; else gain1 = gain_tab1[pGain2->levcode[0]]; if (pGain1->num_gain_data == 0) { for (cnt = 0; cnt < 256; cnt++) - pOut[cnt] = pIn[cnt] * gain1 + pPrev[cnt]; + pOut[cnt] = fixmul16(pIn[cnt], gain1) + pPrev[cnt]; } else { numdata = pGain1->num_gain_data; pGain1->loccode[numdata] = 32; @@ -570,36 +553,38 @@ static void gainCompensateAndOverlap (float *pIn, float *pPrev, float *pOut, gai /* interpolate */ for (; nsample < startLoc; nsample++) - pOut[nsample] = (pIn[nsample] * gain1 + pPrev[nsample]) * gain2; + pOut[nsample] = fixmul16((fixmul16(pIn[nsample], gain1) + pPrev[nsample]), gain2); /* interpolation is done over eight samples */ for (; nsample < endLoc; nsample++) { - pOut[nsample] = (pIn[nsample] * gain1 + pPrev[nsample]) * gain2; - gain2 *= gain_inc; + pOut[nsample] = fixmul16((fixmul16(pIn[nsample], gain1) + pPrev[nsample]),gain2); + gain2 = fixmul16(gain2, gain_inc); } } for (; nsample < 256; nsample++) - pOut[nsample] = (pIn[nsample] * gain1) + pPrev[nsample]; + pOut[nsample] = fixmul16(pIn[nsample], gain1) + pPrev[nsample]; } /* Delay for the overlapping part. */ - memcpy(pPrev, &pIn[256], 256*sizeof(float)); + memcpy(pPrev, &pIn[256], 256*sizeof(int32_t)); } /** * Combine the tonal band spectrum and regular band spectrum * Return position of the last tonal coefficient + * * @param pSpectrum output spectrum buffer * @param numComponents amount of tonal components * @param pComponent tonal components for this band */ -static int addTonalComponents (float *pSpectrum, int numComponents, tonal_component *pComponent) +static int addTonalComponents (int32_t *pSpectrum, int numComponents, tonal_component *pComponent) { int cnt, i, lastPos = -1; - float *pIn, *pOut; + int32_t *pOut; + int32_t *pIn; for (cnt = 0; cnt < numComponents; cnt++){ lastPos = FFMAX(pComponent[cnt].pos + pComponent[cnt].numCoefs, lastPos); @@ -614,13 +599,13 @@ static int addTonalComponents (float *pSpectrum, int numComponents, tonal_compon } -#define INTERPOLATE(old,new,nsample) ((old) + (nsample)*0.125*((new)-(old))) +#define INTERPOLATE(old,new,nsample) ((old*ONE_16) + fixmul16(((nsample*ONE_16)>>3), (((new) - (old))*ONE_16))) -static void reverseMatrixing(float *su1, float *su2, int *pPrevCode, int *pCurrCode) +static void reverseMatrixing(int32_t *su1, int32_t *su2, int *pPrevCode, int *pCurrCode) { int i, band, nsample, s1, s2; - float c1, c2; - float mc1_l, mc1_r, mc2_l, mc2_r; + int32_t c1, c2; + int32_t mc1_l, mc1_r, mc2_l, mc2_r; for (i=0,band = 0; band < 4*256; band+=256,i++) { s1 = pPrevCode[i]; @@ -629,18 +614,18 @@ static void reverseMatrixing(float *su1, float *su2, int *pPrevCode, int *pCurrC if (s1 != s2) { /* Selector value changed, interpolation needed. */ - mc1_l = matrixCoeffs[s1*2]; - mc1_r = matrixCoeffs[s1*2+1]; - mc2_l = matrixCoeffs[s2*2]; - mc2_r = matrixCoeffs[s2*2+1]; + mc1_l = matrixCoeffs_fix[s1<<1]; + mc1_r = matrixCoeffs_fix[(s1<<1)+1]; + mc2_l = matrixCoeffs_fix[s2<<1]; + mc2_r = matrixCoeffs_fix[(s2<<1)+1]; /* Interpolation is done over the first eight samples. */ for(; nsample < 8; nsample++) { c1 = su1[band+nsample]; c2 = su2[band+nsample]; - c2 = c1 * INTERPOLATE(mc1_l,mc2_l,nsample) + c2 * INTERPOLATE(mc1_r,mc2_r,nsample); + c2 = fixmul16(c1, INTERPOLATE(mc1_l, mc2_l, nsample)) + fixmul16(c2, INTERPOLATE(mc1_r, mc2_r, nsample)); su1[band+nsample] = c2; - su2[band+nsample] = c1 * 2.0 - c2; + su2[band+nsample] = (c1 << 1) - c2; } } @@ -650,8 +635,8 @@ static void reverseMatrixing(float *su1, float *su2, int *pPrevCode, int *pCurrC for (; nsample < 256; nsample++) { c1 = su1[band+nsample]; c2 = su2[band+nsample]; - su1[band+nsample] = c2 * 2.0; - su2[band+nsample] = (c1 - c2) * 2.0; + su1[band+nsample] = c2 << 1; + su2[band+nsample] = (c1 - c2) << 1; } break; @@ -659,8 +644,8 @@ static void reverseMatrixing(float *su1, float *su2, int *pPrevCode, int *pCurrC for (; nsample < 256; nsample++) { c1 = su1[band+nsample]; c2 = su2[band+nsample]; - su1[band+nsample] = (c1 + c2) * 2.0; - su2[band+nsample] = c2 * -2.0; + su1[band+nsample] = (c1 + c2) << 1; + su2[band+nsample] = -1*(c2 << 1); } break; case 2: @@ -678,24 +663,23 @@ static void reverseMatrixing(float *su1, float *su2, int *pPrevCode, int *pCurrC } } -static void getChannelWeights (int indx, int flag, float ch[2]){ - +static void getChannelWeights (int indx, int flag, int32_t ch[2]){ if (indx == 7) { - ch[0] = 1.0; - ch[1] = 1.0; + ch[0] = ONE_16; + ch[1] = ONE_16; } else { - ch[0] = (float)(indx & 7) / 7.0; - ch[1] = sqrt(2 - ch[0]*ch[0]); + ch[0] = fixdiv16(((indx & 7)*ONE_16), 7*ONE_16); + ch[1] = fastSqrt((ONE_16 << 1) - fixmul16(ch[0], ch[0])); if(flag) - FFSWAP(float, ch[0], ch[1]); + FFSWAP(int32_t, ch[0], ch[1]); } } -static void channelWeighting (float *su1, float *su2, int *p3) +static void channelWeighting (int32_t *su1, int32_t *su2, int *p3) { int band, nsample; /* w[x][y] y=0 is left y=1 is right */ - float w[2][2]; + int32_t w[2][2]; if (p3[1] != 7 || p3[3] != 7){ getChannelWeights(p3[1], p3[0], w[0]); @@ -704,13 +688,13 @@ static void channelWeighting (float *su1, float *su2, int *p3) for(band = 1; band < 4; band++) { /* scale the channels by the weights */ for(nsample = 0; nsample < 8; nsample++) { - su1[band*256+nsample] *= INTERPOLATE(w[0][0], w[0][1], nsample); - su2[band*256+nsample] *= INTERPOLATE(w[1][0], w[1][1], nsample); + su1[band*256+nsample] = fixmul16(su1[band*256+nsample], INTERPOLATE(w[0][0], w[0][1], nsample)); + su2[band*256+nsample] = fixmul16(su2[band*256+nsample], INTERPOLATE(w[1][0], w[1][1], nsample)); } for(; nsample < 256; nsample++) { - su1[band*256+nsample] *= w[1][0]; - su2[band*256+nsample] *= w[1][1]; + su1[band*256+nsample] = fixmul16(su1[band*256+nsample], w[1][0]); + su2[band*256+nsample] = fixmul16(su2[band*256+nsample], w[1][1]); } } } @@ -728,10 +712,9 @@ static void channelWeighting (float *su1, float *su2, int *p3) */ -static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_unit *pSnd, float *pOut, int channelNum, int codingMode) +static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_unit *pSnd, int32_t *pOut, int channelNum, int codingMode) { int band, result=0, numSubbands, lastTonal, numBands; - if (codingMode == JOINT_STEREO && channelNum == 1) { if (get_bits(gb,2) != 3) { av_log(NULL,AV_LOG_ERROR,"JS mono Sound Unit id != 3.\n"); @@ -771,7 +754,7 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_ if (band <= numBands) { IMLT(&(pSnd->spectrum[band*256]), pSnd->IMDCT_buf, band&1); } else - memset(pSnd->IMDCT_buf, 0, 512 * sizeof(float)); + memset(pSnd->IMDCT_buf, 0, 512 * sizeof(int32_t)); /* gain compensation and overlapping */ gainCompensateAndOverlap (pSnd->IMDCT_buf, &(pSnd->prevFrame[band*256]), &(pOut[band*256]), @@ -795,7 +778,7 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf) { int result, i; - float *p1, *p2, *p3, *p4; + int32_t *p1, *p2, *p3, *p4; uint8_t *ptr1; if (q->codingMode == JOINT_STEREO) { @@ -893,7 +876,6 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf) static int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q, void *data, int *data_size, const uint8_t *buf, int buf_size) { - //ATRAC3Context *q = rmctx->priv_data; int result = 0, i; const uint8_t* databuf; int16_t* samples = data; @@ -919,13 +901,13 @@ static int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q, if (q->channels == 1) { /* mono */ for (i = 0; i<1024; i++) - samples[i] = av_clip_int16(round(q->outSamples[i])); + samples[i] = av_clip_int16(q->outSamples[i]); *data_size = 1024 * sizeof(int16_t); } else { /* stereo */ for (i = 0; i < 1024; i++) { - samples[i*2] = av_clip_int16(round(q->outSamples[i])); - samples[i*2+1] = av_clip_int16(round(q->outSamples[1024+i])); + samples[i*2] = av_clip_int16(q->outSamples[i]); + samples[i*2+1] = av_clip_int16(q->outSamples[1024+i]); } *data_size = 2048 * sizeof(int16_t); } @@ -944,7 +926,6 @@ static av_cold int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx) { int i; const uint8_t *edata_ptr = rmctx->codec_extradata; - //ATRAC3Context *q = rmctx->priv_data; static VLC_TYPE atrac3_vlc_table[4096][2]; static int vlcs_initialized = 0; @@ -1051,17 +1032,6 @@ static av_cold int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx) init_atrac3_transforms(q); - /* Generate the scale factors. */ - for (i=0 ; i<64 ; i++) - SFTable[i] = pow(2.0, (i - 15) / 3.0); - - /* Generate gain tables. */ - for (i=0 ; i<16 ; i++) - gain_tab1[i] = powf (2.0, (4 - i)); - - for (i=-15 ; i<16 ; i++) - gain_tab2[i+15] = powf (2.0, i * -0.125); - /* init the joint-stereo decoding data */ q->weighting_delay[0] = 0; q->weighting_delay[1] = 7; @@ -1076,8 +1046,6 @@ static av_cold int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx) q->matrix_coeff_index_next[i] = 3; } - dsputil_init(&dsp); - q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels); if (!q->pUnits) { av_free(q->decoded_bytes_buffer); -- cgit v1.2.3