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
SBC_Encoder(SBC_ENC_PARAMS * pstrEncParams)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 */
SBC_Encoder_Init(SBC_ENC_PARAMS * pstrEncParams)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)
297*c0ca5c25SMatthias Ringwald pstrEncParams->EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(4*10))>>2)<<2;
298df25739fSMilanka Ringwald else
299*c0ca5c25SMatthias Ringwald pstrEncParams->EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(4*10*2))>>3)<<2;
300df25739fSMilanka Ringwald }
301df25739fSMilanka Ringwald else
302df25739fSMilanka Ringwald {
303df25739fSMilanka Ringwald if (pstrEncParams->s16NumOfChannels==1)
304*c0ca5c25SMatthias Ringwald pstrEncParams->EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(8*10))>>3)<<3;
305df25739fSMilanka Ringwald else
306*c0ca5c25SMatthias Ringwald pstrEncParams->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
3121d3a1229SMatthias Ringwald SbcAnalysisInit(pstrEncParams);
313df25739fSMilanka Ringwald }
314