INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits) { OI_UINT32 d; OI_INT32 result; OI_ASSERT(scale_factor <= 15); OI_ASSERT(bits <= 16); if (bits <= 1) { return 0; } d = (raw * 2) + 1; d *= dequant_long_scaled[bits]; result = d - SBC_DEQUANT_LONG_SCALED_OFFSET; #ifdef DEBUG_DEQUANTIZATION { OI_INT32 integerized_float_result; float float_result; float_result = dequant_float(raw, scale_factor, bits); integerized_float_result = (OI_INT32)floor(0.5f+float_result * (1 << 15)); /* This detects overflow */ OI_ASSERT(((result >= 0) && (integerized_float_result >= 0)) || ((result <= 0) && (integerized_float_result <= 0))); } #endif return result >> (15 - scale_factor); }
/* BK4BTSTACK_CHANGE START */ INLINE void OI_SBC_ReadHeader_mSBC(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data){ OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo; OI_ASSERT(data[0] == OI_mSBC_SYNCWORD); /* Avoid filling out all these strucutures if we already remember the values * from last time. Just in case we get a stream corresponding to data[1] == * 0, DecoderReset is responsible for ensuring the lookup table entries have * already been populated */ frame->reserved_for_future_use[0] = data[1]; frame->reserved_for_future_use[1] = data[2]; frame->freqIndex = 0; frame->frequency = 16000; frame->blocks = 4; // ? frame->nrof_blocks = 15; frame->mode = 0; frame->nrof_channels = 1; frame->alloc = SBC_LOUDNESS; frame->subbands = 1; frame->nrof_subbands = 8; frame->bitpool = 26; frame->crc = data[3]; frame->cachedInfo = 0; }
INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data) { OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo; OI_UINT8 d1; OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD); /* Avoid filling out all these strucutures if we already remember the values * from last time. Just in case we get a stream corresponding to data[1] == * 0, DecoderReset is responsible for ensuring the lookup table entries have * already been populated */ d1 = data[1]; if (d1 != frame->cachedInfo) { frame->freqIndex = (d1 & (BIT7 | BIT6)) >> 6; frame->frequency = freq_values[frame->freqIndex]; frame->blocks = (d1 & (BIT5 | BIT4)) >> 4; frame->nrof_blocks = block_values[frame->blocks]; frame->mode = (d1 & (BIT3 | BIT2)) >> 2; frame->nrof_channels = channel_values[frame->mode]; frame->alloc = (d1 & BIT1) >> 1; frame->subbands = (d1 & BIT0); frame->nrof_subbands = band_values[frame->subbands]; frame->cachedInfo = d1; }
PRIVATE OI_UINT8 OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM *bs) { OI_UINT32 result; OI_ASSERT(bs->bitPtr == 8); result = bs->value >> 16; bs->value = (bs->value << 8) | *bs->ptr.r++; return (OI_UINT8)result; }
PRIVATE OI_UINT8 OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM *bs) { OI_UINT32 result; OI_ASSERT(bs->bitPtr < 16); OI_ASSERT(bs->bitPtr % 4 == 0); if (bs->bitPtr == 8) { result = bs->value << 8; bs->bitPtr = 12; } else { result = bs->value << 12; bs->value = (bs->value << 8) | *bs->ptr.r++; bs->bitPtr = 8; } result >>= 28; OI_ASSERT(result < (1u << 4)); return (OI_UINT8)result; }
INLINE OI_INT32 OI_SBC_Dequant_Unscaled(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits) { OI_UINT32 d; OI_INT32 result; OI_ASSERT(scale_factor <= 15); OI_ASSERT(bits <= 16); if (bits <= 1) { return 0; } if (bits == 16) { result = (raw << 16) + raw - 0x7fff7fff; return SCALE(result, 24 - scale_factor); } d = (raw * 2) + 1; d *= dequant_long_unscaled[bits]; result = d - 0x80000000; return SCALE(result, 24 - scale_factor); }
INLINE float dequant_float(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits) { float result = (1 << (scale_factor+1)) * ((raw * 2.0f + 1.0f) / ((1 << bits) - 1.0f) - 1.0f); result /= SBC_DEQUANT_SCALING_FACTOR; /* Unless the encoder screwed up, all correct dequantized values should * satisfy this inequality. Non-compliant encoders which generate quantized * values with all 1-bits set can, theoretically, trigger this assert. This * is unlikely, however, and only an issue in debug mode. */ OI_ASSERT(fabs(result) < 32768 * 1.6); return result; }
static OI_STATUS DecodeBody(OI_CODEC_SBC_DECODER_CONTEXT *context, const OI_BYTE *bodyData, OI_INT16 *pcmData, OI_UINT32 *pcmBytes, OI_BOOL allowPartial) { OI_BITSTREAM bs; OI_UINT frameSamples = context->common.frameInfo.nrof_blocks * context->common.frameInfo.nrof_subbands; OI_UINT decode_block_count; /* * Based on the header data, make sure that there is enough room to write the output samples. */ if (*pcmBytes < (sizeof(OI_INT16) * frameSamples * context->common.pcmStride) && !allowPartial) { /* If we're not allowing partial decodes, we need room for the entire * codec frame */ TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA")); return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA; } else if (*pcmBytes < sizeof (OI_INT16) * context->common.frameInfo.nrof_subbands * context->common.pcmStride) { /* Even if we're allowing partials, we can still only decode on a frame * boundary */ return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA; } if (context->bufferedBlocks == 0) { TRACE(("Reading scalefactors")); OI_SBC_ReadScalefactors(&context->common, bodyData, &bs); TRACE(("Computing bit allocation")); OI_SBC_ComputeBitAllocation(&context->common); TRACE(("Reading samples")); if (context->common.frameInfo.mode == SBC_JOINT_STEREO) { OI_SBC_ReadSamplesJoint(context, &bs); } else { OI_SBC_ReadSamples(context, &bs); } context->bufferedBlocks = context->common.frameInfo.nrof_blocks; } if (allowPartial) { decode_block_count = *pcmBytes / sizeof(OI_INT16) / context->common.pcmStride / context->common.frameInfo.nrof_subbands; if (decode_block_count > context->bufferedBlocks) { decode_block_count = context->bufferedBlocks; } } else { decode_block_count = context->common.frameInfo.nrof_blocks; } TRACE(("Synthesizing frame")); { OI_UINT start_block = context->common.frameInfo.nrof_blocks - context->bufferedBlocks; OI_SBC_SynthFrame(context, pcmData, start_block, decode_block_count); } OI_ASSERT(context->bufferedBlocks >= decode_block_count); context->bufferedBlocks -= decode_block_count; frameSamples = decode_block_count * context->common.frameInfo.nrof_subbands; /* * When decoding mono into a stride-2 array, copy pcm data to second channel */ if (context->common.frameInfo.nrof_channels == 1 && context->common.pcmStride == 2) { OI_UINT i; for (i = 0; i < frameSamples; ++i) { pcmData[2*i+1] = pcmData[2*i]; } } /* * Return number of pcm bytes generated by the decode operation. */ *pcmBytes = frameSamples * sizeof(OI_INT16) * context->common.pcmStride; if (context->bufferedBlocks > 0) { return OI_CODEC_SBC_PARTIAL_DECODE; } else { return OI_OK; } }