summaryrefslogtreecommitdiffstats
path: root/sbc/sbc.c
diff options
context:
space:
mode:
authorSiarhei Siamashka <siarhei.siamashka@nokia.com>2009-01-29 02:17:36 +0200
committerMarcel Holtmann <marcel@holtmann.org>2009-01-29 08:25:50 +0100
commita563c8ed5a5d5004f4270dd8836f4257c1da2fe8 (patch)
tree520ed16c174f1cab6fc0749b267e5044b9a74e7d /sbc/sbc.c
parent85ad02b73626ee5caca6adb6e2890a7a588ecb38 (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.c21
1 files changed, 5 insertions, 16 deletions
diff --git a/sbc/sbc.c b/sbc/sbc.c
index 365ee1ff..8a2d7825 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -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)