Exemple #1
0
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;
    }
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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);
}
Exemple #7
0
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;
    }
}