xref: /btstack/3rd-party/bluedroid/encoder/srce/sbc_encoder.c (revision f7f65e655cda3d7f5fd12f82303aa2fbafe3771a)
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 /*************************************************************************************************
32df25739fSMilanka Ringwald  * SBC encoder scramble code
33df25739fSMilanka Ringwald  * Purpose: to tie the SBC code with BTE/mobile stack code,
34df25739fSMilanka Ringwald  *          especially for the case when the SBC is ported into a third-party Multimedia chip
35df25739fSMilanka Ringwald  *
36df25739fSMilanka Ringwald  * Algorithm:
37df25739fSMilanka Ringwald  *  init process: all counters reset to 0,
38df25739fSMilanka Ringwald  *                calculate base_index: (6 + s16NumOfChannels*s16NumOfSubBands/2)
39df25739fSMilanka Ringwald  *    scramble side:    the init process happens every time SBC_Encoder_Init() is called.
40df25739fSMilanka Ringwald  *    descramble side:  it would be nice to know if he "init" process has happened.
41df25739fSMilanka Ringwald  *                      alter the SBC SYNC word 0x9C (1001 1100) to 0x8C (1000 1100).
42df25739fSMilanka Ringwald  *
43df25739fSMilanka Ringwald  *  scramble process:
44df25739fSMilanka Ringwald  *    The CRC byte:
45df25739fSMilanka Ringwald  *    Every SBC frame has a frame header.
46df25739fSMilanka Ringwald  *    The 1st byte is the sync word and the following 2 bytes are about the stream format.
47df25739fSMilanka Ringwald  *    They are supposed to be "constant" within a "song"
48df25739fSMilanka Ringwald  *    The 4th byte is the CRC byte. The CRC byte is bound to be random.
49df25739fSMilanka Ringwald  *    Derive 2 items from the CRC byte; one is the "use" bit, the other is the "index".
50df25739fSMilanka Ringwald  *
51df25739fSMilanka Ringwald  *    SBC keeps 2 sets of "use" & "index"; derived the current and the previous frame.
52df25739fSMilanka Ringwald  *
53df25739fSMilanka Ringwald  *    The "use" bit is any bit in SBC_PRTC_USE_MASK is set.
54df25739fSMilanka Ringwald  *    If set, SBC uses the "index" from the current frame.
55df25739fSMilanka Ringwald  *    If not set, SBC uses the "index" from the previous frame or 0.
56df25739fSMilanka Ringwald  *
57df25739fSMilanka Ringwald  *    index = (CRC & 0x3) + ((CRC & 0x30) >> 2) // 8 is the max index
58df25739fSMilanka Ringwald  *
59df25739fSMilanka Ringwald  *    if(index > 0)
60df25739fSMilanka Ringwald  *    {
61df25739fSMilanka Ringwald  *        p = &u8frame[base_index];
62df25739fSMilanka Ringwald  *        if((index&1)&&(u16PacketLength > (base_index+index*2)))
63df25739fSMilanka Ringwald  *        {
64df25739fSMilanka Ringwald  *            // odd index: swap 2 bytes
65df25739fSMilanka Ringwald  *            tmp = p[index];
66df25739fSMilanka Ringwald  *            p[index] = p[index*2];
67df25739fSMilanka Ringwald  *            p[index*2] = tmp;
68df25739fSMilanka Ringwald  *        }
69df25739fSMilanka Ringwald  *        else
70df25739fSMilanka Ringwald  *        {
71df25739fSMilanka Ringwald  *            // even index: shift by 3
72df25739fSMilanka Ringwald  *            tmp = (p[index] >> 5) + (p[index] << 3);
73df25739fSMilanka Ringwald  *            p[index] = tmp;
74df25739fSMilanka Ringwald  *        }
75df25739fSMilanka Ringwald  *    }
76df25739fSMilanka Ringwald  *    //else index is 0. The frame stays unaltered
77df25739fSMilanka Ringwald  *
78df25739fSMilanka Ringwald  */
79df25739fSMilanka Ringwald 
80df25739fSMilanka Ringwald #define SBC_PRTC_CRC_IDX        3
81df25739fSMilanka Ringwald #define SBC_PRTC_USE_MASK       0x64
82df25739fSMilanka Ringwald #define SBC_PRTC_SYNC_MASK      0x10
83df25739fSMilanka Ringwald #define SBC_PRTC_CIDX           0
84df25739fSMilanka Ringwald #define SBC_PRTC_LIDX           1
85df25739fSMilanka Ringwald typedef struct
86df25739fSMilanka Ringwald {
87df25739fSMilanka Ringwald     UINT8   use;
88df25739fSMilanka Ringwald     UINT8   idx;
89df25739fSMilanka Ringwald } tSBC_FR_CB;
90df25739fSMilanka Ringwald 
91df25739fSMilanka Ringwald typedef struct
92df25739fSMilanka Ringwald {
93df25739fSMilanka Ringwald     tSBC_FR_CB      fr[2];
94df25739fSMilanka Ringwald     UINT8           init;
95df25739fSMilanka Ringwald     UINT8           index;
96df25739fSMilanka Ringwald     UINT8           base;
97df25739fSMilanka Ringwald } tSBC_PRTC_CB;
98df25739fSMilanka Ringwald tSBC_PRTC_CB sbc_prtc_cb;
99df25739fSMilanka Ringwald 
100df25739fSMilanka Ringwald #define SBC_PRTC_IDX(sc) (((sc) & 0x3) + (((sc) & 0x30) >> 2))
101df25739fSMilanka Ringwald #define SBC_PRTC_CHK_INIT(ar) {if(sbc_prtc_cb.init == 0){sbc_prtc_cb.init=1; ar[0] &= ~SBC_PRTC_SYNC_MASK;}}
102df25739fSMilanka Ringwald #define SBC_PRTC_C2L() {p_last=&sbc_prtc_cb.fr[SBC_PRTC_LIDX]; p_cur=&sbc_prtc_cb.fr[SBC_PRTC_CIDX]; \
103df25739fSMilanka Ringwald                         p_last->idx = p_cur->idx; p_last->use = p_cur->use;}
104df25739fSMilanka Ringwald #define SBC_PRTC_GETC(ar) {p_cur->use = ar[SBC_PRTC_CRC_IDX] & SBC_PRTC_USE_MASK; \
105df25739fSMilanka Ringwald                            p_cur->idx = SBC_PRTC_IDX(ar[SBC_PRTC_CRC_IDX]);}
106df25739fSMilanka Ringwald #define SBC_PRTC_CHK_CRC(ar) {SBC_PRTC_C2L();SBC_PRTC_GETC(ar);sbc_prtc_cb.index = (p_cur->use)?SBC_PRTC_CIDX:SBC_PRTC_LIDX;}
107df25739fSMilanka Ringwald #define SBC_PRTC_SCRMB(ar) {idx = sbc_prtc_cb.fr[sbc_prtc_cb.index].idx; \
108df25739fSMilanka Ringwald     if(idx > 0){if((idx&1)&&(pstrEncParams->u16PacketLength > (sbc_prtc_cb.base+(idx<<1)))) {tmp2=idx<<1; tmp=ar[idx];ar[idx]=ar[tmp2];ar[tmp2]=tmp;} \
109df25739fSMilanka Ringwald                 else{tmp2=ar[idx]; tmp=(tmp2>>5)+(tmp2<<3);ar[idx]=(UINT8)tmp;}}}
110df25739fSMilanka Ringwald 
111df25739fSMilanka Ringwald #if (SBC_JOINT_STE_INCLUDED == TRUE)
112df25739fSMilanka Ringwald SINT32   s32LRDiff[SBC_MAX_NUM_OF_BLOCKS]    = {0};
113df25739fSMilanka Ringwald SINT32   s32LRSum[SBC_MAX_NUM_OF_BLOCKS]     = {0};
114df25739fSMilanka Ringwald #endif
115df25739fSMilanka Ringwald 
116df25739fSMilanka Ringwald void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
117df25739fSMilanka Ringwald {
118df25739fSMilanka Ringwald     SINT32 s32Ch;                               /* counter for ch*/
119df25739fSMilanka Ringwald     SINT32 s32Sb;                               /* counter for sub-band*/
120df25739fSMilanka Ringwald     UINT32 u32Count, maxBit = 0;                          /* loop count*/
121df25739fSMilanka Ringwald     SINT32 s32MaxValue;                         /* temp variable to store max value */
122df25739fSMilanka Ringwald 
123df25739fSMilanka Ringwald     SINT16 *ps16ScfL;
124df25739fSMilanka Ringwald     SINT32 *SbBuffer;
125df25739fSMilanka Ringwald     SINT32 s32Blk;                              /* counter for block*/
126df25739fSMilanka Ringwald     SINT32  s32NumOfBlocks   = pstrEncParams->s16NumOfBlocks;
127df25739fSMilanka Ringwald #if (SBC_JOINT_STE_INCLUDED == TRUE)
128df25739fSMilanka Ringwald     SINT32 s32MaxValue2;
129df25739fSMilanka Ringwald     UINT32 u32CountSum,u32CountDiff;
130df25739fSMilanka Ringwald     SINT32 *pSum, *pDiff;
131df25739fSMilanka Ringwald #endif
132df25739fSMilanka Ringwald     /* BK4BTSTACK_CHANGE START */
1336704d3d7SMatthias Ringwald     // UINT8  *pu8;
134df25739fSMilanka Ringwald     // tSBC_FR_CB  *p_cur, *p_last;
135df25739fSMilanka Ringwald     // UINT32       idx, tmp, tmp2;
136df25739fSMilanka Ringwald     /* BK4BTSTACK_CHANGE STOP */
137df25739fSMilanka Ringwald     register SINT32  s32NumOfSubBands = pstrEncParams->s16NumOfSubBands;
138df25739fSMilanka Ringwald 
139df25739fSMilanka Ringwald     pstrEncParams->pu8NextPacket = pstrEncParams->pu8Packet;
140df25739fSMilanka Ringwald 
141df25739fSMilanka Ringwald #if (SBC_NO_PCM_CPY_OPTION == TRUE)
142df25739fSMilanka Ringwald     pstrEncParams->ps16NextPcmBuffer = pstrEncParams->ps16PcmBuffer;
143df25739fSMilanka Ringwald #else
144df25739fSMilanka Ringwald     pstrEncParams->ps16NextPcmBuffer  = pstrEncParams->as16PcmBuffer;
145df25739fSMilanka Ringwald #endif
146df25739fSMilanka Ringwald     do
147df25739fSMilanka Ringwald     {
148df25739fSMilanka Ringwald         /* SBC ananlysis filter*/
149df25739fSMilanka Ringwald         if (s32NumOfSubBands == 4)
150df25739fSMilanka Ringwald             SbcAnalysisFilter4(pstrEncParams);
151df25739fSMilanka Ringwald         else
152df25739fSMilanka Ringwald             SbcAnalysisFilter8(pstrEncParams);
153df25739fSMilanka Ringwald 
154df25739fSMilanka Ringwald         /* compute the scale factor, and save the max */
155df25739fSMilanka Ringwald         ps16ScfL = pstrEncParams->as16ScaleFactor;
156df25739fSMilanka Ringwald         s32Ch=pstrEncParams->s16NumOfChannels*s32NumOfSubBands;
157df25739fSMilanka Ringwald 
158df25739fSMilanka Ringwald             pstrEncParams->ps16NextPcmBuffer+=s32Ch*s32NumOfBlocks; /* in case of multible sbc frame to encode update the pcm pointer */
159df25739fSMilanka Ringwald 
160df25739fSMilanka Ringwald         for (s32Sb=0; s32Sb<s32Ch; s32Sb++)
161df25739fSMilanka Ringwald         {
162df25739fSMilanka Ringwald             SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
163df25739fSMilanka Ringwald             s32MaxValue=0;
164df25739fSMilanka Ringwald             for (s32Blk=s32NumOfBlocks;s32Blk>0;s32Blk--)
165df25739fSMilanka Ringwald             {
166df25739fSMilanka Ringwald                 if (s32MaxValue<abs32(*SbBuffer))
167df25739fSMilanka Ringwald                     s32MaxValue=abs32(*SbBuffer);
168df25739fSMilanka Ringwald                 SbBuffer+=s32Ch;
169df25739fSMilanka Ringwald             }
170df25739fSMilanka Ringwald 
171df25739fSMilanka Ringwald             u32Count = (s32MaxValue > 0x800000) ? 9 : 0;
172df25739fSMilanka Ringwald 
173df25739fSMilanka Ringwald             for ( ; u32Count < 15; u32Count++)
174df25739fSMilanka Ringwald             {
175df25739fSMilanka Ringwald                 if (s32MaxValue <= (SINT32)(0x8000 << u32Count))
176df25739fSMilanka Ringwald                     break;
177df25739fSMilanka Ringwald             }
178df25739fSMilanka Ringwald             *ps16ScfL++ = (SINT16)u32Count;
179df25739fSMilanka Ringwald 
180df25739fSMilanka Ringwald             if (u32Count > maxBit)
181df25739fSMilanka Ringwald                 maxBit = u32Count;
182df25739fSMilanka Ringwald         }
183df25739fSMilanka Ringwald         /* In case of JS processing,check whether to use JS */
184df25739fSMilanka Ringwald #if (SBC_JOINT_STE_INCLUDED == TRUE)
185df25739fSMilanka Ringwald         if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
186df25739fSMilanka Ringwald         {
187df25739fSMilanka Ringwald             /* Calculate sum and differance  scale factors for making JS decision   */
188df25739fSMilanka Ringwald             ps16ScfL = pstrEncParams->as16ScaleFactor ;
189df25739fSMilanka Ringwald             /* calculate the scale factor of Joint stereo max sum and diff */
190df25739fSMilanka Ringwald             for (s32Sb = 0; s32Sb < s32NumOfSubBands-1; s32Sb++)
191df25739fSMilanka Ringwald             {
192df25739fSMilanka Ringwald                 SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
193df25739fSMilanka Ringwald                 s32MaxValue2=0;
194df25739fSMilanka Ringwald                 s32MaxValue=0;
195df25739fSMilanka Ringwald                 pSum       = s32LRSum;
196df25739fSMilanka Ringwald                 pDiff      = s32LRDiff;
197df25739fSMilanka Ringwald                 for (s32Blk=0;s32Blk<s32NumOfBlocks;s32Blk++)
198df25739fSMilanka Ringwald                 {
199df25739fSMilanka Ringwald                     *pSum=(*SbBuffer+*(SbBuffer+s32NumOfSubBands))>>1;
200df25739fSMilanka Ringwald                     if (abs32(*pSum)>s32MaxValue)
201df25739fSMilanka Ringwald                         s32MaxValue=abs32(*pSum);
202df25739fSMilanka Ringwald                     pSum++;
203df25739fSMilanka Ringwald                     *pDiff=(*SbBuffer-*(SbBuffer+s32NumOfSubBands))>>1;
204df25739fSMilanka Ringwald                     if (abs32(*pDiff)>s32MaxValue2)
205df25739fSMilanka Ringwald                         s32MaxValue2=abs32(*pDiff);
206df25739fSMilanka Ringwald                     pDiff++;
207df25739fSMilanka Ringwald                     SbBuffer+=s32Ch;
208df25739fSMilanka Ringwald                 }
209df25739fSMilanka Ringwald                 u32Count = (s32MaxValue > 0x800000) ? 9 : 0;
210df25739fSMilanka Ringwald                 for ( ; u32Count < 15; u32Count++)
211df25739fSMilanka Ringwald                 {
212df25739fSMilanka Ringwald                     if (s32MaxValue <= (SINT32)(0x8000 << u32Count))
213df25739fSMilanka Ringwald                         break;
214df25739fSMilanka Ringwald                 }
215df25739fSMilanka Ringwald                 u32CountSum=u32Count;
216df25739fSMilanka Ringwald                 u32Count = (s32MaxValue2 > 0x800000) ? 9 : 0;
217df25739fSMilanka Ringwald                 for ( ; u32Count < 15; u32Count++)
218df25739fSMilanka Ringwald                 {
219df25739fSMilanka Ringwald                     if (s32MaxValue2 <= (SINT32)(0x8000 << u32Count))
220df25739fSMilanka Ringwald                         break;
221df25739fSMilanka Ringwald                 }
222df25739fSMilanka Ringwald                 u32CountDiff=u32Count;
223df25739fSMilanka Ringwald                 if ( (*ps16ScfL + *(ps16ScfL+s32NumOfSubBands)) > (SINT16)(u32CountSum + u32CountDiff) )
224df25739fSMilanka Ringwald                 {
225df25739fSMilanka Ringwald 
226df25739fSMilanka Ringwald                     if (u32CountSum > maxBit)
227df25739fSMilanka Ringwald                         maxBit = u32CountSum;
228df25739fSMilanka Ringwald 
229df25739fSMilanka Ringwald                     if (u32CountDiff > maxBit)
230df25739fSMilanka Ringwald                         maxBit = u32CountDiff;
231df25739fSMilanka Ringwald 
232df25739fSMilanka Ringwald                     *ps16ScfL = (SINT16)u32CountSum;
233df25739fSMilanka Ringwald                     *(ps16ScfL+s32NumOfSubBands) = (SINT16)u32CountDiff;
234df25739fSMilanka Ringwald 
235df25739fSMilanka Ringwald                     SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
236df25739fSMilanka Ringwald                     pSum       = s32LRSum;
237df25739fSMilanka Ringwald                     pDiff      = s32LRDiff;
238df25739fSMilanka Ringwald 
239df25739fSMilanka Ringwald                     for (s32Blk = 0; s32Blk < s32NumOfBlocks; s32Blk++)
240df25739fSMilanka Ringwald                     {
241df25739fSMilanka Ringwald                         *SbBuffer = *pSum;
242df25739fSMilanka Ringwald                         *(SbBuffer+s32NumOfSubBands) = *pDiff;
243df25739fSMilanka Ringwald 
244df25739fSMilanka Ringwald                         SbBuffer += s32NumOfSubBands<<1;
245df25739fSMilanka Ringwald                         pSum++;
246df25739fSMilanka Ringwald                         pDiff++;
247df25739fSMilanka Ringwald                     }
248df25739fSMilanka Ringwald 
249df25739fSMilanka Ringwald                     pstrEncParams->as16Join[s32Sb] = 1;
250df25739fSMilanka Ringwald                 }
251df25739fSMilanka Ringwald                 else
252df25739fSMilanka Ringwald                 {
253df25739fSMilanka Ringwald                     pstrEncParams->as16Join[s32Sb] = 0;
254df25739fSMilanka Ringwald                 }
255df25739fSMilanka Ringwald                 ps16ScfL++;
256df25739fSMilanka Ringwald             }
257df25739fSMilanka Ringwald             pstrEncParams->as16Join[s32Sb] = 0;
258df25739fSMilanka Ringwald         }
259df25739fSMilanka Ringwald #endif
260df25739fSMilanka Ringwald 
261df25739fSMilanka Ringwald         pstrEncParams->s16MaxBitNeed = (SINT16)maxBit;
262df25739fSMilanka Ringwald 
263df25739fSMilanka Ringwald         /* bit allocation */
264df25739fSMilanka Ringwald         if ((pstrEncParams->s16ChannelMode == SBC_STEREO) || (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO))
265df25739fSMilanka Ringwald             sbc_enc_bit_alloc_ste(pstrEncParams);
266df25739fSMilanka Ringwald         else
267df25739fSMilanka Ringwald             sbc_enc_bit_alloc_mono(pstrEncParams);
268df25739fSMilanka Ringwald 
269df25739fSMilanka Ringwald         /* save the beginning of the frame. pu8NextPacket is modified in EncPacking() */
2706704d3d7SMatthias Ringwald         // pu8 = pstrEncParams->pu8NextPacket;
271df25739fSMilanka Ringwald         /* Quantize the encoded audio */
272df25739fSMilanka Ringwald         EncPacking(pstrEncParams);
273df25739fSMilanka Ringwald 
274df25739fSMilanka Ringwald /* BK4BTSTACK_CHANGE START */
275df25739fSMilanka Ringwald         /* scramble the code */
276df25739fSMilanka Ringwald         //SBC_PRTC_CHK_INIT(pu8);
277df25739fSMilanka Ringwald         //SBC_PRTC_CHK_CRC(pu8);
278df25739fSMilanka Ringwald #if 0
279df25739fSMilanka Ringwald         if(pstrEncParams->u16PacketLength > ((sbc_prtc_cb.fr[sbc_prtc_cb.index].idx * 2) + sbc_prtc_cb.base))
280df25739fSMilanka Ringwald             printf("len: %d, idx: %d\n", pstrEncParams->u16PacketLength, sbc_prtc_cb.fr[sbc_prtc_cb.index].idx);
281df25739fSMilanka Ringwald         else
282df25739fSMilanka Ringwald             printf("len: %d, idx: %d!!!!\n", pstrEncParams->u16PacketLength, sbc_prtc_cb.fr[sbc_prtc_cb.index].idx);
283df25739fSMilanka Ringwald #endif
284df25739fSMilanka Ringwald         //SBC_PRTC_SCRMB((&pu8[sbc_prtc_cb.base]));
285df25739fSMilanka Ringwald /* BK4BTSTACK_CHANGE STOP */
286df25739fSMilanka Ringwald 
287df25739fSMilanka Ringwald     }
288df25739fSMilanka Ringwald     while(--(pstrEncParams->u8NumPacketToEncode));
289df25739fSMilanka Ringwald 
290df25739fSMilanka Ringwald     pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */
291df25739fSMilanka Ringwald 
292df25739fSMilanka Ringwald }
293df25739fSMilanka Ringwald 
294df25739fSMilanka Ringwald /****************************************************************************
295df25739fSMilanka Ringwald * InitSbcAnalysisFilt - Initalizes the input data to 0
296df25739fSMilanka Ringwald *
297df25739fSMilanka Ringwald * RETURNS : N/A
298df25739fSMilanka Ringwald */
299df25739fSMilanka Ringwald void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams)
300df25739fSMilanka Ringwald {
301df25739fSMilanka Ringwald     UINT16 s16SamplingFreq; /*temp variable to store smpling freq*/
302df25739fSMilanka Ringwald     SINT16 s16Bitpool;      /*to store bit pool value*/
3036704d3d7SMatthias Ringwald     // SINT16 s16BitRate;      /*to store bitrate*/
304*f7f65e65SMatthias Ringwald     // SINT16 s16FrameLen;     /*to store frame length*/
305df25739fSMilanka Ringwald     UINT16 HeaderParams;
306df25739fSMilanka Ringwald 
307df25739fSMilanka Ringwald     pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */
308df25739fSMilanka Ringwald 
309df25739fSMilanka Ringwald     /* Required number of channels */
310df25739fSMilanka Ringwald     if (pstrEncParams->s16ChannelMode == SBC_MONO)
311df25739fSMilanka Ringwald         pstrEncParams->s16NumOfChannels = 1;
312df25739fSMilanka Ringwald     else
313df25739fSMilanka Ringwald         pstrEncParams->s16NumOfChannels = 2;
314df25739fSMilanka Ringwald 
315*f7f65e65SMatthias Ringwald     /* BK4BTSTACK_CHANGE START */
316df25739fSMilanka Ringwald     /* Bit pool calculation */
317*f7f65e65SMatthias Ringwald     // if (pstrEncParams->s16SamplingFreq == SBC_sf16000)
318*f7f65e65SMatthias Ringwald     //     s16SamplingFreq = 16000;
319*f7f65e65SMatthias Ringwald     // else if (pstrEncParams->s16SamplingFreq == SBC_sf32000)
320*f7f65e65SMatthias Ringwald     //     s16SamplingFreq = 32000;
321*f7f65e65SMatthias Ringwald     // else if (pstrEncParams->s16SamplingFreq == SBC_sf44100)
322*f7f65e65SMatthias Ringwald     //     s16SamplingFreq = 44100;
323*f7f65e65SMatthias Ringwald     // else
324*f7f65e65SMatthias Ringwald     //     s16SamplingFreq = 48000;
325*f7f65e65SMatthias Ringwald     /* BK4BTSTACK_CHANGE END */
326df25739fSMilanka Ringwald 
327df25739fSMilanka Ringwald     if ( (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
328df25739fSMilanka Ringwald         ||  (pstrEncParams->s16ChannelMode == SBC_STEREO) )
329df25739fSMilanka Ringwald     {
3304f0d422dSMilanka Ringwald         /* BK4BTSTACK_CHANGE START */
3314f0d422dSMilanka Ringwald         // s16Bitpool = (SINT16)( (pstrEncParams->u16BitRate *
3324f0d422dSMilanka Ringwald         //     pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
3334f0d422dSMilanka Ringwald         //     -( (32 + (4 * pstrEncParams->s16NumOfSubBands *
3344f0d422dSMilanka Ringwald         //     pstrEncParams->s16NumOfChannels)
3354f0d422dSMilanka Ringwald         //     + ( (pstrEncParams->s16ChannelMode - 2) *
3364f0d422dSMilanka Ringwald         //     pstrEncParams->s16NumOfSubBands )   )
3374f0d422dSMilanka Ringwald         //     / pstrEncParams->s16NumOfBlocks) );
338df25739fSMilanka Ringwald 
339*f7f65e65SMatthias Ringwald         s16Bitpool = pstrEncParams->s16BitPool;
340*f7f65e65SMatthias Ringwald 
341*f7f65e65SMatthias Ringwald         // s16FrameLen = 4 + (4*pstrEncParams->s16NumOfSubBands*
342*f7f65e65SMatthias Ringwald         //     pstrEncParams->s16NumOfChannels)/8
343*f7f65e65SMatthias Ringwald         //     + ( ((pstrEncParams->s16ChannelMode - 2) *
344*f7f65e65SMatthias Ringwald         //     pstrEncParams->s16NumOfSubBands)
345*f7f65e65SMatthias Ringwald         //     + (pstrEncParams->s16NumOfBlocks * s16Bitpool) ) / 8;
3466704d3d7SMatthias Ringwald         // s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
3476704d3d7SMatthias Ringwald         //     / (pstrEncParams->s16NumOfSubBands *
3486704d3d7SMatthias Ringwald         //     pstrEncParams->s16NumOfBlocks * 1000);
3496704d3d7SMatthias Ringwald 
3504f0d422dSMilanka Ringwald         // if (s16BitRate > pstrEncParams->u16BitRate)
3514f0d422dSMilanka Ringwald         //     s16Bitpool--;
3524f0d422dSMilanka Ringwald         /* BK4BTSTACK_CHANGE END */
353df25739fSMilanka Ringwald 
354df25739fSMilanka Ringwald         if(pstrEncParams->s16NumOfSubBands == 8)
355df25739fSMilanka Ringwald             pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool;
356df25739fSMilanka Ringwald         else
357df25739fSMilanka Ringwald             pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool;
358df25739fSMilanka Ringwald     }
359df25739fSMilanka Ringwald     else
360df25739fSMilanka Ringwald     {
3614f0d422dSMilanka Ringwald         if (!pstrEncParams->mSBCEnabled){
3624f0d422dSMilanka Ringwald             /* BK4BTSTACK_CHANGE START */
3634f0d422dSMilanka Ringwald             // s16Bitpool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
3644f0d422dSMilanka Ringwald             //     pstrEncParams->u16BitRate * 1000)
3654f0d422dSMilanka Ringwald             //     / (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
3664f0d422dSMilanka Ringwald             //     -( ( (32 / pstrEncParams->s16NumOfChannels) +
3674f0d422dSMilanka Ringwald             //     (4 * pstrEncParams->s16NumOfSubBands) )
3684f0d422dSMilanka Ringwald             //     /   pstrEncParams->s16NumOfBlocks ) );
3694f0d422dSMilanka Ringwald             s16Bitpool = pstrEncParams->s16BitPool;
3704f0d422dSMilanka Ringwald             /* BK4BTSTACK_CHANGE END */
371df25739fSMilanka Ringwald             pstrEncParams->s16BitPool = (s16Bitpool >
372df25739fSMilanka Ringwald                 (16 * pstrEncParams->s16NumOfSubBands))
373df25739fSMilanka Ringwald                 ? (16*pstrEncParams->s16NumOfSubBands) : s16Bitpool;
374df25739fSMilanka Ringwald         }
3754f0d422dSMilanka Ringwald     }
376df25739fSMilanka Ringwald 
377df25739fSMilanka Ringwald     if (pstrEncParams->s16BitPool < 0)
378df25739fSMilanka Ringwald         pstrEncParams->s16BitPool = 0;
379df25739fSMilanka Ringwald     /* sampling freq */
380df25739fSMilanka Ringwald     HeaderParams = ((pstrEncParams->s16SamplingFreq & 3)<< 6);
381df25739fSMilanka Ringwald 
382df25739fSMilanka Ringwald     /* number of blocks*/
383df25739fSMilanka Ringwald     HeaderParams |= (((pstrEncParams->s16NumOfBlocks -4) & 12) << 2);
384df25739fSMilanka Ringwald 
385df25739fSMilanka Ringwald     /* channel mode: mono, dual...*/
386df25739fSMilanka Ringwald     HeaderParams |= ((pstrEncParams->s16ChannelMode & 3)<< 2);
387df25739fSMilanka Ringwald 
388df25739fSMilanka Ringwald     /* Loudness or SNR */
389df25739fSMilanka Ringwald     HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1)<< 1);
390df25739fSMilanka Ringwald     HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1);  /*4 or 8*/
391df25739fSMilanka Ringwald     pstrEncParams->FrameHeader=HeaderParams;
392df25739fSMilanka Ringwald 
393df25739fSMilanka Ringwald     if (pstrEncParams->s16NumOfSubBands==4)
394df25739fSMilanka Ringwald     {
395df25739fSMilanka Ringwald         if (pstrEncParams->s16NumOfChannels==1)
396df25739fSMilanka Ringwald             EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-4*10)>>2)<<2;
397df25739fSMilanka Ringwald         else
398df25739fSMilanka Ringwald             EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-4*10*2)>>3)<<2;
399df25739fSMilanka Ringwald     }
400df25739fSMilanka Ringwald     else
401df25739fSMilanka Ringwald     {
402df25739fSMilanka Ringwald         if (pstrEncParams->s16NumOfChannels==1)
403df25739fSMilanka Ringwald             EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-8*10)>>3)<<3;
404df25739fSMilanka Ringwald         else
405df25739fSMilanka Ringwald             EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-8*10*2)>>4)<<3;
406df25739fSMilanka Ringwald     }
407df25739fSMilanka Ringwald 
408df25739fSMilanka Ringwald     // APPL_TRACE_EVENT("SBC_Encoder_Init : bitrate %d, bitpool %d",
409df25739fSMilanka Ringwald     //         pstrEncParams->u16BitRate, pstrEncParams->s16BitPool);
410df25739fSMilanka Ringwald 
411df25739fSMilanka Ringwald     SbcAnalysisInit();
412df25739fSMilanka Ringwald 
413df25739fSMilanka Ringwald     memset(&sbc_prtc_cb, 0, sizeof(tSBC_PRTC_CB));
414df25739fSMilanka Ringwald     sbc_prtc_cb.base = 6 + pstrEncParams->s16NumOfChannels*pstrEncParams->s16NumOfSubBands/2;
415df25739fSMilanka Ringwald }
416