From 61f64a95d1e0e8cf4f79b799394444d4bc03b5f7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Jan 2007 08:52:52 +0000 Subject: Add skeleton for embedding SBC library --- sbc/sbc.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 sbc/sbc.c (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c new file mode 100644 index 00000000..de479c4f --- /dev/null +++ b/sbc/sbc.c @@ -0,0 +1,28 @@ +/* + * + * Bluetooth low-complexity, subband codec (SBC) library + * + * Copyright (C) 2004-2007 Marcel Holtmann + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "sbc.h" -- cgit From ec31984c45d9b3dd272ec3ecb9a5270a00494699 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Feb 2007 14:23:25 +0000 Subject: Add SBC helper includes --- sbc/sbc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index de479c4f..f14f59a9 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -25,4 +25,9 @@ #include #endif +#include + +#include "sbc_math.h" +#include "sbc_tables.h" + #include "sbc.h" -- cgit From ad868bd4137e86fbf141175f411898796287ff2a Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sat, 17 Mar 2007 13:37:31 +0000 Subject: update the sbc encoder from the working fixed-point code in the sbc project I also tagged the sbc project with "copied-to-bluez-utils" at the same time. We will do sbc work under bluez and sync it with the old sbc project if necessary. --- sbc/sbc.c | 1398 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1397 insertions(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index f14f59a9..1f16d70a 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -2,7 +2,9 @@ * * Bluetooth low-complexity, subband codec (SBC) library * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2005 Henryk Ploetz + * Copyright (C) 2005-2006 Brad Midgley * * * This library is free software; you can redistribute it and/or @@ -21,13 +23,1407 @@ * */ +/* todo items: + + use a log2 table for byte integer scale factors calculation (sum log2 results for high and low bytes) + fill bitpool by 16 bits instead of one at a time in bits allocation/bitpool generation + port to the dsp + don't consume more bytes than passed into the encoder + +*/ + #ifdef HAVE_CONFIG_H #include #endif +#include +#include #include +#include +#include +#include +#include + #include "sbc_math.h" #include "sbc_tables.h" #include "sbc.h" + +#define SBC_SYNCWORD 0x9C + +/* sampling frequency */ +#define SBC_FS_16 0x00 +#define SBC_FS_32 0x01 +#define SBC_FS_44 0x02 +#define SBC_FS_48 0x03 + +/* nrof_blocks */ +#define SBC_NB_4 0x00 +#define SBC_NB_8 0x01 +#define SBC_NB_12 0x02 +#define SBC_NB_16 0x03 + +/* channel mode */ +#define SBC_CM_MONO 0x00 +#define SBC_CM_DUAL_CHANNEL 0x01 +#define SBC_CM_STEREO 0x02 +#define SBC_CM_JOINT_STEREO 0x03 + +/* allocation mode */ +#define SBC_AM_LOUDNESS 0x00 +#define SBC_AM_SNR 0x01 + +/* subbands */ +#define SBC_SB_4 0x00 +#define SBC_SB_8 0x01 + +/* This structure contains an unpacked SBC frame. + Yes, there is probably quite some unused space herein */ +struct sbc_frame { + uint16_t sampling_frequency; /* in kHz */ + uint8_t blocks; + enum { + MONO = SBC_CM_MONO, + DUAL_CHANNEL = SBC_CM_DUAL_CHANNEL, + STEREO = SBC_CM_STEREO, + JOINT_STEREO = SBC_CM_JOINT_STEREO + } channel_mode; + uint8_t channels; + enum { + LOUDNESS = SBC_AM_LOUDNESS, + SNR = SBC_AM_SNR + } allocation_method; + uint8_t subbands; + uint8_t bitpool; + uint8_t join; /* bit number x set means joint stereo has been used in subband x */ + uint8_t scale_factor[2][8]; /* only the lower 4 bits of every element are to be used */ + uint16_t audio_sample[16][2][8]; /* raw integer subband samples in the frame */ + + int32_t sb_sample_f[16][2][8]; + int32_t sb_sample[16][2][8]; /* modified subband samples */ + int16_t pcm_sample[2][16*8]; /* original pcm audio samples */ +}; + +struct sbc_decoder_state { + int subbands; + int32_t V[2][170]; + int offset[2][16]; +}; + +struct sbc_encoder_state { + int subbands; + int32_t X[2][80]; +}; + +/* + * Calculates the CRC-8 of the first len bits in data + */ +static const uint8_t crc_table[256] = { + 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, + 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, + 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, + 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, + 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, + 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, + 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, + 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1, + 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, + 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, + 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, + 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, + 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, + 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F, + 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, + 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, + 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, + 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, + 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, + 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50, + 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, + 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, + 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, + 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, + 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, + 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, + 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, + 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, + 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, + 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, + 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, + 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4 +}; + +static uint8_t sbc_crc8(const uint8_t * data, size_t len) +{ + uint8_t crc = 0x0f; + size_t i; + uint8_t octet; + + for (i = 0; i < len / 8; i++) + crc = crc_table[crc ^ data[i]]; + + octet = data[i]; + for (i = 0; i < len % 8; i++) { + char bit = ((octet ^ crc) & 0x80) >> 7; + + crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0); + + octet = octet << 1; + } + + return crc; +} + +/* + * Code straight from the spec to calculate the bits array + * Takes a pointer to the frame in question, a pointer to the bits array and the sampling frequency (as 2 bit integer) + */ +static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], uint8_t sf) +{ + if (frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) { + int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice; + int ch, sb; + + for (ch = 0; ch < frame->channels; ch++) { + if (frame->allocation_method == SNR) { + for (sb = 0; sb < frame->subbands; sb++) { + bitneed[ch][sb] = frame->scale_factor[ch][sb]; + } + } else { + for (sb = 0; sb < frame->subbands; sb++) { + if (frame->scale_factor[ch][sb] == 0) { + bitneed[ch][sb] = -5; + } else { + if (frame->subbands == 4) { + loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb]; + } else { + loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb]; + } + if (loudness > 0) { + bitneed[ch][sb] = loudness / 2; + } else { + bitneed[ch][sb] = loudness; + } + } + } + } + + max_bitneed = 0; + for (sb = 0; sb < frame->subbands; sb++) { + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; + } + + bitcount = 0; + slicecount = 0; + bitslice = max_bitneed + 1; + do { + bitslice--; + bitcount += slicecount; + slicecount = 0; + for (sb = 0; sb < frame->subbands; sb++) { + if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16)) { + slicecount++; + } else if (bitneed[ch][sb] == bitslice + 1) { + slicecount += 2; + } + } + } while (bitcount + slicecount < frame->bitpool); + + if (bitcount + slicecount == frame->bitpool) { + bitcount += slicecount; + bitslice--; + } + + for (sb = 0; sb < frame->subbands; sb++) { + if (bitneed[ch][sb] < bitslice + 2) { + bits[ch][sb] = 0; + } else { + bits[ch][sb] = bitneed[ch][sb] - bitslice; + if (bits[ch][sb] > 16) + bits[ch][sb] = 16; + } + } + + sb = 0; + while (bitcount < frame->bitpool && sb < frame->subbands) { + if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) { + bits[ch][sb]++; + bitcount++; + } else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1)) { + bits[ch][sb] = 2; + bitcount += 2; + } + sb++; + } + + sb = 0; + while (bitcount < frame->bitpool && sb < frame->subbands) { + if (bits[ch][sb] < 16) { + bits[ch][sb]++; + bitcount++; + } + sb++; + } + + } + + } else if (frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) { + int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice; + int ch, sb; + + if (frame->allocation_method == SNR) { + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + bitneed[ch][sb] = frame->scale_factor[ch][sb]; + } + } + } else { + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (frame->scale_factor[ch][sb] == 0) { + bitneed[ch][sb] = -5; + } else { + if (frame->subbands == 4) { + loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb]; + } else { + loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb]; + } + if (loudness > 0) { + bitneed[ch][sb] = loudness / 2; + } else { + bitneed[ch][sb] = loudness; + } + } + } + } + } + + max_bitneed = 0; + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; + } + } + + bitcount = 0; + slicecount = 0; + bitslice = max_bitneed + 1; + do { + bitslice--; + bitcount += slicecount; + slicecount = 0; + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16)) { + slicecount++; + } else if (bitneed[ch][sb] == bitslice + 1) { + slicecount += 2; + } + } + } + } while (bitcount + slicecount < frame->bitpool); + if (bitcount + slicecount == frame->bitpool) { + bitcount += slicecount; + bitslice--; + } + + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (bitneed[ch][sb] < bitslice + 2) { + bits[ch][sb] = 0; + } else { + bits[ch][sb] = bitneed[ch][sb] - bitslice; + if (bits[ch][sb] > 16) + bits[ch][sb] = 16; + } + } + } + + ch = 0; + sb = 0; + while ((bitcount < frame->bitpool) && (sb < frame->subbands)) { + if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) { + bits[ch][sb]++; + bitcount++; + } else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1)) { + bits[ch][sb] = 2; + bitcount += 2; + } + if (ch == 1) { + ch = 0; + sb++; + } else { + ch = 1; + } + } + + ch = 0; + sb = 0; + while ((bitcount < frame->bitpool) && (sb < frame->subbands)) { + if (bits[ch][sb] < 16) { + bits[ch][sb]++; + bitcount++; + } + if (ch == 1) { + ch = 0; + sb++; + } else { + ch = 1; + } + } + + } + +} + +/* + * Unpacks a SBC frame at the beginning of the stream in data, + * which has at most len bytes into frame. + * Returns the length in bytes of the packed frame, or a negative + * value on error. The error codes are: + * + * -1 Data stream too short + * -2 Sync byte incorrect + * -3 CRC8 incorrect + * -4 Bitpool value out of bounds + */ +static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_t len) +{ + int consumed; + /* Will copy the parts of the header that are relevant to crc calculation here */ + uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int crc_pos = 0; + int32_t temp; + + uint8_t sf; /* sampling_frequency, temporarily needed as array index */ + + int ch, sb, blk, bit; /* channel, subband, block and bit standard counters */ + int bits[2][8]; /* bits distribution */ + int levels[2][8]; /* levels derived from that */ + + if (len < 4) + return -1; + + if (data[0] != SBC_SYNCWORD) + return -2; + + sf = (data[1] >> 6) & 0x03; + switch (sf) { + case SBC_FS_16: + frame->sampling_frequency = 16000; + break; + case SBC_FS_32: + frame->sampling_frequency = 32000; + break; + case SBC_FS_44: + frame->sampling_frequency = 44100; + break; + case SBC_FS_48: + frame->sampling_frequency = 48000; + break; + } + + switch ((data[1] >> 4) & 0x03) { + case SBC_NB_4: + frame->blocks = 4; + break; + case SBC_NB_8: + frame->blocks = 8; + break; + case SBC_NB_12: + frame->blocks = 12; + break; + case SBC_NB_16: + frame->blocks = 16; + break; + } + + frame->channel_mode = (data[1] >> 2) & 0x03; + switch (frame->channel_mode) { + case MONO: + frame->channels = 1; + break; + case DUAL_CHANNEL: /* fall-through */ + case STEREO: + case JOINT_STEREO: + frame->channels = 2; + break; + } + + frame->allocation_method = (data[1] >> 1) & 0x01; + + frame->subbands = (data[1] & 0x01) ? 8 : 4; + + frame->bitpool = data[2]; + + if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) + && frame->bitpool > 16 * frame->subbands) + || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) + && frame->bitpool > 32 * frame->subbands)) + return -4; + + /* data[3] is crc, we're checking it later */ + + consumed = 32; + + crc_header[0] = data[1]; + crc_header[1] = data[2]; + crc_pos = 16; + + if (frame->channel_mode == JOINT_STEREO) { + if (len * 8 < consumed + frame->subbands) + return -1; + + frame->join = 0x00; + for (sb = 0; sb < frame->subbands - 1; sb++) { + frame->join |= ((data[4] >> (7 - sb)) & 0x01) << sb; + } + if (frame->subbands == 4) { + crc_header[crc_pos / 8] = data[4] & 0xf0; + } else { + crc_header[crc_pos / 8] = data[4]; + } + + consumed += frame->subbands; + crc_pos += frame->subbands; + } + + if (len * 8 < consumed + (4 * frame->subbands * frame->channels)) + return -1; + + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + /* FIXME assert(consumed % 4 == 0); */ + frame->scale_factor[ch][sb] = (data[consumed >> 3] >> (4 - (consumed & 0x7))) & 0x0F; + crc_header[crc_pos >> 3] |= frame->scale_factor[ch][sb] << (4 - (crc_pos & 0x7)); + + consumed += 4; + crc_pos += 4; + } + } + + if (data[3] != sbc_crc8(crc_header, crc_pos)) + return -3; + + sbc_calculate_bits(frame, bits, sf); + + for (blk = 0; blk < frame->blocks; blk++) { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + frame->audio_sample[blk][ch][sb] = 0; + if (bits[ch][sb] == 0) + continue; + + for (bit = 0; bit < bits[ch][sb]; bit++) { + int b; /* A bit */ + if (consumed > len * 8) + return -1; + + b = (data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01; + frame->audio_sample[blk][ch][sb] |= b << (bits[ch][sb] - bit - 1); + + consumed++; + } + } + } + } + + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + levels[ch][sb] = (1 << bits[ch][sb]) - 1; + } + } + + for (blk = 0; blk < frame->blocks; blk++) { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (levels[ch][sb] > 0) { + frame->sb_sample[blk][ch][sb] = + (((frame->audio_sample[blk][ch][sb] << 16) | 0x8000) / levels[ch][sb]) - 0x8000; + + frame->sb_sample[blk][ch][sb] >>= 3; + frame->sb_sample[blk][ch][sb] = (frame->sb_sample[blk][ch][sb] << (frame->scale_factor[ch][sb] + 1)); // Q13 + + } else { + frame->sb_sample[blk][ch][sb] = 0; + } + } + } + } + + if (frame->channel_mode == JOINT_STEREO) { + for (blk = 0; blk < frame->blocks; blk++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (frame->join & (0x01 << sb)) { + temp = frame->sb_sample[blk][0][sb] + frame->sb_sample[blk][1][sb]; + frame->sb_sample[blk][1][sb] = frame->sb_sample[blk][0][sb] - frame->sb_sample[blk][1][sb]; + frame->sb_sample[blk][0][sb] = temp; + } + } + } + } + + if ((consumed & 0x7) != 0) + consumed += 8 - (consumed & 0x7); + + + return consumed >> 3; +} + +static void sbc_decoder_init(struct sbc_decoder_state *state, const struct sbc_frame *frame) +{ + int i, ch; + + memset(state->V, 0, sizeof(state->V)); + state->subbands = frame->subbands; + + for (ch = 0; ch < 2; ch++) + for (i = 0; i < frame->subbands * 2; i++) + state->offset[ch][i] = (10 * i + 10); +} + +static inline void sbc_synthesize_four(struct sbc_decoder_state *state, + struct sbc_frame *frame, int ch, int blk) +{ + int i, j, k, idx; + sbc_extended_t res; + + for(i = 0; i < 8; i++) { + /* Shifting */ + state->offset[ch][i]--; + if(state->offset[ch][i] < 0) { + state->offset[ch][i] = 79; + for(j = 0; j < 9; j++) { + state->V[ch][j+80] = state->V[ch][j]; + } + } + } + + + for(i = 0; i < 8; i++) { + /* Distribute the new matrix value to the shifted position */ + SBC_FIXED_0(res); + for (j = 0; j < 4; j++) { + MULA(res, synmatrix4[i][j], frame->sb_sample[blk][ch][j]); + } + state->V[ch][state->offset[ch][i]] = SCALE4_STAGED1(res); + } + + /* Compute the samples */ + for(idx = 0, i = 0; i < 4; i++) { + k = (i + 4) & 0xf; + SBC_FIXED_0(res); + for(j = 0; j < 10; idx++) { + MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_4_40m0[idx]); + MULA(res, state->V[ch][state->offset[ch][k]+j++], sbc_proto_4_40m1[idx]); + } + /* Store in output */ + frame->pcm_sample[ch][blk * 4 + i] = SCALE4_STAGED2(res); // Q0 + } +} + +static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, + struct sbc_frame *frame, int ch, int blk) +{ + int i, j, k, idx; + sbc_extended_t res; + + for(i = 0; i < 16; i++) { + /* Shifting */ + state->offset[ch][i]--; + if(state->offset[ch][i] < 0) { + state->offset[ch][i] = 159; + for(j = 0; j < 9; j++) { + state->V[ch][j+160] = state->V[ch][j]; + } + } + } + + for(i = 0; i < 16; i++) { + /* Distribute the new matrix value to the shifted position */ + SBC_FIXED_0(res); + for (j = 0; j < 8; j++) { + MULA(res, synmatrix8[i][j], frame->sb_sample[blk][ch][j]); // Q28 = Q15 * Q13 + } + state->V[ch][state->offset[ch][i]] = SCALE8_STAGED1(res); // Q10 + } + + + /* Compute the samples */ + for(idx = 0, i = 0; i < 8; i++) { + k = (i + 8) & 0xf; + SBC_FIXED_0(res); + for(j = 0; j < 10; idx++) { + MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_8_80m0[idx]); + MULA(res, state->V[ch][state->offset[ch][k]+j++], sbc_proto_8_80m1[idx]); + } + /* Store in output */ + frame->pcm_sample[ch][blk * 8 + i] = SCALE8_STAGED2(res); // Q0 + + } +} + +static int sbc_synthesize_audio(struct sbc_decoder_state *state, struct sbc_frame *frame) +{ + int ch, blk; + + switch (frame->subbands) { + case 4: + for (ch = 0; ch < frame->channels; ch++) { + for (blk = 0; blk < frame->blocks; blk++) + sbc_synthesize_four(state, frame, ch, blk); + } + return frame->blocks * 4; + + case 8: + for (ch = 0; ch < frame->channels; ch++) { + for (blk = 0; blk < frame->blocks; blk++) + sbc_synthesize_eight(state, frame, ch, blk); + } + return frame->blocks * 8; + + default: + return -EIO; + } +} + +static void sbc_encoder_init(struct sbc_encoder_state *state, const struct sbc_frame *frame) +{ + memset(&state->X, 0, sizeof(state->X)); + state->subbands = frame->subbands; +} + +static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) +{ + + sbc_extended_t res; + sbc_extended_t t[8]; + + out[0] = out[1] = out[2] = out[3] = 0; + + MUL(res, _sbc_proto_4[0], (in[8] - in[32])); // Q18 + MULA(res, _sbc_proto_4[1], (in[16] - in[24])); + t[0] = SCALE4_STAGE1(res); // Q8 + + MUL(res, _sbc_proto_4[2], in[1]); + MULA(res, _sbc_proto_4[3], in[9]); + MULA(res, _sbc_proto_4[4], in[17]); + MULA(res, _sbc_proto_4[5], in[25]); + MULA(res, _sbc_proto_4[6], in[33]); + t[1] = SCALE4_STAGE1(res); + + MUL(res, _sbc_proto_4[7], in[2]); + MULA(res, _sbc_proto_4[8], in[10]); + MULA(res, _sbc_proto_4[9], in[18]); + MULA(res, _sbc_proto_4[10], in[26]); + MULA(res, _sbc_proto_4[11], in[34]); + t[2] = SCALE4_STAGE1(res); + + MUL(res, _sbc_proto_4[12], in[3]); + MULA(res, _sbc_proto_4[13], in[11]); + MULA(res, _sbc_proto_4[14], in[19]); + MULA(res, _sbc_proto_4[15], in[27]); + MULA(res, _sbc_proto_4[16], in[35]); + t[3] = SCALE4_STAGE1(res); + + MUL(res, _sbc_proto_4[17], in[4]); + MULA(res, _sbc_proto_4[18], (in[12] + in[28])); + MULA(res, _sbc_proto_4[19], in[20]); + MULA(res, _sbc_proto_4[17], in[36]); + t[4] = SCALE4_STAGE1(res); + + MUL(res, _sbc_proto_4[16], in[5]); + MULA(res, _sbc_proto_4[15], in[13]); + MULA(res, _sbc_proto_4[14], in[21]); + MULA(res, _sbc_proto_4[13], in[29]); + MULA(res, _sbc_proto_4[12], in[37]); + t[5] = SCALE4_STAGE1(res); + + MUL(res, _sbc_proto_4[11], in[6]); + MULA(res, _sbc_proto_4[10], in[14]); + MULA(res, _sbc_proto_4[9], in[22]); + MULA(res, _sbc_proto_4[8], in[30]); + MULA(res, _sbc_proto_4[7], in[38]); + t[6] = SCALE4_STAGE1(res); + + MUL(res, _sbc_proto_4[6], in[7]); + MULA(res, _sbc_proto_4[5], in[15]); + MULA(res, _sbc_proto_4[4], in[23]); + MULA(res, _sbc_proto_4[3], in[31]); + MULA(res, _sbc_proto_4[2], in[39]); + t[7] = SCALE4_STAGE1(res); + + MUL(res, _anamatrix4[0], t[0]); + MULA(res, _anamatrix4[1], t[1]); + MULA(res, _anamatrix4[2], t[2]); + MULA(res, _anamatrix4[1], t[3]); + MULA(res, _anamatrix4[0], t[4]); + MULA(res, _anamatrix4[3], t[5]); + MULA(res, -_anamatrix4[3], t[7]); + out[0] = SCALE4_STAGE2(res); // Q0 + + MUL(res, -_anamatrix4[0], t[0]); + MULA(res, _anamatrix4[3], t[1]); + MULA(res, _anamatrix4[2], t[2]); + MULA(res, _anamatrix4[3], t[3]); + MULA(res, -_anamatrix4[0], t[4]); + MULA(res, -_anamatrix4[1], t[5]); + MULA(res, _anamatrix4[1], t[7]); + out[1] = SCALE4_STAGE2(res); + + + MUL(res, -_anamatrix4[0], t[0]); + MULA(res, -_anamatrix4[3], t[1]); + MULA(res, _anamatrix4[2], t[2]); + MULA(res, -_anamatrix4[3], t[3]); + MULA(res, -_anamatrix4[0], t[4]); + MULA(res, _anamatrix4[1], t[5]); + MULA(res, -_anamatrix4[1], t[7]); + out[2] = SCALE4_STAGE2(res); + + MUL(res, _anamatrix4[0], t[0]); + MULA(res, -_anamatrix4[1], t[1]); + MULA(res, _anamatrix4[2], t[2]); + MULA(res, -_anamatrix4[1], t[3]); + MULA(res, _anamatrix4[0], t[4]); + MULA(res, -_anamatrix4[3], t[5]); + MULA(res, _anamatrix4[3], t[7]); + out[3] = SCALE4_STAGE2(res); +} +static inline void sbc_analyze_four(struct sbc_encoder_state *state, + struct sbc_frame *frame, int ch, int blk) +{ + int i; + /* Input 4 New Audio Samples */ + for (i = 39; i >= 4; i--) + state->X[ch][i] = state->X[ch][i - 4]; + for (i = 3; i >= 0; i--) + state->X[ch][i] = frame->pcm_sample[ch][blk * 4 + (3 - i)]; + _sbc_analyze_four(state->X[ch], frame->sb_sample_f[blk][ch]); +} + +static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) +{ + sbc_extended_t res; + sbc_extended_t t[8]; + + out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = 0; + + MUL(res, _sbc_proto_8[0], (in[16] - in[64])); // Q18 = Q18 * Q0 + MULA(res, _sbc_proto_8[1], (in[32] - in[48])); + MULA(res, _sbc_proto_8[2], in[4]); + MULA(res, _sbc_proto_8[3], in[20]); + MULA(res, _sbc_proto_8[4], in[36]); + MULA(res, _sbc_proto_8[5], in[52]); + t[0] = SCALE8_STAGE1(res); // Q10 + + MUL(res, _sbc_proto_8[6], in[2]); + MULA(res, _sbc_proto_8[7], in[18]); + MULA(res, _sbc_proto_8[8], in[34]); + MULA(res, _sbc_proto_8[9], in[50]); + MULA(res, _sbc_proto_8[10], in[66]); + t[1] = SCALE8_STAGE1(res); + + MUL(res, _sbc_proto_8[11], in[1]); + MULA(res, _sbc_proto_8[12], in[17]); + MULA(res, _sbc_proto_8[13], in[33]); + MULA(res, _sbc_proto_8[14], in[49]); + MULA(res, _sbc_proto_8[15], in[65]); + MULA(res, _sbc_proto_8[16], in[3]); + MULA(res, _sbc_proto_8[17], in[19]); + MULA(res, _sbc_proto_8[18], in[35]); + MULA(res, _sbc_proto_8[19], in[51]); + MULA(res, _sbc_proto_8[20], in[67]); + t[2] = SCALE8_STAGE1(res); + + MUL(res, _sbc_proto_8[21], in[5]); + MULA(res, _sbc_proto_8[22], in[21]); + MULA(res, _sbc_proto_8[23], in[37]); + MULA(res, _sbc_proto_8[24], in[53]); + MULA(res, _sbc_proto_8[25], in[69]); + MULA(res, -_sbc_proto_8[15], in[15]); + MULA(res, -_sbc_proto_8[14], in[31]); + MULA(res, -_sbc_proto_8[13], in[47]); + MULA(res, -_sbc_proto_8[12], in[63]); + MULA(res, -_sbc_proto_8[11], in[79]); + t[3] = SCALE8_STAGE1(res); + + MUL(res, _sbc_proto_8[26], in[6]); + MULA(res, _sbc_proto_8[27], in[22]); + MULA(res, _sbc_proto_8[28], in[38]); + MULA(res, _sbc_proto_8[29], in[54]); + MULA(res, _sbc_proto_8[30], in[70]); + MULA(res, -_sbc_proto_8[10], in[14]); + MULA(res, -_sbc_proto_8[9], in[30]); + MULA(res, -_sbc_proto_8[8], in[46]); + MULA(res, -_sbc_proto_8[7], in[62]); + MULA(res, -_sbc_proto_8[6], in[78]); + t[4] = SCALE8_STAGE1(res); + + MUL(res, _sbc_proto_8[31], in[7]); + MULA(res, _sbc_proto_8[32], in[23]); + MULA(res, _sbc_proto_8[33], in[39]); + MULA(res, _sbc_proto_8[34], in[55]); + MULA(res, _sbc_proto_8[35], in[71]); + MULA(res, -_sbc_proto_8[20], in[13]); + MULA(res, -_sbc_proto_8[19], in[29]); + MULA(res, -_sbc_proto_8[18], in[45]); + MULA(res, -_sbc_proto_8[17], in[61]); + MULA(res, -_sbc_proto_8[16], in[77]); + t[5] = SCALE8_STAGE1(res); + + MUL(res, _sbc_proto_8[36], (in[8] + in[72])); + MULA(res, _sbc_proto_8[37], in[24]); + MULA(res, _sbc_proto_8[38], in[40]); + MULA(res, _sbc_proto_8[37], in[56]); + MULA(res, -_sbc_proto_8[39], in[12]); + MULA(res, -_sbc_proto_8[5], in[28]); + MULA(res, -_sbc_proto_8[4], in[44]); + MULA(res, -_sbc_proto_8[3], in[60]); + MULA(res, -_sbc_proto_8[2], in[76]); + t[6] = SCALE8_STAGE1(res); + + MUL(res, _sbc_proto_8[35], in[9]); + MULA(res, _sbc_proto_8[34], in[25]); + MULA(res, _sbc_proto_8[33], in[41]); + MULA(res, _sbc_proto_8[32], in[57]); + MULA(res, _sbc_proto_8[31], in[73]); + MULA(res, -_sbc_proto_8[25], in[11]); + MULA(res, -_sbc_proto_8[24], in[27]); + MULA(res, -_sbc_proto_8[23], in[43]); + MULA(res, -_sbc_proto_8[22], in[59]); + MULA(res, -_sbc_proto_8[21], in[75]); + t[7] = SCALE8_STAGE1(res); + + MUL(res, _anamatrix8[0], t[0]); // = Q14 * Q10 + MULA(res, _anamatrix8[7], t[1]); + MULA(res, _anamatrix8[2], t[2]); + MULA(res, _anamatrix8[3], t[3]); + MULA(res, _anamatrix8[6], t[4]); + MULA(res, _anamatrix8[4], t[5]); + MULA(res, _anamatrix8[1], t[6]); + MULA(res, _anamatrix8[5], t[7]); + out[0] = SCALE8_STAGE2(res); // Q0 + + MUL(res, _anamatrix8[1], t[0]); + MULA(res, _anamatrix8[7], t[1]); + MULA(res, _anamatrix8[3], t[2]); + MULA(res, -_anamatrix8[5], t[3]); + MULA(res, -_anamatrix8[6], t[4]); + MULA(res, -_anamatrix8[2], t[5]); + MULA(res, -_anamatrix8[0], t[6]); + MULA(res, -_anamatrix8[4], t[7]); + out[1] = SCALE8_STAGE2(res); + + MUL(res, -_anamatrix8[1], t[0]); + MULA(res, _anamatrix8[7], t[1]); + MULA(res, _anamatrix8[4], t[2]); + MULA(res, -_anamatrix8[2], t[3]); + MULA(res, -_anamatrix8[6], t[4]); + MULA(res, _anamatrix8[5], t[5]); + MULA(res, _anamatrix8[0], t[6]); + MULA(res, _anamatrix8[3], t[7]); + out[2] = SCALE8_STAGE2(res); + + MUL(res, -_anamatrix8[0], t[0]); + MULA(res, _anamatrix8[7], t[1]); + MULA(res, _anamatrix8[5], t[2]); + MULA(res, -_anamatrix8[4], t[3]); + MULA(res, _anamatrix8[6], t[4]); + MULA(res, _anamatrix8[3], t[5]); + MULA(res, -_anamatrix8[1], t[6]); + MULA(res, -_anamatrix8[2], t[7]); + out[3] = SCALE8_STAGE2(res); + + MUL(res, -_anamatrix8[0], t[0]); + MULA(res, _anamatrix8[7], t[1]); + MULA(res, -_anamatrix8[5], t[2]); + MULA(res, _anamatrix8[4], t[3]); + MULA(res, _anamatrix8[6], t[4]); + MULA(res, -_anamatrix8[3], t[5]); + MULA(res, -_anamatrix8[1], t[6]); + MULA(res, _anamatrix8[2], t[7]); + out[4] = SCALE8_STAGE2(res); + + MUL(res, -_anamatrix8[1], t[0]); + MULA(res, _anamatrix8[7], t[1]); + MULA(res, -_anamatrix8[4], t[2]); + MULA(res, _anamatrix8[2], t[3]); + MULA(res, -_anamatrix8[6], t[4]); + MULA(res, -_anamatrix8[5], t[5]); + MULA(res, _anamatrix8[0], t[6]); + MULA(res, -_anamatrix8[3], t[7]); + out[5] = SCALE8_STAGE2(res); + + MUL(res, _anamatrix8[1], t[0]); + MULA(res, _anamatrix8[7], t[1]); + MULA(res, -_anamatrix8[3], t[2]); + MULA(res, _anamatrix8[5], t[3]); + MULA(res, -_anamatrix8[6], t[4]); + MULA(res, _anamatrix8[2], t[5]); + MULA(res, -_anamatrix8[0], t[6]); + MULA(res, _anamatrix8[4], t[7]); + out[6] = SCALE8_STAGE2(res); + + MUL(res, _anamatrix8[0], t[0]); + MULA(res, _anamatrix8[7], t[1]); + MULA(res, -_anamatrix8[2], t[2]); + MULA(res, -_anamatrix8[3], t[3]); + MULA(res, _anamatrix8[6], t[4]); + MULA(res, -_anamatrix8[4], t[5]); + MULA(res, _anamatrix8[1], t[6]); + MULA(res, -_anamatrix8[5], t[7]); + out[7] = SCALE8_STAGE2(res); +} + +static inline void sbc_analyze_eight(struct sbc_encoder_state *state, + struct sbc_frame *frame, int ch, int blk) +{ + int i; + + /* Input 8 Audio Samples */ + for (i = 79; i >= 8; i--) + state->X[ch][i] = state->X[ch][i - 8]; + for (i = 7; i >= 0; i--) + state->X[ch][i] = frame->pcm_sample[ch][blk * 8 + (7 - i)]; + _sbc_analyze_eight(state->X[ch], frame->sb_sample_f[blk][ch]); +} + +static int sbc_analyze_audio(struct sbc_encoder_state *state, struct sbc_frame *frame) +{ + int ch, blk; + + switch (frame->subbands) { + case 4: + for (ch = 0; ch < frame->channels; ch++) + for (blk = 0; blk < frame->blocks; blk++) { + sbc_analyze_four(state, frame, ch, blk); + } + return frame->blocks * 4; + + case 8: + for (ch = 0; ch < frame->channels; ch++) + for (blk = 0; blk < frame->blocks; blk++) { + sbc_analyze_eight(state, frame, ch, blk); + } + return frame->blocks * 8; + + default: + return -EIO; + } +} + +/* + * Packs the SBC frame from frame into the memory at data. At most len + * bytes will be used, should more memory be needed an appropriate + * error code will be returned. Returns the length of the packed frame + * on success or a negative value on error. + * + * The error codes are: + * -1 Not enough memory reserved + * -2 Unsupported sampling rate + * -3 Unsupported number of blocks + * -4 Unsupported number of subbands + * -5 Bitpool value out of bounds + * -99 not implemented + */ + +static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) +{ + int produced; + /* Will copy the header parts for CRC-8 calculation here */ + uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int crc_pos = 0; + + uint8_t sf; /* Sampling frequency as temporary value for table lookup */ + + int ch, sb, blk, bit; /* channel, subband, block and bit counters */ + int bits[2][8]; /* bits distribution */ + int levels[2][8]; /* levels are derived from that */ + + u_int32_t scalefactor[2][8]; /* derived from frame->scale_factor */ + + if (len < 4) { + return -1; + } + + /* Clear first 4 bytes of data (that's the constant length part of the SBC header) */ + memset(data, 0, 4); + + data[0] = SBC_SYNCWORD; + + if (frame->sampling_frequency == 16000) { + data[1] |= (SBC_FS_16 & 0x03) << 6; + sf = SBC_FS_16; + } else if (frame->sampling_frequency == 32000) { + data[1] |= (SBC_FS_32 & 0x03) << 6; + sf = SBC_FS_32; + } else if (frame->sampling_frequency == 44100) { + data[1] |= (SBC_FS_44 & 0x03) << 6; + sf = SBC_FS_44; + } else if (frame->sampling_frequency == 48000) { + data[1] |= (SBC_FS_48 & 0x03) << 6; + sf = SBC_FS_48; + } else { + return -2; + } + + switch (frame->blocks) { + case 4: + data[1] |= (SBC_NB_4 & 0x03) << 4; + break; + case 8: + data[1] |= (SBC_NB_8 & 0x03) << 4; + break; + case 12: + data[1] |= (SBC_NB_12 & 0x03) << 4; + break; + case 16: + data[1] |= (SBC_NB_16 & 0x03) << 4; + break; + default: + return -3; + break; + } + + data[1] |= (frame->channel_mode & 0x03) << 2; + + data[1] |= (frame->allocation_method & 0x01) << 1; + + switch (frame->subbands) { + case 4: + /* Nothing to do */ + break; + case 8: + data[1] |= 0x01; + break; + default: + return -4; + break; + } + + data[2] = frame->bitpool; + if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) + && frame->bitpool > 16 * frame->subbands) + || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) + && frame->bitpool > 32 * frame->subbands)) { + return -5; + } + + /* Can't fill in crc yet */ + + produced = 32; + + crc_header[0] = data[1]; + 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; + 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->channel_mode == JOINT_STEREO) { + int32_t sb_sample_j[16][2][7]; /* like frame->sb_sample but joint stereo */ + int scalefactor_j[2][7], scale_factor_j[2][7]; /* scalefactor and scale_factor in joint case */ + + /* Calculate joint stereo signal */ + for (sb = 0; sb < frame->subbands - 1; sb++) { + for (blk = 0; blk < frame->blocks; blk++) { + sb_sample_j[blk][0][sb] = (frame->sb_sample_f[blk][0][sb] + frame->sb_sample_f[blk][1][sb]) >> 1; + sb_sample_j[blk][1][sb] = (frame->sb_sample_f[blk][0][sb] - frame->sb_sample_f[blk][1][sb]) >> 1; + } + } + + /* calculate scale_factor_j and scalefactor_j for joint case */ + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands - 1; sb++) { + scale_factor_j[ch][sb] = 0; + scalefactor_j[ch][sb] = 2; + for (blk = 0; blk < frame->blocks; blk++) { + while (scalefactor_j[ch][sb] < fabs(sb_sample_j[blk][ch][sb])) { + scale_factor_j[ch][sb]++; + scalefactor_j[ch][sb] *= 2; + } + } + } + } + + /* decide which subbands to join */ + frame->join = 0; + for (sb = 0; sb < frame->subbands - 1; sb++) { + if ((scalefactor[0][sb] + scalefactor[1][sb]) > + (scalefactor_j[0][sb] + scalefactor_j[1][sb]) ) { + /* use joint stereo for this subband */ + frame->join |= 1 << sb; + frame->scale_factor[0][sb] = scale_factor_j[0][sb]; + frame->scale_factor[1][sb] = scale_factor_j[1][sb]; + scalefactor[0][sb] = scalefactor_j[0][sb]; + scalefactor[1][sb] = scalefactor_j[1][sb]; + for (blk = 0; blk < frame->blocks; blk++) { + frame->sb_sample_f[blk][0][sb] = sb_sample_j[blk][0][sb]; + frame->sb_sample_f[blk][1][sb] = sb_sample_j[blk][1][sb]; + } + } + } + + if (len * 8 < produced + frame->subbands) + return -1; + + data[4] = 0; + for (sb = 0; sb < frame->subbands - 1; sb++) { + data[4] |= ((frame->join >> sb) & 0x01) << (7 - sb); + } + if (frame->subbands == 4) { + crc_header[crc_pos / 8] = data[4] & 0xf0; + } else { + crc_header[crc_pos / 8] = data[4]; + } + + produced += frame->subbands; + crc_pos += frame->subbands; + } + + if (len * 8 < produced + (4 * frame->subbands * frame->channels)) + return -1; + + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (produced % 8 == 0) + data[produced / 8] = 0; + data[produced / 8] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (produced % 8))); + crc_header[crc_pos / 8] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (crc_pos % 8))); + + produced += 4; + crc_pos += 4; + } + } + + data[3] = sbc_crc8(crc_header, crc_pos); + + sbc_calculate_bits(frame, bits, sf); + + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + levels[ch][sb] = (1 << bits[ch][sb]) - 1; + } + } + + for (blk = 0; blk < frame->blocks; blk++) { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (levels[ch][sb] > 0) { + frame->audio_sample[blk][ch][sb] = + (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >> (frame->scale_factor[ch][sb] + 1)) + + levels[ch][sb]) >> 1); + } else { + frame->audio_sample[blk][ch][sb] = 0; + } + } + } + } + + for (blk = 0; blk < frame->blocks; blk++) { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (bits[ch][sb] != 0) { + for (bit = 0; bit < bits[ch][sb]; bit++) { + int b; /* A bit */ + if (produced > len * 8) { + return -1; + } + if (produced % 8 == 0) { + data[produced / 8] = 0; + } + b = ((frame->audio_sample[blk][ch][sb]) >> (bits[ch][sb] - bit - + 1)) & 0x01; + data[produced / 8] |= b << (7 - (produced % 8)); + produced++; + } + } + } + } + } + + if (produced % 8 != 0) { + produced += 8 - (produced % 8); + } + + return produced / 8; +} + +struct sbc_priv { + int init; + struct sbc_frame frame; + struct sbc_decoder_state dec_state; + struct sbc_encoder_state enc_state; +}; + +int sbc_init(sbc_t *sbc, unsigned long flags) +{ + if (!sbc) + return -EIO; + + memset(sbc, 0, sizeof(sbc_t)); + + sbc->priv = malloc(sizeof(struct sbc_priv)); + if (!sbc->priv) + return -ENOMEM; + + memset(sbc->priv, 0, sizeof(struct sbc_priv)); + + sbc->rate = 44100; + sbc->channels = 2; + sbc->joint = 0; + sbc->subbands = 8; + sbc->blocks = 16; + sbc->bitpool = 32; + + return 0; +} + +int sbc_decode(sbc_t *sbc, void *data, int count) +{ + struct sbc_priv *priv; + char *ptr; + int i, ch, framelen, samples; + + if (!sbc) + return -EIO; + + priv = sbc->priv; + + framelen = sbc_unpack_frame(data, &priv->frame, count); + + + if (!priv->init) { + sbc_decoder_init(&priv->dec_state, &priv->frame); + priv->init = 1; + + sbc->rate = priv->frame.sampling_frequency; + sbc->channels = priv->frame.channels; + sbc->subbands = priv->frame.subbands; + sbc->blocks = priv->frame.blocks; + sbc->bitpool = priv->frame.bitpool; + } + + samples = sbc_synthesize_audio(&priv->dec_state, &priv->frame); + + if (!sbc->data) { + sbc->size = samples * priv->frame.channels * 2; + sbc->data = malloc(sbc->size); + } + + if (sbc->size < samples * priv->frame.channels * 2) { + sbc->size = samples * priv->frame.channels * 2; + sbc->data = realloc(sbc->data, sbc->size); + } + + if (!sbc->data) { + sbc->size = 0; + return -ENOMEM; + } + + ptr = sbc->data; + + for (i = 0; i < samples; i++) { + for (ch = 0; ch < priv->frame.channels; ch++) { + int16_t s; + s = priv->frame.pcm_sample[ch][i]; + *ptr++ = (s & 0xff00) >> 8; + *ptr++ = (s & 0x00ff); + } + } + + sbc->len = samples * priv->frame.channels * 2; + + return framelen; +} + +int sbc_encode(sbc_t *sbc, void *data, int count) +{ + struct sbc_priv *priv; + char *ptr; + int i, ch, framelen, samples; + + if (!sbc) + return -EIO; + + priv = sbc->priv; + + if (!priv->init) { + priv->frame.sampling_frequency = sbc->rate; + priv->frame.channels = sbc->channels; + + if (sbc->channels > 1) { + if (sbc->joint) + priv->frame.channel_mode = JOINT_STEREO; + else + priv->frame.channel_mode = STEREO; + } else + priv->frame.channel_mode = MONO; + + priv->frame.allocation_method = SNR; + priv->frame.subbands = sbc->subbands; + priv->frame.blocks = sbc->blocks; + priv->frame.bitpool = sbc->bitpool; + + sbc_encoder_init(&priv->enc_state, &priv->frame); + priv->init = 1; + } + + ptr = data; + + for (i = 0; i < priv->frame.subbands * priv->frame.blocks; i++) { + for (ch = 0; ch < sbc->channels; ch++) { + int16_t s = (ptr[0] & 0xff) << 8 | (ptr[1] & 0xff); + ptr += 2; + priv->frame.pcm_sample[ch][i] = s; + } + } + + samples = sbc_analyze_audio(&priv->enc_state, &priv->frame); + + if (!sbc->data) { + sbc->size = 1024; + sbc->data = malloc(sbc->size); + } + + if (!sbc->data) { + sbc->size = 0; + return -ENOMEM; + } + + framelen = sbc_pack_frame(sbc->data, &priv->frame, sbc->size); + + sbc->len = framelen; + + sbc->duration = (1000000 * priv->frame.subbands * priv->frame.blocks) / sbc->rate; + + return samples * sbc->channels * 2; +} + +void sbc_finish(sbc_t *sbc) +{ + if (!sbc) + return; + + if (sbc->data) + free(sbc->data); + + if (sbc->priv) + free(sbc->priv); + + memset(sbc, 0, sizeof(sbc_t)); +} -- cgit From a745805cb3961ccf88f0119f28dc919ed9c571e5 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sat, 24 Mar 2007 14:01:31 +0000 Subject: whitespace fixes --- sbc/sbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 1f16d70a..ce6252df 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -594,7 +594,7 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, for(i = 0; i < 8; i++) { /* Shifting */ state->offset[ch][i]--; - if(state->offset[ch][i] < 0) { + if (state->offset[ch][i] < 0) { state->offset[ch][i] = 79; for(j = 0; j < 9; j++) { state->V[ch][j+80] = state->V[ch][j]; @@ -634,7 +634,7 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, for(i = 0; i < 16; i++) { /* Shifting */ state->offset[ch][i]--; - if(state->offset[ch][i] < 0) { + if (state->offset[ch][i] < 0) { state->offset[ch][i] = 159; for(j = 0; j < 9; j++) { state->V[ch][j+160] = state->V[ch][j]; -- cgit From 46e860574f3d6d70d961e38270522764191cea20 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 11 Aug 2007 10:56:46 +0000 Subject: Don't hardcode allocation method to SNR --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index ce6252df..d485a5fd 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1374,7 +1374,7 @@ int sbc_encode(sbc_t *sbc, void *data, int count) } else priv->frame.channel_mode = MONO; - priv->frame.allocation_method = SNR; + priv->frame.allocation_method = sbc->allocation; priv->frame.subbands = sbc->subbands; priv->frame.blocks = sbc->blocks; priv->frame.bitpool = sbc->bitpool; -- cgit From b1618922db92f9bc65b0841f66eb71742bc1b553 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 21 Aug 2007 21:32:09 +0000 Subject: Add swap member to sbc struct and fix pcm plugin to not swap the buffer. --- sbc/sbc.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index d485a5fd..d27c1e9a 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1289,6 +1289,7 @@ int sbc_init(sbc_t *sbc, unsigned long flags) sbc->subbands = 8; sbc->blocks = 16; sbc->bitpool = 32; + sbc->swap = 0; return 0; } @@ -1341,8 +1342,14 @@ int sbc_decode(sbc_t *sbc, void *data, int count) for (ch = 0; ch < priv->frame.channels; ch++) { int16_t s; s = priv->frame.pcm_sample[ch][i]; - *ptr++ = (s & 0xff00) >> 8; - *ptr++ = (s & 0x00ff); + + if (sbc->swap) { + *ptr++ = (s & 0xff00) >> 8; + *ptr++ = (s & 0x00ff); + } else { + *ptr++ = (s & 0x00ff); + *ptr++ = (s & 0xff00) >> 8; + } } } @@ -1387,7 +1394,12 @@ int sbc_encode(sbc_t *sbc, void *data, int count) for (i = 0; i < priv->frame.subbands * priv->frame.blocks; i++) { for (ch = 0; ch < sbc->channels; ch++) { - int16_t s = (ptr[0] & 0xff) << 8 | (ptr[1] & 0xff); + int16_t s; + + if (sbc->swap) + s = (ptr[0] & 0xff) << 8 | (ptr[1] & 0xff); + else + s = (ptr[0] & 0xff) | (ptr[1] & 0xff) << 8; ptr += 2; priv->frame.pcm_sample[ch][i] = s; } -- cgit From 5689ce1423a12a2c20aef9e48146282e978c4adb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 25 Aug 2007 13:23:51 +0000 Subject: Update copyright information --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index d27c1e9a..ca683e86 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -2,7 +2,7 @@ * * Bluetooth low-complexity, subband codec (SBC) library * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * Copyright (C) 2004-2005 Henryk Ploetz * Copyright (C) 2005-2006 Brad Midgley * -- cgit From c82412ad9e399b9b6391ef73c24f36ff83983e9d Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sun, 26 Aug 2007 01:05:25 +0000 Subject: indicate 0 bytes consumed in encoder if input is too short. caller is responsible for filling the end of the input if it really wants the frame encoded (ie with silence at the end) --- sbc/sbc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index ca683e86..240a5d24 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -28,7 +28,6 @@ use a log2 table for byte integer scale factors calculation (sum log2 results for high and low bytes) fill bitpool by 16 bits instead of one at a time in bits allocation/bitpool generation port to the dsp - don't consume more bytes than passed into the encoder */ @@ -1390,6 +1389,10 @@ int sbc_encode(sbc_t *sbc, void *data, int count) priv->init = 1; } + /* input must be large enough to encode a complete frame */ + if (count < priv->frame.subbands * priv->frame.blocks * sbc->channels * 2) + return 0; + ptr = data; for (i = 0; i < priv->frame.subbands * priv->frame.blocks; i++) { -- cgit From d9bccae488ef82fc0e1d927b30db9228bfd91169 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 26 Aug 2007 13:54:24 +0000 Subject: Add simple implementation of sbc_parse() --- sbc/sbc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 240a5d24..7cd267b1 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1293,6 +1293,11 @@ int sbc_init(sbc_t *sbc, unsigned long flags) return 0; } +int sbc_parse(sbc_t *sbc, void *data, int count) +{ + return sbc_decode(sbc, data, count); +} + int sbc_decode(sbc_t *sbc, void *data, int count) { struct sbc_priv *priv; -- cgit From c434c0b49544551f784c34fec4ef220423ad2a51 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 4 Oct 2007 05:15:07 +0000 Subject: optimizations for 2nd stage of 4-subband encoder disabled but in place so indt folks don't duplicate the optimization effort --- sbc/sbc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 7cd267b1..c9728ec9 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -701,6 +701,10 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) sbc_extended_t res; sbc_extended_t t[8]; +#if 0 + /* temporary results */ + sbc_extended_t s[2], p[6], d[4]; +#endif out[0] = out[1] = out[2] = out[3] = 0; MUL(res, _sbc_proto_4[0], (in[8] - in[32])); // Q18 @@ -755,6 +759,7 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, _sbc_proto_4[2], in[39]); t[7] = SCALE4_STAGE1(res); +#if 1 MUL(res, _anamatrix4[0], t[0]); MULA(res, _anamatrix4[1], t[1]); MULA(res, _anamatrix4[2], t[2]); @@ -791,6 +796,24 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, -_anamatrix4[3], t[5]); MULA(res, _anamatrix4[3], t[7]); out[3] = SCALE4_STAGE2(res); +#else + s[0] = t[1] + t[3]; + s[1] = t[5] - t[6]; + MUL(p[0], _anamatrix4[0], t[0] + t[4]); + MUL(p[1], _anamatrix4[1], s[0]); + MUL(p[2], _anamatrix4[2], t[2]); + MUL(p[3], _anamatrix4[3], s[0]); + MUL(p[4], _anamatrix4[3], s[1]); + MUL(p[5], _anamatrix4[1], s[1]); + d[0] = p[0] + p[2]; + d[1] = p[2] - p[0]; + d[2] = p[1] + p[4]; + d[3] = p[3] - p[5]; + out[0] = SCALE4_STAGE2(d[0] + d[2]); + out[1] = SCALE4_STAGE2(d[1] + d[3]); + out[2] = SCALE4_STAGE2(d[1] - d[3]); + out[3] = SCALE4_STAGE2(d[0] - d[2]); +#endif } static inline void sbc_analyze_four(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) -- cgit From 6ee3949547dfad9aadc975646f455bde96ae06c6 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 4 Oct 2007 07:42:57 +0000 Subject: a (disabled for now) cpu optimization for the bottom half of the 8 subbands encoder. seems to work fine. --- sbc/sbc.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index c9728ec9..1cf83329 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -832,6 +832,10 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) sbc_extended_t res; sbc_extended_t t[8]; +#if 0 + /* temporary results */ + sbc_extended_t s[8]; +#endif out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = 0; MUL(res, _sbc_proto_8[0], (in[16] - in[64])); // Q18 = Q18 * Q0 @@ -920,6 +924,7 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) MULA(res, -_sbc_proto_8[21], in[75]); t[7] = SCALE8_STAGE1(res); +#if 1 MUL(res, _anamatrix8[0], t[0]); // = Q14 * Q10 MULA(res, _anamatrix8[7], t[1]); MULA(res, _anamatrix8[2], t[2]); @@ -999,6 +1004,38 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) MULA(res, _anamatrix8[1], t[6]); MULA(res, -_anamatrix8[5], t[7]); out[7] = SCALE8_STAGE2(res); +#else + MUL(s[0], _anamatrix8[0], t[0]); + MULA(s[0], _anamatrix8[1], t[6]); + MUL(s[1], _anamatrix8[7], t[1]); + MUL(s[2], _anamatrix8[2], t[3]); + MULA(s[2], _anamatrix8[3], t[4]); + MULA(s[2], _anamatrix8[4], t[5]); + MULA(s[2], _anamatrix8[5], t[7]); + MUL(s[3], _anamatrix8[6], t[4]); + MUL(s[4], _anamatrix8[3], t[2]); + MULA(s[4], -_anamatrix8[5], t[3]); + MULA(s[4], -_anamatrix8[2], t[5]); + MULA(s[4], -_anamatrix8[4], t[7]); + MUL(s[5], _anamatrix8[4], t[2]); + MULA(s[5], -_anamatrix8[2], t[3]); + MULA(s[5], _anamatrix8[5], t[5]); + MULA(s[5], _anamatrix8[3], t[7]); + MUL(s[6], _anamatrix8[1], t[0]); + MULA(s[6], -_anamatrix8[0], t[6]); + MUL(s[7], _anamatrix8[5], t[2]); + MULA(s[7], -_anamatrix8[4], t[3]); + MULA(s[7], _anamatrix8[3], t[5]); + MULA(s[7], _anamatrix8[2], t[7]); + out[0] = SCALE8_STAGE2( s[0] + s[1] + s[2] + s[3]); + out[1] = SCALE8_STAGE2( s[1] - s[3] + s[4] + s[6]); + out[2] = SCALE8_STAGE2( s[1] - s[3] + s[5] - s[6]); + out[3] = SCALE8_STAGE2(-s[0] + s[1] + s[3] + s[7]); + out[4] = SCALE8_STAGE2(-s[0] + s[1] + s[3] - s[7]); + out[5] = SCALE8_STAGE2( s[1] - s[3] - s[5] + s[6]); + out[6] = SCALE8_STAGE2( s[1] - s[3] - s[4] + s[6]); + out[7] = SCALE8_STAGE2( s[0] + s[1] - s[2] + s[3]); +#endif } static inline void sbc_analyze_eight(struct sbc_encoder_state *state, -- cgit From aaad5f279f2fc2156799ebc6d171a76113724de4 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 4 Oct 2007 08:08:59 +0000 Subject: off-by-one problem in 8 subband optimization --- sbc/sbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 1cf83329..25244e0d 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1008,8 +1008,8 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) MUL(s[0], _anamatrix8[0], t[0]); MULA(s[0], _anamatrix8[1], t[6]); MUL(s[1], _anamatrix8[7], t[1]); - MUL(s[2], _anamatrix8[2], t[3]); - MULA(s[2], _anamatrix8[3], t[4]); + MUL(s[2], _anamatrix8[2], t[2]); + MULA(s[2], _anamatrix8[3], t[3]); MULA(s[2], _anamatrix8[4], t[5]); MULA(s[2], _anamatrix8[5], t[7]); MUL(s[3], _anamatrix8[6], t[4]); -- cgit From 4cbaa35cb32fe5fe0f79e7f323cff3075a9f5b42 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 4 Oct 2007 16:05:40 +0000 Subject: fix & enable 8-subband second half optimization --- sbc/sbc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 25244e0d..dcff5382 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -796,7 +796,8 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, -_anamatrix4[3], t[5]); MULA(res, _anamatrix4[3], t[7]); out[3] = SCALE4_STAGE2(res); -#else +#endif +#if 0 s[0] = t[1] + t[3]; s[1] = t[5] - t[6]; MUL(p[0], _anamatrix4[0], t[0] + t[4]); @@ -832,7 +833,7 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) sbc_extended_t res; sbc_extended_t t[8]; -#if 0 +#if 1 /* temporary results */ sbc_extended_t s[8]; #endif @@ -924,7 +925,7 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) MULA(res, -_sbc_proto_8[21], in[75]); t[7] = SCALE8_STAGE1(res); -#if 1 +#if 0 MUL(res, _anamatrix8[0], t[0]); // = Q14 * Q10 MULA(res, _anamatrix8[7], t[1]); MULA(res, _anamatrix8[2], t[2]); @@ -1026,7 +1027,7 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) MUL(s[7], _anamatrix8[5], t[2]); MULA(s[7], -_anamatrix8[4], t[3]); MULA(s[7], _anamatrix8[3], t[5]); - MULA(s[7], _anamatrix8[2], t[7]); + MULA(s[7], -_anamatrix8[2], t[7]); out[0] = SCALE8_STAGE2( s[0] + s[1] + s[2] + s[3]); out[1] = SCALE8_STAGE2( s[1] - s[3] + s[4] + s[6]); out[2] = SCALE8_STAGE2( s[1] - s[3] + s[5] - s[6]); -- cgit From 7fbcefdd87d222c04023dcb1b3ff3cf5aeae8613 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 4 Oct 2007 18:28:17 +0000 Subject: enable 4 subband lower half optimizations --- sbc/sbc.c | 55 +++++++++++++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index dcff5382..a5cbf803 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -700,12 +700,7 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) sbc_extended_t res; sbc_extended_t t[8]; - -#if 0 - /* temporary results */ - sbc_extended_t s[2], p[6], d[4]; -#endif - out[0] = out[1] = out[2] = out[3] = 0; + sbc_extended_t s[4]; MUL(res, _sbc_proto_4[0], (in[8] - in[32])); // Q18 MULA(res, _sbc_proto_4[1], (in[16] - in[24])); @@ -744,14 +739,15 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, _sbc_proto_4[13], in[29]); MULA(res, _sbc_proto_4[12], in[37]); t[5] = SCALE4_STAGE1(res); - +#if 0 + /* don't compute... this term always multiplies with cos(pi) = 0*/ MUL(res, _sbc_proto_4[11], in[6]); MULA(res, _sbc_proto_4[10], in[14]); MULA(res, _sbc_proto_4[9], in[22]); MULA(res, _sbc_proto_4[8], in[30]); MULA(res, _sbc_proto_4[7], in[38]); t[6] = SCALE4_STAGE1(res); - +#endif MUL(res, _sbc_proto_4[6], in[7]); MULA(res, _sbc_proto_4[5], in[15]); MULA(res, _sbc_proto_4[4], in[23]); @@ -759,7 +755,7 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, _sbc_proto_4[2], in[39]); t[7] = SCALE4_STAGE1(res); -#if 1 +#if 0 MUL(res, _anamatrix4[0], t[0]); MULA(res, _anamatrix4[1], t[1]); MULA(res, _anamatrix4[2], t[2]); @@ -796,24 +792,24 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, -_anamatrix4[3], t[5]); MULA(res, _anamatrix4[3], t[7]); out[3] = SCALE4_STAGE2(res); -#endif -#if 0 - s[0] = t[1] + t[3]; - s[1] = t[5] - t[6]; - MUL(p[0], _anamatrix4[0], t[0] + t[4]); - MUL(p[1], _anamatrix4[1], s[0]); - MUL(p[2], _anamatrix4[2], t[2]); - MUL(p[3], _anamatrix4[3], s[0]); - MUL(p[4], _anamatrix4[3], s[1]); - MUL(p[5], _anamatrix4[1], s[1]); - d[0] = p[0] + p[2]; - d[1] = p[2] - p[0]; - d[2] = p[1] + p[4]; - d[3] = p[3] - p[5]; - out[0] = SCALE4_STAGE2(d[0] + d[2]); - out[1] = SCALE4_STAGE2(d[1] + d[3]); - out[2] = SCALE4_STAGE2(d[1] - d[3]); - out[3] = SCALE4_STAGE2(d[0] - d[2]); +#else + /* some of these multiplies could be factored more but something overflows */ + /* eg replace the first two lines with MUL(s[0], _anamatrix4[0], t[0] + t[4]) */ + MUL(s[0], _anamatrix4[0], t[0]); + MULA(s[0], _anamatrix4[0], t[4]); + MUL(s[1], _anamatrix4[2], t[2]); + MUL(s[2], _anamatrix4[1], t[1]); + MULA(s[2], _anamatrix4[1], t[3]); + MULA(s[2], _anamatrix4[3], t[5]); + MULA(s[2], -_anamatrix4[3], t[7]); + MUL(s[3], _anamatrix4[3], t[1]); + MULA(s[3], _anamatrix4[3], t[3]); + MULA(s[3], -_anamatrix4[1], t[5]); + MULA(s[3], _anamatrix4[1], t[7]); + out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2]); + out[1] = SCALE4_STAGE2(-s[0] + s[1] + s[3]); + out[2] = SCALE4_STAGE2(-s[0] + s[1] - s[3]); + out[3] = SCALE4_STAGE2( s[0] + s[1] - s[2]); #endif } static inline void sbc_analyze_four(struct sbc_encoder_state *state, @@ -832,12 +828,7 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) { sbc_extended_t res; sbc_extended_t t[8]; - -#if 1 - /* temporary results */ sbc_extended_t s[8]; -#endif - out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = 0; MUL(res, _sbc_proto_8[0], (in[16] - in[64])); // Q18 = Q18 * Q0 MULA(res, _sbc_proto_8[1], (in[32] - in[48])); -- cgit From 99b92496ace832a5c75776a55126d731ee42df43 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 5 Oct 2007 05:42:55 +0000 Subject: fix MUL* macros with () factor more multiplies in 4-subband encoder --- sbc/sbc.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index a5cbf803..c262f16d 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -793,19 +793,12 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, _anamatrix4[3], t[7]); out[3] = SCALE4_STAGE2(res); #else - /* some of these multiplies could be factored more but something overflows */ - /* eg replace the first two lines with MUL(s[0], _anamatrix4[0], t[0] + t[4]) */ - MUL(s[0], _anamatrix4[0], t[0]); - MULA(s[0], _anamatrix4[0], t[4]); + MUL(s[0], _anamatrix4[0], t[0] + t[4]); MUL(s[1], _anamatrix4[2], t[2]); - MUL(s[2], _anamatrix4[1], t[1]); - MULA(s[2], _anamatrix4[1], t[3]); - MULA(s[2], _anamatrix4[3], t[5]); - MULA(s[2], -_anamatrix4[3], t[7]); - MUL(s[3], _anamatrix4[3], t[1]); - MULA(s[3], _anamatrix4[3], t[3]); - MULA(s[3], -_anamatrix4[1], t[5]); - MULA(s[3], _anamatrix4[1], t[7]); + MUL(s[2], _anamatrix4[1], t[1] + t[3]); + MULA(s[2], _anamatrix4[3], t[5] + t[7]); + MUL(s[3], _anamatrix4[3], t[1] + t[3]); + MULA(s[3], _anamatrix4[1], - t[5] + t[7]); out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2]); out[1] = SCALE4_STAGE2(-s[0] + s[1] + s[3]); out[2] = SCALE4_STAGE2(-s[0] + s[1] - s[3]); -- cgit From 3820937249249165f9ee41a74954dca81a843eeb Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sat, 6 Oct 2007 00:01:51 +0000 Subject: clean out dead code --- sbc/sbc.c | 137 +++----------------------------------------------------------- 1 file changed, 5 insertions(+), 132 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index c262f16d..a7f8888c 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -739,15 +739,9 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, _sbc_proto_4[13], in[29]); MULA(res, _sbc_proto_4[12], in[37]); t[5] = SCALE4_STAGE1(res); -#if 0 - /* don't compute... this term always multiplies with cos(pi) = 0*/ - MUL(res, _sbc_proto_4[11], in[6]); - MULA(res, _sbc_proto_4[10], in[14]); - MULA(res, _sbc_proto_4[9], in[22]); - MULA(res, _sbc_proto_4[8], in[30]); - MULA(res, _sbc_proto_4[7], in[38]); - t[6] = SCALE4_STAGE1(res); -#endif + + /* don't compute t[6]... this term always multiplies with cos(pi/2) = 0 */ + MUL(res, _sbc_proto_4[6], in[7]); MULA(res, _sbc_proto_4[5], in[15]); MULA(res, _sbc_proto_4[4], in[23]); @@ -755,55 +749,16 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, _sbc_proto_4[2], in[39]); t[7] = SCALE4_STAGE1(res); -#if 0 - MUL(res, _anamatrix4[0], t[0]); - MULA(res, _anamatrix4[1], t[1]); - MULA(res, _anamatrix4[2], t[2]); - MULA(res, _anamatrix4[1], t[3]); - MULA(res, _anamatrix4[0], t[4]); - MULA(res, _anamatrix4[3], t[5]); - MULA(res, -_anamatrix4[3], t[7]); - out[0] = SCALE4_STAGE2(res); // Q0 - - MUL(res, -_anamatrix4[0], t[0]); - MULA(res, _anamatrix4[3], t[1]); - MULA(res, _anamatrix4[2], t[2]); - MULA(res, _anamatrix4[3], t[3]); - MULA(res, -_anamatrix4[0], t[4]); - MULA(res, -_anamatrix4[1], t[5]); - MULA(res, _anamatrix4[1], t[7]); - out[1] = SCALE4_STAGE2(res); - - - MUL(res, -_anamatrix4[0], t[0]); - MULA(res, -_anamatrix4[3], t[1]); - MULA(res, _anamatrix4[2], t[2]); - MULA(res, -_anamatrix4[3], t[3]); - MULA(res, -_anamatrix4[0], t[4]); - MULA(res, _anamatrix4[1], t[5]); - MULA(res, -_anamatrix4[1], t[7]); - out[2] = SCALE4_STAGE2(res); - - MUL(res, _anamatrix4[0], t[0]); - MULA(res, -_anamatrix4[1], t[1]); - MULA(res, _anamatrix4[2], t[2]); - MULA(res, -_anamatrix4[1], t[3]); - MULA(res, _anamatrix4[0], t[4]); - MULA(res, -_anamatrix4[3], t[5]); - MULA(res, _anamatrix4[3], t[7]); - out[3] = SCALE4_STAGE2(res); -#else MUL(s[0], _anamatrix4[0], t[0] + t[4]); MUL(s[1], _anamatrix4[2], t[2]); MUL(s[2], _anamatrix4[1], t[1] + t[3]); MULA(s[2], _anamatrix4[3], t[5] + t[7]); MUL(s[3], _anamatrix4[3], t[1] + t[3]); MULA(s[3], _anamatrix4[1], - t[5] + t[7]); - out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2]); + out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2]); // Q0 out[1] = SCALE4_STAGE2(-s[0] + s[1] + s[3]); out[2] = SCALE4_STAGE2(-s[0] + s[1] - s[3]); out[3] = SCALE4_STAGE2( s[0] + s[1] - s[2]); -#endif } static inline void sbc_analyze_four(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) @@ -909,88 +864,7 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) MULA(res, -_sbc_proto_8[21], in[75]); t[7] = SCALE8_STAGE1(res); -#if 0 - MUL(res, _anamatrix8[0], t[0]); // = Q14 * Q10 - MULA(res, _anamatrix8[7], t[1]); - MULA(res, _anamatrix8[2], t[2]); - MULA(res, _anamatrix8[3], t[3]); - MULA(res, _anamatrix8[6], t[4]); - MULA(res, _anamatrix8[4], t[5]); - MULA(res, _anamatrix8[1], t[6]); - MULA(res, _anamatrix8[5], t[7]); - out[0] = SCALE8_STAGE2(res); // Q0 - - MUL(res, _anamatrix8[1], t[0]); - MULA(res, _anamatrix8[7], t[1]); - MULA(res, _anamatrix8[3], t[2]); - MULA(res, -_anamatrix8[5], t[3]); - MULA(res, -_anamatrix8[6], t[4]); - MULA(res, -_anamatrix8[2], t[5]); - MULA(res, -_anamatrix8[0], t[6]); - MULA(res, -_anamatrix8[4], t[7]); - out[1] = SCALE8_STAGE2(res); - - MUL(res, -_anamatrix8[1], t[0]); - MULA(res, _anamatrix8[7], t[1]); - MULA(res, _anamatrix8[4], t[2]); - MULA(res, -_anamatrix8[2], t[3]); - MULA(res, -_anamatrix8[6], t[4]); - MULA(res, _anamatrix8[5], t[5]); - MULA(res, _anamatrix8[0], t[6]); - MULA(res, _anamatrix8[3], t[7]); - out[2] = SCALE8_STAGE2(res); - - MUL(res, -_anamatrix8[0], t[0]); - MULA(res, _anamatrix8[7], t[1]); - MULA(res, _anamatrix8[5], t[2]); - MULA(res, -_anamatrix8[4], t[3]); - MULA(res, _anamatrix8[6], t[4]); - MULA(res, _anamatrix8[3], t[5]); - MULA(res, -_anamatrix8[1], t[6]); - MULA(res, -_anamatrix8[2], t[7]); - out[3] = SCALE8_STAGE2(res); - - MUL(res, -_anamatrix8[0], t[0]); - MULA(res, _anamatrix8[7], t[1]); - MULA(res, -_anamatrix8[5], t[2]); - MULA(res, _anamatrix8[4], t[3]); - MULA(res, _anamatrix8[6], t[4]); - MULA(res, -_anamatrix8[3], t[5]); - MULA(res, -_anamatrix8[1], t[6]); - MULA(res, _anamatrix8[2], t[7]); - out[4] = SCALE8_STAGE2(res); - - MUL(res, -_anamatrix8[1], t[0]); - MULA(res, _anamatrix8[7], t[1]); - MULA(res, -_anamatrix8[4], t[2]); - MULA(res, _anamatrix8[2], t[3]); - MULA(res, -_anamatrix8[6], t[4]); - MULA(res, -_anamatrix8[5], t[5]); - MULA(res, _anamatrix8[0], t[6]); - MULA(res, -_anamatrix8[3], t[7]); - out[5] = SCALE8_STAGE2(res); - - MUL(res, _anamatrix8[1], t[0]); - MULA(res, _anamatrix8[7], t[1]); - MULA(res, -_anamatrix8[3], t[2]); - MULA(res, _anamatrix8[5], t[3]); - MULA(res, -_anamatrix8[6], t[4]); - MULA(res, _anamatrix8[2], t[5]); - MULA(res, -_anamatrix8[0], t[6]); - MULA(res, _anamatrix8[4], t[7]); - out[6] = SCALE8_STAGE2(res); - - MUL(res, _anamatrix8[0], t[0]); - MULA(res, _anamatrix8[7], t[1]); - MULA(res, -_anamatrix8[2], t[2]); - MULA(res, -_anamatrix8[3], t[3]); - MULA(res, _anamatrix8[6], t[4]); - MULA(res, -_anamatrix8[4], t[5]); - MULA(res, _anamatrix8[1], t[6]); - MULA(res, -_anamatrix8[5], t[7]); - out[7] = SCALE8_STAGE2(res); -#else - MUL(s[0], _anamatrix8[0], t[0]); + MUL(s[0], _anamatrix8[0], t[0]); // = Q14 * Q10 MULA(s[0], _anamatrix8[1], t[6]); MUL(s[1], _anamatrix8[7], t[1]); MUL(s[2], _anamatrix8[2], t[2]); @@ -1020,7 +894,6 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) out[5] = SCALE8_STAGE2( s[1] - s[3] - s[5] + s[6]); out[6] = SCALE8_STAGE2( s[1] - s[3] - s[4] + s[6]); out[7] = SCALE8_STAGE2( s[0] + s[1] - s[2] + s[3]); -#endif } static inline void sbc_analyze_eight(struct sbc_encoder_state *state, -- cgit From 8fab528b8616b9a194dfe497ee9cc0fa455bab58 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sat, 6 Oct 2007 00:34:35 +0000 Subject: a little more factoring --- sbc/sbc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index a7f8888c..6fcf6e24 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -616,7 +616,7 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, k = (i + 4) & 0xf; SBC_FIXED_0(res); for(j = 0; j < 10; idx++) { - MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_4_40m0[idx]); + MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_4_40m0[idx]); MULA(res, state->V[ch][state->offset[ch][k]+j++], sbc_proto_4_40m1[idx]); } /* Store in output */ @@ -727,10 +727,9 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, _sbc_proto_4[16], in[35]); t[3] = SCALE4_STAGE1(res); - MUL(res, _sbc_proto_4[17], in[4]); - MULA(res, _sbc_proto_4[18], (in[12] + in[28])); + MUL(res, _sbc_proto_4[17], in[4] + in[36]); + MULA(res, _sbc_proto_4[18], in[12] + in[28]); MULA(res, _sbc_proto_4[19], in[20]); - MULA(res, _sbc_proto_4[17], in[36]); t[4] = SCALE4_STAGE1(res); MUL(res, _sbc_proto_4[16], in[5]); @@ -841,10 +840,9 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) MULA(res, -_sbc_proto_8[16], in[77]); t[5] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[36], (in[8] + in[72])); - MULA(res, _sbc_proto_8[37], in[24]); + MUL(res, _sbc_proto_8[36], in[8] + in[72]); + MULA(res, _sbc_proto_8[37], in[24] + in[56]); MULA(res, _sbc_proto_8[38], in[40]); - MULA(res, _sbc_proto_8[37], in[56]); MULA(res, -_sbc_proto_8[39], in[12]); MULA(res, -_sbc_proto_8[5], in[28]); MULA(res, -_sbc_proto_8[4], in[44]); -- cgit From f06a303b02c9188efd7cb00c2cce19b14098874b Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Wed, 17 Oct 2007 07:36:25 +0000 Subject: 8-subband encoder had a sign error that made high frequencies noisy --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 6fcf6e24..94e5c752 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -889,7 +889,7 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) out[2] = SCALE8_STAGE2( s[1] - s[3] + s[5] - s[6]); out[3] = SCALE8_STAGE2(-s[0] + s[1] + s[3] + s[7]); out[4] = SCALE8_STAGE2(-s[0] + s[1] + s[3] - s[7]); - out[5] = SCALE8_STAGE2( s[1] - s[3] - s[5] + s[6]); + out[5] = SCALE8_STAGE2( s[1] - s[3] - s[5] - s[6]); out[6] = SCALE8_STAGE2( s[1] - s[3] - s[4] + s[6]); out[7] = SCALE8_STAGE2( s[0] + s[1] - s[2] + s[3]); } -- cgit From 9138f99acb799d7ce702afb357c134042f933f4b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 1 Nov 2007 15:27:38 +0000 Subject: Coding style cleanup --- sbc/sbc.c | 297 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 157 insertions(+), 140 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 94e5c752..3e65603d 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -25,9 +25,9 @@ /* todo items: - use a log2 table for byte integer scale factors calculation (sum log2 results for high and low bytes) - fill bitpool by 16 bits instead of one at a time in bits allocation/bitpool generation - port to the dsp + use a log2 table for byte integer scale factors calculation (sum log2 results + for high and low bytes) fill bitpool by 16 bits instead of one at a time in + bits allocation/bitpool generation port to the dsp */ @@ -77,7 +77,7 @@ #define SBC_SB_4 0x00 #define SBC_SB_8 0x01 -/* This structure contains an unpacked SBC frame. +/* This structure contains an unpacked SBC frame. Yes, there is probably quite some unused space herein */ struct sbc_frame { uint16_t sampling_frequency; /* in kHz */ @@ -95,13 +95,19 @@ struct sbc_frame { } allocation_method; uint8_t subbands; uint8_t bitpool; - uint8_t join; /* bit number x set means joint stereo has been used in subband x */ - uint8_t scale_factor[2][8]; /* only the lower 4 bits of every element are to be used */ - uint16_t audio_sample[16][2][8]; /* raw integer subband samples in the frame */ + + /* bit number x set means joint stereo has been used in subband x */ + uint8_t join; + + /* only the lower 4 bits of every element are to be used */ + uint8_t scale_factor[2][8]; + + /* raw integer subband samples in the frame */ + uint16_t audio_sample[16][2][8]; int32_t sb_sample_f[16][2][8]; - int32_t sb_sample[16][2][8]; /* modified subband samples */ - int16_t pcm_sample[2][16*8]; /* original pcm audio samples */ + int32_t sb_sample[16][2][8]; /* modified subband samples */ + int16_t pcm_sample[2][16*8]; /* original pcm audio samples */ }; struct sbc_decoder_state { @@ -175,8 +181,9 @@ static uint8_t sbc_crc8(const uint8_t * data, size_t len) } /* - * Code straight from the spec to calculate the bits array - * Takes a pointer to the frame in question, a pointer to the bits array and the sampling frequency (as 2 bit integer) + * Code straight from the spec to calculate the bits array + * Takes a pointer to the frame in question, a pointer to the bits array and + * the sampling frequency (as 2 bit integer) */ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], uint8_t sf) { @@ -186,24 +193,21 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui for (ch = 0; ch < frame->channels; ch++) { if (frame->allocation_method == SNR) { - for (sb = 0; sb < frame->subbands; sb++) { + for (sb = 0; sb < frame->subbands; sb++) bitneed[ch][sb] = frame->scale_factor[ch][sb]; - } } else { for (sb = 0; sb < frame->subbands; sb++) { - if (frame->scale_factor[ch][sb] == 0) { + if (frame->scale_factor[ch][sb] == 0) bitneed[ch][sb] = -5; - } else { - if (frame->subbands == 4) { + else { + if (frame->subbands == 4) loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb]; - } else { + else loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb]; - } - if (loudness > 0) { + if (loudness > 0) bitneed[ch][sb] = loudness / 2; - } else { + else bitneed[ch][sb] = loudness; - } } } } @@ -222,11 +226,10 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui bitcount += slicecount; slicecount = 0; for (sb = 0; sb < frame->subbands; sb++) { - if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16)) { + if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16)) slicecount++; - } else if (bitneed[ch][sb] == bitslice + 1) { + else if (bitneed[ch][sb] == bitslice + 1) slicecount += 2; - } } } while (bitcount + slicecount < frame->bitpool); @@ -236,9 +239,9 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui } for (sb = 0; sb < frame->subbands; sb++) { - if (bitneed[ch][sb] < bitslice + 2) { + if (bitneed[ch][sb] < bitslice + 2) bits[ch][sb] = 0; - } else { + else { bits[ch][sb] = bitneed[ch][sb] - bitslice; if (bits[ch][sb] > 16) bits[ch][sb] = 16; @@ -274,26 +277,23 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui if (frame->allocation_method == SNR) { for (ch = 0; ch < 2; ch++) { - for (sb = 0; sb < frame->subbands; sb++) { + for (sb = 0; sb < frame->subbands; sb++) bitneed[ch][sb] = frame->scale_factor[ch][sb]; - } } } else { for (ch = 0; ch < 2; ch++) { for (sb = 0; sb < frame->subbands; sb++) { - if (frame->scale_factor[ch][sb] == 0) { + if (frame->scale_factor[ch][sb] == 0) bitneed[ch][sb] = -5; - } else { - if (frame->subbands == 4) { + else { + if (frame->subbands == 4) loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb]; - } else { + else loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb]; - } - if (loudness > 0) { + if (loudness > 0) bitneed[ch][sb] = loudness / 2; - } else { + else bitneed[ch][sb] = loudness; - } } } } @@ -316,11 +316,10 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui slicecount = 0; for (ch = 0; ch < 2; ch++) { for (sb = 0; sb < frame->subbands; sb++) { - if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16)) { + if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16)) slicecount++; - } else if (bitneed[ch][sb] == bitslice + 1) { + else if (bitneed[ch][sb] == bitslice + 1) slicecount += 2; - } } } } while (bitcount + slicecount < frame->bitpool); @@ -354,9 +353,8 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui if (ch == 1) { ch = 0; sb++; - } else { + } else ch = 1; - } } ch = 0; @@ -369,16 +367,15 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui if (ch == 1) { ch = 0; sb++; - } else { + } else ch = 1; - } } } } -/* +/* * Unpacks a SBC frame at the beginning of the stream in data, * which has at most len bytes into frame. * Returns the length in bytes of the packed frame, or a negative @@ -389,17 +386,21 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui * -3 CRC8 incorrect * -4 Bitpool value out of bounds */ -static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_t len) +static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, + size_t len) { int consumed; - /* Will copy the parts of the header that are relevant to crc calculation here */ + /* Will copy the parts of the header that are relevant to crc + * calculation here */ uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int crc_pos = 0; int32_t temp; - uint8_t sf; /* sampling_frequency, temporarily needed as array index */ + uint8_t sf; /* sampling_frequency, temporarily needed as + array index */ - int ch, sb, blk, bit; /* channel, subband, block and bit standard counters */ + int ch, sb, blk, bit; /* channel, subband, block and bit standard + counters */ int bits[2][8]; /* bits distribution */ int levels[2][8]; /* levels derived from that */ @@ -458,10 +459,12 @@ static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_ frame->bitpool = data[2]; - if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) - && frame->bitpool > 16 * frame->subbands) - || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) - && frame->bitpool > 32 * frame->subbands)) + if (((frame->channel_mode == MONO || + frame->channel_mode == DUAL_CHANNEL) && + frame->bitpool > 16 * frame->subbands) || + ((frame->channel_mode == STEREO || + frame->channel_mode == JOINT_STEREO) && + frame->bitpool > 32 * frame->subbands)) return -4; /* data[3] is crc, we're checking it later */ @@ -477,14 +480,12 @@ static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_ return -1; frame->join = 0x00; - for (sb = 0; sb < frame->subbands - 1; sb++) { + for (sb = 0; sb < frame->subbands - 1; sb++) frame->join |= ((data[4] >> (7 - sb)) & 0x01) << sb; - } - if (frame->subbands == 4) { + if (frame->subbands == 4) crc_header[crc_pos / 8] = data[4] & 0xf0; - } else { + else crc_header[crc_pos / 8] = data[4]; - } consumed += frame->subbands; crc_pos += frame->subbands; @@ -496,8 +497,10 @@ static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_ for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) { /* FIXME assert(consumed % 4 == 0); */ - frame->scale_factor[ch][sb] = (data[consumed >> 3] >> (4 - (consumed & 0x7))) & 0x0F; - crc_header[crc_pos >> 3] |= frame->scale_factor[ch][sb] << (4 - (crc_pos & 0x7)); + frame->scale_factor[ch][sb] = + (data[consumed >> 3] >> (4 - (consumed & 0x7))) & 0x0F; + crc_header[crc_pos >> 3] |= + frame->scale_factor[ch][sb] << (4 - (crc_pos & 0x7)); consumed += 4; crc_pos += 4; @@ -522,7 +525,8 @@ static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_ return -1; b = (data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01; - frame->audio_sample[blk][ch][sb] |= b << (bits[ch][sb] - bit - 1); + frame->audio_sample[blk][ch][sb] |= + b << (bits[ch][sb] - bit - 1); consumed++; } @@ -531,24 +535,27 @@ static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_ } for (ch = 0; ch < frame->channels; ch++) { - for (sb = 0; sb < frame->subbands; sb++) { + for (sb = 0; sb < frame->subbands; sb++) levels[ch][sb] = (1 << bits[ch][sb]) - 1; - } } for (blk = 0; blk < frame->blocks; blk++) { for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) { if (levels[ch][sb] > 0) { - frame->sb_sample[blk][ch][sb] = - (((frame->audio_sample[blk][ch][sb] << 16) | 0x8000) / levels[ch][sb]) - 0x8000; + frame->sb_sample[blk][ch][sb] = + (((frame->audio_sample[blk][ch][sb] << 16) | 0x8000) / + levels[ch][sb]) - 0x8000; frame->sb_sample[blk][ch][sb] >>= 3; - frame->sb_sample[blk][ch][sb] = (frame->sb_sample[blk][ch][sb] << (frame->scale_factor[ch][sb] + 1)); // Q13 - } else { + /* Q13 */ + frame->sb_sample[blk][ch][sb] = + (frame->sb_sample[blk][ch][sb] << + (frame->scale_factor[ch][sb] + 1)); + + } else frame->sb_sample[blk][ch][sb] = 0; - } } } } @@ -557,8 +564,11 @@ static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_ for (blk = 0; blk < frame->blocks; blk++) { for (sb = 0; sb < frame->subbands; sb++) { if (frame->join & (0x01 << sb)) { - temp = frame->sb_sample[blk][0][sb] + frame->sb_sample[blk][1][sb]; - frame->sb_sample[blk][1][sb] = frame->sb_sample[blk][0][sb] - frame->sb_sample[blk][1][sb]; + temp = frame->sb_sample[blk][0][sb] + + frame->sb_sample[blk][1][sb]; + frame->sb_sample[blk][1][sb] = + frame->sb_sample[blk][0][sb] - + frame->sb_sample[blk][1][sb]; frame->sb_sample[blk][0][sb] = temp; } } @@ -568,11 +578,11 @@ static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_ if ((consumed & 0x7) != 0) consumed += 8 - (consumed & 0x7); - return consumed >> 3; } -static void sbc_decoder_init(struct sbc_decoder_state *state, const struct sbc_frame *frame) +static void sbc_decoder_init(struct sbc_decoder_state *state, + const struct sbc_frame *frame) { int i, ch; @@ -595,19 +605,16 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, state->offset[ch][i]--; if (state->offset[ch][i] < 0) { state->offset[ch][i] = 79; - for(j = 0; j < 9; j++) { + for(j = 0; j < 9; j++) state->V[ch][j+80] = state->V[ch][j]; - } } } - for(i = 0; i < 8; i++) { /* Distribute the new matrix value to the shifted position */ SBC_FIXED_0(res); - for (j = 0; j < 4; j++) { + for (j = 0; j < 4; j++) MULA(res, synmatrix4[i][j], frame->sb_sample[blk][ch][j]); - } state->V[ch][state->offset[ch][i]] = SCALE4_STAGED1(res); } @@ -616,11 +623,14 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, k = (i + 4) & 0xf; SBC_FIXED_0(res); for(j = 0; j < 10; idx++) { - MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_4_40m0[idx]); - MULA(res, state->V[ch][state->offset[ch][k]+j++], sbc_proto_4_40m1[idx]); + MULA(res, state->V[ch][state->offset[ch][i]+j++], + sbc_proto_4_40m0[idx]); + MULA(res, state->V[ch][state->offset[ch][k]+j++], + sbc_proto_4_40m1[idx]); } - /* Store in output */ - frame->pcm_sample[ch][blk * 4 + i] = SCALE4_STAGED2(res); // Q0 + + /* Store in output, Q0 */ + frame->pcm_sample[ch][blk * 4 + i] = SCALE4_STAGED2(res); } } @@ -635,9 +645,8 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, state->offset[ch][i]--; if (state->offset[ch][i] < 0) { state->offset[ch][i] = 159; - for(j = 0; j < 9; j++) { - state->V[ch][j+160] = state->V[ch][j]; - } + for(j = 0; j < 9; j++) + state->V[ch][j+160] = state->V[ch][j]; } } @@ -645,11 +654,12 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, /* Distribute the new matrix value to the shifted position */ SBC_FIXED_0(res); for (j = 0; j < 8; j++) { - MULA(res, synmatrix8[i][j], frame->sb_sample[blk][ch][j]); // Q28 = Q15 * Q13 + /* Q28 = Q15 * Q13 */ + MULA(res, synmatrix8[i][j], frame->sb_sample[blk][ch][j]); } - state->V[ch][state->offset[ch][i]] = SCALE8_STAGED1(res); // Q10 + /* Q10 */ + state->V[ch][state->offset[ch][i]] = SCALE8_STAGED1(res); } - /* Compute the samples */ for(idx = 0, i = 0; i < 8; i++) { @@ -665,10 +675,11 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, } } -static int sbc_synthesize_audio(struct sbc_decoder_state *state, struct sbc_frame *frame) +static int sbc_synthesize_audio(struct sbc_decoder_state *state, + struct sbc_frame *frame) { int ch, blk; - + switch (frame->subbands) { case 4: for (ch = 0; ch < frame->channels; ch++) { @@ -689,7 +700,8 @@ static int sbc_synthesize_audio(struct sbc_decoder_state *state, struct sbc_fram } } -static void sbc_encoder_init(struct sbc_encoder_state *state, const struct sbc_frame *frame) +static void sbc_encoder_init(struct sbc_encoder_state *state, + const struct sbc_frame *frame) { memset(&state->X, 0, sizeof(state->X)); state->subbands = frame->subbands; @@ -702,9 +714,9 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) sbc_extended_t t[8]; sbc_extended_t s[4]; - MUL(res, _sbc_proto_4[0], (in[8] - in[32])); // Q18 + MUL(res, _sbc_proto_4[0], (in[8] - in[32])); /* Q18 */ MULA(res, _sbc_proto_4[1], (in[16] - in[24])); - t[0] = SCALE4_STAGE1(res); // Q8 + t[0] = SCALE4_STAGE1(res); /* Q8 */ MUL(res, _sbc_proto_4[2], in[1]); MULA(res, _sbc_proto_4[3], in[9]); @@ -739,7 +751,8 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(res, _sbc_proto_4[12], in[37]); t[5] = SCALE4_STAGE1(res); - /* don't compute t[6]... this term always multiplies with cos(pi/2) = 0 */ + /* don't compute t[6]... this term always multiplies + * with cos(pi/2) = 0 */ MUL(res, _sbc_proto_4[6], in[7]); MULA(res, _sbc_proto_4[5], in[15]); @@ -754,7 +767,7 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MULA(s[2], _anamatrix4[3], t[5] + t[7]); MUL(s[3], _anamatrix4[3], t[1] + t[3]); MULA(s[3], _anamatrix4[1], - t[5] + t[7]); - out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2]); // Q0 + out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2]); /* Q0 */ out[1] = SCALE4_STAGE2(-s[0] + s[1] + s[3]); out[2] = SCALE4_STAGE2(-s[0] + s[1] - s[3]); out[3] = SCALE4_STAGE2( s[0] + s[1] - s[2]); @@ -776,14 +789,14 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) sbc_extended_t res; sbc_extended_t t[8]; sbc_extended_t s[8]; - - MUL(res, _sbc_proto_8[0], (in[16] - in[64])); // Q18 = Q18 * Q0 + + MUL(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ MULA(res, _sbc_proto_8[1], (in[32] - in[48])); MULA(res, _sbc_proto_8[2], in[4]); MULA(res, _sbc_proto_8[3], in[20]); MULA(res, _sbc_proto_8[4], in[36]); MULA(res, _sbc_proto_8[5], in[52]); - t[0] = SCALE8_STAGE1(res); // Q10 + t[0] = SCALE8_STAGE1(res); /* Q10 */ MUL(res, _sbc_proto_8[6], in[2]); MULA(res, _sbc_proto_8[7], in[18]); @@ -862,7 +875,7 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) MULA(res, -_sbc_proto_8[21], in[75]); t[7] = SCALE8_STAGE1(res); - MUL(s[0], _anamatrix8[0], t[0]); // = Q14 * Q10 + MUL(s[0], _anamatrix8[0], t[0]); /* = Q14 * Q10 */ MULA(s[0], _anamatrix8[1], t[6]); MUL(s[1], _anamatrix8[7], t[1]); MUL(s[2], _anamatrix8[2], t[2]); @@ -895,7 +908,8 @@ static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) } static inline void sbc_analyze_eight(struct sbc_encoder_state *state, - struct sbc_frame *frame, int ch, int blk) + struct sbc_frame *frame, int ch, + int blk) { int i; @@ -907,23 +921,22 @@ static inline void sbc_analyze_eight(struct sbc_encoder_state *state, _sbc_analyze_eight(state->X[ch], frame->sb_sample_f[blk][ch]); } -static int sbc_analyze_audio(struct sbc_encoder_state *state, struct sbc_frame *frame) +static int sbc_analyze_audio(struct sbc_encoder_state *state, + struct sbc_frame *frame) { int ch, blk; switch (frame->subbands) { case 4: for (ch = 0; ch < frame->channels; ch++) - for (blk = 0; blk < frame->blocks; blk++) { + for (blk = 0; blk < frame->blocks; blk++) sbc_analyze_four(state, frame, ch, blk); - } return frame->blocks * 4; case 8: for (ch = 0; ch < frame->channels; ch++) - for (blk = 0; blk < frame->blocks; blk++) { + for (blk = 0; blk < frame->blocks; blk++) sbc_analyze_eight(state, frame, ch, blk); - } return frame->blocks * 8; default: @@ -933,9 +946,9 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state, struct sbc_frame * /* * Packs the SBC frame from frame into the memory at data. At most len - * bytes will be used, should more memory be needed an appropriate + * bytes will be used, should more memory be needed an appropriate * error code will be returned. Returns the length of the packed frame - * on success or a negative value on error. + * on success or a negative value on error. * * The error codes are: * -1 Not enough memory reserved @@ -953,7 +966,8 @@ 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; - uint8_t sf; /* Sampling frequency as temporary value for table lookup */ + /* Sampling frequency as temporary value for table lookup */ + uint8_t sf; int ch, sb, blk, bit; /* channel, subband, block and bit counters */ int bits[2][8]; /* bits distribution */ @@ -965,7 +979,8 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) return -1; } - /* Clear first 4 bytes of data (that's the constant length part of the SBC header) */ + /* Clear first 4 bytes of data (that's the constant length part of the + * SBC header) */ memset(data, 0, 4); data[0] = SBC_SYNCWORD; @@ -1021,12 +1036,13 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) } data[2] = frame->bitpool; - if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) - && frame->bitpool > 16 * frame->subbands) - || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) - && frame->bitpool > 32 * frame->subbands)) { + if ((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) && + frame->bitpool > 16 * frame->subbands) + return -5; + + if ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) && + frame->bitpool > 32 * frame->subbands) return -5; - } /* Can't fill in crc yet */ @@ -1050,14 +1066,20 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) } if (frame->channel_mode == JOINT_STEREO) { - int32_t sb_sample_j[16][2][7]; /* like frame->sb_sample but joint stereo */ - int scalefactor_j[2][7], scale_factor_j[2][7]; /* scalefactor and scale_factor in joint case */ + /* like frame->sb_sample but joint stereo */ + int32_t sb_sample_j[16][2][7]; + /* scalefactor and scale_factor in joint case */ + int scalefactor_j[2][7], scale_factor_j[2][7]; /* Calculate joint stereo signal */ for (sb = 0; sb < frame->subbands - 1; sb++) { for (blk = 0; blk < frame->blocks; blk++) { - sb_sample_j[blk][0][sb] = (frame->sb_sample_f[blk][0][sb] + frame->sb_sample_f[blk][1][sb]) >> 1; - sb_sample_j[blk][1][sb] = (frame->sb_sample_f[blk][0][sb] - frame->sb_sample_f[blk][1][sb]) >> 1; + sb_sample_j[blk][0][sb] = + (frame->sb_sample_f[blk][0][sb] + + frame->sb_sample_f[blk][1][sb]) >> 1; + sb_sample_j[blk][1][sb] = + (frame->sb_sample_f[blk][0][sb] - + frame->sb_sample_f[blk][1][sb]) >> 1; } } @@ -1087,8 +1109,10 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) scalefactor[0][sb] = scalefactor_j[0][sb]; scalefactor[1][sb] = scalefactor_j[1][sb]; for (blk = 0; blk < frame->blocks; blk++) { - frame->sb_sample_f[blk][0][sb] = sb_sample_j[blk][0][sb]; - frame->sb_sample_f[blk][1][sb] = sb_sample_j[blk][1][sb]; + frame->sb_sample_f[blk][0][sb] = + sb_sample_j[blk][0][sb]; + frame->sb_sample_f[blk][1][sb] = + sb_sample_j[blk][1][sb]; } } } @@ -1097,15 +1121,13 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) return -1; data[4] = 0; - for (sb = 0; sb < frame->subbands - 1; sb++) { + for (sb = 0; sb < frame->subbands - 1; sb++) data[4] |= ((frame->join >> sb) & 0x01) << (7 - sb); - } - if (frame->subbands == 4) { + if (frame->subbands == 4) crc_header[crc_pos / 8] = data[4] & 0xf0; - } else { + else crc_header[crc_pos / 8] = data[4]; - } - + produced += frame->subbands; crc_pos += frame->subbands; } @@ -1130,21 +1152,20 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) sbc_calculate_bits(frame, bits, sf); for (ch = 0; ch < frame->channels; ch++) { - for (sb = 0; sb < frame->subbands; sb++) { + for (sb = 0; sb < frame->subbands; sb++) levels[ch][sb] = (1 << bits[ch][sb]) - 1; - } } for (blk = 0; blk < frame->blocks; blk++) { for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) { - if (levels[ch][sb] > 0) { + if (levels[ch][sb] > 0) frame->audio_sample[blk][ch][sb] = - (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >> (frame->scale_factor[ch][sb] + 1)) + - levels[ch][sb]) >> 1); - } else { + (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >> + (frame->scale_factor[ch][sb] + 1)) + + levels[ch][sb]) >> 1); + else frame->audio_sample[blk][ch][sb] = 0; - } } } } @@ -1155,14 +1176,12 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) if (bits[ch][sb] != 0) { for (bit = 0; bit < bits[ch][sb]; bit++) { int b; /* A bit */ - if (produced > len * 8) { + if (produced > len * 8) return -1; - } - if (produced % 8 == 0) { + if (produced % 8 == 0) data[produced / 8] = 0; - } - b = ((frame->audio_sample[blk][ch][sb]) >> (bits[ch][sb] - bit - - 1)) & 0x01; + b = ((frame->audio_sample[blk][ch][sb]) >> + (bits[ch][sb] - bit - 1)) & 0x01; data[produced / 8] |= b << (7 - (produced % 8)); produced++; } @@ -1171,9 +1190,8 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) } } - if (produced % 8 != 0) { + if (produced % 8 != 0) produced += 8 - (produced % 8); - } return produced / 8; } @@ -1226,7 +1244,6 @@ int sbc_decode(sbc_t *sbc, void *data, int count) priv = sbc->priv; framelen = sbc_unpack_frame(data, &priv->frame, count); - if (!priv->init) { sbc_decoder_init(&priv->dec_state, &priv->frame); -- cgit From ec233a1f849d1880697ef741f19906a4f9fcbc05 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 2 Nov 2007 09:05:57 +0000 Subject: More coding style cleanup --- sbc/sbc.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 3e65603d..76df0652 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -159,7 +159,7 @@ static const uint8_t crc_table[256] = { 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4 }; -static uint8_t sbc_crc8(const uint8_t * data, size_t len) +static uint8_t sbc_crc8(const uint8_t *data, size_t len) { uint8_t crc = 0x0f; size_t i; @@ -323,6 +323,7 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui } } } while (bitcount + slicecount < frame->bitpool); + if (bitcount + slicecount == frame->bitpool) { bitcount += slicecount; bitslice--; @@ -386,7 +387,7 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui * -3 CRC8 incorrect * -4 Bitpool value out of bounds */ -static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, +static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, size_t len) { int consumed; @@ -459,12 +460,12 @@ static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, frame->bitpool = data[2]; - if (((frame->channel_mode == MONO || - frame->channel_mode == DUAL_CHANNEL) && - frame->bitpool > 16 * frame->subbands) || - ((frame->channel_mode == STEREO || - frame->channel_mode == JOINT_STEREO) && - frame->bitpool > 32 * frame->subbands)) + if ((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) && + frame->bitpool > 16 * frame->subbands) + return -4; + + if ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) && + frame->bitpool > 32 * frame->subbands) return -4; /* data[3] is crc, we're checking it later */ @@ -600,17 +601,17 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, int i, j, k, idx; sbc_extended_t res; - for(i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { /* Shifting */ state->offset[ch][i]--; if (state->offset[ch][i] < 0) { state->offset[ch][i] = 79; - for(j = 0; j < 9; j++) + for (j = 0; j < 9; j++) state->V[ch][j+80] = state->V[ch][j]; } } - for(i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { /* Distribute the new matrix value to the shifted position */ SBC_FIXED_0(res); for (j = 0; j < 4; j++) @@ -619,10 +620,10 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, } /* Compute the samples */ - for(idx = 0, i = 0; i < 4; i++) { + for (idx = 0, i = 0; i < 4; i++) { k = (i + 4) & 0xf; SBC_FIXED_0(res); - for(j = 0; j < 10; idx++) { + for (j = 0; j < 10; idx++) { MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_4_40m0[idx]); MULA(res, state->V[ch][state->offset[ch][k]+j++], @@ -640,17 +641,17 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, int i, j, k, idx; sbc_extended_t res; - for(i = 0; i < 16; i++) { + for (i = 0; i < 16; i++) { /* Shifting */ state->offset[ch][i]--; if (state->offset[ch][i] < 0) { state->offset[ch][i] = 159; - for(j = 0; j < 9; j++) + for (j = 0; j < 9; j++) state->V[ch][j+160] = state->V[ch][j]; } } - for(i = 0; i < 16; i++) { + for (i = 0; i < 16; i++) { /* Distribute the new matrix value to the shifted position */ SBC_FIXED_0(res); for (j = 0; j < 8; j++) { @@ -662,10 +663,10 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, } /* Compute the samples */ - for(idx = 0, i = 0; i < 8; i++) { + for (idx = 0, i = 0; i < 8; i++) { k = (i + 8) & 0xf; SBC_FIXED_0(res); - for(j = 0; j < 10; idx++) { + for (j = 0; j < 10; idx++) { MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_8_80m0[idx]); MULA(res, state->V[ch][state->offset[ch][k]+j++], sbc_proto_8_80m1[idx]); } @@ -772,6 +773,7 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) out[2] = SCALE4_STAGE2(-s[0] + s[1] - s[3]); out[3] = SCALE4_STAGE2( s[0] + s[1] - s[2]); } + static inline void sbc_analyze_four(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { @@ -959,7 +961,7 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state, * -99 not implemented */ -static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) +static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) { int produced; /* Will copy the header parts for CRC-8 calculation here */ @@ -975,9 +977,8 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) u_int32_t scalefactor[2][8]; /* derived from frame->scale_factor */ - if (len < 4) { + if (len < 4) return -1; - } /* Clear first 4 bytes of data (that's the constant length part of the * SBC header) */ @@ -997,9 +998,8 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) } else if (frame->sampling_frequency == 48000) { data[1] |= (SBC_FS_48 & 0x03) << 6; sf = SBC_FS_48; - } else { + } else return -2; - } switch (frame->blocks) { case 4: @@ -1036,6 +1036,7 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) } data[2] = frame->bitpool; + if ((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) && frame->bitpool > 16 * frame->subbands) return -5; @@ -1123,6 +1124,7 @@ static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len) data[4] = 0; for (sb = 0; sb < frame->subbands - 1; sb++) data[4] |= ((frame->join >> sb) & 0x01) << (7 - sb); + if (frame->subbands == 4) crc_header[crc_pos / 8] = data[4] & 0xf0; else -- cgit From 316166212f59f4bc7bad778ff46e8b6986c52874 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Mon, 5 Nov 2007 15:54:50 +0000 Subject: correction in the 4 subband optimization --- sbc/sbc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 76df0652..c95862a0 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -713,7 +713,7 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) sbc_extended_t res; sbc_extended_t t[8]; - sbc_extended_t s[4]; + sbc_extended_t s[5]; MUL(res, _sbc_proto_4[0], (in[8] - in[32])); /* Q18 */ MULA(res, _sbc_proto_4[1], (in[16] - in[24])); @@ -765,13 +765,14 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) MUL(s[0], _anamatrix4[0], t[0] + t[4]); MUL(s[1], _anamatrix4[2], t[2]); MUL(s[2], _anamatrix4[1], t[1] + t[3]); - MULA(s[2], _anamatrix4[3], t[5] + t[7]); + MULA(s[2], _anamatrix4[3], t[5]); MUL(s[3], _anamatrix4[3], t[1] + t[3]); MULA(s[3], _anamatrix4[1], - t[5] + t[7]); - out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2]); /* Q0 */ + MUL(s[4], _anamatrix4[3], t[7]); + out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2] + s[4]); /* Q0 */ out[1] = SCALE4_STAGE2(-s[0] + s[1] + s[3]); out[2] = SCALE4_STAGE2(-s[0] + s[1] - s[3]); - out[3] = SCALE4_STAGE2( s[0] + s[1] - s[2]); + out[3] = SCALE4_STAGE2( s[0] + s[1] - s[2] - s[4]); } static inline void sbc_analyze_four(struct sbc_encoder_state *state, -- cgit From 397d6c2b3bc7661f978c1777442d33fd86ada21e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 12 Nov 2007 18:15:59 +0000 Subject: Make sbc codec to write directly in application buffers and so avoiding memcpys. --- sbc/sbc.c | 98 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 39 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index c95862a0..ec1cc37d 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -95,6 +95,8 @@ struct sbc_frame { } allocation_method; uint8_t subbands; uint8_t bitpool; + uint8_t codesize; + uint8_t length; /* bit number x set means joint stereo has been used in subband x */ uint8_t join; @@ -1230,23 +1232,24 @@ int sbc_init(sbc_t *sbc, unsigned long flags) return 0; } -int sbc_parse(sbc_t *sbc, void *data, int count) +int sbc_parse(sbc_t *sbc, void *input, int input_len) { - return sbc_decode(sbc, data, count); + return sbc_decode(sbc, input, input_len, NULL, 0, NULL); } -int sbc_decode(sbc_t *sbc, void *data, int count) +int sbc_decode(sbc_t *sbc, void *input, int input_len, void *output, + int output_len, int *written) { struct sbc_priv *priv; char *ptr; int i, ch, framelen, samples; - if (!sbc) + if (!sbc && !input) return -EIO; priv = sbc->priv; - framelen = sbc_unpack_frame(data, &priv->frame, count); + framelen = sbc_unpack_frame(input, &priv->frame, input_len); if (!priv->init) { sbc_decoder_init(&priv->dec_state, &priv->frame); @@ -1257,26 +1260,23 @@ int sbc_decode(sbc_t *sbc, void *data, int count) sbc->subbands = priv->frame.subbands; sbc->blocks = priv->frame.blocks; sbc->bitpool = priv->frame.bitpool; + + priv->frame.codesize = sbc_get_codesize(sbc); + priv->frame.length = sbc_get_frame_length(sbc); } - samples = sbc_synthesize_audio(&priv->dec_state, &priv->frame); + if (!output) + return framelen; - if (!sbc->data) { - sbc->size = samples * priv->frame.channels * 2; - sbc->data = malloc(sbc->size); - } + if (written) + *written = 0; - if (sbc->size < samples * priv->frame.channels * 2) { - sbc->size = samples * priv->frame.channels * 2; - sbc->data = realloc(sbc->data, sbc->size); - } + samples = sbc_synthesize_audio(&priv->dec_state, &priv->frame); - if (!sbc->data) { - sbc->size = 0; - return -ENOMEM; - } + ptr = output; - ptr = sbc->data; + if (output_len < samples * priv->frame.channels * 2) + samples = output_len / (priv->frame.channels * 2); for (i = 0; i < samples; i++) { for (ch = 0; ch < priv->frame.channels; ch++) { @@ -1293,22 +1293,27 @@ int sbc_decode(sbc_t *sbc, void *data, int count) } } - sbc->len = samples * priv->frame.channels * 2; + if (written) + *written = samples * priv->frame.channels * 2; return framelen; } -int sbc_encode(sbc_t *sbc, void *data, int count) +int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output, + int output_len, int *written) { struct sbc_priv *priv; char *ptr; int i, ch, framelen, samples; - if (!sbc) + if (!sbc && !input) return -EIO; priv = sbc->priv; + if (written) + *written = 0; + if (!priv->init) { priv->frame.sampling_frequency = sbc->rate; priv->frame.channels = sbc->channels; @@ -1325,16 +1330,22 @@ int sbc_encode(sbc_t *sbc, void *data, int count) priv->frame.subbands = sbc->subbands; priv->frame.blocks = sbc->blocks; priv->frame.bitpool = sbc->bitpool; + priv->frame.codesize = sbc_get_codesize(sbc); + priv->frame.length = sbc_get_frame_length(sbc); sbc_encoder_init(&priv->enc_state, &priv->frame); priv->init = 1; } /* input must be large enough to encode a complete frame */ - if (count < priv->frame.subbands * priv->frame.blocks * sbc->channels * 2) + if (input_len < priv->frame.codesize) return 0; - ptr = data; + /* output must be large enough to receive the encoded frame */ + if (!output || output_len < priv->frame.length) + return -ENOSPC; + + ptr = input; for (i = 0; i < priv->frame.subbands * priv->frame.blocks; i++) { for (ch = 0; ch < sbc->channels; ch++) { @@ -1351,19 +1362,10 @@ int sbc_encode(sbc_t *sbc, void *data, int count) samples = sbc_analyze_audio(&priv->enc_state, &priv->frame); - if (!sbc->data) { - sbc->size = 1024; - sbc->data = malloc(sbc->size); - } - - if (!sbc->data) { - sbc->size = 0; - return -ENOMEM; - } + framelen = sbc_pack_frame(output, &priv->frame, output_len); - framelen = sbc_pack_frame(sbc->data, &priv->frame, sbc->size); - - sbc->len = framelen; + if (written) + *written = framelen; sbc->duration = (1000000 * priv->frame.subbands * priv->frame.blocks) / sbc->rate; @@ -1375,11 +1377,29 @@ void sbc_finish(sbc_t *sbc) if (!sbc) return; - if (sbc->data) - free(sbc->data); - if (sbc->priv) free(sbc->priv); memset(sbc, 0, sizeof(sbc_t)); } + +int sbc_get_frame_length(sbc_t *sbc) +{ + int ret; + + ret = 4 + (4 * sbc->subbands * sbc->channels) / 8; + + /* This term is not always evenly devide so we round it up */ + if (sbc->channels == 1) + ret += ((sbc->blocks * sbc->channels * sbc->bitpool) + 7) / 8; + else + ret += ((sbc->joint * sbc->subbands + sbc->blocks * sbc->bitpool) + + 7) / 8; + + return ret; +} + +int sbc_get_codesize(sbc_t *sbc) +{ + return sbc->subbands * sbc->blocks * sbc->channels * 2; +} -- cgit From 6d94a5b2e34c55611f2d6ea70c241971e65afc8c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 13 Nov 2007 20:04:12 +0000 Subject: Add sbc_reinit. --- sbc/sbc.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index ec1cc37d..12906718 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1208,6 +1208,17 @@ struct sbc_priv { struct sbc_encoder_state enc_state; }; +static void sbc_fill_defaults(sbc_t *sbc, unsigned long flags) +{ + sbc->rate = 44100; + sbc->channels = 2; + sbc->joint = 0; + sbc->subbands = 8; + sbc->blocks = 16; + sbc->bitpool = 32; + sbc->swap = 0; +} + int sbc_init(sbc_t *sbc, unsigned long flags) { if (!sbc) @@ -1221,13 +1232,7 @@ int sbc_init(sbc_t *sbc, unsigned long flags) memset(sbc->priv, 0, sizeof(struct sbc_priv)); - sbc->rate = 44100; - sbc->channels = 2; - sbc->joint = 0; - sbc->subbands = 8; - sbc->blocks = 16; - sbc->bitpool = 32; - sbc->swap = 0; + sbc_fill_defaults(sbc, flags); return 0; } @@ -1389,7 +1394,7 @@ int sbc_get_frame_length(sbc_t *sbc) ret = 4 + (4 * sbc->subbands * sbc->channels) / 8; - /* This term is not always evenly devide so we round it up */ + /* This term is not always evenly divide so we round it up */ if (sbc->channels == 1) ret += ((sbc->blocks * sbc->channels * sbc->bitpool) + 7) / 8; else @@ -1403,3 +1408,20 @@ int sbc_get_codesize(sbc_t *sbc) { return sbc->subbands * sbc->blocks * sbc->channels * 2; } + +int sbc_reinit(sbc_t *sbc, unsigned long flags) +{ + struct sbc_priv *priv; + + if (!sbc || !sbc->priv) + return -EIO; + + priv = sbc->priv; + + if (priv->init == 1) + memset(sbc->priv, 0, sizeof(struct sbc_priv)); + + sbc_fill_defaults(sbc, flags); + + return 0; +} -- cgit From 54e6e9fcea08bce3bc2b01fb562a74feafaa52be Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 13 Nov 2007 20:59:17 +0000 Subject: Change name of sbc_fill_defaults to sbc_set_defaults. --- sbc/sbc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 12906718..50af4a1e 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1208,7 +1208,7 @@ struct sbc_priv { struct sbc_encoder_state enc_state; }; -static void sbc_fill_defaults(sbc_t *sbc, unsigned long flags) +static void sbc_set_defaults(sbc_t *sbc, unsigned long flags) { sbc->rate = 44100; sbc->channels = 2; @@ -1232,7 +1232,7 @@ int sbc_init(sbc_t *sbc, unsigned long flags) memset(sbc->priv, 0, sizeof(struct sbc_priv)); - sbc_fill_defaults(sbc, flags); + sbc_set_defaults(sbc, flags); return 0; } @@ -1421,7 +1421,7 @@ int sbc_reinit(sbc_t *sbc, unsigned long flags) if (priv->init == 1) memset(sbc->priv, 0, sizeof(struct sbc_priv)); - sbc_fill_defaults(sbc, flags); + sbc_set_defaults(sbc, flags); return 0; } -- cgit From 8db224b3cae791b950abcc826259ef342161f454 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 23 Nov 2007 14:24:23 +0000 Subject: Introduce sbc_get_frame_duration. --- sbc/sbc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 50af4a1e..c090dd83 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1372,8 +1372,6 @@ int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output, if (written) *written = framelen; - sbc->duration = (1000000 * priv->frame.subbands * priv->frame.blocks) / sbc->rate; - return samples * sbc->channels * 2; } @@ -1404,6 +1402,11 @@ int sbc_get_frame_length(sbc_t *sbc) return ret; } +int sbc_get_frame_duration(sbc_t *sbc) +{ + return (1000000 * sbc->blocks * sbc->subbands) / sbc->rate; +} + int sbc_get_codesize(sbc_t *sbc) { return sbc->subbands * sbc->blocks * sbc->channels * 2; -- cgit From 75d93a32258f2c0158c05014fce4d791660a4e45 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Tue, 27 Nov 2007 02:42:29 +0000 Subject: rework joint subband test--uses a lot less stack space, simplify multiple loops into one, unroll one tiny loop --- sbc/sbc.c | 58 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index c090dd83..880e1b47 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1071,52 +1071,56 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) if (frame->channel_mode == JOINT_STEREO) { /* like frame->sb_sample but joint stereo */ - int32_t sb_sample_j[16][2][7]; + int32_t sb_sample_j[16][2]; /* scalefactor and scale_factor in joint case */ - int scalefactor_j[2][7], scale_factor_j[2][7]; + u_int32_t scalefactor_j[2]; + uint8_t scale_factor_j[2]; + + frame->join = 0; - /* Calculate joint stereo signal */ for (sb = 0; sb < frame->subbands - 1; sb++) { + /* Calculate joint stereo signal */ for (blk = 0; blk < frame->blocks; blk++) { - sb_sample_j[blk][0][sb] = + sb_sample_j[blk][0] = (frame->sb_sample_f[blk][0][sb] + frame->sb_sample_f[blk][1][sb]) >> 1; - sb_sample_j[blk][1][sb] = + sb_sample_j[blk][1] = (frame->sb_sample_f[blk][0][sb] - frame->sb_sample_f[blk][1][sb]) >> 1; } - } - /* calculate scale_factor_j and scalefactor_j for joint case */ - for (ch = 0; ch < 2; ch++) { - for (sb = 0; sb < frame->subbands - 1; sb++) { - scale_factor_j[ch][sb] = 0; - scalefactor_j[ch][sb] = 2; - for (blk = 0; blk < frame->blocks; blk++) { - while (scalefactor_j[ch][sb] < fabs(sb_sample_j[blk][ch][sb])) { - scale_factor_j[ch][sb]++; - scalefactor_j[ch][sb] *= 2; - } + /* calculate scale_factor_j and scalefactor_j for joint case */ + scale_factor_j[0] = 0; + scalefactor_j[0] = 2; + for (blk = 0; blk < frame->blocks; blk++) { + while (scalefactor_j[0] < fabs(sb_sample_j[blk][0])) { + scale_factor_j[0]++; + scalefactor_j[0] *= 2; + } + } + scale_factor_j[1] = 0; + scalefactor_j[1] = 2; + for (blk = 0; blk < frame->blocks; blk++) { + while (scalefactor_j[1] < fabs(sb_sample_j[blk][1])) { + scale_factor_j[1]++; + scalefactor_j[1] *= 2; } } - } - /* decide which subbands to join */ - frame->join = 0; - for (sb = 0; sb < frame->subbands - 1; sb++) { + /* decide whether to join this subband */ if ((scalefactor[0][sb] + scalefactor[1][sb]) > - (scalefactor_j[0][sb] + scalefactor_j[1][sb]) ) { + (scalefactor_j[0] + scalefactor_j[1]) ) { /* use joint stereo for this subband */ frame->join |= 1 << sb; - frame->scale_factor[0][sb] = scale_factor_j[0][sb]; - frame->scale_factor[1][sb] = scale_factor_j[1][sb]; - scalefactor[0][sb] = scalefactor_j[0][sb]; - scalefactor[1][sb] = scalefactor_j[1][sb]; + frame->scale_factor[0][sb] = scale_factor_j[0]; + frame->scale_factor[1][sb] = scale_factor_j[1]; + scalefactor[0][sb] = scalefactor_j[0]; + scalefactor[1][sb] = scalefactor_j[1]; for (blk = 0; blk < frame->blocks; blk++) { frame->sb_sample_f[blk][0][sb] = - sb_sample_j[blk][0][sb]; + sb_sample_j[blk][0]; frame->sb_sample_f[blk][1][sb] = - sb_sample_j[blk][1][sb]; + sb_sample_j[blk][1]; } } } -- cgit From 6a2bcc32bffe68e452c2ce7e0bb328b1f7b7b9bb Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Tue, 27 Nov 2007 03:15:36 +0000 Subject: combine the blk loops inside the joint conditional --- sbc/sbc.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 880e1b47..d5ccf1fa 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1079,28 +1079,25 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) frame->join = 0; for (sb = 0; sb < frame->subbands - 1; sb++) { - /* Calculate joint stereo signal */ + scale_factor_j[0] = 0; + scalefactor_j[0] = 2; + scale_factor_j[1] = 0; + scalefactor_j[1] = 2; + for (blk = 0; blk < frame->blocks; blk++) { + /* Calculate joint stereo signal */ sb_sample_j[blk][0] = (frame->sb_sample_f[blk][0][sb] + frame->sb_sample_f[blk][1][sb]) >> 1; sb_sample_j[blk][1] = (frame->sb_sample_f[blk][0][sb] - frame->sb_sample_f[blk][1][sb]) >> 1; - } - /* calculate scale_factor_j and scalefactor_j for joint case */ - scale_factor_j[0] = 0; - scalefactor_j[0] = 2; - for (blk = 0; blk < frame->blocks; blk++) { + /* calculate scale_factor_j and scalefactor_j for joint case */ while (scalefactor_j[0] < fabs(sb_sample_j[blk][0])) { scale_factor_j[0]++; scalefactor_j[0] *= 2; } - } - scale_factor_j[1] = 0; - scalefactor_j[1] = 2; - for (blk = 0; blk < frame->blocks; blk++) { while (scalefactor_j[1] < fabs(sb_sample_j[blk][1])) { scale_factor_j[1]++; scalefactor_j[1] *= 2; -- cgit From 4a2b8a2e67d13e8ed974e2e91e093383493883a7 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Tue, 27 Nov 2007 06:22:48 +0000 Subject: eliminate extra loop for bitneed compute make a couple while loops easier to read as for loops --- sbc/sbc.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index d5ccf1fa..de88f82a 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -194,9 +194,13 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui int ch, sb; for (ch = 0; ch < frame->channels; ch++) { + max_bitneed = 0; if (frame->allocation_method == SNR) { - for (sb = 0; sb < frame->subbands; sb++) + for (sb = 0; sb < frame->subbands; sb++) { bitneed[ch][sb] = frame->scale_factor[ch][sb]; + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; + } } else { for (sb = 0; sb < frame->subbands; sb++) { if (frame->scale_factor[ch][sb] == 0) @@ -211,15 +215,11 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui else bitneed[ch][sb] = loudness; } + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; } } - max_bitneed = 0; - for (sb = 0; sb < frame->subbands; sb++) { - if (bitneed[ch][sb] > max_bitneed) - max_bitneed = bitneed[ch][sb]; - } - bitcount = 0; slicecount = 0; bitslice = max_bitneed + 1; @@ -250,8 +250,7 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui } } - sb = 0; - while (bitcount < frame->bitpool && sb < frame->subbands) { + for (sb = 0; bitcount < frame->bitpool && sb < frame->subbands; sb++) { if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) { bits[ch][sb]++; bitcount++; @@ -259,16 +258,13 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui bits[ch][sb] = 2; bitcount += 2; } - sb++; } - sb = 0; - while (bitcount < frame->bitpool && sb < frame->subbands) { + for (sb = 0; bitcount < frame->bitpool && sb < frame->subbands; sb++) { if (bits[ch][sb] < 16) { bits[ch][sb]++; bitcount++; } - sb++; } } -- cgit From 41c458777419bf2ff42a911d1315d81b30607ba5 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Tue, 27 Nov 2007 06:47:38 +0000 Subject: eliminate another max_bitneed loop, eliminate extraneous loop termination tests --- sbc/sbc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index de88f82a..ebf4a9d0 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -273,10 +273,14 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice; int ch, sb; + max_bitneed = 0; if (frame->allocation_method == SNR) { for (ch = 0; ch < 2; ch++) { - for (sb = 0; sb < frame->subbands; sb++) + for (sb = 0; sb < frame->subbands; sb++) { bitneed[ch][sb] = frame->scale_factor[ch][sb]; + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; + } } } else { for (ch = 0; ch < 2; ch++) { @@ -293,18 +297,12 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui else bitneed[ch][sb] = loudness; } + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; } } } - max_bitneed = 0; - for (ch = 0; ch < 2; ch++) { - for (sb = 0; sb < frame->subbands; sb++) { - if (bitneed[ch][sb] > max_bitneed) - max_bitneed = bitneed[ch][sb]; - } - } - bitcount = 0; slicecount = 0; bitslice = max_bitneed + 1; @@ -341,7 +339,7 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui ch = 0; sb = 0; - while ((bitcount < frame->bitpool) && (sb < frame->subbands)) { + while (bitcount < frame->bitpool) { if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) { bits[ch][sb]++; bitcount++; @@ -352,13 +350,14 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui if (ch == 1) { ch = 0; sb++; + if (sb >= frame->subbands) break; } else ch = 1; } ch = 0; sb = 0; - while ((bitcount < frame->bitpool) && (sb < frame->subbands)) { + while (bitcount < frame->bitpool) { if (bits[ch][sb] < 16) { bits[ch][sb]++; bitcount++; @@ -366,6 +365,7 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui if (ch == 1) { ch = 0; sb++; + if (sb >= frame->subbands) break; } else ch = 1; } -- cgit From 56dc26cadc212be0727b64e522723d45673d67a3 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 29 Nov 2007 20:23:22 +0000 Subject: Remove unnecessary checks for output buffer length and some optimizations. --- sbc/sbc.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index ebf4a9d0..c3d39478 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -976,9 +976,6 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) u_int32_t scalefactor[2][8]; /* derived from frame->scale_factor */ - if (len < 4) - return -1; - /* Clear first 4 bytes of data (that's the constant length part of the * SBC header) */ memset(data, 0, 4); @@ -1037,11 +1034,11 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) data[2] = frame->bitpool; if ((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) && - frame->bitpool > 16 * frame->subbands) + frame->bitpool > frame->subbands << 4) return -5; if ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) && - frame->bitpool > 32 * frame->subbands) + frame->bitpool > frame->subbands << 5) return -5; /* Can't fill in crc yet */ @@ -1118,31 +1115,25 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) } } - if (len * 8 < produced + frame->subbands) - return -1; - data[4] = 0; for (sb = 0; sb < frame->subbands - 1; sb++) data[4] |= ((frame->join >> sb) & 0x01) << (7 - sb); if (frame->subbands == 4) - crc_header[crc_pos / 8] = data[4] & 0xf0; + crc_header[crc_pos >> 3] = data[4] & 0xf0; else - crc_header[crc_pos / 8] = data[4]; + crc_header[crc_pos >> 3] = data[4]; produced += frame->subbands; crc_pos += frame->subbands; } - if (len * 8 < produced + (4 * frame->subbands * frame->channels)) - return -1; - for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) { if (produced % 8 == 0) data[produced / 8] = 0; - data[produced / 8] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (produced % 8))); - crc_header[crc_pos / 8] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (crc_pos % 8))); + data[produced >> 3] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (produced % 8))); + crc_header[crc_pos >> 3] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (crc_pos % 8))); produced += 4; crc_pos += 4; @@ -1168,23 +1159,15 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) levels[ch][sb]) >> 1); else frame->audio_sample[blk][ch][sb] = 0; - } - } - } - for (blk = 0; blk < frame->blocks; blk++) { - for (ch = 0; ch < frame->channels; ch++) { - for (sb = 0; sb < frame->subbands; sb++) { if (bits[ch][sb] != 0) { for (bit = 0; bit < bits[ch][sb]; bit++) { int b; /* A bit */ - if (produced > len * 8) - return -1; if (produced % 8 == 0) - data[produced / 8] = 0; + data[produced >> 3] = 0; b = ((frame->audio_sample[blk][ch][sb]) >> (bits[ch][sb] - bit - 1)) & 0x01; - data[produced / 8] |= b << (7 - (produced % 8)); + data[produced >> 3] |= b << (7 - (produced % 8)); produced++; } } @@ -1195,7 +1178,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) if (produced % 8 != 0) produced += 8 - (produced % 8); - return produced / 8; + return produced >> 3; } struct sbc_priv { -- cgit From 4161e8201ea54fe605b2aa14d864e0bad941c5d8 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 29 Nov 2007 21:48:12 +0000 Subject: don't use the audio_sample array inside the frame struct it's totally unnecessary to keep all these temporary results around --- sbc/sbc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index c3d39478..904227b5 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -969,6 +969,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) /* Sampling frequency as temporary value for table lookup */ uint8_t sf; + uint16_t audio_sample; int ch, sb, blk, bit; /* channel, subband, block and bit counters */ int bits[2][8]; /* bits distribution */ @@ -1153,19 +1154,19 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) { if (levels[ch][sb] > 0) - frame->audio_sample[blk][ch][sb] = + audio_sample = (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >> (frame->scale_factor[ch][sb] + 1)) + levels[ch][sb]) >> 1); else - frame->audio_sample[blk][ch][sb] = 0; + audio_sample = 0; if (bits[ch][sb] != 0) { for (bit = 0; bit < bits[ch][sb]; bit++) { int b; /* A bit */ if (produced % 8 == 0) data[produced >> 3] = 0; - b = ((frame->audio_sample[blk][ch][sb]) >> + b = ((audio_sample) >> (bits[ch][sb] - bit - 1)) & 0x01; data[produced >> 3] |= b << (7 - (produced % 8)); produced++; @@ -1175,10 +1176,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) } } - if (produced % 8 != 0) - produced += 8 - (produced % 8); - - return produced >> 3; + return (produced + 7) >> 3; } struct sbc_priv { -- cgit From 76e595a98b7b73ee54ae17e6162f05ad81c9b654 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 30 Nov 2007 01:20:01 +0000 Subject: change inner loop bit packing to use shift-in-place instead of complex ops --- sbc/sbc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 904227b5..a785c48d 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1162,20 +1162,21 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) audio_sample = 0; if (bits[ch][sb] != 0) { + audio_sample <<= 16 - bits[ch][sb]; for (bit = 0; bit < bits[ch][sb]; bit++) { - int b; /* A bit */ - if (produced % 8 == 0) - data[produced >> 3] = 0; - b = ((audio_sample) >> - (bits[ch][sb] - bit - 1)) & 0x01; - data[produced >> 3] |= b << (7 - (produced % 8)); + data[produced >> 3] <<= 1; + if(audio_sample & 0x8000) + data[produced >> 3] |= 0x1; + audio_sample <<= 1; produced++; } } } } } - + /* align the last byte */ + if(produced % 8) data[produced >> 3] <<= 8 - (produced % 8); + return (produced + 7) >> 3; } -- cgit From 87f83cd60537de472248311f48b6eb4cde6801d4 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 30 Nov 2007 15:53:04 +0000 Subject: combine two conditionals in bit packing --- sbc/sbc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index a785c48d..001910a5 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1153,15 +1153,11 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) for (blk = 0; blk < frame->blocks; blk++) { for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) { - if (levels[ch][sb] > 0) + if (levels[ch][sb] > 0) { audio_sample = (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >> (frame->scale_factor[ch][sb] + 1)) + levels[ch][sb]) >> 1); - else - audio_sample = 0; - - if (bits[ch][sb] != 0) { audio_sample <<= 16 - bits[ch][sb]; for (bit = 0; bit < bits[ch][sb]; bit++) { data[produced >> 3] <<= 1; -- cgit From 2e6b3caf16b973b4bcf71ae1f31d5c8276939f70 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 13 Dec 2007 17:16:20 +0000 Subject: don't need to memset the data header --- sbc/sbc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 001910a5..647760bb 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -977,23 +977,19 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) u_int32_t scalefactor[2][8]; /* derived from frame->scale_factor */ - /* Clear first 4 bytes of data (that's the constant length part of the - * SBC header) */ - memset(data, 0, 4); - data[0] = SBC_SYNCWORD; if (frame->sampling_frequency == 16000) { - data[1] |= (SBC_FS_16 & 0x03) << 6; + data[1] = (SBC_FS_16 & 0x03) << 6; sf = SBC_FS_16; } else if (frame->sampling_frequency == 32000) { - data[1] |= (SBC_FS_32 & 0x03) << 6; + data[1] = (SBC_FS_32 & 0x03) << 6; sf = SBC_FS_32; } else if (frame->sampling_frequency == 44100) { - data[1] |= (SBC_FS_44 & 0x03) << 6; + data[1] = (SBC_FS_44 & 0x03) << 6; sf = SBC_FS_44; } else if (frame->sampling_frequency == 48000) { - data[1] |= (SBC_FS_48 & 0x03) << 6; + data[1] = (SBC_FS_48 & 0x03) << 6; sf = SBC_FS_48; } else return -2; -- cgit From c5e43eefcc34641b875f2565c1c4b5b4616d3f58 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 14 Dec 2007 00:13:07 +0000 Subject: roll back the shift-in-place bitpack optimization while we figure out if it tickles a bug or creates a bug for 4 subbands --- sbc/sbc.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 647760bb..86efadcf 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1154,20 +1154,19 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >> (frame->scale_factor[ch][sb] + 1)) + levels[ch][sb]) >> 1); - audio_sample <<= 16 - bits[ch][sb]; for (bit = 0; bit < bits[ch][sb]; bit++) { - data[produced >> 3] <<= 1; - if(audio_sample & 0x8000) - data[produced >> 3] |= 0x1; - audio_sample <<= 1; + int b; /* A bit */ + if (produced % 8 == 0) + data[produced >> 3] = 0; + b = ((audio_sample) >> + (bits[ch][sb] - bit - 1)) & 0x01; + data[produced >> 3] |= b << (7 - (produced % 8)); produced++; } } } } } - /* align the last byte */ - if(produced % 8) data[produced >> 3] <<= 8 - (produced % 8); return (produced + 7) >> 3; } -- cgit From 356a8b48cde75a93680350454c293dc8913f4104 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 14 Dec 2007 00:15:33 +0000 Subject: be more strict about calculating from joint since client may set it to a funky value other than 0/1 --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 86efadcf..960a5bc5 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1366,7 +1366,7 @@ int sbc_get_frame_length(sbc_t *sbc) if (sbc->channels == 1) ret += ((sbc->blocks * sbc->channels * sbc->bitpool) + 7) / 8; else - ret += ((sbc->joint * sbc->subbands + sbc->blocks * sbc->bitpool) + ret += (((sbc->joint? sbc->subbands:0) + sbc->blocks * sbc->bitpool) + 7) / 8; return ret; -- cgit From 5acc7043cf566207181bb5030ebcd9e401b097df Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 14 Dec 2007 00:46:09 +0000 Subject: coding style on ?: --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 960a5bc5..9a4d8800 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1366,7 +1366,7 @@ int sbc_get_frame_length(sbc_t *sbc) if (sbc->channels == 1) ret += ((sbc->blocks * sbc->channels * sbc->bitpool) + 7) / 8; else - ret += (((sbc->joint? sbc->subbands:0) + sbc->blocks * sbc->bitpool) + ret += (((sbc->joint ? sbc->subbands : 0) + sbc->blocks * sbc->bitpool) + 7) / 8; return ret; -- cgit From c1ce3b25c4981ae88218fa46921969260b3afc43 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 14 Dec 2007 06:07:52 +0000 Subject: shift-in-place opt is back in, with a bugfix for the 4-subband case --- sbc/sbc.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 9a4d8800..a192ad83 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1137,6 +1137,10 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) } } + /* this is temporary until we use an in-place shift above */ + if(produced % 8) + data[produced >> 3] >>= 8 - (produced % 8); + data[3] = sbc_crc8(crc_header, crc_pos); sbc_calculate_bits(frame, bits, sf); @@ -1154,20 +1158,24 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >> (frame->scale_factor[ch][sb] + 1)) + levels[ch][sb]) >> 1); + audio_sample <<= 16 - bits[ch][sb]; for (bit = 0; bit < bits[ch][sb]; bit++) { - int b; /* A bit */ - if (produced % 8 == 0) - data[produced >> 3] = 0; - b = ((audio_sample) >> - (bits[ch][sb] - bit - 1)) & 0x01; - data[produced >> 3] |= b << (7 - (produced % 8)); + data[produced >> 3] <<= 1; + if(audio_sample & 0x8000) + data[produced >> 3] |= 0x1; + audio_sample <<= 1; produced++; } } } } } - + + /* align the last byte */ + if(produced % 8) { + data[produced >> 3] <<= 8 - (produced % 8); + } + return (produced + 7) >> 3; } -- cgit From 9a14d423e7def6933b4df4bae8e9185a62b346ea Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 14 Dec 2007 06:43:06 +0000 Subject: push in-place-shift optimization up into scalefactors section --- sbc/sbc.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index a192ad83..36f6696b 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1123,23 +1123,29 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) produced += frame->subbands; crc_pos += frame->subbands; + + /* this is temporary until we use an in-place shift above */ + if(produced % 8) { + data[produced >> 3] >>= 8 - (produced % 8); + crc_header[crc_pos >> 3] >>= 8 - (crc_pos % 8); + } } for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) { - if (produced % 8 == 0) - data[produced / 8] = 0; - data[produced >> 3] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (produced % 8))); - crc_header[crc_pos >> 3] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (crc_pos % 8))); + data[produced >> 3] <<= 4; + crc_header[crc_pos >> 3] <<= 4; + data[produced >> 3] |= frame->scale_factor[ch][sb] & 0x0F; + crc_header[crc_pos >> 3] |= frame->scale_factor[ch][sb] & 0x0F; produced += 4; crc_pos += 4; } } - /* this is temporary until we use an in-place shift above */ - if(produced % 8) - data[produced >> 3] >>= 8 - (produced % 8); + /* align the last crc byte */ + if(crc_pos % 8) + crc_header[crc_pos >> 3] <<= 8 - (crc_pos % 8); data[3] = sbc_crc8(crc_header, crc_pos); -- cgit From 1da4920f71140a3d9478f013a1ff000197f9a1eb Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 14 Dec 2007 06:54:19 +0000 Subject: smooth out last shift-in-place wrinkle --- sbc/sbc.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 36f6696b..cf27b38e 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1114,21 +1114,12 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) data[4] = 0; for (sb = 0; sb < frame->subbands - 1; sb++) - data[4] |= ((frame->join >> sb) & 0x01) << (7 - sb); + data[4] |= ((frame->join >> sb) & 0x01) << (frame->subbands - 1 - sb); - if (frame->subbands == 4) - crc_header[crc_pos >> 3] = data[4] & 0xf0; - else - crc_header[crc_pos >> 3] = data[4]; + crc_header[crc_pos >> 3] = data[4]; produced += frame->subbands; crc_pos += frame->subbands; - - /* this is temporary until we use an in-place shift above */ - if(produced % 8) { - data[produced >> 3] >>= 8 - (produced % 8); - crc_header[crc_pos >> 3] >>= 8 - (crc_pos % 8); - } } for (ch = 0; ch < frame->channels; ch++) { -- cgit From 40d383bb1ed20bcc638e738c8d0fb7a79008b126 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Tue, 8 Jan 2008 20:56:17 +0000 Subject: optimizations: use memmove instead of a loop, unroll short loop --- sbc/sbc.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index cf27b38e..991a5e1a 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -776,12 +776,16 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) static inline void sbc_analyze_four(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int i; - /* Input 4 New Audio Samples */ - for (i = 39; i >= 4; i--) - state->X[ch][i] = state->X[ch][i - 4]; - for (i = 3; i >= 0; i--) - state->X[ch][i] = frame->pcm_sample[ch][blk * 4 + (3 - i)]; + int32_t *x = state->X[ch]; + int16_t *pcm = &frame->pcm_sample[ch][blk * 8]; + + /* Input 4 Audio Samples */ + memmove(x + 4, x, 36 * sizeof(*x)); + x[3] = pcm[0]; + x[2] = pcm[1]; + x[1] = pcm[2]; + x[0] = pcm[3]; + _sbc_analyze_four(state->X[ch], frame->sb_sample_f[blk][ch]); } @@ -912,13 +916,20 @@ static inline void sbc_analyze_eight(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int i; + int32_t *x = state->X[ch]; + int16_t *pcm = &frame->pcm_sample[ch][blk * 8]; /* Input 8 Audio Samples */ - for (i = 79; i >= 8; i--) - state->X[ch][i] = state->X[ch][i - 8]; - for (i = 7; i >= 0; i--) - state->X[ch][i] = frame->pcm_sample[ch][blk * 8 + (7 - i)]; + memmove(x + 8, x, 72 * sizeof(*x)); + x[7] = pcm[0]; + x[6] = pcm[1]; + x[5] = pcm[2]; + x[4] = pcm[3]; + x[3] = pcm[4]; + x[2] = pcm[5]; + x[1] = pcm[6]; + x[0] = pcm[7]; + _sbc_analyze_eight(state->X[ch], frame->sb_sample_f[blk][ch]); } -- cgit From 0dda8d7230df625baf35aeb9dd72b20d0923aebd Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 11 Jan 2008 20:28:18 +0000 Subject: tweak to the memmove for 4 subbands --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 991a5e1a..0472762e 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -777,7 +777,7 @@ static inline void sbc_analyze_four(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { int32_t *x = state->X[ch]; - int16_t *pcm = &frame->pcm_sample[ch][blk * 8]; + int16_t *pcm = &frame->pcm_sample[ch][blk * 4]; /* Input 4 Audio Samples */ memmove(x + 4, x, 36 * sizeof(*x)); -- cgit From d4d085c9a00d2d457b1a97b46b5f52bf68cd4a1a Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Mon, 14 Jan 2008 14:40:57 +0000 Subject: take out memmove in sbc analyze --- sbc/sbc.c | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 0472762e..8e2aff62 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -120,7 +120,8 @@ struct sbc_decoder_state { struct sbc_encoder_state { int subbands; - int32_t X[2][80]; + int position[2]; + int32_t X[2][160]; }; /* @@ -704,6 +705,7 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, { memset(&state->X, 0, sizeof(state->X)); state->subbands = frame->subbands; + state->position[0] = state->position[1] = 80; } static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) @@ -776,17 +778,20 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) static inline void sbc_analyze_four(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int32_t *x = state->X[ch]; + int32_t *x = &state->X[ch][state->position[ch]]; int16_t *pcm = &frame->pcm_sample[ch][blk * 4]; - /* Input 4 Audio Samples */ - memmove(x + 4, x, 36 * sizeof(*x)); - x[3] = pcm[0]; - x[2] = pcm[1]; - x[1] = pcm[2]; - x[0] = pcm[3]; + /* Input 8 Audio Samples */ + x[40] = x[0] = pcm[3]; + x[41] = x[1] = pcm[2]; + x[42] = x[2] = pcm[1]; + x[43] = x[3] = pcm[0]; + + _sbc_analyze_four(x, frame->sb_sample_f[blk][ch]); - _sbc_analyze_four(state->X[ch], frame->sb_sample_f[blk][ch]); + state->position[ch] -= 4; + if (state->position[ch] < 0) + state->position[ch] = 36; } static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) @@ -916,21 +921,24 @@ static inline void sbc_analyze_eight(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int32_t *x = state->X[ch]; + int32_t *x = &state->X[ch][state->position[ch]]; int16_t *pcm = &frame->pcm_sample[ch][blk * 8]; /* Input 8 Audio Samples */ - memmove(x + 8, x, 72 * sizeof(*x)); - x[7] = pcm[0]; - x[6] = pcm[1]; - x[5] = pcm[2]; - x[4] = pcm[3]; - x[3] = pcm[4]; - x[2] = pcm[5]; - x[1] = pcm[6]; - x[0] = pcm[7]; - - _sbc_analyze_eight(state->X[ch], frame->sb_sample_f[blk][ch]); + x[80] = x[0] = pcm[7]; + x[81] = x[1] = pcm[6]; + x[82] = x[2] = pcm[5]; + x[83] = x[3] = pcm[4]; + x[84] = x[4] = pcm[3]; + x[85] = x[5] = pcm[2]; + x[86] = x[6] = pcm[1]; + x[87] = x[7] = pcm[0]; + + _sbc_analyze_eight(x, frame->sb_sample_f[blk][ch]); + + state->position[ch] -= 8; + if (state->position[ch] < 0) + state->position[ch] = 72; } static int sbc_analyze_audio(struct sbc_encoder_state *state, -- cgit From 23f3e84ba43efde94aa52c77455ff28662ed2b79 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Mon, 14 Jan 2008 15:03:23 +0000 Subject: fix initialization --- sbc/sbc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 8e2aff62..d8385bd8 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -705,7 +705,10 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, { memset(&state->X, 0, sizeof(state->X)); state->subbands = frame->subbands; - state->position[0] = state->position[1] = 80; + if(frame->subbands == 8) + state->position[0] = state->position[1] = 72; + else + state->position[0] = state->position[1] = 36; } static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) -- cgit From 8c72b28a0ccaf232e871863d32fedb9da750e6eb Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Mon, 14 Jan 2008 20:03:42 +0000 Subject: comment typo --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index d8385bd8..ac40dc26 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -784,7 +784,7 @@ static inline void sbc_analyze_four(struct sbc_encoder_state *state, int32_t *x = &state->X[ch][state->position[ch]]; int16_t *pcm = &frame->pcm_sample[ch][blk * 4]; - /* Input 8 Audio Samples */ + /* Input 4 Audio Samples */ x[40] = x[0] = pcm[3]; x[41] = x[1] = pcm[2]; x[42] = x[2] = pcm[1]; -- cgit From 910d62035726402a249d13b58b4b52baa9e7466e Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Mon, 14 Jan 2008 22:15:17 +0000 Subject: coding style --- sbc/sbc.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index ac40dc26..3202e602 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -705,10 +705,7 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, { memset(&state->X, 0, sizeof(state->X)); state->subbands = frame->subbands; - if(frame->subbands == 8) - state->position[0] = state->position[1] = 72; - else - state->position[0] = state->position[1] = 36; + state->position[0] = state->position[1] = 9 * frame->subbands; } static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) @@ -1157,7 +1154,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) } /* align the last crc byte */ - if(crc_pos % 8) + if (crc_pos % 8) crc_header[crc_pos >> 3] <<= 8 - (crc_pos % 8); data[3] = sbc_crc8(crc_header, crc_pos); @@ -1180,7 +1177,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) audio_sample <<= 16 - bits[ch][sb]; for (bit = 0; bit < bits[ch][sb]; bit++) { data[produced >> 3] <<= 1; - if(audio_sample & 0x8000) + if (audio_sample & 0x8000) data[produced >> 3] |= 0x1; audio_sample <<= 1; produced++; @@ -1191,7 +1188,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) } /* align the last byte */ - if(produced % 8) { + if (produced % 8) { data[produced >> 3] <<= 8 - (produced % 8); } -- cgit From 66fe637352aeb2b5d376bff7095a7a5fd209a426 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sat, 19 Jan 2008 15:56:52 +0000 Subject: update copyrights --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 3202e602..9e6156ec 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -4,7 +4,7 @@ * * Copyright (C) 2004-2007 Marcel Holtmann * Copyright (C) 2004-2005 Henryk Ploetz - * Copyright (C) 2005-2006 Brad Midgley + * Copyright (C) 2005-2008 Brad Midgley * * * This library is free software; you can redistribute it and/or -- cgit From dae52eacbae42da81c3a569c28c4f09755f4f93b Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sat, 26 Jan 2008 05:24:50 +0000 Subject: pcm input array should be 16 not 32 bits use 32-bit product when multiplying two values limited to 16 bits each --- sbc/sbc.c | 150 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 75 insertions(+), 75 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 9e6156ec..a83dc7ce 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -121,7 +121,7 @@ struct sbc_decoder_state { struct sbc_encoder_state { int subbands; int position[2]; - int32_t X[2][160]; + int16_t X[2][160]; }; /* @@ -708,11 +708,11 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, state->position[0] = state->position[1] = 9 * frame->subbands; } -static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) -{ +static inline void _sbc_analyze_four(const int16_t *in, int32_t *out) +{ sbc_extended_t res; - sbc_extended_t t[8]; + sbc_fixed_t t[8]; sbc_extended_t s[5]; MUL(res, _sbc_proto_4[0], (in[8] - in[32])); /* Q18 */ @@ -778,7 +778,7 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) static inline void sbc_analyze_four(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int32_t *x = &state->X[ch][state->position[ch]]; + int16_t *x = &state->X[ch][state->position[ch]]; int16_t *pcm = &frame->pcm_sample[ch][blk * 4]; /* Input 4 Audio Samples */ @@ -794,95 +794,95 @@ static inline void sbc_analyze_four(struct sbc_encoder_state *state, state->position[ch] = 36; } -static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) +static inline void _sbc_analyze_eight(const int16_t *in, int32_t *out) { sbc_extended_t res; - sbc_extended_t t[8]; + sbc_fixed_t t[8]; sbc_extended_t s[8]; - MUL(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ - MULA(res, _sbc_proto_8[1], (in[32] - in[48])); - MULA(res, _sbc_proto_8[2], in[4]); - MULA(res, _sbc_proto_8[3], in[20]); - MULA(res, _sbc_proto_8[4], in[36]); - MULA(res, _sbc_proto_8[5], in[52]); + MUL32(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ + MULA32(res, _sbc_proto_8[1], (in[32] - in[48])); + MULA32(res, _sbc_proto_8[2], in[4]); + MULA32(res, _sbc_proto_8[3], in[20]); + MULA32(res, _sbc_proto_8[4], in[36]); + MULA32(res, _sbc_proto_8[5], in[52]); t[0] = SCALE8_STAGE1(res); /* Q10 */ - MUL(res, _sbc_proto_8[6], in[2]); - MULA(res, _sbc_proto_8[7], in[18]); - MULA(res, _sbc_proto_8[8], in[34]); - MULA(res, _sbc_proto_8[9], in[50]); - MULA(res, _sbc_proto_8[10], in[66]); + MUL32(res, _sbc_proto_8[6], in[2]); + MULA32(res, _sbc_proto_8[7], in[18]); + MULA32(res, _sbc_proto_8[8], in[34]); + MULA32(res, _sbc_proto_8[9], in[50]); + MULA32(res, _sbc_proto_8[10], in[66]); t[1] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[11], in[1]); - MULA(res, _sbc_proto_8[12], in[17]); - MULA(res, _sbc_proto_8[13], in[33]); - MULA(res, _sbc_proto_8[14], in[49]); - MULA(res, _sbc_proto_8[15], in[65]); - MULA(res, _sbc_proto_8[16], in[3]); - MULA(res, _sbc_proto_8[17], in[19]); - MULA(res, _sbc_proto_8[18], in[35]); - MULA(res, _sbc_proto_8[19], in[51]); - MULA(res, _sbc_proto_8[20], in[67]); + MUL32(res, _sbc_proto_8[11], in[1]); + MULA32(res, _sbc_proto_8[12], in[17]); + MULA32(res, _sbc_proto_8[13], in[33]); + MULA32(res, _sbc_proto_8[14], in[49]); + MULA32(res, _sbc_proto_8[15], in[65]); + MULA32(res, _sbc_proto_8[16], in[3]); + MULA32(res, _sbc_proto_8[17], in[19]); + MULA32(res, _sbc_proto_8[18], in[35]); + MULA32(res, _sbc_proto_8[19], in[51]); + MULA32(res, _sbc_proto_8[20], in[67]); t[2] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[21], in[5]); - MULA(res, _sbc_proto_8[22], in[21]); - MULA(res, _sbc_proto_8[23], in[37]); - MULA(res, _sbc_proto_8[24], in[53]); - MULA(res, _sbc_proto_8[25], in[69]); - MULA(res, -_sbc_proto_8[15], in[15]); - MULA(res, -_sbc_proto_8[14], in[31]); - MULA(res, -_sbc_proto_8[13], in[47]); - MULA(res, -_sbc_proto_8[12], in[63]); - MULA(res, -_sbc_proto_8[11], in[79]); + MUL32(res, _sbc_proto_8[21], in[5]); + MULA32(res, _sbc_proto_8[22], in[21]); + MULA32(res, _sbc_proto_8[23], in[37]); + MULA32(res, _sbc_proto_8[24], in[53]); + MULA32(res, _sbc_proto_8[25], in[69]); + MULA32(res, -_sbc_proto_8[15], in[15]); + MULA32(res, -_sbc_proto_8[14], in[31]); + MULA32(res, -_sbc_proto_8[13], in[47]); + MULA32(res, -_sbc_proto_8[12], in[63]); + MULA32(res, -_sbc_proto_8[11], in[79]); t[3] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[26], in[6]); - MULA(res, _sbc_proto_8[27], in[22]); - MULA(res, _sbc_proto_8[28], in[38]); - MULA(res, _sbc_proto_8[29], in[54]); - MULA(res, _sbc_proto_8[30], in[70]); - MULA(res, -_sbc_proto_8[10], in[14]); - MULA(res, -_sbc_proto_8[9], in[30]); - MULA(res, -_sbc_proto_8[8], in[46]); - MULA(res, -_sbc_proto_8[7], in[62]); - MULA(res, -_sbc_proto_8[6], in[78]); + MUL32(res, _sbc_proto_8[26], in[6]); + MULA32(res, _sbc_proto_8[27], in[22]); + MULA32(res, _sbc_proto_8[28], in[38]); + MULA32(res, _sbc_proto_8[29], in[54]); + MULA32(res, _sbc_proto_8[30], in[70]); + MULA32(res, -_sbc_proto_8[10], in[14]); + MULA32(res, -_sbc_proto_8[9], in[30]); + MULA32(res, -_sbc_proto_8[8], in[46]); + MULA32(res, -_sbc_proto_8[7], in[62]); + MULA32(res, -_sbc_proto_8[6], in[78]); t[4] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[31], in[7]); - MULA(res, _sbc_proto_8[32], in[23]); - MULA(res, _sbc_proto_8[33], in[39]); - MULA(res, _sbc_proto_8[34], in[55]); - MULA(res, _sbc_proto_8[35], in[71]); - MULA(res, -_sbc_proto_8[20], in[13]); - MULA(res, -_sbc_proto_8[19], in[29]); - MULA(res, -_sbc_proto_8[18], in[45]); - MULA(res, -_sbc_proto_8[17], in[61]); - MULA(res, -_sbc_proto_8[16], in[77]); + MUL32(res, _sbc_proto_8[31], in[7]); + MULA32(res, _sbc_proto_8[32], in[23]); + MULA32(res, _sbc_proto_8[33], in[39]); + MULA32(res, _sbc_proto_8[34], in[55]); + MULA32(res, _sbc_proto_8[35], in[71]); + MULA32(res, -_sbc_proto_8[20], in[13]); + MULA32(res, -_sbc_proto_8[19], in[29]); + MULA32(res, -_sbc_proto_8[18], in[45]); + MULA32(res, -_sbc_proto_8[17], in[61]); + MULA32(res, -_sbc_proto_8[16], in[77]); t[5] = SCALE8_STAGE1(res); MUL(res, _sbc_proto_8[36], in[8] + in[72]); MULA(res, _sbc_proto_8[37], in[24] + in[56]); - MULA(res, _sbc_proto_8[38], in[40]); - MULA(res, -_sbc_proto_8[39], in[12]); - MULA(res, -_sbc_proto_8[5], in[28]); - MULA(res, -_sbc_proto_8[4], in[44]); - MULA(res, -_sbc_proto_8[3], in[60]); - MULA(res, -_sbc_proto_8[2], in[76]); + MULA32(res, _sbc_proto_8[38], in[40]); + MULA32(res, -_sbc_proto_8[39], in[12]); + MULA32(res, -_sbc_proto_8[5], in[28]); + MULA32(res, -_sbc_proto_8[4], in[44]); + MULA32(res, -_sbc_proto_8[3], in[60]); + MULA32(res, -_sbc_proto_8[2], in[76]); t[6] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[35], in[9]); - MULA(res, _sbc_proto_8[34], in[25]); - MULA(res, _sbc_proto_8[33], in[41]); - MULA(res, _sbc_proto_8[32], in[57]); - MULA(res, _sbc_proto_8[31], in[73]); - MULA(res, -_sbc_proto_8[25], in[11]); - MULA(res, -_sbc_proto_8[24], in[27]); - MULA(res, -_sbc_proto_8[23], in[43]); - MULA(res, -_sbc_proto_8[22], in[59]); - MULA(res, -_sbc_proto_8[21], in[75]); + MUL32(res, _sbc_proto_8[35], in[9]); + MULA32(res, _sbc_proto_8[34], in[25]); + MULA32(res, _sbc_proto_8[33], in[41]); + MULA32(res, _sbc_proto_8[32], in[57]); + MULA32(res, _sbc_proto_8[31], in[73]); + MULA32(res, -_sbc_proto_8[25], in[11]); + MULA32(res, -_sbc_proto_8[24], in[27]); + MULA32(res, -_sbc_proto_8[23], in[43]); + MULA32(res, -_sbc_proto_8[22], in[59]); + MULA32(res, -_sbc_proto_8[21], in[75]); t[7] = SCALE8_STAGE1(res); MUL(s[0], _anamatrix8[0], t[0]); /* = Q14 * Q10 */ @@ -921,7 +921,7 @@ static inline void sbc_analyze_eight(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int32_t *x = &state->X[ch][state->position[ch]]; + int16_t *x = &state->X[ch][state->position[ch]]; int16_t *pcm = &frame->pcm_sample[ch][blk * 8]; /* Input 8 Audio Samples */ -- cgit From c9b510105937825c04c729b4bb02b87596b795fb Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sat, 26 Jan 2008 19:45:54 +0000 Subject: shorten the encoder tables to 16 bits, take out mula32/mul32 for now for simplicity --- sbc/sbc.c | 134 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 67 insertions(+), 67 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index a83dc7ce..cfcf6432 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -800,89 +800,89 @@ static inline void _sbc_analyze_eight(const int16_t *in, int32_t *out) sbc_fixed_t t[8]; sbc_extended_t s[8]; - MUL32(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ - MULA32(res, _sbc_proto_8[1], (in[32] - in[48])); - MULA32(res, _sbc_proto_8[2], in[4]); - MULA32(res, _sbc_proto_8[3], in[20]); - MULA32(res, _sbc_proto_8[4], in[36]); - MULA32(res, _sbc_proto_8[5], in[52]); + MUL(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ + MULA(res, _sbc_proto_8[1], (in[32] - in[48])); + MULA(res, _sbc_proto_8[2], in[4]); + MULA(res, _sbc_proto_8[3], in[20]); + MULA(res, _sbc_proto_8[4], in[36]); + MULA(res, _sbc_proto_8[5], in[52]); t[0] = SCALE8_STAGE1(res); /* Q10 */ - MUL32(res, _sbc_proto_8[6], in[2]); - MULA32(res, _sbc_proto_8[7], in[18]); - MULA32(res, _sbc_proto_8[8], in[34]); - MULA32(res, _sbc_proto_8[9], in[50]); - MULA32(res, _sbc_proto_8[10], in[66]); + MUL(res, _sbc_proto_8[6], in[2]); + MULA(res, _sbc_proto_8[7], in[18]); + MULA(res, _sbc_proto_8[8], in[34]); + MULA(res, _sbc_proto_8[9], in[50]); + MULA(res, _sbc_proto_8[10], in[66]); t[1] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[11], in[1]); - MULA32(res, _sbc_proto_8[12], in[17]); - MULA32(res, _sbc_proto_8[13], in[33]); - MULA32(res, _sbc_proto_8[14], in[49]); - MULA32(res, _sbc_proto_8[15], in[65]); - MULA32(res, _sbc_proto_8[16], in[3]); - MULA32(res, _sbc_proto_8[17], in[19]); - MULA32(res, _sbc_proto_8[18], in[35]); - MULA32(res, _sbc_proto_8[19], in[51]); - MULA32(res, _sbc_proto_8[20], in[67]); + MUL(res, _sbc_proto_8[11], in[1]); + MULA(res, _sbc_proto_8[12], in[17]); + MULA(res, _sbc_proto_8[13], in[33]); + MULA(res, _sbc_proto_8[14], in[49]); + MULA(res, _sbc_proto_8[15], in[65]); + MULA(res, _sbc_proto_8[16], in[3]); + MULA(res, _sbc_proto_8[17], in[19]); + MULA(res, _sbc_proto_8[18], in[35]); + MULA(res, _sbc_proto_8[19], in[51]); + MULA(res, _sbc_proto_8[20], in[67]); t[2] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[21], in[5]); - MULA32(res, _sbc_proto_8[22], in[21]); - MULA32(res, _sbc_proto_8[23], in[37]); - MULA32(res, _sbc_proto_8[24], in[53]); - MULA32(res, _sbc_proto_8[25], in[69]); - MULA32(res, -_sbc_proto_8[15], in[15]); - MULA32(res, -_sbc_proto_8[14], in[31]); - MULA32(res, -_sbc_proto_8[13], in[47]); - MULA32(res, -_sbc_proto_8[12], in[63]); - MULA32(res, -_sbc_proto_8[11], in[79]); + MUL(res, _sbc_proto_8[21], in[5]); + MULA(res, _sbc_proto_8[22], in[21]); + MULA(res, _sbc_proto_8[23], in[37]); + MULA(res, _sbc_proto_8[24], in[53]); + MULA(res, _sbc_proto_8[25], in[69]); + MULA(res, -_sbc_proto_8[15], in[15]); + MULA(res, -_sbc_proto_8[14], in[31]); + MULA(res, -_sbc_proto_8[13], in[47]); + MULA(res, -_sbc_proto_8[12], in[63]); + MULA(res, -_sbc_proto_8[11], in[79]); t[3] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[26], in[6]); - MULA32(res, _sbc_proto_8[27], in[22]); - MULA32(res, _sbc_proto_8[28], in[38]); - MULA32(res, _sbc_proto_8[29], in[54]); - MULA32(res, _sbc_proto_8[30], in[70]); - MULA32(res, -_sbc_proto_8[10], in[14]); - MULA32(res, -_sbc_proto_8[9], in[30]); - MULA32(res, -_sbc_proto_8[8], in[46]); - MULA32(res, -_sbc_proto_8[7], in[62]); - MULA32(res, -_sbc_proto_8[6], in[78]); + MUL(res, _sbc_proto_8[26], in[6]); + MULA(res, _sbc_proto_8[27], in[22]); + MULA(res, _sbc_proto_8[28], in[38]); + MULA(res, _sbc_proto_8[29], in[54]); + MULA(res, _sbc_proto_8[30], in[70]); + MULA(res, -_sbc_proto_8[10], in[14]); + MULA(res, -_sbc_proto_8[9], in[30]); + MULA(res, -_sbc_proto_8[8], in[46]); + MULA(res, -_sbc_proto_8[7], in[62]); + MULA(res, -_sbc_proto_8[6], in[78]); t[4] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[31], in[7]); - MULA32(res, _sbc_proto_8[32], in[23]); - MULA32(res, _sbc_proto_8[33], in[39]); - MULA32(res, _sbc_proto_8[34], in[55]); - MULA32(res, _sbc_proto_8[35], in[71]); - MULA32(res, -_sbc_proto_8[20], in[13]); - MULA32(res, -_sbc_proto_8[19], in[29]); - MULA32(res, -_sbc_proto_8[18], in[45]); - MULA32(res, -_sbc_proto_8[17], in[61]); - MULA32(res, -_sbc_proto_8[16], in[77]); + MUL(res, _sbc_proto_8[31], in[7]); + MULA(res, _sbc_proto_8[32], in[23]); + MULA(res, _sbc_proto_8[33], in[39]); + MULA(res, _sbc_proto_8[34], in[55]); + MULA(res, _sbc_proto_8[35], in[71]); + MULA(res, -_sbc_proto_8[20], in[13]); + MULA(res, -_sbc_proto_8[19], in[29]); + MULA(res, -_sbc_proto_8[18], in[45]); + MULA(res, -_sbc_proto_8[17], in[61]); + MULA(res, -_sbc_proto_8[16], in[77]); t[5] = SCALE8_STAGE1(res); MUL(res, _sbc_proto_8[36], in[8] + in[72]); MULA(res, _sbc_proto_8[37], in[24] + in[56]); - MULA32(res, _sbc_proto_8[38], in[40]); - MULA32(res, -_sbc_proto_8[39], in[12]); - MULA32(res, -_sbc_proto_8[5], in[28]); - MULA32(res, -_sbc_proto_8[4], in[44]); - MULA32(res, -_sbc_proto_8[3], in[60]); - MULA32(res, -_sbc_proto_8[2], in[76]); + MULA(res, _sbc_proto_8[38], in[40]); + MULA(res, -_sbc_proto_8[39], in[12]); + MULA(res, -_sbc_proto_8[5], in[28]); + MULA(res, -_sbc_proto_8[4], in[44]); + MULA(res, -_sbc_proto_8[3], in[60]); + MULA(res, -_sbc_proto_8[2], in[76]); t[6] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[35], in[9]); - MULA32(res, _sbc_proto_8[34], in[25]); - MULA32(res, _sbc_proto_8[33], in[41]); - MULA32(res, _sbc_proto_8[32], in[57]); - MULA32(res, _sbc_proto_8[31], in[73]); - MULA32(res, -_sbc_proto_8[25], in[11]); - MULA32(res, -_sbc_proto_8[24], in[27]); - MULA32(res, -_sbc_proto_8[23], in[43]); - MULA32(res, -_sbc_proto_8[22], in[59]); - MULA32(res, -_sbc_proto_8[21], in[75]); + MUL(res, _sbc_proto_8[35], in[9]); + MULA(res, _sbc_proto_8[34], in[25]); + MULA(res, _sbc_proto_8[33], in[41]); + MULA(res, _sbc_proto_8[32], in[57]); + MULA(res, _sbc_proto_8[31], in[73]); + MULA(res, -_sbc_proto_8[25], in[11]); + MULA(res, -_sbc_proto_8[24], in[27]); + MULA(res, -_sbc_proto_8[23], in[43]); + MULA(res, -_sbc_proto_8[22], in[59]); + MULA(res, -_sbc_proto_8[21], in[75]); t[7] = SCALE8_STAGE1(res); MUL(s[0], _anamatrix8[0], t[0]); /* = Q14 * Q10 */ -- cgit From c2ce7c2d410cfb0e67c1635ebf60fc06ae864f33 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sun, 27 Jan 2008 03:35:53 +0000 Subject: get 32-bit products whenever we're sure the multiplicands are both 16 bits --- sbc/sbc.c | 190 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 95 insertions(+), 95 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index cfcf6432..f83c3485 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -715,51 +715,51 @@ static inline void _sbc_analyze_four(const int16_t *in, int32_t *out) sbc_fixed_t t[8]; sbc_extended_t s[5]; - MUL(res, _sbc_proto_4[0], (in[8] - in[32])); /* Q18 */ - MULA(res, _sbc_proto_4[1], (in[16] - in[24])); + MUL32(res, _sbc_proto_4[0], (in[8] - in[32])); /* Q18 */ + MULA32(res, _sbc_proto_4[1], (in[16] - in[24])); t[0] = SCALE4_STAGE1(res); /* Q8 */ - MUL(res, _sbc_proto_4[2], in[1]); - MULA(res, _sbc_proto_4[3], in[9]); - MULA(res, _sbc_proto_4[4], in[17]); - MULA(res, _sbc_proto_4[5], in[25]); - MULA(res, _sbc_proto_4[6], in[33]); + MUL32(res, _sbc_proto_4[2], in[1]); + MULA32(res, _sbc_proto_4[3], in[9]); + MULA32(res, _sbc_proto_4[4], in[17]); + MULA32(res, _sbc_proto_4[5], in[25]); + MULA32(res, _sbc_proto_4[6], in[33]); t[1] = SCALE4_STAGE1(res); - MUL(res, _sbc_proto_4[7], in[2]); - MULA(res, _sbc_proto_4[8], in[10]); - MULA(res, _sbc_proto_4[9], in[18]); - MULA(res, _sbc_proto_4[10], in[26]); - MULA(res, _sbc_proto_4[11], in[34]); + MUL32(res, _sbc_proto_4[7], in[2]); + MULA32(res, _sbc_proto_4[8], in[10]); + MULA32(res, _sbc_proto_4[9], in[18]); + MULA32(res, _sbc_proto_4[10], in[26]); + MULA32(res, _sbc_proto_4[11], in[34]); t[2] = SCALE4_STAGE1(res); - MUL(res, _sbc_proto_4[12], in[3]); - MULA(res, _sbc_proto_4[13], in[11]); - MULA(res, _sbc_proto_4[14], in[19]); - MULA(res, _sbc_proto_4[15], in[27]); - MULA(res, _sbc_proto_4[16], in[35]); + MUL32(res, _sbc_proto_4[12], in[3]); + MULA32(res, _sbc_proto_4[13], in[11]); + MULA32(res, _sbc_proto_4[14], in[19]); + MULA32(res, _sbc_proto_4[15], in[27]); + MULA32(res, _sbc_proto_4[16], in[35]); t[3] = SCALE4_STAGE1(res); MUL(res, _sbc_proto_4[17], in[4] + in[36]); MULA(res, _sbc_proto_4[18], in[12] + in[28]); - MULA(res, _sbc_proto_4[19], in[20]); + MULA32(res, _sbc_proto_4[19], in[20]); t[4] = SCALE4_STAGE1(res); - MUL(res, _sbc_proto_4[16], in[5]); - MULA(res, _sbc_proto_4[15], in[13]); - MULA(res, _sbc_proto_4[14], in[21]); - MULA(res, _sbc_proto_4[13], in[29]); - MULA(res, _sbc_proto_4[12], in[37]); + MUL32(res, _sbc_proto_4[16], in[5]); + MULA32(res, _sbc_proto_4[15], in[13]); + MULA32(res, _sbc_proto_4[14], in[21]); + MULA32(res, _sbc_proto_4[13], in[29]); + MULA32(res, _sbc_proto_4[12], in[37]); t[5] = SCALE4_STAGE1(res); /* don't compute t[6]... this term always multiplies * with cos(pi/2) = 0 */ - MUL(res, _sbc_proto_4[6], in[7]); - MULA(res, _sbc_proto_4[5], in[15]); - MULA(res, _sbc_proto_4[4], in[23]); - MULA(res, _sbc_proto_4[3], in[31]); - MULA(res, _sbc_proto_4[2], in[39]); + MUL32(res, _sbc_proto_4[6], in[7]); + MULA32(res, _sbc_proto_4[5], in[15]); + MULA32(res, _sbc_proto_4[4], in[23]); + MULA32(res, _sbc_proto_4[3], in[31]); + MULA32(res, _sbc_proto_4[2], in[39]); t[7] = SCALE4_STAGE1(res); MUL(s[0], _anamatrix4[0], t[0] + t[4]); @@ -800,89 +800,89 @@ static inline void _sbc_analyze_eight(const int16_t *in, int32_t *out) sbc_fixed_t t[8]; sbc_extended_t s[8]; - MUL(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ - MULA(res, _sbc_proto_8[1], (in[32] - in[48])); - MULA(res, _sbc_proto_8[2], in[4]); - MULA(res, _sbc_proto_8[3], in[20]); - MULA(res, _sbc_proto_8[4], in[36]); - MULA(res, _sbc_proto_8[5], in[52]); + MUL32(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ + MULA32(res, _sbc_proto_8[1], (in[32] - in[48])); + MULA32(res, _sbc_proto_8[2], in[4]); + MULA32(res, _sbc_proto_8[3], in[20]); + MULA32(res, _sbc_proto_8[4], in[36]); + MULA32(res, _sbc_proto_8[5], in[52]); t[0] = SCALE8_STAGE1(res); /* Q10 */ - MUL(res, _sbc_proto_8[6], in[2]); - MULA(res, _sbc_proto_8[7], in[18]); - MULA(res, _sbc_proto_8[8], in[34]); - MULA(res, _sbc_proto_8[9], in[50]); - MULA(res, _sbc_proto_8[10], in[66]); + MUL32(res, _sbc_proto_8[6], in[2]); + MULA32(res, _sbc_proto_8[7], in[18]); + MULA32(res, _sbc_proto_8[8], in[34]); + MULA32(res, _sbc_proto_8[9], in[50]); + MULA32(res, _sbc_proto_8[10], in[66]); t[1] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[11], in[1]); - MULA(res, _sbc_proto_8[12], in[17]); - MULA(res, _sbc_proto_8[13], in[33]); - MULA(res, _sbc_proto_8[14], in[49]); - MULA(res, _sbc_proto_8[15], in[65]); - MULA(res, _sbc_proto_8[16], in[3]); - MULA(res, _sbc_proto_8[17], in[19]); - MULA(res, _sbc_proto_8[18], in[35]); - MULA(res, _sbc_proto_8[19], in[51]); - MULA(res, _sbc_proto_8[20], in[67]); + MUL32(res, _sbc_proto_8[11], in[1]); + MULA32(res, _sbc_proto_8[12], in[17]); + MULA32(res, _sbc_proto_8[13], in[33]); + MULA32(res, _sbc_proto_8[14], in[49]); + MULA32(res, _sbc_proto_8[15], in[65]); + MULA32(res, _sbc_proto_8[16], in[3]); + MULA32(res, _sbc_proto_8[17], in[19]); + MULA32(res, _sbc_proto_8[18], in[35]); + MULA32(res, _sbc_proto_8[19], in[51]); + MULA32(res, _sbc_proto_8[20], in[67]); t[2] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[21], in[5]); - MULA(res, _sbc_proto_8[22], in[21]); - MULA(res, _sbc_proto_8[23], in[37]); - MULA(res, _sbc_proto_8[24], in[53]); - MULA(res, _sbc_proto_8[25], in[69]); - MULA(res, -_sbc_proto_8[15], in[15]); - MULA(res, -_sbc_proto_8[14], in[31]); - MULA(res, -_sbc_proto_8[13], in[47]); - MULA(res, -_sbc_proto_8[12], in[63]); - MULA(res, -_sbc_proto_8[11], in[79]); + MUL32(res, _sbc_proto_8[21], in[5]); + MULA32(res, _sbc_proto_8[22], in[21]); + MULA32(res, _sbc_proto_8[23], in[37]); + MULA32(res, _sbc_proto_8[24], in[53]); + MULA32(res, _sbc_proto_8[25], in[69]); + MULA32(res, -_sbc_proto_8[15], in[15]); + MULA32(res, -_sbc_proto_8[14], in[31]); + MULA32(res, -_sbc_proto_8[13], in[47]); + MULA32(res, -_sbc_proto_8[12], in[63]); + MULA32(res, -_sbc_proto_8[11], in[79]); t[3] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[26], in[6]); - MULA(res, _sbc_proto_8[27], in[22]); - MULA(res, _sbc_proto_8[28], in[38]); - MULA(res, _sbc_proto_8[29], in[54]); - MULA(res, _sbc_proto_8[30], in[70]); - MULA(res, -_sbc_proto_8[10], in[14]); - MULA(res, -_sbc_proto_8[9], in[30]); - MULA(res, -_sbc_proto_8[8], in[46]); - MULA(res, -_sbc_proto_8[7], in[62]); - MULA(res, -_sbc_proto_8[6], in[78]); + MUL32(res, _sbc_proto_8[26], in[6]); + MULA32(res, _sbc_proto_8[27], in[22]); + MULA32(res, _sbc_proto_8[28], in[38]); + MULA32(res, _sbc_proto_8[29], in[54]); + MULA32(res, _sbc_proto_8[30], in[70]); + MULA32(res, -_sbc_proto_8[10], in[14]); + MULA32(res, -_sbc_proto_8[9], in[30]); + MULA32(res, -_sbc_proto_8[8], in[46]); + MULA32(res, -_sbc_proto_8[7], in[62]); + MULA32(res, -_sbc_proto_8[6], in[78]); t[4] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[31], in[7]); - MULA(res, _sbc_proto_8[32], in[23]); - MULA(res, _sbc_proto_8[33], in[39]); - MULA(res, _sbc_proto_8[34], in[55]); - MULA(res, _sbc_proto_8[35], in[71]); - MULA(res, -_sbc_proto_8[20], in[13]); - MULA(res, -_sbc_proto_8[19], in[29]); - MULA(res, -_sbc_proto_8[18], in[45]); - MULA(res, -_sbc_proto_8[17], in[61]); - MULA(res, -_sbc_proto_8[16], in[77]); + MUL32(res, _sbc_proto_8[31], in[7]); + MULA32(res, _sbc_proto_8[32], in[23]); + MULA32(res, _sbc_proto_8[33], in[39]); + MULA32(res, _sbc_proto_8[34], in[55]); + MULA32(res, _sbc_proto_8[35], in[71]); + MULA32(res, -_sbc_proto_8[20], in[13]); + MULA32(res, -_sbc_proto_8[19], in[29]); + MULA32(res, -_sbc_proto_8[18], in[45]); + MULA32(res, -_sbc_proto_8[17], in[61]); + MULA32(res, -_sbc_proto_8[16], in[77]); t[5] = SCALE8_STAGE1(res); MUL(res, _sbc_proto_8[36], in[8] + in[72]); MULA(res, _sbc_proto_8[37], in[24] + in[56]); - MULA(res, _sbc_proto_8[38], in[40]); - MULA(res, -_sbc_proto_8[39], in[12]); - MULA(res, -_sbc_proto_8[5], in[28]); - MULA(res, -_sbc_proto_8[4], in[44]); - MULA(res, -_sbc_proto_8[3], in[60]); - MULA(res, -_sbc_proto_8[2], in[76]); + MULA32(res, _sbc_proto_8[38], in[40]); + MULA32(res, -_sbc_proto_8[39], in[12]); + MULA32(res, -_sbc_proto_8[5], in[28]); + MULA32(res, -_sbc_proto_8[4], in[44]); + MULA32(res, -_sbc_proto_8[3], in[60]); + MULA32(res, -_sbc_proto_8[2], in[76]); t[6] = SCALE8_STAGE1(res); - MUL(res, _sbc_proto_8[35], in[9]); - MULA(res, _sbc_proto_8[34], in[25]); - MULA(res, _sbc_proto_8[33], in[41]); - MULA(res, _sbc_proto_8[32], in[57]); - MULA(res, _sbc_proto_8[31], in[73]); - MULA(res, -_sbc_proto_8[25], in[11]); - MULA(res, -_sbc_proto_8[24], in[27]); - MULA(res, -_sbc_proto_8[23], in[43]); - MULA(res, -_sbc_proto_8[22], in[59]); - MULA(res, -_sbc_proto_8[21], in[75]); + MUL32(res, _sbc_proto_8[35], in[9]); + MULA32(res, _sbc_proto_8[34], in[25]); + MULA32(res, _sbc_proto_8[33], in[41]); + MULA32(res, _sbc_proto_8[32], in[57]); + MULA32(res, _sbc_proto_8[31], in[73]); + MULA32(res, -_sbc_proto_8[25], in[11]); + MULA32(res, -_sbc_proto_8[24], in[27]); + MULA32(res, -_sbc_proto_8[23], in[43]); + MULA32(res, -_sbc_proto_8[22], in[59]); + MULA32(res, -_sbc_proto_8[21], in[75]); t[7] = SCALE8_STAGE1(res); MUL(s[0], _anamatrix8[0], t[0]); /* = Q14 * Q10 */ -- cgit From d352bd04383f1c1a5ec17e267cb8d0ce70720519 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sun, 27 Jan 2008 04:29:08 +0000 Subject: avoid an (unlikely) overflow --- sbc/sbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index f83c3485..0cb839b6 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -715,8 +715,8 @@ static inline void _sbc_analyze_four(const int16_t *in, int32_t *out) sbc_fixed_t t[8]; sbc_extended_t s[5]; - MUL32(res, _sbc_proto_4[0], (in[8] - in[32])); /* Q18 */ - MULA32(res, _sbc_proto_4[1], (in[16] - in[24])); + MUL(res, _sbc_proto_4[0], in[8] - in[32]); /* Q18 */ + MULA(res, _sbc_proto_4[1], in[16] - in[24]); t[0] = SCALE4_STAGE1(res); /* Q8 */ MUL32(res, _sbc_proto_4[2], in[1]); -- cgit From ba255beb79afb9c00ae5b71821f84f911aa8d1fe Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 28 Jan 2008 10:38:40 +0000 Subject: Whitespace cleanup --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 0cb839b6..c9ea5b5c 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -1154,7 +1154,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) } /* align the last crc byte */ - if (crc_pos % 8) + if (crc_pos % 8) crc_header[crc_pos >> 3] <<= 8 - (crc_pos % 8); data[3] = sbc_crc8(crc_header, crc_pos); -- cgit From 38158dc5dd8e7c62ad2decfec395e3ec2c7e280b Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Mon, 28 Jan 2008 17:26:22 +0000 Subject: remove 16x16 mult optimization--gcc actually generates more costly code --- sbc/sbc.c | 186 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 93 insertions(+), 93 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index c9ea5b5c..97614fb9 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -719,47 +719,47 @@ static inline void _sbc_analyze_four(const int16_t *in, int32_t *out) MULA(res, _sbc_proto_4[1], in[16] - in[24]); t[0] = SCALE4_STAGE1(res); /* Q8 */ - MUL32(res, _sbc_proto_4[2], in[1]); - MULA32(res, _sbc_proto_4[3], in[9]); - MULA32(res, _sbc_proto_4[4], in[17]); - MULA32(res, _sbc_proto_4[5], in[25]); - MULA32(res, _sbc_proto_4[6], in[33]); + MUL(res, _sbc_proto_4[2], in[1]); + MULA(res, _sbc_proto_4[3], in[9]); + MULA(res, _sbc_proto_4[4], in[17]); + MULA(res, _sbc_proto_4[5], in[25]); + MULA(res, _sbc_proto_4[6], in[33]); t[1] = SCALE4_STAGE1(res); - MUL32(res, _sbc_proto_4[7], in[2]); - MULA32(res, _sbc_proto_4[8], in[10]); - MULA32(res, _sbc_proto_4[9], in[18]); - MULA32(res, _sbc_proto_4[10], in[26]); - MULA32(res, _sbc_proto_4[11], in[34]); + MUL(res, _sbc_proto_4[7], in[2]); + MULA(res, _sbc_proto_4[8], in[10]); + MULA(res, _sbc_proto_4[9], in[18]); + MULA(res, _sbc_proto_4[10], in[26]); + MULA(res, _sbc_proto_4[11], in[34]); t[2] = SCALE4_STAGE1(res); - MUL32(res, _sbc_proto_4[12], in[3]); - MULA32(res, _sbc_proto_4[13], in[11]); - MULA32(res, _sbc_proto_4[14], in[19]); - MULA32(res, _sbc_proto_4[15], in[27]); - MULA32(res, _sbc_proto_4[16], in[35]); + MUL(res, _sbc_proto_4[12], in[3]); + MULA(res, _sbc_proto_4[13], in[11]); + MULA(res, _sbc_proto_4[14], in[19]); + MULA(res, _sbc_proto_4[15], in[27]); + MULA(res, _sbc_proto_4[16], in[35]); t[3] = SCALE4_STAGE1(res); MUL(res, _sbc_proto_4[17], in[4] + in[36]); MULA(res, _sbc_proto_4[18], in[12] + in[28]); - MULA32(res, _sbc_proto_4[19], in[20]); + MULA(res, _sbc_proto_4[19], in[20]); t[4] = SCALE4_STAGE1(res); - MUL32(res, _sbc_proto_4[16], in[5]); - MULA32(res, _sbc_proto_4[15], in[13]); - MULA32(res, _sbc_proto_4[14], in[21]); - MULA32(res, _sbc_proto_4[13], in[29]); - MULA32(res, _sbc_proto_4[12], in[37]); + MUL(res, _sbc_proto_4[16], in[5]); + MULA(res, _sbc_proto_4[15], in[13]); + MULA(res, _sbc_proto_4[14], in[21]); + MULA(res, _sbc_proto_4[13], in[29]); + MULA(res, _sbc_proto_4[12], in[37]); t[5] = SCALE4_STAGE1(res); /* don't compute t[6]... this term always multiplies * with cos(pi/2) = 0 */ - MUL32(res, _sbc_proto_4[6], in[7]); - MULA32(res, _sbc_proto_4[5], in[15]); - MULA32(res, _sbc_proto_4[4], in[23]); - MULA32(res, _sbc_proto_4[3], in[31]); - MULA32(res, _sbc_proto_4[2], in[39]); + MUL(res, _sbc_proto_4[6], in[7]); + MULA(res, _sbc_proto_4[5], in[15]); + MULA(res, _sbc_proto_4[4], in[23]); + MULA(res, _sbc_proto_4[3], in[31]); + MULA(res, _sbc_proto_4[2], in[39]); t[7] = SCALE4_STAGE1(res); MUL(s[0], _anamatrix4[0], t[0] + t[4]); @@ -800,89 +800,89 @@ static inline void _sbc_analyze_eight(const int16_t *in, int32_t *out) sbc_fixed_t t[8]; sbc_extended_t s[8]; - MUL32(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ - MULA32(res, _sbc_proto_8[1], (in[32] - in[48])); - MULA32(res, _sbc_proto_8[2], in[4]); - MULA32(res, _sbc_proto_8[3], in[20]); - MULA32(res, _sbc_proto_8[4], in[36]); - MULA32(res, _sbc_proto_8[5], in[52]); + MUL(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ + MULA(res, _sbc_proto_8[1], (in[32] - in[48])); + MULA(res, _sbc_proto_8[2], in[4]); + MULA(res, _sbc_proto_8[3], in[20]); + MULA(res, _sbc_proto_8[4], in[36]); + MULA(res, _sbc_proto_8[5], in[52]); t[0] = SCALE8_STAGE1(res); /* Q10 */ - MUL32(res, _sbc_proto_8[6], in[2]); - MULA32(res, _sbc_proto_8[7], in[18]); - MULA32(res, _sbc_proto_8[8], in[34]); - MULA32(res, _sbc_proto_8[9], in[50]); - MULA32(res, _sbc_proto_8[10], in[66]); + MUL(res, _sbc_proto_8[6], in[2]); + MULA(res, _sbc_proto_8[7], in[18]); + MULA(res, _sbc_proto_8[8], in[34]); + MULA(res, _sbc_proto_8[9], in[50]); + MULA(res, _sbc_proto_8[10], in[66]); t[1] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[11], in[1]); - MULA32(res, _sbc_proto_8[12], in[17]); - MULA32(res, _sbc_proto_8[13], in[33]); - MULA32(res, _sbc_proto_8[14], in[49]); - MULA32(res, _sbc_proto_8[15], in[65]); - MULA32(res, _sbc_proto_8[16], in[3]); - MULA32(res, _sbc_proto_8[17], in[19]); - MULA32(res, _sbc_proto_8[18], in[35]); - MULA32(res, _sbc_proto_8[19], in[51]); - MULA32(res, _sbc_proto_8[20], in[67]); + MUL(res, _sbc_proto_8[11], in[1]); + MULA(res, _sbc_proto_8[12], in[17]); + MULA(res, _sbc_proto_8[13], in[33]); + MULA(res, _sbc_proto_8[14], in[49]); + MULA(res, _sbc_proto_8[15], in[65]); + MULA(res, _sbc_proto_8[16], in[3]); + MULA(res, _sbc_proto_8[17], in[19]); + MULA(res, _sbc_proto_8[18], in[35]); + MULA(res, _sbc_proto_8[19], in[51]); + MULA(res, _sbc_proto_8[20], in[67]); t[2] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[21], in[5]); - MULA32(res, _sbc_proto_8[22], in[21]); - MULA32(res, _sbc_proto_8[23], in[37]); - MULA32(res, _sbc_proto_8[24], in[53]); - MULA32(res, _sbc_proto_8[25], in[69]); - MULA32(res, -_sbc_proto_8[15], in[15]); - MULA32(res, -_sbc_proto_8[14], in[31]); - MULA32(res, -_sbc_proto_8[13], in[47]); - MULA32(res, -_sbc_proto_8[12], in[63]); - MULA32(res, -_sbc_proto_8[11], in[79]); + MUL(res, _sbc_proto_8[21], in[5]); + MULA(res, _sbc_proto_8[22], in[21]); + MULA(res, _sbc_proto_8[23], in[37]); + MULA(res, _sbc_proto_8[24], in[53]); + MULA(res, _sbc_proto_8[25], in[69]); + MULA(res, -_sbc_proto_8[15], in[15]); + MULA(res, -_sbc_proto_8[14], in[31]); + MULA(res, -_sbc_proto_8[13], in[47]); + MULA(res, -_sbc_proto_8[12], in[63]); + MULA(res, -_sbc_proto_8[11], in[79]); t[3] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[26], in[6]); - MULA32(res, _sbc_proto_8[27], in[22]); - MULA32(res, _sbc_proto_8[28], in[38]); - MULA32(res, _sbc_proto_8[29], in[54]); - MULA32(res, _sbc_proto_8[30], in[70]); - MULA32(res, -_sbc_proto_8[10], in[14]); - MULA32(res, -_sbc_proto_8[9], in[30]); - MULA32(res, -_sbc_proto_8[8], in[46]); - MULA32(res, -_sbc_proto_8[7], in[62]); - MULA32(res, -_sbc_proto_8[6], in[78]); + MUL(res, _sbc_proto_8[26], in[6]); + MULA(res, _sbc_proto_8[27], in[22]); + MULA(res, _sbc_proto_8[28], in[38]); + MULA(res, _sbc_proto_8[29], in[54]); + MULA(res, _sbc_proto_8[30], in[70]); + MULA(res, -_sbc_proto_8[10], in[14]); + MULA(res, -_sbc_proto_8[9], in[30]); + MULA(res, -_sbc_proto_8[8], in[46]); + MULA(res, -_sbc_proto_8[7], in[62]); + MULA(res, -_sbc_proto_8[6], in[78]); t[4] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[31], in[7]); - MULA32(res, _sbc_proto_8[32], in[23]); - MULA32(res, _sbc_proto_8[33], in[39]); - MULA32(res, _sbc_proto_8[34], in[55]); - MULA32(res, _sbc_proto_8[35], in[71]); - MULA32(res, -_sbc_proto_8[20], in[13]); - MULA32(res, -_sbc_proto_8[19], in[29]); - MULA32(res, -_sbc_proto_8[18], in[45]); - MULA32(res, -_sbc_proto_8[17], in[61]); - MULA32(res, -_sbc_proto_8[16], in[77]); + MUL(res, _sbc_proto_8[31], in[7]); + MULA(res, _sbc_proto_8[32], in[23]); + MULA(res, _sbc_proto_8[33], in[39]); + MULA(res, _sbc_proto_8[34], in[55]); + MULA(res, _sbc_proto_8[35], in[71]); + MULA(res, -_sbc_proto_8[20], in[13]); + MULA(res, -_sbc_proto_8[19], in[29]); + MULA(res, -_sbc_proto_8[18], in[45]); + MULA(res, -_sbc_proto_8[17], in[61]); + MULA(res, -_sbc_proto_8[16], in[77]); t[5] = SCALE8_STAGE1(res); MUL(res, _sbc_proto_8[36], in[8] + in[72]); MULA(res, _sbc_proto_8[37], in[24] + in[56]); - MULA32(res, _sbc_proto_8[38], in[40]); - MULA32(res, -_sbc_proto_8[39], in[12]); - MULA32(res, -_sbc_proto_8[5], in[28]); - MULA32(res, -_sbc_proto_8[4], in[44]); - MULA32(res, -_sbc_proto_8[3], in[60]); - MULA32(res, -_sbc_proto_8[2], in[76]); + MULA(res, _sbc_proto_8[38], in[40]); + MULA(res, -_sbc_proto_8[39], in[12]); + MULA(res, -_sbc_proto_8[5], in[28]); + MULA(res, -_sbc_proto_8[4], in[44]); + MULA(res, -_sbc_proto_8[3], in[60]); + MULA(res, -_sbc_proto_8[2], in[76]); t[6] = SCALE8_STAGE1(res); - MUL32(res, _sbc_proto_8[35], in[9]); - MULA32(res, _sbc_proto_8[34], in[25]); - MULA32(res, _sbc_proto_8[33], in[41]); - MULA32(res, _sbc_proto_8[32], in[57]); - MULA32(res, _sbc_proto_8[31], in[73]); - MULA32(res, -_sbc_proto_8[25], in[11]); - MULA32(res, -_sbc_proto_8[24], in[27]); - MULA32(res, -_sbc_proto_8[23], in[43]); - MULA32(res, -_sbc_proto_8[22], in[59]); - MULA32(res, -_sbc_proto_8[21], in[75]); + MUL(res, _sbc_proto_8[35], in[9]); + MULA(res, _sbc_proto_8[34], in[25]); + MULA(res, _sbc_proto_8[33], in[41]); + MULA(res, _sbc_proto_8[32], in[57]); + MULA(res, _sbc_proto_8[31], in[73]); + MULA(res, -_sbc_proto_8[25], in[11]); + MULA(res, -_sbc_proto_8[24], in[27]); + MULA(res, -_sbc_proto_8[23], in[43]); + MULA(res, -_sbc_proto_8[22], in[59]); + MULA(res, -_sbc_proto_8[21], in[75]); t[7] = SCALE8_STAGE1(res); MUL(s[0], _anamatrix8[0], t[0]); /* = Q14 * Q10 */ -- cgit From 358888c52324aadb2d9814f2f5df5183706f70f7 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Mon, 28 Jan 2008 17:48:21 +0000 Subject: change function signature so the arm optimization will work --- sbc/sbc.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 97614fb9..7d57b283 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -708,10 +708,15 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, state->position[0] = state->position[1] = 9 * frame->subbands; } - +#ifdef __arm__ +void _sbc_analyze_four(const int16_t *in, int32_t *out) +{ + sbc_extended_t register res asm("r4"); +#else static inline void _sbc_analyze_four(const int16_t *in, int32_t *out) { sbc_extended_t res; +#endif sbc_fixed_t t[8]; sbc_extended_t s[5]; @@ -794,9 +799,15 @@ static inline void sbc_analyze_four(struct sbc_encoder_state *state, state->position[ch] = 36; } +#ifdef __arm__ +void _sbc_analyze_eight(const int16_t *in, int32_t *out) +{ + sbc_extended_t register res asm("r4"); +#else static inline void _sbc_analyze_eight(const int16_t *in, int32_t *out) { sbc_extended_t res; +#endif sbc_fixed_t t[8]; sbc_extended_t s[8]; -- cgit From 6d205fda030a21d99ea5064b9501d58a11b6efa5 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Mon, 28 Jan 2008 18:00:51 +0000 Subject: revert arm conditional code --- sbc/sbc.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 7d57b283..97614fb9 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -708,15 +708,10 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, state->position[0] = state->position[1] = 9 * frame->subbands; } -#ifdef __arm__ -void _sbc_analyze_four(const int16_t *in, int32_t *out) -{ - sbc_extended_t register res asm("r4"); -#else + static inline void _sbc_analyze_four(const int16_t *in, int32_t *out) { sbc_extended_t res; -#endif sbc_fixed_t t[8]; sbc_extended_t s[5]; @@ -799,15 +794,9 @@ static inline void sbc_analyze_four(struct sbc_encoder_state *state, state->position[ch] = 36; } -#ifdef __arm__ -void _sbc_analyze_eight(const int16_t *in, int32_t *out) -{ - sbc_extended_t register res asm("r4"); -#else static inline void _sbc_analyze_eight(const int16_t *in, int32_t *out) { sbc_extended_t res; -#endif sbc_fixed_t t[8]; sbc_extended_t s[8]; -- cgit From c6d9a4373d855d72d7d7fe63718cd4dc79fd3881 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Tue, 29 Jan 2008 18:56:13 +0000 Subject: revert 16-bit state.X change (bad on arm) --- sbc/sbc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 97614fb9..a4f7b7dd 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -121,7 +121,7 @@ struct sbc_decoder_state { struct sbc_encoder_state { int subbands; int position[2]; - int16_t X[2][160]; + int32_t X[2][160]; }; /* @@ -709,7 +709,7 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, } -static inline void _sbc_analyze_four(const int16_t *in, int32_t *out) +static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) { sbc_extended_t res; sbc_fixed_t t[8]; @@ -794,7 +794,7 @@ static inline void sbc_analyze_four(struct sbc_encoder_state *state, state->position[ch] = 36; } -static inline void _sbc_analyze_eight(const int16_t *in, int32_t *out) +static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) { sbc_extended_t res; sbc_fixed_t t[8]; @@ -921,7 +921,7 @@ static inline void sbc_analyze_eight(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int16_t *x = &state->X[ch][state->position[ch]]; + int32_t *x = &state->X[ch][state->position[ch]]; int16_t *pcm = &frame->pcm_sample[ch][blk * 8]; /* Input 8 Audio Samples */ -- cgit From 4b8bfb24c7666cb0b6eb26abe9a7d5072e3f9c4e Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Tue, 29 Jan 2008 19:47:49 +0000 Subject: one more .X 32-bitism --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index a4f7b7dd..e46c2b0f 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -778,7 +778,7 @@ static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) static inline void sbc_analyze_four(struct sbc_encoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int16_t *x = &state->X[ch][state->position[ch]]; + int32_t *x = &state->X[ch][state->position[ch]]; int16_t *pcm = &frame->pcm_sample[ch][blk * 4]; /* Input 4 Audio Samples */ -- cgit From 82540ead6bfe7d0398256b48500e6fbecb0e28e1 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Wed, 30 Jan 2008 20:37:49 +0000 Subject: change MUL/MULA semantics --- sbc/sbc.c | 339 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 171 insertions(+), 168 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index e46c2b0f..260e31c4 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -614,7 +614,8 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, /* Distribute the new matrix value to the shifted position */ SBC_FIXED_0(res); for (j = 0; j < 4; j++) - MULA(res, synmatrix4[i][j], frame->sb_sample[blk][ch][j]); + res = MULA(synmatrix4[i][j], + frame->sb_sample[blk][ch][j], res); state->V[ch][state->offset[ch][i]] = SCALE4_STAGED1(res); } @@ -623,10 +624,10 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, k = (i + 4) & 0xf; SBC_FIXED_0(res); for (j = 0; j < 10; idx++) { - MULA(res, state->V[ch][state->offset[ch][i]+j++], - sbc_proto_4_40m0[idx]); - MULA(res, state->V[ch][state->offset[ch][k]+j++], - sbc_proto_4_40m1[idx]); + res = MULA(state->V[ch][state->offset[ch][i]+j++], + sbc_proto_4_40m0[idx], res); + res = MULA(state->V[ch][state->offset[ch][k]+j++], + sbc_proto_4_40m1[idx], res); } /* Store in output, Q0 */ @@ -655,7 +656,8 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, SBC_FIXED_0(res); for (j = 0; j < 8; j++) { /* Q28 = Q15 * Q13 */ - MULA(res, synmatrix8[i][j], frame->sb_sample[blk][ch][j]); + res = MULA(synmatrix8[i][j], + frame->sb_sample[blk][ch][j], res); } /* Q10 */ state->V[ch][state->offset[ch][i]] = SCALE8_STAGED1(res); @@ -666,8 +668,10 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, k = (i + 8) & 0xf; SBC_FIXED_0(res); for (j = 0; j < 10; idx++) { - MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_8_80m0[idx]); - MULA(res, state->V[ch][state->offset[ch][k]+j++], sbc_proto_8_80m1[idx]); + res = MULA(state->V[ch][state->offset[ch][i]+j++], + sbc_proto_8_80m0[idx], res); + res = MULA(state->V[ch][state->offset[ch][k]+j++], + sbc_proto_8_80m1[idx], res); } /* Store in output */ frame->pcm_sample[ch][blk * 8 + i] = SCALE8_STAGED2(res); // Q0 @@ -708,67 +712,66 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, state->position[0] = state->position[1] = 9 * frame->subbands; } - static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) { - sbc_extended_t res; sbc_fixed_t t[8]; sbc_extended_t s[5]; - MUL(res, _sbc_proto_4[0], in[8] - in[32]); /* Q18 */ - MULA(res, _sbc_proto_4[1], in[16] - in[24]); - t[0] = SCALE4_STAGE1(res); /* Q8 */ - - MUL(res, _sbc_proto_4[2], in[1]); - MULA(res, _sbc_proto_4[3], in[9]); - MULA(res, _sbc_proto_4[4], in[17]); - MULA(res, _sbc_proto_4[5], in[25]); - MULA(res, _sbc_proto_4[6], in[33]); - t[1] = SCALE4_STAGE1(res); - - MUL(res, _sbc_proto_4[7], in[2]); - MULA(res, _sbc_proto_4[8], in[10]); - MULA(res, _sbc_proto_4[9], in[18]); - MULA(res, _sbc_proto_4[10], in[26]); - MULA(res, _sbc_proto_4[11], in[34]); - t[2] = SCALE4_STAGE1(res); - - MUL(res, _sbc_proto_4[12], in[3]); - MULA(res, _sbc_proto_4[13], in[11]); - MULA(res, _sbc_proto_4[14], in[19]); - MULA(res, _sbc_proto_4[15], in[27]); - MULA(res, _sbc_proto_4[16], in[35]); - t[3] = SCALE4_STAGE1(res); - - MUL(res, _sbc_proto_4[17], in[4] + in[36]); - MULA(res, _sbc_proto_4[18], in[12] + in[28]); - MULA(res, _sbc_proto_4[19], in[20]); - t[4] = SCALE4_STAGE1(res); - - MUL(res, _sbc_proto_4[16], in[5]); - MULA(res, _sbc_proto_4[15], in[13]); - MULA(res, _sbc_proto_4[14], in[21]); - MULA(res, _sbc_proto_4[13], in[29]); - MULA(res, _sbc_proto_4[12], in[37]); - t[5] = SCALE4_STAGE1(res); + t[0] = SCALE4_STAGE1( /* Q8 */ + MULA(_sbc_proto_4[0], in[8] - in[32], /* Q18 */ + MUL( _sbc_proto_4[1], in[16] - in[24]))); + + t[1] = SCALE4_STAGE1( + MULA(_sbc_proto_4[2], in[1], + MULA(_sbc_proto_4[3], in[9], + MULA(_sbc_proto_4[4], in[17], + MULA(_sbc_proto_4[5], in[25], + MUL( _sbc_proto_4[6], in[33])))))); + + t[2] = SCALE4_STAGE1( + MULA(_sbc_proto_4[7], in[2], + MULA(_sbc_proto_4[8], in[10], + MULA(_sbc_proto_4[9], in[18], + MULA(_sbc_proto_4[10], in[26], + MUL( _sbc_proto_4[11], in[34])))))); + + t[3] = SCALE4_STAGE1( + MULA(_sbc_proto_4[12], in[3], + MULA(_sbc_proto_4[13], in[11], + MULA(_sbc_proto_4[14], in[19], + MULA(_sbc_proto_4[15], in[27], + MUL( _sbc_proto_4[16], in[35])))))); + + t[4] = SCALE4_STAGE1( + MULA(_sbc_proto_4[17], in[4] + in[36], + MULA(_sbc_proto_4[18], in[12] + in[28], + MUL( _sbc_proto_4[19], in[20])))); + + t[5] = SCALE4_STAGE1( + MULA(_sbc_proto_4[16], in[5], + MULA(_sbc_proto_4[15], in[13], + MULA(_sbc_proto_4[14], in[21], + MULA(_sbc_proto_4[13], in[29], + MUL( _sbc_proto_4[12], in[37])))))); /* don't compute t[6]... this term always multiplies * with cos(pi/2) = 0 */ - MUL(res, _sbc_proto_4[6], in[7]); - MULA(res, _sbc_proto_4[5], in[15]); - MULA(res, _sbc_proto_4[4], in[23]); - MULA(res, _sbc_proto_4[3], in[31]); - MULA(res, _sbc_proto_4[2], in[39]); - t[7] = SCALE4_STAGE1(res); - - MUL(s[0], _anamatrix4[0], t[0] + t[4]); - MUL(s[1], _anamatrix4[2], t[2]); - MUL(s[2], _anamatrix4[1], t[1] + t[3]); - MULA(s[2], _anamatrix4[3], t[5]); - MUL(s[3], _anamatrix4[3], t[1] + t[3]); - MULA(s[3], _anamatrix4[1], - t[5] + t[7]); - MUL(s[4], _anamatrix4[3], t[7]); + t[7] = SCALE4_STAGE1( + MULA(_sbc_proto_4[6], in[7], + MULA(_sbc_proto_4[5], in[15], + MULA(_sbc_proto_4[4], in[23], + MULA(_sbc_proto_4[3], in[31], + MUL( _sbc_proto_4[2], in[39])))))); + + s[0] = MUL( _anamatrix4[0], t[0] + t[4]); + s[1] = MUL( _anamatrix4[2], t[2]); + s[2] = MULA(_anamatrix4[1], t[1] + t[3], + MUL(_anamatrix4[3], t[5])); + s[3] = MULA(_anamatrix4[3], t[1] + t[3], + MUL(_anamatrix4[1], -t[5] + t[7])); + s[4] = MUL( _anamatrix4[3], t[7]); + out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2] + s[4]); /* Q0 */ out[1] = SCALE4_STAGE2(-s[0] + s[1] + s[3]); out[2] = SCALE4_STAGE2(-s[0] + s[1] - s[3]); @@ -796,117 +799,117 @@ static inline void sbc_analyze_four(struct sbc_encoder_state *state, static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) { - sbc_extended_t res; sbc_fixed_t t[8]; sbc_extended_t s[8]; - MUL(res, _sbc_proto_8[0], (in[16] - in[64])); /* Q18 = Q18 * Q0 */ - MULA(res, _sbc_proto_8[1], (in[32] - in[48])); - MULA(res, _sbc_proto_8[2], in[4]); - MULA(res, _sbc_proto_8[3], in[20]); - MULA(res, _sbc_proto_8[4], in[36]); - MULA(res, _sbc_proto_8[5], in[52]); - t[0] = SCALE8_STAGE1(res); /* Q10 */ - - MUL(res, _sbc_proto_8[6], in[2]); - MULA(res, _sbc_proto_8[7], in[18]); - MULA(res, _sbc_proto_8[8], in[34]); - MULA(res, _sbc_proto_8[9], in[50]); - MULA(res, _sbc_proto_8[10], in[66]); - t[1] = SCALE8_STAGE1(res); - - MUL(res, _sbc_proto_8[11], in[1]); - MULA(res, _sbc_proto_8[12], in[17]); - MULA(res, _sbc_proto_8[13], in[33]); - MULA(res, _sbc_proto_8[14], in[49]); - MULA(res, _sbc_proto_8[15], in[65]); - MULA(res, _sbc_proto_8[16], in[3]); - MULA(res, _sbc_proto_8[17], in[19]); - MULA(res, _sbc_proto_8[18], in[35]); - MULA(res, _sbc_proto_8[19], in[51]); - MULA(res, _sbc_proto_8[20], in[67]); - t[2] = SCALE8_STAGE1(res); - - MUL(res, _sbc_proto_8[21], in[5]); - MULA(res, _sbc_proto_8[22], in[21]); - MULA(res, _sbc_proto_8[23], in[37]); - MULA(res, _sbc_proto_8[24], in[53]); - MULA(res, _sbc_proto_8[25], in[69]); - MULA(res, -_sbc_proto_8[15], in[15]); - MULA(res, -_sbc_proto_8[14], in[31]); - MULA(res, -_sbc_proto_8[13], in[47]); - MULA(res, -_sbc_proto_8[12], in[63]); - MULA(res, -_sbc_proto_8[11], in[79]); - t[3] = SCALE8_STAGE1(res); - - MUL(res, _sbc_proto_8[26], in[6]); - MULA(res, _sbc_proto_8[27], in[22]); - MULA(res, _sbc_proto_8[28], in[38]); - MULA(res, _sbc_proto_8[29], in[54]); - MULA(res, _sbc_proto_8[30], in[70]); - MULA(res, -_sbc_proto_8[10], in[14]); - MULA(res, -_sbc_proto_8[9], in[30]); - MULA(res, -_sbc_proto_8[8], in[46]); - MULA(res, -_sbc_proto_8[7], in[62]); - MULA(res, -_sbc_proto_8[6], in[78]); - t[4] = SCALE8_STAGE1(res); - - MUL(res, _sbc_proto_8[31], in[7]); - MULA(res, _sbc_proto_8[32], in[23]); - MULA(res, _sbc_proto_8[33], in[39]); - MULA(res, _sbc_proto_8[34], in[55]); - MULA(res, _sbc_proto_8[35], in[71]); - MULA(res, -_sbc_proto_8[20], in[13]); - MULA(res, -_sbc_proto_8[19], in[29]); - MULA(res, -_sbc_proto_8[18], in[45]); - MULA(res, -_sbc_proto_8[17], in[61]); - MULA(res, -_sbc_proto_8[16], in[77]); - t[5] = SCALE8_STAGE1(res); - - MUL(res, _sbc_proto_8[36], in[8] + in[72]); - MULA(res, _sbc_proto_8[37], in[24] + in[56]); - MULA(res, _sbc_proto_8[38], in[40]); - MULA(res, -_sbc_proto_8[39], in[12]); - MULA(res, -_sbc_proto_8[5], in[28]); - MULA(res, -_sbc_proto_8[4], in[44]); - MULA(res, -_sbc_proto_8[3], in[60]); - MULA(res, -_sbc_proto_8[2], in[76]); - t[6] = SCALE8_STAGE1(res); - - MUL(res, _sbc_proto_8[35], in[9]); - MULA(res, _sbc_proto_8[34], in[25]); - MULA(res, _sbc_proto_8[33], in[41]); - MULA(res, _sbc_proto_8[32], in[57]); - MULA(res, _sbc_proto_8[31], in[73]); - MULA(res, -_sbc_proto_8[25], in[11]); - MULA(res, -_sbc_proto_8[24], in[27]); - MULA(res, -_sbc_proto_8[23], in[43]); - MULA(res, -_sbc_proto_8[22], in[59]); - MULA(res, -_sbc_proto_8[21], in[75]); - t[7] = SCALE8_STAGE1(res); - - MUL(s[0], _anamatrix8[0], t[0]); /* = Q14 * Q10 */ - MULA(s[0], _anamatrix8[1], t[6]); - MUL(s[1], _anamatrix8[7], t[1]); - MUL(s[2], _anamatrix8[2], t[2]); - MULA(s[2], _anamatrix8[3], t[3]); - MULA(s[2], _anamatrix8[4], t[5]); - MULA(s[2], _anamatrix8[5], t[7]); - MUL(s[3], _anamatrix8[6], t[4]); - MUL(s[4], _anamatrix8[3], t[2]); - MULA(s[4], -_anamatrix8[5], t[3]); - MULA(s[4], -_anamatrix8[2], t[5]); - MULA(s[4], -_anamatrix8[4], t[7]); - MUL(s[5], _anamatrix8[4], t[2]); - MULA(s[5], -_anamatrix8[2], t[3]); - MULA(s[5], _anamatrix8[5], t[5]); - MULA(s[5], _anamatrix8[3], t[7]); - MUL(s[6], _anamatrix8[1], t[0]); - MULA(s[6], -_anamatrix8[0], t[6]); - MUL(s[7], _anamatrix8[5], t[2]); - MULA(s[7], -_anamatrix8[4], t[3]); - MULA(s[7], _anamatrix8[3], t[5]); - MULA(s[7], -_anamatrix8[2], t[7]); + t[0] = SCALE8_STAGE1( /* Q10 */ + MULA(_sbc_proto_8[0], (in[16] - in[64]), /* Q18 = Q18 * Q0 */ + MULA(_sbc_proto_8[1], (in[32] - in[48]), + MULA(_sbc_proto_8[2], in[4], + MULA(_sbc_proto_8[3], in[20], + MULA(_sbc_proto_8[4], in[36], + MUL( _sbc_proto_8[5], in[52]))))))); + + t[1] = SCALE8_STAGE1( + MULA(_sbc_proto_8[6], in[2], + MULA(_sbc_proto_8[7], in[18], + MULA(_sbc_proto_8[8], in[34], + MULA(_sbc_proto_8[9], in[50], + MUL(_sbc_proto_8[10], in[66])))))); + + t[2] = SCALE8_STAGE1( + MULA(_sbc_proto_8[11], in[1], + MULA(_sbc_proto_8[12], in[17], + MULA(_sbc_proto_8[13], in[33], + MULA(_sbc_proto_8[14], in[49], + MULA(_sbc_proto_8[15], in[65], + MULA(_sbc_proto_8[16], in[3], + MULA(_sbc_proto_8[17], in[19], + MULA(_sbc_proto_8[18], in[35], + MULA(_sbc_proto_8[19], in[51], + MUL( _sbc_proto_8[20], in[67]))))))))))); + + t[3] = SCALE8_STAGE1( + MULA( _sbc_proto_8[21], in[5], + MULA( _sbc_proto_8[22], in[21], + MULA( _sbc_proto_8[23], in[37], + MULA( _sbc_proto_8[24], in[53], + MULA( _sbc_proto_8[25], in[69], + MULA(-_sbc_proto_8[15], in[15], + MULA(-_sbc_proto_8[14], in[31], + MULA(-_sbc_proto_8[13], in[47], + MULA(-_sbc_proto_8[12], in[63], + MUL( -_sbc_proto_8[11], in[79]))))))))))); + + t[4] = SCALE8_STAGE1( + MULA( _sbc_proto_8[26], in[6], + MULA( _sbc_proto_8[27], in[22], + MULA( _sbc_proto_8[28], in[38], + MULA( _sbc_proto_8[29], in[54], + MULA( _sbc_proto_8[30], in[70], + MULA(-_sbc_proto_8[10], in[14], + MULA(-_sbc_proto_8[9], in[30], + MULA(-_sbc_proto_8[8], in[46], + MULA(-_sbc_proto_8[7], in[62], + MUL( -_sbc_proto_8[6], in[78]))))))))))); + + t[5] = SCALE8_STAGE1( + MULA( _sbc_proto_8[31], in[7], + MULA( _sbc_proto_8[32], in[23], + MULA( _sbc_proto_8[33], in[39], + MULA( _sbc_proto_8[34], in[55], + MULA( _sbc_proto_8[35], in[71], + MULA(-_sbc_proto_8[20], in[13], + MULA(-_sbc_proto_8[19], in[29], + MULA(-_sbc_proto_8[18], in[45], + MULA(-_sbc_proto_8[17], in[61], + MUL( -_sbc_proto_8[16], in[77]))))))))))); + + t[6] = SCALE8_STAGE1( + MULA( _sbc_proto_8[36], (in[8] + in[72]), + MULA( _sbc_proto_8[37], (in[24] + in[56]), + MULA( _sbc_proto_8[38], in[40], + MULA(-_sbc_proto_8[39], in[12], + MULA(-_sbc_proto_8[5], in[28], + MULA(-_sbc_proto_8[4], in[44], + MULA(-_sbc_proto_8[3], in[60], + MUL( -_sbc_proto_8[2], in[76]))))))))); + + t[7] = SCALE8_STAGE1( + MULA( _sbc_proto_8[35], in[9], + MULA( _sbc_proto_8[34], in[25], + MULA( _sbc_proto_8[33], in[41], + MULA( _sbc_proto_8[32], in[57], + MULA( _sbc_proto_8[31], in[73], + MULA(-_sbc_proto_8[25], in[11], + MULA(-_sbc_proto_8[24], in[27], + MULA(-_sbc_proto_8[23], in[43], + MULA(-_sbc_proto_8[22], in[59], + MUL( -_sbc_proto_8[21], in[75]))))))))))); + + s[0] = MULA( _anamatrix8[0], t[0], + MUL( _anamatrix8[1], t[6])); + s[1] = MUL( _anamatrix8[7], t[1]); + s[2] = MULA( _anamatrix8[2], t[2], + MULA( _anamatrix8[3], t[3], + MULA( _anamatrix8[4], t[5], + MUL( _anamatrix8[5], t[7])))); + s[3] = MUL( _anamatrix8[6], t[4]); + s[4] = MULA( _anamatrix8[3], t[2], + MULA(-_anamatrix8[5], t[3], + MULA(-_anamatrix8[2], t[5], + MUL( -_anamatrix8[4], t[7])))); + s[5] = MULA( _anamatrix8[4], t[2], + MULA(-_anamatrix8[2], t[3], + MULA( _anamatrix8[5], t[5], + MUL( _anamatrix8[3], t[7])))); + s[6] = MULA( _anamatrix8[1], t[0], + MUL( -_anamatrix8[0], t[6])); + s[7] = MULA( _anamatrix8[5], t[2], + MULA(-_anamatrix8[4], t[3], + MULA( _anamatrix8[3], t[5], + MUL( -_anamatrix8[2], t[7])))); + out[0] = SCALE8_STAGE2( s[0] + s[1] + s[2] + s[3]); out[1] = SCALE8_STAGE2( s[1] - s[3] + s[4] + s[6]); out[2] = SCALE8_STAGE2( s[1] - s[3] + s[5] - s[6]); -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- sbc/sbc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 260e31c4..642a7676 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -2,7 +2,7 @@ * * Bluetooth low-complexity, subband codec (SBC) library * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * Copyright (C) 2004-2005 Henryk Ploetz * Copyright (C) 2005-2008 Brad Midgley * @@ -43,7 +43,6 @@ #include #include - #include "sbc_math.h" #include "sbc_tables.h" -- cgit From ff51f4b0b2724754184baa08b09a47cad7b7b4d5 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 15 Feb 2008 18:06:32 +0000 Subject: fix for decoder noise at high bitpools --- sbc/sbc.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 642a7676..bc0b771c 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -543,16 +543,8 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, for (sb = 0; sb < frame->subbands; sb++) { if (levels[ch][sb] > 0) { frame->sb_sample[blk][ch][sb] = - (((frame->audio_sample[blk][ch][sb] << 16) | 0x8000) / - levels[ch][sb]) - 0x8000; - - frame->sb_sample[blk][ch][sb] >>= 3; - - /* Q13 */ - frame->sb_sample[blk][ch][sb] = - (frame->sb_sample[blk][ch][sb] << - (frame->scale_factor[ch][sb] + 1)); - + (((frame->audio_sample[blk][ch][sb] << 1) | 1) << frame->scale_factor[ch][sb])/ + levels[ch][sb] - (1 << frame->scale_factor[ch][sb]); } else frame->sb_sample[blk][ch][sb] = 0; } -- cgit From ce342bf2524b69b19ea5a4ad604faf1aa40ad19c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 19 Feb 2008 19:47:25 +0000 Subject: Introduce sbc new API. --- sbc/sbc.c | 310 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 157 insertions(+), 153 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index bc0b771c..0b0bbc94 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -37,7 +37,6 @@ #include #include -#include #include #include #include @@ -50,55 +49,31 @@ #define SBC_SYNCWORD 0x9C -/* sampling frequency */ -#define SBC_FS_16 0x00 -#define SBC_FS_32 0x01 -#define SBC_FS_44 0x02 -#define SBC_FS_48 0x03 - -/* nrof_blocks */ -#define SBC_NB_4 0x00 -#define SBC_NB_8 0x01 -#define SBC_NB_12 0x02 -#define SBC_NB_16 0x03 - -/* channel mode */ -#define SBC_CM_MONO 0x00 -#define SBC_CM_DUAL_CHANNEL 0x01 -#define SBC_CM_STEREO 0x02 -#define SBC_CM_JOINT_STEREO 0x03 - -/* allocation mode */ -#define SBC_AM_LOUDNESS 0x00 -#define SBC_AM_SNR 0x01 - -/* subbands */ -#define SBC_SB_4 0x00 -#define SBC_SB_8 0x01 - /* This structure contains an unpacked SBC frame. Yes, there is probably quite some unused space herein */ struct sbc_frame { - uint16_t sampling_frequency; /* in kHz */ + uint8_t frequency; + uint8_t block_mode; uint8_t blocks; enum { - MONO = SBC_CM_MONO, - DUAL_CHANNEL = SBC_CM_DUAL_CHANNEL, - STEREO = SBC_CM_STEREO, - JOINT_STEREO = SBC_CM_JOINT_STEREO - } channel_mode; + MONO = SBC_MODE_MONO, + DUAL_CHANNEL = SBC_MODE_DUAL_CHANNEL, + STEREO = SBC_MODE_STEREO, + JOINT_STEREO = SBC_MODE_JOINT_STEREO + } mode; uint8_t channels; enum { LOUDNESS = SBC_AM_LOUDNESS, SNR = SBC_AM_SNR - } allocation_method; + } allocation; + uint8_t subband_mode; uint8_t subbands; uint8_t bitpool; uint8_t codesize; uint8_t length; /* bit number x set means joint stereo has been used in subband x */ - uint8_t join; + uint8_t joint; /* only the lower 4 bits of every element are to be used */ uint8_t scale_factor[2][8]; @@ -187,15 +162,17 @@ static uint8_t sbc_crc8(const uint8_t *data, size_t len) * Takes a pointer to the frame in question, a pointer to the bits array and * the sampling frequency (as 2 bit integer) */ -static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], uint8_t sf) +static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8]) { - if (frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) { + uint8_t sf = frame->frequency; + + if (frame->mode == MONO || frame->mode == DUAL_CHANNEL) { int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice; int ch, sb; for (ch = 0; ch < frame->channels; ch++) { max_bitneed = 0; - if (frame->allocation_method == SNR) { + if (frame->allocation == SNR) { for (sb = 0; sb < frame->subbands; sb++) { bitneed[ch][sb] = frame->scale_factor[ch][sb]; if (bitneed[ch][sb] > max_bitneed) @@ -269,12 +246,12 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], ui } - } else if (frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) { + } else if (frame->mode == STEREO || frame->mode == JOINT_STEREO) { int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice; int ch, sb; max_bitneed = 0; - if (frame->allocation_method == SNR) { + if (frame->allocation == SNR) { for (ch = 0; ch < 2; ch++) { for (sb = 0; sb < frame->subbands; sb++) { bitneed[ch][sb] = frame->scale_factor[ch][sb]; @@ -395,9 +372,6 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, int crc_pos = 0; int32_t temp; - uint8_t sf; /* sampling_frequency, temporarily needed as - array index */ - int ch, sb, blk, bit; /* channel, subband, block and bit standard counters */ int bits[2][8]; /* bits distribution */ @@ -409,39 +383,26 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, if (data[0] != SBC_SYNCWORD) return -2; - sf = (data[1] >> 6) & 0x03; - switch (sf) { - case SBC_FS_16: - frame->sampling_frequency = 16000; - break; - case SBC_FS_32: - frame->sampling_frequency = 32000; - break; - case SBC_FS_44: - frame->sampling_frequency = 44100; - break; - case SBC_FS_48: - frame->sampling_frequency = 48000; - break; - } + frame->frequency = (data[1] >> 6) & 0x03; - switch ((data[1] >> 4) & 0x03) { - case SBC_NB_4: + frame->block_mode = (data[1] >> 4) & 0x03; + switch (frame->block_mode) { + case SBC_BLK_4: frame->blocks = 4; break; - case SBC_NB_8: + case SBC_BLK_8: frame->blocks = 8; break; - case SBC_NB_12: + case SBC_BLK_12: frame->blocks = 12; break; - case SBC_NB_16: + case SBC_BLK_16: frame->blocks = 16; break; } - frame->channel_mode = (data[1] >> 2) & 0x03; - switch (frame->channel_mode) { + frame->mode = (data[1] >> 2) & 0x03; + switch (frame->mode) { case MONO: frame->channels = 1; break; @@ -452,17 +413,18 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, break; } - frame->allocation_method = (data[1] >> 1) & 0x01; + frame->allocation = (data[1] >> 1) & 0x01; - frame->subbands = (data[1] & 0x01) ? 8 : 4; + frame->subband_mode = (data[1] & 0x01); + frame->subbands = frame->subband_mode ? 8 : 4; frame->bitpool = data[2]; - if ((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) && + if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) && frame->bitpool > 16 * frame->subbands) return -4; - if ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) && + if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) && frame->bitpool > 32 * frame->subbands) return -4; @@ -474,13 +436,13 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, crc_header[1] = data[2]; crc_pos = 16; - if (frame->channel_mode == JOINT_STEREO) { + if (frame->mode == JOINT_STEREO) { if (len * 8 < consumed + frame->subbands) return -1; - frame->join = 0x00; + frame->joint = 0x00; for (sb = 0; sb < frame->subbands - 1; sb++) - frame->join |= ((data[4] >> (7 - sb)) & 0x01) << sb; + frame->joint |= ((data[4] >> (7 - sb)) & 0x01) << sb; if (frame->subbands == 4) crc_header[crc_pos / 8] = data[4] & 0xf0; else @@ -509,7 +471,7 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, if (data[3] != sbc_crc8(crc_header, crc_pos)) return -3; - sbc_calculate_bits(frame, bits, sf); + sbc_calculate_bits(frame, bits); for (blk = 0; blk < frame->blocks; blk++) { for (ch = 0; ch < frame->channels; ch++) { @@ -551,10 +513,10 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, } } - if (frame->channel_mode == JOINT_STEREO) { + if (frame->mode == JOINT_STEREO) { for (blk = 0; blk < frame->blocks; blk++) { for (sb = 0; sb < frame->subbands; sb++) { - if (frame->join & (0x01 << sb)) { + if (frame->joint & (0x01 << sb)) { temp = frame->sb_sample[blk][0][sb] + frame->sb_sample[blk][1][sb]; frame->sb_sample[blk][1][sb] = @@ -980,8 +942,6 @@ 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; - /* Sampling frequency as temporary value for table lookup */ - uint8_t sf; uint16_t audio_sample; int ch, sb, blk, bit; /* channel, subband, block and bit counters */ @@ -992,42 +952,13 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) data[0] = SBC_SYNCWORD; - if (frame->sampling_frequency == 16000) { - data[1] = (SBC_FS_16 & 0x03) << 6; - sf = SBC_FS_16; - } else if (frame->sampling_frequency == 32000) { - data[1] = (SBC_FS_32 & 0x03) << 6; - sf = SBC_FS_32; - } else if (frame->sampling_frequency == 44100) { - data[1] = (SBC_FS_44 & 0x03) << 6; - sf = SBC_FS_44; - } else if (frame->sampling_frequency == 48000) { - data[1] = (SBC_FS_48 & 0x03) << 6; - sf = SBC_FS_48; - } else - return -2; + data[1] = (frame->frequency & 0x03) << 6; - switch (frame->blocks) { - case 4: - data[1] |= (SBC_NB_4 & 0x03) << 4; - break; - case 8: - data[1] |= (SBC_NB_8 & 0x03) << 4; - break; - case 12: - data[1] |= (SBC_NB_12 & 0x03) << 4; - break; - case 16: - data[1] |= (SBC_NB_16 & 0x03) << 4; - break; - default: - return -3; - break; - } + data[1] |= (frame->block_mode & 0x03) << 4; - data[1] |= (frame->channel_mode & 0x03) << 2; + data[1] |= (frame->mode & 0x03) << 2; - data[1] |= (frame->allocation_method & 0x01) << 1; + data[1] |= (frame->allocation & 0x01) << 1; switch (frame->subbands) { case 4: @@ -1043,11 +974,11 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) data[2] = frame->bitpool; - if ((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) && + if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) && frame->bitpool > frame->subbands << 4) return -5; - if ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) && + if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) && frame->bitpool > frame->subbands << 5) return -5; @@ -1072,14 +1003,14 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) } } - if (frame->channel_mode == JOINT_STEREO) { + if (frame->mode == JOINT_STEREO) { /* like frame->sb_sample but joint stereo */ int32_t sb_sample_j[16][2]; /* scalefactor and scale_factor in joint case */ u_int32_t scalefactor_j[2]; uint8_t scale_factor_j[2]; - frame->join = 0; + frame->joint = 0; for (sb = 0; sb < frame->subbands - 1; sb++) { scale_factor_j[0] = 0; @@ -1111,7 +1042,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) if ((scalefactor[0][sb] + scalefactor[1][sb]) > (scalefactor_j[0] + scalefactor_j[1]) ) { /* use joint stereo for this subband */ - frame->join |= 1 << sb; + frame->joint |= 1 << sb; frame->scale_factor[0][sb] = scale_factor_j[0]; frame->scale_factor[1][sb] = scale_factor_j[1]; scalefactor[0][sb] = scalefactor_j[0]; @@ -1127,7 +1058,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) data[4] = 0; for (sb = 0; sb < frame->subbands - 1; sb++) - data[4] |= ((frame->join >> sb) & 0x01) << (frame->subbands - 1 - sb); + data[4] |= ((frame->joint >> sb) & 0x01) << (frame->subbands - 1 - sb); crc_header[crc_pos >> 3] = data[4]; @@ -1153,7 +1084,7 @@ static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len) data[3] = sbc_crc8(crc_header, crc_pos); - sbc_calculate_bits(frame, bits, sf); + sbc_calculate_bits(frame, bits); for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) @@ -1198,13 +1129,18 @@ struct sbc_priv { static void sbc_set_defaults(sbc_t *sbc, unsigned long flags) { - sbc->rate = 44100; - sbc->channels = 2; - sbc->joint = 0; - sbc->subbands = 8; - sbc->blocks = 16; + sbc->frequency = SBC_FREQ_44100; + sbc->mode = SBC_MODE_STEREO; + sbc->subbands = SBC_SB_8; + sbc->blocks = SBC_BLK_16; sbc->bitpool = 32; - sbc->swap = 0; +#if __BYTE_ORDER == __LITTLE_ENDIAN + sbc->endian = SBC_LE; +#elif __BYTE_ORDER == __BIG_ENDIAN + sbc->endian = SBC_BE; +#else +#error "Unknown byte order" +#endif } int sbc_init(sbc_t *sbc, unsigned long flags) @@ -1248,10 +1184,11 @@ int sbc_decode(sbc_t *sbc, void *input, int input_len, void *output, sbc_decoder_init(&priv->dec_state, &priv->frame); priv->init = 1; - sbc->rate = priv->frame.sampling_frequency; - sbc->channels = priv->frame.channels; - sbc->subbands = priv->frame.subbands; - sbc->blocks = priv->frame.blocks; + sbc->frequency = priv->frame.frequency; + sbc->mode = priv->frame.mode; + sbc->subbands = priv->frame.subband_mode; + sbc->blocks = priv->frame.block_mode; + sbc->allocation = priv->frame.allocation; sbc->bitpool = priv->frame.bitpool; priv->frame.codesize = sbc_get_codesize(sbc); @@ -1276,7 +1213,13 @@ int sbc_decode(sbc_t *sbc, void *input, int input_len, void *output, int16_t s; s = priv->frame.pcm_sample[ch][i]; - if (sbc->swap) { +#if __BYTE_ORDER == __LITTLE_ENDIAN + if (sbc->endian == SBC_BE) { +#elif __BYTE_ORDER == __BIG_ENDIAN + if (sbc->endian == SBC_LE) { +#else +#error "Unknown byte order" +#endif *ptr++ = (s & 0xff00) >> 8; *ptr++ = (s & 0x00ff); } else { @@ -1308,20 +1251,14 @@ int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output, *written = 0; if (!priv->init) { - priv->frame.sampling_frequency = sbc->rate; - priv->frame.channels = sbc->channels; - - if (sbc->channels > 1) { - if (sbc->joint) - priv->frame.channel_mode = JOINT_STEREO; - else - priv->frame.channel_mode = STEREO; - } else - priv->frame.channel_mode = MONO; - - priv->frame.allocation_method = sbc->allocation; - priv->frame.subbands = sbc->subbands; - priv->frame.blocks = sbc->blocks; + priv->frame.frequency = sbc->frequency; + priv->frame.mode = sbc->mode; + priv->frame.channels = sbc->mode == SBC_MODE_MONO ? 1 : 2; + priv->frame.allocation = sbc->allocation; + priv->frame.subband_mode = sbc->subbands; + priv->frame.subbands = sbc->subbands ? 8 : 4; + priv->frame.block_mode = sbc->blocks; + priv->frame.blocks = 4 + (sbc->blocks * 4); priv->frame.bitpool = sbc->bitpool; priv->frame.codesize = sbc_get_codesize(sbc); priv->frame.length = sbc_get_frame_length(sbc); @@ -1341,10 +1278,15 @@ int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output, ptr = input; for (i = 0; i < priv->frame.subbands * priv->frame.blocks; i++) { - for (ch = 0; ch < sbc->channels; ch++) { + for (ch = 0; ch < priv->frame.channels; ch++) { int16_t s; - - if (sbc->swap) +#if __BYTE_ORDER == __LITTLE_ENDIAN + if (sbc->endian == SBC_BE) +#elif __BYTE_ORDER == __BIG_ENDIAN + if (sbc->endian == SBC_LE) +#else +#error "Unknown byte order" +#endif s = (ptr[0] & 0xff) << 8 | (ptr[1] & 0xff); else s = (ptr[0] & 0xff) | (ptr[1] & 0xff) << 8; @@ -1360,7 +1302,7 @@ int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output, if (written) *written = framelen; - return samples * sbc->channels * 2; + return samples * priv->frame.channels * 2; } void sbc_finish(sbc_t *sbc) @@ -1377,27 +1319,89 @@ void sbc_finish(sbc_t *sbc) int sbc_get_frame_length(sbc_t *sbc) { int ret; + uint8_t subbands, channels, blocks, joint; + struct sbc_priv *priv; + + priv = sbc->priv; + if (!priv->init) { + subbands = sbc->subbands ? 8 : 4; + blocks = 4 + (sbc->blocks * 4); + channels = sbc->mode == SBC_MODE_MONO ? 1 : 2; + joint = sbc->mode == SBC_MODE_JOINT_STEREO ? 1 : 0; + } else { + subbands = priv->frame.subbands; + blocks = priv->frame.blocks; + channels = priv->frame.channels; + joint = priv->frame.joint; + } - ret = 4 + (4 * sbc->subbands * sbc->channels) / 8; + ret = 4 + (4 * subbands * channels) / 8; /* This term is not always evenly divide so we round it up */ - if (sbc->channels == 1) - ret += ((sbc->blocks * sbc->channels * sbc->bitpool) + 7) / 8; + if (channels == 1) + ret += ((blocks * channels * sbc->bitpool) + 7) / 8; else - ret += (((sbc->joint ? sbc->subbands : 0) + sbc->blocks * sbc->bitpool) - + 7) / 8; + ret += (((joint ? subbands : 0) + blocks * sbc->bitpool) + 7) + / 8; return ret; } int sbc_get_frame_duration(sbc_t *sbc) { - return (1000000 * sbc->blocks * sbc->subbands) / sbc->rate; + uint8_t subbands, blocks; + uint16_t frequency; + struct sbc_priv *priv; + + priv = sbc->priv; + if (!priv->init) { + subbands = sbc->subbands ? 8 : 4; + blocks = 4 + (sbc->blocks * 4); + } else { + subbands = priv->frame.subbands; + blocks = priv->frame.blocks; + } + + switch (sbc->frequency) { + case SBC_FREQ_16000: + frequency = 16000; + break; + + case SBC_FREQ_32000: + frequency = 32000; + break; + + case SBC_FREQ_44100: + frequency = 44100; + break; + + case SBC_FREQ_48000: + frequency = 48000; + break; + default: + return 0; + } + + return (1000000 * blocks * subbands) / frequency; } int sbc_get_codesize(sbc_t *sbc) { - return sbc->subbands * sbc->blocks * sbc->channels * 2; + uint8_t subbands, channels, blocks; + struct sbc_priv *priv; + + priv = sbc->priv; + if (!priv->init) { + subbands = sbc->subbands ? 8 : 4; + blocks = 4 + (sbc->blocks * 4); + channels = sbc->mode == SBC_MODE_MONO ? 1 : 2; + } else { + subbands = priv->frame.subbands; + blocks = priv->frame.blocks; + channels = priv->frame.channels; + } + + return subbands * blocks * channels * 2; } int sbc_reinit(sbc_t *sbc, unsigned long flags) -- cgit From 4170955ad1f97eb8b7bf4f96025a654dab531571 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 22 Feb 2008 13:41:02 +0000 Subject: Replace 64bits multiplies by 32bits to further optimize the code --- sbc/sbc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 0b0bbc94..21a68063 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -551,7 +551,7 @@ static inline void sbc_synthesize_four(struct sbc_decoder_state *state, struct sbc_frame *frame, int ch, int blk) { int i, j, k, idx; - sbc_extended_t res; + sbc_fixed_t res; for (i = 0; i < 8; i++) { /* Shifting */ @@ -592,7 +592,7 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, struct sbc_frame *frame, int ch, int blk) { int i, j, k, idx; - sbc_extended_t res; + sbc_fixed_t res; for (i = 0; i < 16; i++) { /* Shifting */ @@ -667,8 +667,7 @@ static void sbc_encoder_init(struct sbc_encoder_state *state, static inline void _sbc_analyze_four(const int32_t *in, int32_t *out) { - sbc_fixed_t t[8]; - sbc_extended_t s[5]; + sbc_fixed_t t[8], s[5]; t[0] = SCALE4_STAGE1( /* Q8 */ MULA(_sbc_proto_4[0], in[8] - in[32], /* Q18 */ @@ -752,8 +751,7 @@ static inline void sbc_analyze_four(struct sbc_encoder_state *state, static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out) { - sbc_fixed_t t[8]; - sbc_extended_t s[8]; + sbc_fixed_t t[8], s[8]; t[0] = SCALE8_STAGE1( /* Q10 */ MULA(_sbc_proto_8[0], (in[16] - in[64]), /* Q18 = Q18 * Q0 */ -- cgit From 7a68b05beaed5944dcd88f23002c9f55a2f74ba6 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Fri, 29 Feb 2008 03:56:22 +0000 Subject: Cidorvan's 4-subband overflow fixes --- sbc/sbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 21a68063..5fc4752f 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -375,7 +375,7 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, int ch, sb, blk, bit; /* channel, subband, block and bit standard counters */ int bits[2][8]; /* bits distribution */ - int levels[2][8]; /* levels derived from that */ + uint32_t levels[2][8]; /* levels derived from that */ if (len < 4) return -1; -- cgit From 51a5483169faa3b64b50970891a545192836ee9b Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 6 Mar 2008 14:04:43 +0000 Subject: decoder optimization, now using nested multiply calls --- sbc/sbc.c | 99 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 51 insertions(+), 48 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 5fc4752f..beacfd6e 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -550,41 +550,42 @@ static void sbc_decoder_init(struct sbc_decoder_state *state, static inline void sbc_synthesize_four(struct sbc_decoder_state *state, struct sbc_frame *frame, int ch, int blk) { - int i, j, k, idx; - sbc_fixed_t res; + int i, k, idx; + int32_t *v = state->V[ch]; + int *offset = state->offset[ch]; for (i = 0; i < 8; i++) { /* Shifting */ - state->offset[ch][i]--; - if (state->offset[ch][i] < 0) { - state->offset[ch][i] = 79; - for (j = 0; j < 9; j++) - state->V[ch][j+80] = state->V[ch][j]; + offset[i]--; + if (offset[i] < 0) { + offset[i] = 79; + memcpy(v + 80, v, 9 * sizeof(*v)); } - } - for (i = 0; i < 8; i++) { /* Distribute the new matrix value to the shifted position */ - SBC_FIXED_0(res); - for (j = 0; j < 4; j++) - res = MULA(synmatrix4[i][j], - frame->sb_sample[blk][ch][j], res); - state->V[ch][state->offset[ch][i]] = SCALE4_STAGED1(res); + v[offset[i]] = SCALE4_STAGED1( + MULA(synmatrix4[i][0], frame->sb_sample[blk][ch][0], + MULA(synmatrix4[i][1], frame->sb_sample[blk][ch][1], + MULA(synmatrix4[i][2], frame->sb_sample[blk][ch][2], + MUL (synmatrix4[i][3], frame->sb_sample[blk][ch][3]))))); } /* Compute the samples */ - for (idx = 0, i = 0; i < 4; i++) { + for (idx = 0, i = 0; i < 4; i++, idx += 5) { k = (i + 4) & 0xf; - SBC_FIXED_0(res); - for (j = 0; j < 10; idx++) { - res = MULA(state->V[ch][state->offset[ch][i]+j++], - sbc_proto_4_40m0[idx], res); - res = MULA(state->V[ch][state->offset[ch][k]+j++], - sbc_proto_4_40m1[idx], res); - } /* Store in output, Q0 */ - frame->pcm_sample[ch][blk * 4 + i] = SCALE4_STAGED2(res); + frame->pcm_sample[ch][blk * 4 + i] = SCALE4_STAGED2( + MULA(v[offset[i] + 0], sbc_proto_4_40m0[idx + 0], + MULA(v[offset[k] + 1], sbc_proto_4_40m1[idx + 0], + MULA(v[offset[i] + 2], sbc_proto_4_40m0[idx + 1], + MULA(v[offset[k] + 3], sbc_proto_4_40m1[idx + 1], + MULA(v[offset[i] + 4], sbc_proto_4_40m0[idx + 2], + MULA(v[offset[k] + 5], sbc_proto_4_40m1[idx + 2], + MULA(v[offset[i] + 6], sbc_proto_4_40m0[idx + 3], + MULA(v[offset[k] + 7], sbc_proto_4_40m1[idx + 3], + MULA(v[offset[i] + 8], sbc_proto_4_40m0[idx + 4], + MUL( v[offset[k] + 9], sbc_proto_4_40m1[idx + 4]))))))))))); } } @@ -592,43 +593,45 @@ static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, struct sbc_frame *frame, int ch, int blk) { int i, j, k, idx; - sbc_fixed_t res; + int *offset = state->offset[ch]; for (i = 0; i < 16; i++) { /* Shifting */ - state->offset[ch][i]--; - if (state->offset[ch][i] < 0) { - state->offset[ch][i] = 159; + offset[i]--; + if (offset[i] < 0) { + offset[i] = 159; for (j = 0; j < 9; j++) - state->V[ch][j+160] = state->V[ch][j]; + state->V[ch][j + 160] = state->V[ch][j]; } - } - for (i = 0; i < 16; i++) { /* Distribute the new matrix value to the shifted position */ - SBC_FIXED_0(res); - for (j = 0; j < 8; j++) { - /* Q28 = Q15 * Q13 */ - res = MULA(synmatrix8[i][j], - frame->sb_sample[blk][ch][j], res); - } - /* Q10 */ - state->V[ch][state->offset[ch][i]] = SCALE8_STAGED1(res); + state->V[ch][offset[i]] = SCALE8_STAGED1( + MULA(synmatrix8[i][0], frame->sb_sample[blk][ch][0], + MULA(synmatrix8[i][1], frame->sb_sample[blk][ch][1], + MULA(synmatrix8[i][2], frame->sb_sample[blk][ch][2], + MULA(synmatrix8[i][3], frame->sb_sample[blk][ch][3], + MULA(synmatrix8[i][4], frame->sb_sample[blk][ch][4], + MULA(synmatrix8[i][5], frame->sb_sample[blk][ch][5], + MULA(synmatrix8[i][6], frame->sb_sample[blk][ch][6], + MUL( synmatrix8[i][7], frame->sb_sample[blk][ch][7]))))))))); } /* Compute the samples */ - for (idx = 0, i = 0; i < 8; i++) { + for (idx = 0, i = 0; i < 8; i++, idx += 5) { k = (i + 8) & 0xf; - SBC_FIXED_0(res); - for (j = 0; j < 10; idx++) { - res = MULA(state->V[ch][state->offset[ch][i]+j++], - sbc_proto_8_80m0[idx], res); - res = MULA(state->V[ch][state->offset[ch][k]+j++], - sbc_proto_8_80m1[idx], res); - } - /* Store in output */ - frame->pcm_sample[ch][blk * 8 + i] = SCALE8_STAGED2(res); // Q0 + /* Store in output */ + frame->pcm_sample[ch][blk * 8 + i] = SCALE8_STAGED2( // Q0 + MULA(state->V[ch][offset[i] + 0], sbc_proto_8_80m0[idx + 0], + MULA(state->V[ch][offset[k] + 1], sbc_proto_8_80m1[idx + 0], + MULA(state->V[ch][offset[i] + 2], sbc_proto_8_80m0[idx + 1], + MULA(state->V[ch][offset[k] + 3], sbc_proto_8_80m1[idx + 1], + MULA(state->V[ch][offset[i] + 4], sbc_proto_8_80m0[idx + 2], + MULA(state->V[ch][offset[k] + 5], sbc_proto_8_80m1[idx + 2], + MULA(state->V[ch][offset[i] + 6], sbc_proto_8_80m0[idx + 3], + MULA(state->V[ch][offset[k] + 7], sbc_proto_8_80m1[idx + 3], + MULA(state->V[ch][offset[i] + 8], sbc_proto_8_80m0[idx + 4], + MUL( state->V[ch][offset[k] + 9], sbc_proto_8_80m1[idx + 4]))))))))))); } } -- cgit From 9e446dba514577bd52f93f492903f0e4eb9941c7 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Sat, 8 Mar 2008 05:21:26 +0000 Subject: Cidorvan found another place where the spec had us saving a bunch of values that were used immediately. Just compute and use instead of saving. In the decoder. --- sbc/sbc.c | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index beacfd6e..1a19ac79 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -79,7 +79,6 @@ struct sbc_frame { uint8_t scale_factor[2][8]; /* raw integer subband samples in the frame */ - uint16_t audio_sample[16][2][8]; int32_t sb_sample_f[16][2][8]; int32_t sb_sample[16][2][8]; /* modified subband samples */ @@ -372,6 +371,7 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, int crc_pos = 0; int32_t temp; + int audio_sample; int ch, sb, blk, bit; /* channel, subband, block and bit standard counters */ int bits[2][8]; /* bits distribution */ @@ -473,28 +473,6 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, sbc_calculate_bits(frame, bits); - for (blk = 0; blk < frame->blocks; blk++) { - for (ch = 0; ch < frame->channels; ch++) { - for (sb = 0; sb < frame->subbands; sb++) { - frame->audio_sample[blk][ch][sb] = 0; - if (bits[ch][sb] == 0) - continue; - - for (bit = 0; bit < bits[ch][sb]; bit++) { - int b; /* A bit */ - if (consumed > len * 8) - return -1; - - b = (data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01; - frame->audio_sample[blk][ch][sb] |= - b << (bits[ch][sb] - bit - 1); - - consumed++; - } - } - } - } - for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) levels[ch][sb] = (1 << bits[ch][sb]) - 1; @@ -504,8 +482,19 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, for (ch = 0; ch < frame->channels; ch++) { for (sb = 0; sb < frame->subbands; sb++) { if (levels[ch][sb] > 0) { + audio_sample = 0; + for (bit = 0; bit < bits[ch][sb]; bit++) { + if (consumed > len * 8) + return -1; + + if ((data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01) + audio_sample |= 1 << (bits[ch][sb] - bit - 1); + + consumed++; + } + frame->sb_sample[blk][ch][sb] = - (((frame->audio_sample[blk][ch][sb] << 1) | 1) << frame->scale_factor[ch][sb])/ + (((audio_sample << 1) | 1) << frame->scale_factor[ch][sb]) / levels[ch][sb] - (1 << frame->scale_factor[ch][sb]); } else frame->sb_sample[blk][ch][sb] = 0; -- cgit From 45c36dbd276501aa76d9798a8fafe6c202db7276 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 11 Jun 2008 13:20:50 +0000 Subject: Avoid direct inclusion of malloc.h --- sbc/sbc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sbc/sbc.c') diff --git a/sbc/sbc.c b/sbc/sbc.c index 1a19ac79..6303421f 100644 --- a/sbc/sbc.c +++ b/sbc/sbc.c @@ -37,7 +37,6 @@ #include #include -#include #include #include #include -- cgit