diff options
author | Siarhei Siamashka <siarhei.siamashka@nokia.com> | 2009-01-29 02:17:36 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-01-29 08:25:50 +0100 |
commit | a563c8ed5a5d5004f4270dd8836f4257c1da2fe8 (patch) | |
tree | 520ed16c174f1cab6fc0749b267e5044b9a74e7d /sbc/sbc.c | |
parent | 85ad02b73626ee5caca6adb6e2890a7a588ecb38 (diff) |
SBC encoder scale factors calculation optimized with __builtin_clz
Count leading zeros operation is often implemented using a special
instruction for it on various architectures (at least this is true
for ARM and x86). Using __builtin_clz gcc intrinsic allows to
eliminate innermost loop in scale factors calculation and improve
performance. Also scale factors calculation can be optimized even
more using SIMD instructions.
Diffstat (limited to 'sbc/sbc.c')
-rw-r--r-- | sbc/sbc.c | 21 |
1 files changed, 5 insertions, 16 deletions
@@ -77,7 +77,7 @@ struct sbc_frame { uint8_t joint; /* only the lower 4 bits of every element are to be used */ - uint8_t scale_factor[2][8]; + uint32_t scale_factor[2][8]; /* raw integer subband samples in the frame */ int32_t SBC_ALIGNED sb_sample_f[16][2][8]; @@ -745,8 +745,6 @@ static SBC_ALWAYS_INLINE int sbc_pack_frame_internal( 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 */ - data[0] = SBC_SYNCWORD; data[1] = (frame->frequency & 0x03) << 6; @@ -785,19 +783,6 @@ static SBC_ALWAYS_INLINE int sbc_pack_frame_internal( crc_header[1] = data[2]; crc_pos = 16; - for (ch = 0; ch < frame_channels; ch++) { - for (sb = 0; sb < frame_subbands; sb++) { - frame->scale_factor[ch][sb] = 0; - scalefactor[ch][sb] = 2 << SCALE_OUT_BITS; - for (blk = 0; blk < frame->blocks; blk++) { - while (scalefactor[ch][sb] < fabs(frame->sb_sample_f[blk][ch][sb])) { - frame->scale_factor[ch][sb]++; - scalefactor[ch][sb] *= 2; - } - } - } - } - if (frame->mode == JOINT_STEREO) { /* like frame->sb_sample but joint stereo */ int32_t sb_sample_j[16][2]; @@ -1115,6 +1100,10 @@ int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output, samples = sbc_analyze_audio(&priv->enc_state, &priv->frame); + priv->enc_state.sbc_calc_scalefactors( + priv->frame.sb_sample_f, priv->frame.scale_factor, + priv->frame.blocks, priv->frame.channels, priv->frame.subbands); + framelen = sbc_pack_frame(output, &priv->frame, output_len); if (written) |