diff options
author | Mohamed Tarek <mt@rockbox.org> | 2010-07-05 22:33:37 +0000 |
---|---|---|
committer | Mohamed Tarek <mt@rockbox.org> | 2010-07-05 22:33:37 +0000 |
commit | d884af2b9992f12e98a3e8548aff76b232b5bfb3 (patch) | |
tree | d3aefbc2195382025105b252c16b00087778beed /apps/codecs/libwmapro/wmaprodec.c | |
parent | 6a04479d63dd4d7dfc54849e4c925d360d55fa9c (diff) | |
download | rockbox-d884af2b9992f12e98a3e8548aff76b232b5bfb3.tar.gz rockbox-d884af2b9992f12e98a3e8548aff76b232b5bfb3.zip |
Partial conversion of the wmapro decoder to fixed point arithmetic. Currently inverse quantization & rescaling,
imdct and windowing are all in fixed point.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27302 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwmapro/wmaprodec.c')
-rw-r--r-- | apps/codecs/libwmapro/wmaprodec.c | 89 |
1 files changed, 61 insertions, 28 deletions
diff --git a/apps/codecs/libwmapro/wmaprodec.c b/apps/codecs/libwmapro/wmaprodec.c index 9d9e2cbc61..5c72032fce 100644 --- a/apps/codecs/libwmapro/wmaprodec.c +++ b/apps/codecs/libwmapro/wmaprodec.c | |||
@@ -94,6 +94,12 @@ | |||
94 | #include "dsputil.h" | 94 | #include "dsputil.h" |
95 | #include "wma.h" | 95 | #include "wma.h" |
96 | #include "wmaprodec.h" | 96 | #include "wmaprodec.h" |
97 | #include "wmapro_mdct.h" | ||
98 | #include "mdct_tables.h" | ||
99 | #include "quant.h" | ||
100 | #include "types.h" | ||
101 | #include "wmapro_math.h" | ||
102 | #include "codecs.h" | ||
97 | 103 | ||
98 | /* Some defines to make it compile */ | 104 | /* Some defines to make it compile */ |
99 | #define AVERROR_INVALIDDATA -1 | 105 | #define AVERROR_INVALIDDATA -1 |
@@ -148,7 +154,9 @@ typedef struct { | |||
148 | int* scale_factors; ///< pointer to the scale factor values used for decoding | 154 | int* scale_factors; ///< pointer to the scale factor values used for decoding |
149 | uint8_t table_idx; ///< index in sf_offsets for the scale factor reference block | 155 | uint8_t table_idx; ///< index in sf_offsets for the scale factor reference block |
150 | float* coeffs; ///< pointer to the subframe decode buffer | 156 | float* coeffs; ///< pointer to the subframe decode buffer |
157 | FIXED* fixcoeffs; | ||
151 | DECLARE_ALIGNED(16, float, out)[WMAPRO_BLOCK_MAX_SIZE + WMAPRO_BLOCK_MAX_SIZE / 2]; ///< output buffer | 158 | DECLARE_ALIGNED(16, float, out)[WMAPRO_BLOCK_MAX_SIZE + WMAPRO_BLOCK_MAX_SIZE / 2]; ///< output buffer |
159 | DECLARE_ALIGNED(16, FIXED, fixout)[WMAPRO_BLOCK_MAX_SIZE + WMAPRO_BLOCK_MAX_SIZE / 2]; ///< output buffer | ||
152 | } WMAProChannelCtx; | 160 | } WMAProChannelCtx; |
153 | 161 | ||
154 | /** | 162 | /** |
@@ -174,6 +182,7 @@ typedef struct WMAProDecodeCtx { | |||
174 | PutBitContext pb; ///< context for filling the frame_data buffer | 182 | PutBitContext pb; ///< context for filling the frame_data buffer |
175 | FFTContext mdct_ctx[WMAPRO_BLOCK_SIZES]; ///< MDCT context per block size | 183 | FFTContext mdct_ctx[WMAPRO_BLOCK_SIZES]; ///< MDCT context per block size |
176 | DECLARE_ALIGNED(16, float, tmp)[WMAPRO_BLOCK_MAX_SIZE]; ///< IMDCT output buffer | 184 | DECLARE_ALIGNED(16, float, tmp)[WMAPRO_BLOCK_MAX_SIZE]; ///< IMDCT output buffer |
185 | DECLARE_ALIGNED(16, FIXED, fixtmp)[WMAPRO_BLOCK_MAX_SIZE]; ///< IMDCT output buffer | ||
177 | float* windows[WMAPRO_BLOCK_SIZES]; ///< windows for the different block sizes | 186 | float* windows[WMAPRO_BLOCK_SIZES]; ///< windows for the different block sizes |
178 | 187 | ||
179 | /* frame size dependent frame information (set during initialization) */ | 188 | /* frame size dependent frame information (set during initialization) */ |
@@ -208,8 +217,9 @@ typedef struct WMAProDecodeCtx { | |||
208 | uint32_t frame_num; ///< current frame number (not used for decoding) | 217 | uint32_t frame_num; ///< current frame number (not used for decoding) |
209 | GetBitContext gb; ///< bitstream reader context | 218 | GetBitContext gb; ///< bitstream reader context |
210 | int buf_bit_size; ///< buffer size in bits | 219 | int buf_bit_size; ///< buffer size in bits |
211 | float* samples; ///< current samplebuffer pointer | 220 | float* samplesf; ///< current samplebuffer pointer |
212 | float* samples_end; ///< maximum samplebuffer pointer | 221 | FIXED* samples; |
222 | FIXED* samples_end; ///< maximum samplebuffer pointer | ||
213 | uint8_t drc_gain; ///< gain for the DRC tool | 223 | uint8_t drc_gain; ///< gain for the DRC tool |
214 | int8_t skip_frame; ///< skip output step | 224 | int8_t skip_frame; ///< skip output step |
215 | int8_t parsed_all_subframes; ///< all subframes decoded? | 225 | int8_t parsed_all_subframes; ///< all subframes decoded? |
@@ -1023,22 +1033,30 @@ static void inverse_channel_transform(WMAProDecodeCtx *s) | |||
1023 | static void wmapro_window(WMAProDecodeCtx *s) | 1033 | static void wmapro_window(WMAProDecodeCtx *s) |
1024 | { | 1034 | { |
1025 | int i; | 1035 | int i; |
1036 | |||
1026 | for (i = 0; i < s->channels_for_cur_subframe; i++) { | 1037 | for (i = 0; i < s->channels_for_cur_subframe; i++) { |
1027 | int c = s->channel_indexes_for_cur_subframe[i]; | 1038 | int c = s->channel_indexes_for_cur_subframe[i]; |
1028 | float* window; | 1039 | FIXED* window; |
1040 | float* win2; | ||
1029 | int winlen = s->channel[c].prev_block_len; | 1041 | int winlen = s->channel[c].prev_block_len; |
1030 | float* start = s->channel[c].coeffs - (winlen >> 1); | 1042 | float* start = s->channel[c].coeffs - (winlen >> 1); |
1043 | FIXED *xstart= s->channel[c].fixcoeffs - (winlen >> 1); | ||
1044 | int j; | ||
1031 | 1045 | ||
1032 | if (s->subframe_len < winlen) { | 1046 | if (s->subframe_len < winlen) { |
1033 | start += (winlen - s->subframe_len) >> 1; | 1047 | start += (winlen - s->subframe_len) >> 1; |
1048 | xstart += (winlen - s->subframe_len) >> 1; | ||
1034 | winlen = s->subframe_len; | 1049 | winlen = s->subframe_len; |
1035 | } | 1050 | } |
1036 | 1051 | ||
1037 | window = s->windows[av_log2(winlen) - BLOCK_MIN_BITS]; | 1052 | window = sine_windows[av_log2(winlen) - BLOCK_MIN_BITS]; |
1038 | 1053 | win2 = s->windows[av_log2(winlen) - BLOCK_MIN_BITS]; | |
1054 | |||
1039 | winlen >>= 1; | 1055 | winlen >>= 1; |
1040 | 1056 | ||
1041 | s->dsp.vector_fmul_window(start, start, start + winlen, | 1057 | s->dsp.vector_fmul_window(start, start, start + winlen, |
1058 | win2, 0, winlen); | ||
1059 | vector_fixmul_window(xstart, xstart, xstart + winlen, | ||
1042 | window, 0, winlen); | 1060 | window, 0, winlen); |
1043 | 1061 | ||
1044 | s->channel[c].prev_block_len = s->subframe_len; | 1062 | s->channel[c].prev_block_len = s->subframe_len; |
@@ -1116,6 +1134,8 @@ static int decode_subframe(WMAProDecodeCtx *s) | |||
1116 | 1134 | ||
1117 | s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) | 1135 | s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) |
1118 | + offset]; | 1136 | + offset]; |
1137 | s->channel[c].fixcoeffs = &s->channel[c].fixout[(s->samples_per_frame >> 1) | ||
1138 | + offset]; | ||
1119 | } | 1139 | } |
1120 | 1140 | ||
1121 | s->subframe_len = subframe_len; | 1141 | s->subframe_len = subframe_len; |
@@ -1228,10 +1248,12 @@ static int decode_subframe(WMAProDecodeCtx *s) | |||
1228 | const int* sf = s->channel[c].scale_factors; | 1248 | const int* sf = s->channel[c].scale_factors; |
1229 | int b; | 1249 | int b; |
1230 | 1250 | ||
1231 | if (c == s->lfe_channel) | 1251 | if (c == s->lfe_channel){ |
1232 | memset(&s->tmp[cur_subwoofer_cutoff], 0, sizeof(*s->tmp) * | 1252 | memset(&s->tmp[cur_subwoofer_cutoff], 0, sizeof(*s->tmp) * |
1233 | (subframe_len - cur_subwoofer_cutoff)); | 1253 | (subframe_len - cur_subwoofer_cutoff)); |
1234 | 1254 | memset(&s->fixtmp[cur_subwoofer_cutoff], 0, sizeof(*s->fixtmp) * | |
1255 | (subframe_len - cur_subwoofer_cutoff)); | ||
1256 | } | ||
1235 | /** inverse quantization and rescaling */ | 1257 | /** inverse quantization and rescaling */ |
1236 | for (b = 0; b < s->num_bands; b++) { | 1258 | for (b = 0; b < s->num_bands; b++) { |
1237 | const int end = FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len); | 1259 | const int end = FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len); |
@@ -1239,21 +1261,42 @@ static int decode_subframe(WMAProDecodeCtx *s) | |||
1239 | (s->channel[c].max_scale_factor - *sf++) * | 1261 | (s->channel[c].max_scale_factor - *sf++) * |
1240 | s->channel[c].scale_factor_step; | 1262 | s->channel[c].scale_factor_step; |
1241 | const float quant = pow(10.0, exp / 20.0); | 1263 | const float quant = pow(10.0, exp / 20.0); |
1264 | |||
1265 | if(exp < EXP_MIN || exp > EXP_MAX) { | ||
1266 | LOGF("in wmaprodec.c : unhandled value for exp, please report sample.\n"); | ||
1267 | return -1; | ||
1268 | } | ||
1269 | const FIXED fixquant = QUANT(exp); | ||
1242 | int start = s->cur_sfb_offsets[b]; | 1270 | int start = s->cur_sfb_offsets[b]; |
1271 | |||
1272 | int j; | ||
1273 | for(j = 0; j < WMAPRO_BLOCK_MAX_SIZE + WMAPRO_BLOCK_MAX_SIZE/2; j++) | ||
1274 | s->channel[c].fixout[j] = ftofix16(s->channel[c].out[j]); | ||
1275 | |||
1243 | s->dsp.vector_fmul_scalar(s->tmp + start, | 1276 | s->dsp.vector_fmul_scalar(s->tmp + start, |
1244 | s->channel[c].coeffs + start, | 1277 | s->channel[c].coeffs + start, |
1245 | quant, end - start); | 1278 | quant, end - start); |
1279 | vector_fixmul_scalar(s->fixtmp+start, | ||
1280 | s->channel[c].fixcoeffs + start, | ||
1281 | fixquant, end-start); | ||
1282 | |||
1246 | } | 1283 | } |
1284 | |||
1285 | int j; | ||
1247 | 1286 | ||
1248 | /** apply imdct (ff_imdct_half == DCTIV with reverse) */ | 1287 | /** apply imdct (ff_imdct_half == DCTIV with reverse) */ |
1249 | ff_imdct_half(&s->mdct_ctx[av_log2(subframe_len) - BLOCK_MIN_BITS], | 1288 | fff_imdct_half(&s->mdct_ctx[av_log2(subframe_len) - BLOCK_MIN_BITS], |
1250 | s->channel[c].coeffs, s->tmp); | 1289 | s->channel[c].coeffs, s->tmp); |
1290 | imdct_half((s->mdct_ctx[av_log2(subframe_len) - BLOCK_MIN_BITS]).mdct_bits, | ||
1291 | s->channel[c].fixcoeffs, s->fixtmp); | ||
1292 | |||
1251 | } | 1293 | } |
1252 | } | 1294 | } |
1253 | 1295 | ||
1254 | /** window and overlapp-add */ | 1296 | /** window and overlapp-add */ |
1255 | wmapro_window(s); | 1297 | wmapro_window(s); |
1256 | 1298 | ||
1299 | |||
1257 | /** handled one subframe */ | 1300 | /** handled one subframe */ |
1258 | for (i = 0; i < s->channels_for_cur_subframe; i++) { | 1301 | for (i = 0; i < s->channels_for_cur_subframe; i++) { |
1259 | int c = s->channel_indexes_for_cur_subframe[i]; | 1302 | int c = s->channel_indexes_for_cur_subframe[i]; |
@@ -1354,13 +1397,17 @@ static int decode_frame(WMAProDecodeCtx *s) | |||
1354 | 1397 | ||
1355 | /** interleave samples and write them to the output buffer */ | 1398 | /** interleave samples and write them to the output buffer */ |
1356 | for (i = 0; i < s->num_channels; i++) { | 1399 | for (i = 0; i < s->num_channels; i++) { |
1357 | float* ptr = s->samples + i; | 1400 | FIXED* ptr = s->samples + i; |
1401 | float* fptr = s->samplesf + i; | ||
1358 | int incr = s->num_channels; | 1402 | int incr = s->num_channels; |
1359 | float* iptr = s->channel[i].out; | 1403 | FIXED* iptr = s->channel[i].fixout; |
1360 | float* iend = iptr + s->samples_per_frame; | 1404 | float* fiptr = s->channel[i].out; |
1361 | 1405 | FIXED* iend = iptr + s->samples_per_frame; | |
1406 | float* fiend = fiptr + s->samples_per_frame; | ||
1407 | int j; | ||
1408 | |||
1362 | while (iptr < iend) { | 1409 | while (iptr < iend) { |
1363 | *ptr = av_clipf(*iptr++, -1.0, 32767.0 / 32768.0); | 1410 | *ptr = *iptr++ << 1; |
1364 | ptr += incr; | 1411 | ptr += incr; |
1365 | } | 1412 | } |
1366 | 1413 | ||
@@ -1548,20 +1595,6 @@ int decode_packet(AVCodecContext *avctx, | |||
1548 | *data_size = (int8_t *)s->samples - (int8_t *)data; | 1595 | *data_size = (int8_t *)s->samples - (int8_t *)data; |
1549 | s->packet_offset = get_bits_count(gb) & 7; | 1596 | s->packet_offset = get_bits_count(gb) & 7; |
1550 | 1597 | ||
1551 | /* Convert the pcm samples to signed 16-bit integers. This is the format that | ||
1552 | * the rockbox simulator works with. */ | ||
1553 | #ifdef ROCKBOX | ||
1554 | float* fptr = data; | ||
1555 | int32_t* ptr = data; | ||
1556 | int x; | ||
1557 | for(x = 0; x < *data_size; x++) | ||
1558 | { | ||
1559 | fptr[x] *= ((float)(INT32_MAX)); | ||
1560 | ptr[x] = (int32_t)fptr[x]; | ||
1561 | |||
1562 | } | ||
1563 | #endif | ||
1564 | |||
1565 | return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3; | 1598 | return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3; |
1566 | } | 1599 | } |
1567 | 1600 | ||