1df25739fSMilanka Ringwald /****************************************************************************** 2df25739fSMilanka Ringwald * 3df25739fSMilanka Ringwald * Copyright (C) 2014 The Android Open Source Project 4df25739fSMilanka Ringwald * Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved. 5df25739fSMilanka Ringwald * 6df25739fSMilanka Ringwald * Licensed under the Apache License, Version 2.0 (the "License"); 7df25739fSMilanka Ringwald * you may not use this file except in compliance with the License. 8df25739fSMilanka Ringwald * You may obtain a copy of the License at: 9df25739fSMilanka Ringwald * 10df25739fSMilanka Ringwald * http://www.apache.org/licenses/LICENSE-2.0 11df25739fSMilanka Ringwald * 12df25739fSMilanka Ringwald * Unless required by applicable law or agreed to in writing, software 13df25739fSMilanka Ringwald * distributed under the License is distributed on an "AS IS" BASIS, 14df25739fSMilanka Ringwald * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15df25739fSMilanka Ringwald * See the License for the specific language governing permissions and 16df25739fSMilanka Ringwald * limitations under the License. 17df25739fSMilanka Ringwald * 18df25739fSMilanka Ringwald ******************************************************************************/ 19df25739fSMilanka Ringwald 20df25739fSMilanka Ringwald /********************************************************************************** 21df25739fSMilanka Ringwald $Revision: #1 $ 22df25739fSMilanka Ringwald ***********************************************************************************/ 23df25739fSMilanka Ringwald 24df25739fSMilanka Ringwald /** 25df25739fSMilanka Ringwald @file 26df25739fSMilanka Ringwald This file drives SBC decoding. 27df25739fSMilanka Ringwald 28df25739fSMilanka Ringwald @ingroup codec_internal 29df25739fSMilanka Ringwald */ 30df25739fSMilanka Ringwald 31df25739fSMilanka Ringwald /** 32df25739fSMilanka Ringwald @addtogroup codec_internal 33df25739fSMilanka Ringwald @{ 34df25739fSMilanka Ringwald */ 35df25739fSMilanka Ringwald 36df25739fSMilanka Ringwald #include "oi_codec_sbc_private.h" 37df25739fSMilanka Ringwald #include "oi_bitstream.h" 38df25739fSMilanka Ringwald #include <stdio.h> 39df25739fSMilanka Ringwald 40df25739fSMilanka Ringwald OI_CHAR * const OI_Codec_Copyright = "Copyright 2002-2007 Open Interface North America, Inc. All rights reserved"; 41df25739fSMilanka Ringwald 42df25739fSMilanka Ringwald INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context, 43df25739fSMilanka Ringwald OI_UINT32 *decoderData, 44df25739fSMilanka Ringwald OI_UINT32 decoderDataBytes, 45df25739fSMilanka Ringwald OI_BYTE maxChannels, 46df25739fSMilanka Ringwald OI_BYTE pcmStride, 47df25739fSMilanka Ringwald OI_BOOL enhanced) 48df25739fSMilanka Ringwald { 49df25739fSMilanka Ringwald OI_UINT i; 50df25739fSMilanka Ringwald OI_STATUS status; 51df25739fSMilanka Ringwald 52df25739fSMilanka Ringwald for (i = 0; i < sizeof(*context); i++) { 53df25739fSMilanka Ringwald ((char *)context)[i] = 0; 54df25739fSMilanka Ringwald } 55df25739fSMilanka Ringwald 56df25739fSMilanka Ringwald #ifdef SBC_ENHANCED 57df25739fSMilanka Ringwald context->enhancedEnabled = enhanced ? TRUE : FALSE; 58df25739fSMilanka Ringwald #else 59df25739fSMilanka Ringwald context->enhancedEnabled = FALSE; 60df25739fSMilanka Ringwald if (enhanced){ 61df25739fSMilanka Ringwald return OI_STATUS_INVALID_PARAMETERS; 62df25739fSMilanka Ringwald } 63df25739fSMilanka Ringwald #endif 64df25739fSMilanka Ringwald 65df25739fSMilanka Ringwald status = OI_CODEC_SBC_Alloc(&context->common, decoderData, decoderDataBytes, maxChannels, pcmStride); 66df25739fSMilanka Ringwald 67df25739fSMilanka Ringwald if (!OI_SUCCESS(status)) { 68df25739fSMilanka Ringwald return status; 69df25739fSMilanka Ringwald } 70df25739fSMilanka Ringwald 71df25739fSMilanka Ringwald context->common.codecInfo = OI_Codec_Copyright; 72df25739fSMilanka Ringwald context->common.maxBitneed = 0; 73df25739fSMilanka Ringwald context->limitFrameFormat = FALSE; 74df25739fSMilanka Ringwald OI_SBC_ExpandFrameFields(&context->common.frameInfo); 75df25739fSMilanka Ringwald 76df25739fSMilanka Ringwald /*PLATFORM_DECODER_RESET(context);*/ 77df25739fSMilanka Ringwald 78df25739fSMilanka Ringwald return OI_OK; 79df25739fSMilanka Ringwald } 80df25739fSMilanka Ringwald 81df25739fSMilanka Ringwald 82df25739fSMilanka Ringwald 83df25739fSMilanka Ringwald 84df25739fSMilanka Ringwald /** 85df25739fSMilanka Ringwald * Read the SBC header up to but not including the joint stereo mask. The syncword has already been 86df25739fSMilanka Ringwald * examined, and the enhanced mode flag set, by FindSyncword. 87df25739fSMilanka Ringwald */ 88*fcb08cdbSMilanka Ringwald 89*fcb08cdbSMilanka Ringwald /* BK4BTSTACK_CHANGE START */ 90*fcb08cdbSMilanka Ringwald INLINE void OI_SBC_ReadHeader_mSBC(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data){ 91*fcb08cdbSMilanka Ringwald OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo; 92*fcb08cdbSMilanka Ringwald 93*fcb08cdbSMilanka Ringwald OI_ASSERT(data[0] == OI_mSBC_SYNCWORD); 94*fcb08cdbSMilanka Ringwald 95*fcb08cdbSMilanka Ringwald /* Avoid filling out all these strucutures if we already remember the values 96*fcb08cdbSMilanka Ringwald * from last time. Just in case we get a stream corresponding to data[1] == 97*fcb08cdbSMilanka Ringwald * 0, DecoderReset is responsible for ensuring the lookup table entries have 98*fcb08cdbSMilanka Ringwald * already been populated 99*fcb08cdbSMilanka Ringwald */ 100*fcb08cdbSMilanka Ringwald frame->reserved_for_future_use[0] = data[1]; 101*fcb08cdbSMilanka Ringwald frame->reserved_for_future_use[1] = data[2]; 102*fcb08cdbSMilanka Ringwald 103*fcb08cdbSMilanka Ringwald frame->freqIndex = 0; 104*fcb08cdbSMilanka Ringwald frame->frequency = 16000; 105*fcb08cdbSMilanka Ringwald 106*fcb08cdbSMilanka Ringwald frame->blocks = 4; // ? 107*fcb08cdbSMilanka Ringwald frame->nrof_blocks = 15; 108*fcb08cdbSMilanka Ringwald 109*fcb08cdbSMilanka Ringwald frame->mode = 0; 110*fcb08cdbSMilanka Ringwald frame->nrof_channels = 1; 111*fcb08cdbSMilanka Ringwald 112*fcb08cdbSMilanka Ringwald frame->alloc = SBC_LOUDNESS; 113*fcb08cdbSMilanka Ringwald 114*fcb08cdbSMilanka Ringwald frame->subbands = 1; 115*fcb08cdbSMilanka Ringwald frame->nrof_subbands = 8; 116*fcb08cdbSMilanka Ringwald 117*fcb08cdbSMilanka Ringwald frame->bitpool = 26; 118*fcb08cdbSMilanka Ringwald 119*fcb08cdbSMilanka Ringwald frame->crc = data[3]; 120*fcb08cdbSMilanka Ringwald 121*fcb08cdbSMilanka Ringwald frame->cachedInfo = 0; 122*fcb08cdbSMilanka Ringwald } 123*fcb08cdbSMilanka Ringwald 124*fcb08cdbSMilanka Ringwald /* BK4BTSTACK_CHANGE END */ 125*fcb08cdbSMilanka Ringwald 126*fcb08cdbSMilanka Ringwald 127df25739fSMilanka Ringwald INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data) 128df25739fSMilanka Ringwald { 129df25739fSMilanka Ringwald OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo; 130df25739fSMilanka Ringwald OI_UINT8 d1; 131df25739fSMilanka Ringwald 132df25739fSMilanka Ringwald OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD); 133df25739fSMilanka Ringwald 134df25739fSMilanka Ringwald /* Avoid filling out all these strucutures if we already remember the values 135df25739fSMilanka Ringwald * from last time. Just in case we get a stream corresponding to data[1] == 136df25739fSMilanka Ringwald * 0, DecoderReset is responsible for ensuring the lookup table entries have 137df25739fSMilanka Ringwald * already been populated 138df25739fSMilanka Ringwald */ 139df25739fSMilanka Ringwald d1 = data[1]; 140df25739fSMilanka Ringwald if (d1 != frame->cachedInfo) { 141df25739fSMilanka Ringwald 142df25739fSMilanka Ringwald frame->freqIndex = (d1 & (BIT7 | BIT6)) >> 6; 143df25739fSMilanka Ringwald frame->frequency = freq_values[frame->freqIndex]; 144df25739fSMilanka Ringwald 145df25739fSMilanka Ringwald frame->blocks = (d1 & (BIT5 | BIT4)) >> 4; 146df25739fSMilanka Ringwald frame->nrof_blocks = block_values[frame->blocks]; 147df25739fSMilanka Ringwald 148df25739fSMilanka Ringwald frame->mode = (d1 & (BIT3 | BIT2)) >> 2; 149df25739fSMilanka Ringwald frame->nrof_channels = channel_values[frame->mode]; 150df25739fSMilanka Ringwald 151df25739fSMilanka Ringwald frame->alloc = (d1 & BIT1) >> 1; 152df25739fSMilanka Ringwald 153df25739fSMilanka Ringwald frame->subbands = (d1 & BIT0); 154df25739fSMilanka Ringwald frame->nrof_subbands = band_values[frame->subbands]; 155df25739fSMilanka Ringwald 156df25739fSMilanka Ringwald frame->cachedInfo = d1; 157df25739fSMilanka Ringwald } 158df25739fSMilanka Ringwald /* 159df25739fSMilanka Ringwald * For decode, the bit allocator needs to know the bitpool value 160df25739fSMilanka Ringwald */ 161df25739fSMilanka Ringwald frame->bitpool = data[2]; 162df25739fSMilanka Ringwald frame->crc = data[3]; 163df25739fSMilanka Ringwald } 164df25739fSMilanka Ringwald 165df25739fSMilanka Ringwald 166df25739fSMilanka Ringwald #define LOW(x) ((x)& 0xf) 167df25739fSMilanka Ringwald #define HIGH(x) ((x) >> 4) 168df25739fSMilanka Ringwald 169df25739fSMilanka Ringwald /* 170df25739fSMilanka Ringwald * Read scalefactor values and prepare the bitstream for OI_SBC_ReadSamples 171df25739fSMilanka Ringwald */ 172df25739fSMilanka Ringwald PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT *common, 173df25739fSMilanka Ringwald const OI_BYTE *b, 174df25739fSMilanka Ringwald OI_BITSTREAM *bs) 175df25739fSMilanka Ringwald { 176df25739fSMilanka Ringwald OI_UINT i = common->frameInfo.nrof_subbands * common->frameInfo.nrof_channels; 177df25739fSMilanka Ringwald OI_INT8 *scale_factor = common->scale_factor; 178df25739fSMilanka Ringwald OI_UINT f; 179df25739fSMilanka Ringwald 180df25739fSMilanka Ringwald if (common->frameInfo.nrof_subbands == 8 || common->frameInfo.mode != SBC_JOINT_STEREO) { 181df25739fSMilanka Ringwald if (common->frameInfo.mode == SBC_JOINT_STEREO) { 182df25739fSMilanka Ringwald common->frameInfo.join = *b++; 183df25739fSMilanka Ringwald } else { 184df25739fSMilanka Ringwald common->frameInfo.join = 0; 185df25739fSMilanka Ringwald } 186df25739fSMilanka Ringwald i /= 2; 187df25739fSMilanka Ringwald do { 188df25739fSMilanka Ringwald *scale_factor++ = HIGH(f = *b++); 189df25739fSMilanka Ringwald *scale_factor++ = LOW(f); 190df25739fSMilanka Ringwald } while (--i); 191df25739fSMilanka Ringwald /* 192df25739fSMilanka Ringwald * In this case we know that the scale factors end on a byte boundary so all we need to do 193df25739fSMilanka Ringwald * is initialize the bitstream. 194df25739fSMilanka Ringwald */ 195df25739fSMilanka Ringwald OI_BITSTREAM_ReadInit(bs, b); 196df25739fSMilanka Ringwald } else { 197df25739fSMilanka Ringwald OI_ASSERT(common->frameInfo.nrof_subbands == 4 && common->frameInfo.mode == SBC_JOINT_STEREO); 198df25739fSMilanka Ringwald common->frameInfo.join = HIGH(f = *b++); 199df25739fSMilanka Ringwald i = (i - 1) / 2; 200df25739fSMilanka Ringwald do { 201df25739fSMilanka Ringwald *scale_factor++ = LOW(f); 202df25739fSMilanka Ringwald *scale_factor++ = HIGH(f = *b++); 203df25739fSMilanka Ringwald } while (--i); 204df25739fSMilanka Ringwald *scale_factor++ = LOW(f); 205df25739fSMilanka Ringwald /* 206df25739fSMilanka Ringwald * In 4-subband joint stereo mode, the joint stereo information ends on a half-byte 207df25739fSMilanka Ringwald * boundary, so it's necessary to use the bitstream abstraction to read it, since 208df25739fSMilanka Ringwald * OI_SBC_ReadSamples will need to pick up in mid-byte. 209df25739fSMilanka Ringwald */ 210df25739fSMilanka Ringwald OI_BITSTREAM_ReadInit(bs, b); 211df25739fSMilanka Ringwald *scale_factor++ = OI_BITSTREAM_ReadUINT4Aligned(bs); 212df25739fSMilanka Ringwald } 213df25739fSMilanka Ringwald } 214df25739fSMilanka Ringwald 215df25739fSMilanka Ringwald /** Read quantized subband samples from the input bitstream and expand them. */ 216df25739fSMilanka Ringwald PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs) 217df25739fSMilanka Ringwald { 218df25739fSMilanka Ringwald OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common; 219df25739fSMilanka Ringwald OI_UINT nrof_blocks = common->frameInfo.nrof_blocks; 220df25739fSMilanka Ringwald OI_INT32 * RESTRICT s = common->subdata; 221df25739fSMilanka Ringwald OI_UINT8 *ptr = global_bs->ptr.w; 222df25739fSMilanka Ringwald OI_UINT32 value = global_bs->value; 223df25739fSMilanka Ringwald OI_UINT bitPtr = global_bs->bitPtr; 224df25739fSMilanka Ringwald 225df25739fSMilanka Ringwald const OI_UINT iter_count = common->frameInfo.nrof_channels * common->frameInfo.nrof_subbands / 4; 226df25739fSMilanka Ringwald do { 227df25739fSMilanka Ringwald OI_UINT i; 228df25739fSMilanka Ringwald for (i = 0; i < iter_count; ++i) { 229df25739fSMilanka Ringwald OI_UINT32 sf_by4 = ((OI_UINT32*)common->scale_factor)[i]; 230df25739fSMilanka Ringwald OI_UINT32 bits_by4 = common->bits.uint32[i]; 231df25739fSMilanka Ringwald OI_UINT n; 232df25739fSMilanka Ringwald for (n = 0; n < 4; ++n) { 233df25739fSMilanka Ringwald OI_INT32 dequant; 234df25739fSMilanka Ringwald OI_UINT bits; 235df25739fSMilanka Ringwald OI_INT sf; 236df25739fSMilanka Ringwald 237df25739fSMilanka Ringwald if (OI_CPU_BYTE_ORDER == OI_LITTLE_ENDIAN_BYTE_ORDER) { 238df25739fSMilanka Ringwald bits = bits_by4 & 0xFF; 239df25739fSMilanka Ringwald bits_by4 >>= 8; 240df25739fSMilanka Ringwald sf = sf_by4 & 0xFF; 241df25739fSMilanka Ringwald sf_by4 >>= 8; 242df25739fSMilanka Ringwald } else { 243df25739fSMilanka Ringwald bits = (bits_by4 >> 24) & 0xFF; 244df25739fSMilanka Ringwald bits_by4 <<= 8; 245df25739fSMilanka Ringwald sf = (sf_by4 >> 24) & 0xFF; 246df25739fSMilanka Ringwald sf_by4 <<= 8; 247df25739fSMilanka Ringwald } 248df25739fSMilanka Ringwald 249df25739fSMilanka Ringwald if (bits) { 250df25739fSMilanka Ringwald OI_UINT32 raw; 251df25739fSMilanka Ringwald // return raw == audio sample (uint16) 252df25739fSMilanka Ringwald // bits == number of bits to read from stream 253df25739fSMilanka Ringwald // ptr == position in stream 254df25739fSMilanka Ringwald // value == 32bit value 255df25739fSMilanka Ringwald // bitPtr offset in 32bit value 256df25739fSMilanka Ringwald OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr); 257df25739fSMilanka Ringwald // dequant == sb_sample (int32) 258df25739fSMilanka Ringwald dequant = OI_SBC_Dequant(raw, sf, bits); 259df25739fSMilanka Ringwald } else { 260df25739fSMilanka Ringwald dequant = 0; 261df25739fSMilanka Ringwald } 262df25739fSMilanka Ringwald *s++ = dequant; 263df25739fSMilanka Ringwald } 264df25739fSMilanka Ringwald } 265df25739fSMilanka Ringwald } while (--nrof_blocks); 266df25739fSMilanka Ringwald } 267df25739fSMilanka Ringwald 268df25739fSMilanka Ringwald 269df25739fSMilanka Ringwald 270df25739fSMilanka Ringwald /** 271df25739fSMilanka Ringwald @} 272df25739fSMilanka Ringwald */ 273