diff options
author | Siarhei Siamashka <siarhei.siamashka@nokia.com> | 2009-01-04 03:11:12 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-01-06 03:39:27 +0100 |
commit | 365f92ed452f021d4f372220d1e8ea5076dda81a (patch) | |
tree | 98109b9756dd60dc6e64a42030652d6eda83e0ed | |
parent | fb333f1c88df9c50529a390297565a6627bcf7ad (diff) |
Use of constant shift in SBC quantization code to make it faster
The result of 32x32->64 unsigned long multiplication is returned
in two registers (high and low 32-bit parts) for many 32-bit
architectures. For these architectures constant right shift by
32 bits is optimized out by the compiler to just taking the high
32-bit part. Also some data needed at the quantization stage is
precalculated beforehand to improve performance.
-rw-r--r-- | sbc/sbc.c | 23 |
1 files changed, 13 insertions, 10 deletions
@@ -880,11 +880,12 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int crc_pos = 0; - uint16_t audio_sample; + uint32_t audio_sample; int ch, sb, blk; /* channel, subband, block and bit counters */ int bits[2][8]; /* bits distribution */ - int levels[2][8]; /* levels are derived from that */ + uint32_t levels[2][8]; /* levels are derived from that */ + uint32_t sb_sample_delta[2][8]; u_int32_t scalefactor[2][8]; /* derived from frame->scale_factor */ @@ -1017,8 +1018,14 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) sbc_calculate_bits(frame, bits); for (ch = 0; ch < frame->channels; ch++) { - for (sb = 0; sb < frame->subbands; sb++) - levels[ch][sb] = (1 << bits[ch][sb]) - 1; + for (sb = 0; sb < frame->subbands; sb++) { + levels[ch][sb] = ((1 << bits[ch][sb]) - 1) << + (32 - (frame->scale_factor[ch][sb] + + SCALE_OUT_BITS + 2)); + sb_sample_delta[ch][sb] = (uint32_t) 1 << + (frame->scale_factor[ch][sb] + + SCALE_OUT_BITS + 1); + } } for (blk = 0; blk < frame->blocks; blk++) { @@ -1029,12 +1036,8 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) continue; audio_sample = ((uint64_t) levels[ch][sb] * - (((uint32_t) 1 << - (frame->scale_factor[ch][sb] + - SCALE_OUT_BITS + 1)) + - frame->sb_sample_f[blk][ch][sb])) >> - (frame->scale_factor[ch][sb] + - SCALE_OUT_BITS + 2); + (sb_sample_delta[ch][sb] + + frame->sb_sample_f[blk][ch][sb])) >> 32; PUT_BITS(audio_sample, bits[ch][sb]); } |