发布时间:2025-12-09 14:10:38 浏览次数:3
void SBC_Decode(uint8_t * DataIn, FILE * fOutput){#define SBC_SAMPLING_FREQ 16#define SBC_CHANNEL_MODE 0#define SBC_NUM_OF_SUBBANDS 8#define SBC_NUM_OF_CHANNELS 1#define SBC_NUM_OF_BLOCKS 15#define SBC_ALLOC_METHOD 0#define SBC_BITPOOL 26 #define SBC_DECODED_BUFFER_SIZE (16*8)uint8_t blocks_per_packet = SBC_NUM_OF_BLOCKS;uint8_t num_bits = SBC_BITPOOL;const uint8_t * buf = (DataIn+1);//ignore CRC byteuint16_t len = SBC_GROUP_SIZE;uint16_t usDecodedBuffer[SBC_DECODED_BUFFER_SIZE];/* convenience */const uint8_t * end = buf + len;#define left (end - buf)uint16_t * outBufPtr = usDecodedBuffer;/* workspace */static INSAMPLE samples[16][8]; /* We blow the stack if this is not static. */ ITER i, j, k;uint32_t scaleFactors[8]; //= {0x0f, 0x0c, 0x0b, 0x0b, 0x0a, 0x0a, 0x09, 0x09};int32_t bitneed[8];uint32_t bits[8];int32_t bitcount, slicecount, bitslice;uint8_t samplingRate, blocks, snr, numSubbands, bitpoolSz, bitpos = 0x80;int8_t max_bitneed = 0; #ifndef SPEED_OVER_ACCURACYint32_t levels[8];#endif#if (DEBUG_DECODING == 1)const uint8_t *start_buf = buf;pr_info("%s: blocks_per_packet = %d, num_bits = %d, buf = %p, len = %d\n",__func__, blocks_per_packet, num_bits, buf, len);for (i = 0; i < len; i++) {pr_info("buf[%d] = 0x%02x\n", i, buf[i]);}#endif/* look into the frame header */if (left < SBC_GROUP_SIZE) goto out;/* too short a frame header *//* use Bemote specific constants */samplingRate = 0; /* always 16000 Hz */blocks = blocks_per_packet;snr = 0;numSubbands = SBC_NUM_OF_SUBBANDS;bitpoolSz = num_bits; /* read scale factors *//* pr_info("sbc_decode: read scale factors, numSubbands = %d\n", numSubbands); *//**/for(i = 0; i < numSubbands; i++){if(bitpos == 0x80){scaleFactors[i] = (*buf) >> 4;bitpos = 0x08;}else{scaleFactors[i] = (*buf++) & 0x0F;bitpos = 0x80;}}/* calculate bitneed table and max_bitneed value (A2DP 12.6.3.1) */if(snr){for(i = 0; i < numSubbands; i++){bitneed[i] = scaleFactors[i];if(bitneed[i] > max_bitneed) max_bitneed = bitneed[i];}}else{const signed char* tbl;if(numSubbands == 4) tbl = (const signed char*)loudness_4[samplingRate];else tbl = (const signed char*)loudness_8[samplingRate];for(i = 0; i < numSubbands; i++){if(scaleFactors[i]){int loudness = scaleFactors[i] - tbl[i];if(loudness > 0) loudness /= 2;bitneed[i] = loudness;}else bitneed[i] = -5;if(bitneed[i] > max_bitneed) max_bitneed = bitneed[i];}} /* fit bitslices into the bitpool */bitcount = 0;slicecount = 0;bitslice = max_bitneed + 1;/* pr_info("sbc_decode: fit bitslices into the bitpool, bitslice = %d\n", bitslice ); */do{bitslice--;bitcount += slicecount;slicecount = 0;for(i = 0; i < numSubbands; i++){if(bitneed[i] > bitslice + 1 && bitneed[i] < bitslice + 16) slicecount++;else if(bitneed[i] == bitslice + 1) slicecount += 2;}}while(bitcount + slicecount < bitpoolSz); /* distribute bits */for(i = 0; i < numSubbands; i++){if(bitneed[i] < bitslice + 2) bits[i] = 0;else{int8_t v = bitneed[i] - bitslice;if(v > 16) v = 16;bits[i] = v;}} /* allocate remaining bits */for(i = 0; i < numSubbands && bitcount < bitpoolSz; i++){if(bits[i] >= 2 && bits[i] < 16){bits[i]++;bitcount++;}else if(bitneed[i] == bitslice + 1 && bitpoolSz > bitcount + 1){bits[i] = 2;bitcount += 2;}}for(i = 0; i < numSubbands && bitcount < bitpoolSz; i++){if(bits[i] < 16){bits[i]++;bitcount++;}} /* reconstruct subband samples (A2DP 12.6.4) */#ifndef SPEED_OVER_ACCURACYfor(i = 0; i < numSubbands; i++) levels[i] = (1 << bits[i]) - 1;#endif/* pr_info("sbc_decode: reconstruct subband samples, blocks = %d\n", blocks ); */for(j = 0; j < blocks; j++){for(i = 0; i < numSubbands; i++){if(bits[i]){uint32_t val = 0;k = bits[i];do{val <<= 1;#if (DEBUG_DECODING == 1)pr_info("%s: buf = %p, offset %d\n",__func__, buf, buf-start_buf);#endifif(*buf & bitpos) val++;if(!(bitpos >>= 1)){bitpos = 0x80;buf++;}}while(--k);val = (val << 1) | 1;val <<= scaleFactors[i];#ifdef SPEED_OVER_ACCURACYval = mulshift(val, bits[i]);#elseval /= levels[i];#endifval -= (1 << scaleFactors[i]);samples[j][i] = SAMPLE_CVT(val);}else samples[j][i] = SAMPLE_CVT(0);}} //sbc_decoder_reset();for(j = 0; j < blocks; j++){synth(outBufPtr, samples[j], numSubbands, gV);outBufPtr += numSubbands;}/* if we used a byte partially, skip the rest of it, it is "padding" */if(bitpos != 0x80) buf++;out:#if (DEBUG_DECODING == 1)if(left < 0)pr_err("SBC: buffer over-read by %d bytes.\n", -left);if(left > 0)pr_err("SBC: buffer under-read by %d bytes.\n", left);#endif fwrite(usDecodedBuffer, sizeof(uint16_t), 120, fOutput);fflush(fOutput);memset(usDecodedBuffer, 0, sizeof(usDecodedBuffer));}1. LOW-POWER IMPLEMENTATION OF THE BLUETOOTH SUBBAND AUDIO CODEC.pdf
2. A2DP_SPEC_V12.pdf
3. 音频数据SBC算法编码方法及蓝牙立体声子系统.pdf