1df25739fSMilanka Ringwald /****************************************************************************** 2df25739fSMilanka Ringwald * 3df25739fSMilanka Ringwald * Copyright (C) 1999-2012 Broadcom Corporation 4df25739fSMilanka Ringwald * 5df25739fSMilanka Ringwald * Licensed under the Apache License, Version 2.0 (the "License"); 6df25739fSMilanka Ringwald * you may not use this file except in compliance with the License. 7df25739fSMilanka Ringwald * You may obtain a copy of the License at: 8df25739fSMilanka Ringwald * 9df25739fSMilanka Ringwald * http://www.apache.org/licenses/LICENSE-2.0 10df25739fSMilanka Ringwald * 11df25739fSMilanka Ringwald * Unless required by applicable law or agreed to in writing, software 12df25739fSMilanka Ringwald * distributed under the License is distributed on an "AS IS" BASIS, 13df25739fSMilanka Ringwald * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14df25739fSMilanka Ringwald * See the License for the specific language governing permissions and 15df25739fSMilanka Ringwald * limitations under the License. 16df25739fSMilanka Ringwald * 17df25739fSMilanka Ringwald ******************************************************************************/ 18df25739fSMilanka Ringwald 19df25739fSMilanka Ringwald /****************************************************************************** 20df25739fSMilanka Ringwald * 21df25739fSMilanka Ringwald * contains code for encoder flow and initalization of encoder 22df25739fSMilanka Ringwald * 23df25739fSMilanka Ringwald ******************************************************************************/ 24df25739fSMilanka Ringwald 25df25739fSMilanka Ringwald #include <string.h> 26df25739fSMilanka Ringwald #include "sbc_encoder.h" 27df25739fSMilanka Ringwald #include "sbc_enc_func_declare.h" 28df25739fSMilanka Ringwald 29df25739fSMilanka Ringwald SINT16 EncMaxShiftCounter; 30df25739fSMilanka Ringwald 31df25739fSMilanka Ringwald #if (SBC_JOINT_STE_INCLUDED == TRUE) 32df25739fSMilanka Ringwald SINT32 s32LRDiff[SBC_MAX_NUM_OF_BLOCKS] = {0}; 33df25739fSMilanka Ringwald SINT32 s32LRSum[SBC_MAX_NUM_OF_BLOCKS] = {0}; 34df25739fSMilanka Ringwald #endif 35df25739fSMilanka Ringwald 36df25739fSMilanka Ringwald void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams) 37df25739fSMilanka Ringwald { 38df25739fSMilanka Ringwald SINT32 s32Ch; /* counter for ch*/ 39df25739fSMilanka Ringwald SINT32 s32Sb; /* counter for sub-band*/ 40df25739fSMilanka Ringwald UINT32 u32Count, maxBit = 0; /* loop count*/ 41df25739fSMilanka Ringwald SINT32 s32MaxValue; /* temp variable to store max value */ 42df25739fSMilanka Ringwald 43df25739fSMilanka Ringwald SINT16 *ps16ScfL; 44df25739fSMilanka Ringwald SINT32 *SbBuffer; 45df25739fSMilanka Ringwald SINT32 s32Blk; /* counter for block*/ 46df25739fSMilanka Ringwald SINT32 s32NumOfBlocks = pstrEncParams->s16NumOfBlocks; 47df25739fSMilanka Ringwald #if (SBC_JOINT_STE_INCLUDED == TRUE) 48df25739fSMilanka Ringwald SINT32 s32MaxValue2; 49df25739fSMilanka Ringwald UINT32 u32CountSum,u32CountDiff; 50df25739fSMilanka Ringwald SINT32 *pSum, *pDiff; 51df25739fSMilanka Ringwald #endif 52df25739fSMilanka Ringwald register SINT32 s32NumOfSubBands = pstrEncParams->s16NumOfSubBands; 53df25739fSMilanka Ringwald 54df25739fSMilanka Ringwald pstrEncParams->pu8NextPacket = pstrEncParams->pu8Packet; 55df25739fSMilanka Ringwald 56df25739fSMilanka Ringwald #if (SBC_NO_PCM_CPY_OPTION == TRUE) 57df25739fSMilanka Ringwald pstrEncParams->ps16NextPcmBuffer = pstrEncParams->ps16PcmBuffer; 58df25739fSMilanka Ringwald #else 59df25739fSMilanka Ringwald pstrEncParams->ps16NextPcmBuffer = pstrEncParams->as16PcmBuffer; 60df25739fSMilanka Ringwald #endif 61df25739fSMilanka Ringwald do 62df25739fSMilanka Ringwald { 63df25739fSMilanka Ringwald /* SBC ananlysis filter*/ 64df25739fSMilanka Ringwald if (s32NumOfSubBands == 4) 65df25739fSMilanka Ringwald SbcAnalysisFilter4(pstrEncParams); 66df25739fSMilanka Ringwald else 67df25739fSMilanka Ringwald SbcAnalysisFilter8(pstrEncParams); 68df25739fSMilanka Ringwald 69df25739fSMilanka Ringwald /* compute the scale factor, and save the max */ 70df25739fSMilanka Ringwald ps16ScfL = pstrEncParams->as16ScaleFactor; 71df25739fSMilanka Ringwald s32Ch=pstrEncParams->s16NumOfChannels*s32NumOfSubBands; 72df25739fSMilanka Ringwald 73df25739fSMilanka Ringwald pstrEncParams->ps16NextPcmBuffer+=s32Ch*s32NumOfBlocks; /* in case of multible sbc frame to encode update the pcm pointer */ 74df25739fSMilanka Ringwald 75df25739fSMilanka Ringwald for (s32Sb=0; s32Sb<s32Ch; s32Sb++) 76df25739fSMilanka Ringwald { 77df25739fSMilanka Ringwald SbBuffer=pstrEncParams->s32SbBuffer+s32Sb; 78df25739fSMilanka Ringwald s32MaxValue=0; 79df25739fSMilanka Ringwald for (s32Blk=s32NumOfBlocks;s32Blk>0;s32Blk--) 80df25739fSMilanka Ringwald { 81df25739fSMilanka Ringwald if (s32MaxValue<abs32(*SbBuffer)) 82df25739fSMilanka Ringwald s32MaxValue=abs32(*SbBuffer); 83df25739fSMilanka Ringwald SbBuffer+=s32Ch; 84df25739fSMilanka Ringwald } 85df25739fSMilanka Ringwald 86df25739fSMilanka Ringwald u32Count = (s32MaxValue > 0x800000) ? 9 : 0; 87df25739fSMilanka Ringwald 88df25739fSMilanka Ringwald for ( ; u32Count < 15; u32Count++) 89df25739fSMilanka Ringwald { 90df25739fSMilanka Ringwald if (s32MaxValue <= (SINT32)(0x8000 << u32Count)) 91df25739fSMilanka Ringwald break; 92df25739fSMilanka Ringwald } 93df25739fSMilanka Ringwald *ps16ScfL++ = (SINT16)u32Count; 94df25739fSMilanka Ringwald 95df25739fSMilanka Ringwald if (u32Count > maxBit) 96df25739fSMilanka Ringwald maxBit = u32Count; 97df25739fSMilanka Ringwald } 98df25739fSMilanka Ringwald /* In case of JS processing,check whether to use JS */ 99df25739fSMilanka Ringwald #if (SBC_JOINT_STE_INCLUDED == TRUE) 100df25739fSMilanka Ringwald if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) 101df25739fSMilanka Ringwald { 102df25739fSMilanka Ringwald /* Calculate sum and differance scale factors for making JS decision */ 103df25739fSMilanka Ringwald ps16ScfL = pstrEncParams->as16ScaleFactor ; 104df25739fSMilanka Ringwald /* calculate the scale factor of Joint stereo max sum and diff */ 105c1ab6cc1SMatthias Ringwald for (s32Sb = 0; s32Sb < (s32NumOfSubBands-1); s32Sb++) 106df25739fSMilanka Ringwald { 107df25739fSMilanka Ringwald SbBuffer=pstrEncParams->s32SbBuffer+s32Sb; 108df25739fSMilanka Ringwald s32MaxValue2=0; 109df25739fSMilanka Ringwald s32MaxValue=0; 110df25739fSMilanka Ringwald pSum = s32LRSum; 111df25739fSMilanka Ringwald pDiff = s32LRDiff; 112df25739fSMilanka Ringwald for (s32Blk=0;s32Blk<s32NumOfBlocks;s32Blk++) 113df25739fSMilanka Ringwald { 114df25739fSMilanka Ringwald *pSum=(*SbBuffer+*(SbBuffer+s32NumOfSubBands))>>1; 115df25739fSMilanka Ringwald if (abs32(*pSum)>s32MaxValue) 116df25739fSMilanka Ringwald s32MaxValue=abs32(*pSum); 117df25739fSMilanka Ringwald pSum++; 118df25739fSMilanka Ringwald *pDiff=(*SbBuffer-*(SbBuffer+s32NumOfSubBands))>>1; 119df25739fSMilanka Ringwald if (abs32(*pDiff)>s32MaxValue2) 120df25739fSMilanka Ringwald s32MaxValue2=abs32(*pDiff); 121df25739fSMilanka Ringwald pDiff++; 122df25739fSMilanka Ringwald SbBuffer+=s32Ch; 123df25739fSMilanka Ringwald } 124df25739fSMilanka Ringwald u32Count = (s32MaxValue > 0x800000) ? 9 : 0; 125df25739fSMilanka Ringwald for ( ; u32Count < 15; u32Count++) 126df25739fSMilanka Ringwald { 127df25739fSMilanka Ringwald if (s32MaxValue <= (SINT32)(0x8000 << u32Count)) 128df25739fSMilanka Ringwald break; 129df25739fSMilanka Ringwald } 130df25739fSMilanka Ringwald u32CountSum=u32Count; 131df25739fSMilanka Ringwald u32Count = (s32MaxValue2 > 0x800000) ? 9 : 0; 132df25739fSMilanka Ringwald for ( ; u32Count < 15; u32Count++) 133df25739fSMilanka Ringwald { 134df25739fSMilanka Ringwald if (s32MaxValue2 <= (SINT32)(0x8000 << u32Count)) 135df25739fSMilanka Ringwald break; 136df25739fSMilanka Ringwald } 137df25739fSMilanka Ringwald u32CountDiff=u32Count; 138df25739fSMilanka Ringwald if ( (*ps16ScfL + *(ps16ScfL+s32NumOfSubBands)) > (SINT16)(u32CountSum + u32CountDiff) ) 139df25739fSMilanka Ringwald { 140df25739fSMilanka Ringwald 141df25739fSMilanka Ringwald if (u32CountSum > maxBit) 142df25739fSMilanka Ringwald maxBit = u32CountSum; 143df25739fSMilanka Ringwald 144df25739fSMilanka Ringwald if (u32CountDiff > maxBit) 145df25739fSMilanka Ringwald maxBit = u32CountDiff; 146df25739fSMilanka Ringwald 147df25739fSMilanka Ringwald *ps16ScfL = (SINT16)u32CountSum; 148df25739fSMilanka Ringwald *(ps16ScfL+s32NumOfSubBands) = (SINT16)u32CountDiff; 149df25739fSMilanka Ringwald 150df25739fSMilanka Ringwald SbBuffer=pstrEncParams->s32SbBuffer+s32Sb; 151df25739fSMilanka Ringwald pSum = s32LRSum; 152df25739fSMilanka Ringwald pDiff = s32LRDiff; 153df25739fSMilanka Ringwald 154df25739fSMilanka Ringwald for (s32Blk = 0; s32Blk < s32NumOfBlocks; s32Blk++) 155df25739fSMilanka Ringwald { 156df25739fSMilanka Ringwald *SbBuffer = *pSum; 157df25739fSMilanka Ringwald *(SbBuffer+s32NumOfSubBands) = *pDiff; 158df25739fSMilanka Ringwald 159df25739fSMilanka Ringwald SbBuffer += s32NumOfSubBands<<1; 160df25739fSMilanka Ringwald pSum++; 161df25739fSMilanka Ringwald pDiff++; 162df25739fSMilanka Ringwald } 163df25739fSMilanka Ringwald 164df25739fSMilanka Ringwald pstrEncParams->as16Join[s32Sb] = 1; 165df25739fSMilanka Ringwald } 166df25739fSMilanka Ringwald else 167df25739fSMilanka Ringwald { 168df25739fSMilanka Ringwald pstrEncParams->as16Join[s32Sb] = 0; 169df25739fSMilanka Ringwald } 170df25739fSMilanka Ringwald ps16ScfL++; 171df25739fSMilanka Ringwald } 172df25739fSMilanka Ringwald pstrEncParams->as16Join[s32Sb] = 0; 173df25739fSMilanka Ringwald } 174df25739fSMilanka Ringwald #endif 175df25739fSMilanka Ringwald 176df25739fSMilanka Ringwald pstrEncParams->s16MaxBitNeed = (SINT16)maxBit; 177df25739fSMilanka Ringwald 178df25739fSMilanka Ringwald /* bit allocation */ 179df25739fSMilanka Ringwald if ((pstrEncParams->s16ChannelMode == SBC_STEREO) || (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)) 180df25739fSMilanka Ringwald sbc_enc_bit_alloc_ste(pstrEncParams); 181df25739fSMilanka Ringwald else 182df25739fSMilanka Ringwald sbc_enc_bit_alloc_mono(pstrEncParams); 183df25739fSMilanka Ringwald 184df25739fSMilanka Ringwald /* save the beginning of the frame. pu8NextPacket is modified in EncPacking() */ 1856704d3d7SMatthias Ringwald // pu8 = pstrEncParams->pu8NextPacket; 186df25739fSMilanka Ringwald /* Quantize the encoded audio */ 187df25739fSMilanka Ringwald EncPacking(pstrEncParams); 188df25739fSMilanka Ringwald } 189df25739fSMilanka Ringwald while(--(pstrEncParams->u8NumPacketToEncode)); 190df25739fSMilanka Ringwald 191df25739fSMilanka Ringwald pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */ 192df25739fSMilanka Ringwald 193df25739fSMilanka Ringwald } 194df25739fSMilanka Ringwald 195df25739fSMilanka Ringwald /**************************************************************************** 196df25739fSMilanka Ringwald * InitSbcAnalysisFilt - Initalizes the input data to 0 197df25739fSMilanka Ringwald * 198df25739fSMilanka Ringwald * RETURNS : N/A 199df25739fSMilanka Ringwald */ 200df25739fSMilanka Ringwald void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams) 201df25739fSMilanka Ringwald { 202b58bea6eSMatthias Ringwald // UINT16 s16SamplingFreq; /*temp variable to store smpling freq*/ 203df25739fSMilanka Ringwald SINT16 s16Bitpool; /*to store bit pool value*/ 2046704d3d7SMatthias Ringwald // SINT16 s16BitRate; /*to store bitrate*/ 205f7f65e65SMatthias Ringwald // SINT16 s16FrameLen; /*to store frame length*/ 206df25739fSMilanka Ringwald UINT16 HeaderParams; 207df25739fSMilanka Ringwald 208df25739fSMilanka Ringwald pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */ 209df25739fSMilanka Ringwald 210df25739fSMilanka Ringwald /* Required number of channels */ 211df25739fSMilanka Ringwald if (pstrEncParams->s16ChannelMode == SBC_MONO) 212df25739fSMilanka Ringwald pstrEncParams->s16NumOfChannels = 1; 213df25739fSMilanka Ringwald else 214df25739fSMilanka Ringwald pstrEncParams->s16NumOfChannels = 2; 215df25739fSMilanka Ringwald 216f7f65e65SMatthias Ringwald /* BK4BTSTACK_CHANGE START */ 217df25739fSMilanka Ringwald /* Bit pool calculation */ 218f7f65e65SMatthias Ringwald // if (pstrEncParams->s16SamplingFreq == SBC_sf16000) 219f7f65e65SMatthias Ringwald // s16SamplingFreq = 16000; 220f7f65e65SMatthias Ringwald // else if (pstrEncParams->s16SamplingFreq == SBC_sf32000) 221f7f65e65SMatthias Ringwald // s16SamplingFreq = 32000; 222f7f65e65SMatthias Ringwald // else if (pstrEncParams->s16SamplingFreq == SBC_sf44100) 223f7f65e65SMatthias Ringwald // s16SamplingFreq = 44100; 224f7f65e65SMatthias Ringwald // else 225f7f65e65SMatthias Ringwald // s16SamplingFreq = 48000; 226f7f65e65SMatthias Ringwald /* BK4BTSTACK_CHANGE END */ 227df25739fSMilanka Ringwald 228df25739fSMilanka Ringwald if ( (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) 229df25739fSMilanka Ringwald || (pstrEncParams->s16ChannelMode == SBC_STEREO) ) 230df25739fSMilanka Ringwald { 2314f0d422dSMilanka Ringwald /* BK4BTSTACK_CHANGE START */ 2324f0d422dSMilanka Ringwald // s16Bitpool = (SINT16)( (pstrEncParams->u16BitRate * 2334f0d422dSMilanka Ringwald // pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq) 2344f0d422dSMilanka Ringwald // -( (32 + (4 * pstrEncParams->s16NumOfSubBands * 2354f0d422dSMilanka Ringwald // pstrEncParams->s16NumOfChannels) 2364f0d422dSMilanka Ringwald // + ( (pstrEncParams->s16ChannelMode - 2) * 2374f0d422dSMilanka Ringwald // pstrEncParams->s16NumOfSubBands ) ) 2384f0d422dSMilanka Ringwald // / pstrEncParams->s16NumOfBlocks) ); 239df25739fSMilanka Ringwald 240f7f65e65SMatthias Ringwald s16Bitpool = pstrEncParams->s16BitPool; 241f7f65e65SMatthias Ringwald 242f7f65e65SMatthias Ringwald // s16FrameLen = 4 + (4*pstrEncParams->s16NumOfSubBands* 243f7f65e65SMatthias Ringwald // pstrEncParams->s16NumOfChannels)/8 244f7f65e65SMatthias Ringwald // + ( ((pstrEncParams->s16ChannelMode - 2) * 245f7f65e65SMatthias Ringwald // pstrEncParams->s16NumOfSubBands) 246f7f65e65SMatthias Ringwald // + (pstrEncParams->s16NumOfBlocks * s16Bitpool) ) / 8; 2476704d3d7SMatthias Ringwald // s16BitRate = (8 * s16FrameLen * s16SamplingFreq) 2486704d3d7SMatthias Ringwald // / (pstrEncParams->s16NumOfSubBands * 2496704d3d7SMatthias Ringwald // pstrEncParams->s16NumOfBlocks * 1000); 2506704d3d7SMatthias Ringwald 2514f0d422dSMilanka Ringwald // if (s16BitRate > pstrEncParams->u16BitRate) 2524f0d422dSMilanka Ringwald // s16Bitpool--; 2534f0d422dSMilanka Ringwald /* BK4BTSTACK_CHANGE END */ 254df25739fSMilanka Ringwald 255df25739fSMilanka Ringwald if(pstrEncParams->s16NumOfSubBands == 8) 256df25739fSMilanka Ringwald pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool; 257df25739fSMilanka Ringwald else 258df25739fSMilanka Ringwald pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool; 259df25739fSMilanka Ringwald } 260df25739fSMilanka Ringwald else 261df25739fSMilanka Ringwald { 2624f0d422dSMilanka Ringwald if (!pstrEncParams->mSBCEnabled){ 2634f0d422dSMilanka Ringwald /* BK4BTSTACK_CHANGE START */ 2644f0d422dSMilanka Ringwald // s16Bitpool = (SINT16)( ((pstrEncParams->s16NumOfSubBands * 2654f0d422dSMilanka Ringwald // pstrEncParams->u16BitRate * 1000) 2664f0d422dSMilanka Ringwald // / (s16SamplingFreq * pstrEncParams->s16NumOfChannels)) 2674f0d422dSMilanka Ringwald // -( ( (32 / pstrEncParams->s16NumOfChannels) + 2684f0d422dSMilanka Ringwald // (4 * pstrEncParams->s16NumOfSubBands) ) 2694f0d422dSMilanka Ringwald // / pstrEncParams->s16NumOfBlocks ) ); 2704f0d422dSMilanka Ringwald s16Bitpool = pstrEncParams->s16BitPool; 2714f0d422dSMilanka Ringwald /* BK4BTSTACK_CHANGE END */ 272df25739fSMilanka Ringwald pstrEncParams->s16BitPool = (s16Bitpool > 273df25739fSMilanka Ringwald (16 * pstrEncParams->s16NumOfSubBands)) 274df25739fSMilanka Ringwald ? (16*pstrEncParams->s16NumOfSubBands) : s16Bitpool; 275df25739fSMilanka Ringwald } 2764f0d422dSMilanka Ringwald } 277df25739fSMilanka Ringwald 278df25739fSMilanka Ringwald if (pstrEncParams->s16BitPool < 0) 279df25739fSMilanka Ringwald pstrEncParams->s16BitPool = 0; 280df25739fSMilanka Ringwald /* sampling freq */ 281df25739fSMilanka Ringwald HeaderParams = ((pstrEncParams->s16SamplingFreq & 3)<< 6); 282df25739fSMilanka Ringwald 283df25739fSMilanka Ringwald /* number of blocks*/ 284df25739fSMilanka Ringwald HeaderParams |= (((pstrEncParams->s16NumOfBlocks -4) & 12) << 2); 285df25739fSMilanka Ringwald 286df25739fSMilanka Ringwald /* channel mode: mono, dual...*/ 287df25739fSMilanka Ringwald HeaderParams |= ((pstrEncParams->s16ChannelMode & 3)<< 2); 288df25739fSMilanka Ringwald 289df25739fSMilanka Ringwald /* Loudness or SNR */ 290df25739fSMilanka Ringwald HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1)<< 1); 291df25739fSMilanka Ringwald HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1); /*4 or 8*/ 292df25739fSMilanka Ringwald pstrEncParams->FrameHeader=HeaderParams; 293df25739fSMilanka Ringwald 294df25739fSMilanka Ringwald if (pstrEncParams->s16NumOfSubBands==4) 295df25739fSMilanka Ringwald { 296df25739fSMilanka Ringwald if (pstrEncParams->s16NumOfChannels==1) 297c1ab6cc1SMatthias Ringwald EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(4*10))>>2)<<2; 298df25739fSMilanka Ringwald else 299c1ab6cc1SMatthias Ringwald EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(4*10*2))>>3)<<2; 300df25739fSMilanka Ringwald } 301df25739fSMilanka Ringwald else 302df25739fSMilanka Ringwald { 303df25739fSMilanka Ringwald if (pstrEncParams->s16NumOfChannels==1) 304c1ab6cc1SMatthias Ringwald EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(8*10))>>3)<<3; 305df25739fSMilanka Ringwald else 306c1ab6cc1SMatthias Ringwald EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(8*10*2))>>4)<<3; 307df25739fSMilanka Ringwald } 308df25739fSMilanka Ringwald 309df25739fSMilanka Ringwald // APPL_TRACE_EVENT("SBC_Encoder_Init : bitrate %d, bitpool %d", 310df25739fSMilanka Ringwald // pstrEncParams->u16BitRate, pstrEncParams->s16BitPool); 311df25739fSMilanka Ringwald 312*1d3a1229SMatthias Ringwald SbcAnalysisInit(pstrEncParams); 313df25739fSMilanka Ringwald } 314