xref: /btstack/3rd-party/bluedroid/encoder/srce/sbc_enc_bit_alloc_mono.c (revision c1ab6cc1beb14b16b46e74a3723644016d8c3cc7)
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  *  This file contains the code for bit allocation algorithm. It calculates
22df25739fSMilanka Ringwald  *  the number of bits required for the encoded stream of data.
23df25739fSMilanka Ringwald  *
24df25739fSMilanka Ringwald  ******************************************************************************/
25df25739fSMilanka Ringwald 
26df25739fSMilanka Ringwald /*Includes*/
27df25739fSMilanka Ringwald #include "sbc_encoder.h"
28df25739fSMilanka Ringwald #include "sbc_enc_func_declare.h"
29df25739fSMilanka Ringwald 
30df25739fSMilanka Ringwald /*global arrays*/
31df25739fSMilanka Ringwald const SINT16 sbc_enc_as16Offset4[4][4] = {  {-1, 0, 0, 0}, {-2, 0, 0, 1},
32df25739fSMilanka Ringwald                                     {-2, 0, 0, 1}, {-2, 0, 0, 1} };
33df25739fSMilanka Ringwald const SINT16 sbc_enc_as16Offset8[4][8] = {  {-2, 0, 0, 0, 0, 0, 0, 1},
34df25739fSMilanka Ringwald                                     {-3, 0, 0, 0, 0, 0, 1, 2},
35df25739fSMilanka Ringwald                                     {-4, 0, 0, 0, 0, 0, 1, 2},
36df25739fSMilanka Ringwald                                     {-4, 0, 0, 0, 0, 0, 1, 2} };
37df25739fSMilanka Ringwald 
38df25739fSMilanka Ringwald /****************************************************************************
39df25739fSMilanka Ringwald * BitAlloc - Calculates the required number of bits for the given scale factor
40df25739fSMilanka Ringwald * and the number of subbands.
41df25739fSMilanka Ringwald *
42df25739fSMilanka Ringwald * RETURNS : N/A
43df25739fSMilanka Ringwald */
44df25739fSMilanka Ringwald 
sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS * pstrCodecParams)45df25739fSMilanka Ringwald void sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS *pstrCodecParams)
46df25739fSMilanka Ringwald {
47df25739fSMilanka Ringwald     SINT32 s32MaxBitNeed;   /*to store the max bits needed per sb*/
48df25739fSMilanka Ringwald     SINT32 s32BitCount;     /*the used number of bits*/
49df25739fSMilanka Ringwald     SINT32 s32SliceCount;   /*to store hwo many slices can be put in bitpool*/
50df25739fSMilanka Ringwald     SINT32 s32BitSlice;     /*number of bitslices in bitpool*/
51df25739fSMilanka Ringwald     SINT32 s32Sb;           /*counter for sub-band*/
52df25739fSMilanka Ringwald     SINT32 s32Ch;           /*counter for channel*/
53df25739fSMilanka Ringwald     SINT16 *ps16BitNeed;    /*temp memory to store required number of bits*/
54df25739fSMilanka Ringwald     SINT32 s32Loudness;     /*used in Loudness calculation*/
55df25739fSMilanka Ringwald     SINT16 *ps16GenBufPtr;
56df25739fSMilanka Ringwald     SINT16 *ps16GenArrPtr;
57df25739fSMilanka Ringwald     SINT16 *ps16GenTabPtr;
58df25739fSMilanka Ringwald     SINT32  s32NumOfSubBands = pstrCodecParams->s16NumOfSubBands;
59df25739fSMilanka Ringwald 
60df25739fSMilanka Ringwald     ps16BitNeed = pstrCodecParams->s16ScartchMemForBitAlloc;
61df25739fSMilanka Ringwald 
62df25739fSMilanka Ringwald     for (s32Ch = 0; s32Ch < pstrCodecParams->s16NumOfChannels; s32Ch++)
63df25739fSMilanka Ringwald     {
64*c1ab6cc1SMatthias Ringwald         ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
65*c1ab6cc1SMatthias Ringwald         ps16GenArrPtr = pstrCodecParams->as16Bits+(s32Ch*SBC_MAX_NUM_OF_SUBBANDS);
66df25739fSMilanka Ringwald 
67df25739fSMilanka Ringwald         /* bitneed values are derived from scale factor */
68df25739fSMilanka Ringwald         if (pstrCodecParams->s16AllocationMethod == SBC_SNR)
69df25739fSMilanka Ringwald         {
70df25739fSMilanka Ringwald             ps16BitNeed = pstrCodecParams->as16ScaleFactor;
71*c1ab6cc1SMatthias Ringwald             ps16GenBufPtr = ps16BitNeed + (s32Ch * s32NumOfSubBands);
72df25739fSMilanka Ringwald         }
73df25739fSMilanka Ringwald         else
74df25739fSMilanka Ringwald         {
75*c1ab6cc1SMatthias Ringwald             ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
76df25739fSMilanka Ringwald             if(s32NumOfSubBands == 4)
77df25739fSMilanka Ringwald             {
78df25739fSMilanka Ringwald                 ps16GenTabPtr = (SINT16 *)
79df25739fSMilanka Ringwald                     sbc_enc_as16Offset4[pstrCodecParams->s16SamplingFreq];
80df25739fSMilanka Ringwald             }
81df25739fSMilanka Ringwald             else
82df25739fSMilanka Ringwald             {
83df25739fSMilanka Ringwald                 ps16GenTabPtr = (SINT16 *)
84df25739fSMilanka Ringwald                     sbc_enc_as16Offset8[pstrCodecParams->s16SamplingFreq];
85df25739fSMilanka Ringwald             }
86df25739fSMilanka Ringwald             for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
87df25739fSMilanka Ringwald             {
88*c1ab6cc1SMatthias Ringwald                 if(pstrCodecParams->as16ScaleFactor[(s32Ch*s32NumOfSubBands)+s32Sb] == 0)
89df25739fSMilanka Ringwald                     *(ps16GenBufPtr) = -5;
90df25739fSMilanka Ringwald                 else
91df25739fSMilanka Ringwald                 {
92df25739fSMilanka Ringwald                     s32Loudness =
93*c1ab6cc1SMatthias Ringwald                         (SINT32)(pstrCodecParams->as16ScaleFactor[(s32Ch*s32NumOfSubBands)+s32Sb]
94df25739fSMilanka Ringwald                                                             - *ps16GenTabPtr);
95df25739fSMilanka Ringwald                     if(s32Loudness > 0)
96df25739fSMilanka Ringwald                         *(ps16GenBufPtr) = (SINT16)(s32Loudness >>1);
97df25739fSMilanka Ringwald                     else
98df25739fSMilanka Ringwald                         *(ps16GenBufPtr) = (SINT16)s32Loudness;
99df25739fSMilanka Ringwald                 }
100df25739fSMilanka Ringwald                 ps16GenBufPtr++;
101df25739fSMilanka Ringwald                 ps16GenTabPtr++;
102df25739fSMilanka Ringwald             }
103df25739fSMilanka Ringwald 
104df25739fSMilanka Ringwald         }
105df25739fSMilanka Ringwald 
106df25739fSMilanka Ringwald         /* max bitneed index is searched*/
107df25739fSMilanka Ringwald         s32MaxBitNeed = 0;
108*c1ab6cc1SMatthias Ringwald         ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
109df25739fSMilanka Ringwald         for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
110df25739fSMilanka Ringwald         {
111df25739fSMilanka Ringwald             if( *(ps16GenBufPtr) > s32MaxBitNeed)
112df25739fSMilanka Ringwald                 s32MaxBitNeed = *(ps16GenBufPtr);
113df25739fSMilanka Ringwald 
114df25739fSMilanka Ringwald             ps16GenBufPtr++;
115df25739fSMilanka Ringwald         }
116*c1ab6cc1SMatthias Ringwald         ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
117df25739fSMilanka Ringwald         /*iterative process to find hwo many bitslices fit into the bitpool*/
118df25739fSMilanka Ringwald         s32BitSlice = s32MaxBitNeed + 1;
119df25739fSMilanka Ringwald         s32BitCount = pstrCodecParams->s16BitPool;
120df25739fSMilanka Ringwald         s32SliceCount = 0;
121df25739fSMilanka Ringwald         do
122df25739fSMilanka Ringwald         {
123df25739fSMilanka Ringwald             s32BitSlice --;
124df25739fSMilanka Ringwald             s32BitCount -= s32SliceCount;
125df25739fSMilanka Ringwald             s32SliceCount = 0;
126df25739fSMilanka Ringwald 
127df25739fSMilanka Ringwald             for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
128df25739fSMilanka Ringwald             {
129*c1ab6cc1SMatthias Ringwald                 if( (((*ps16GenBufPtr-s32BitSlice)< 16) && ((*ps16GenBufPtr-s32BitSlice) >= 1)))
130df25739fSMilanka Ringwald                 {
131df25739fSMilanka Ringwald                     if((*ps16GenBufPtr-s32BitSlice) == 1)
132df25739fSMilanka Ringwald                         s32SliceCount+=2;
133df25739fSMilanka Ringwald                     else
134df25739fSMilanka Ringwald                         s32SliceCount++;
135df25739fSMilanka Ringwald                 }
136df25739fSMilanka Ringwald                 ps16GenBufPtr++;
137df25739fSMilanka Ringwald 
138df25739fSMilanka Ringwald             }/*end of for*/
139*c1ab6cc1SMatthias Ringwald             ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
140*c1ab6cc1SMatthias Ringwald         }while((s32BitCount-s32SliceCount)>0);
141df25739fSMilanka Ringwald 
142df25739fSMilanka Ringwald         if(s32BitCount == 0)
143df25739fSMilanka Ringwald         {
144df25739fSMilanka Ringwald             s32BitCount -= s32SliceCount;
145df25739fSMilanka Ringwald             s32BitSlice --;
146df25739fSMilanka Ringwald         }
147df25739fSMilanka Ringwald 
148df25739fSMilanka Ringwald         /*Bits are distributed until the last bitslice is reached*/
149*c1ab6cc1SMatthias Ringwald         ps16GenArrPtr = pstrCodecParams->as16Bits+(s32Ch*s32NumOfSubBands);
150*c1ab6cc1SMatthias Ringwald         ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
151df25739fSMilanka Ringwald         for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
152df25739fSMilanka Ringwald         {
153*c1ab6cc1SMatthias Ringwald             if(*(ps16GenBufPtr) < (s32BitSlice+2))
154df25739fSMilanka Ringwald                 *(ps16GenArrPtr) = 0;
155df25739fSMilanka Ringwald             else
156df25739fSMilanka Ringwald                 *(ps16GenArrPtr) = ((*(ps16GenBufPtr)-s32BitSlice)<16) ?
157df25739fSMilanka Ringwald                     (SINT16)(*(ps16GenBufPtr)-s32BitSlice) : 16;
158df25739fSMilanka Ringwald 
159df25739fSMilanka Ringwald             ps16GenBufPtr++;
160df25739fSMilanka Ringwald             ps16GenArrPtr++;
161df25739fSMilanka Ringwald         }
162*c1ab6cc1SMatthias Ringwald         ps16GenArrPtr = pstrCodecParams->as16Bits+(s32Ch*s32NumOfSubBands);
163*c1ab6cc1SMatthias Ringwald         ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
164df25739fSMilanka Ringwald         /*the remaining bits are allocated starting at subband 0*/
165df25739fSMilanka Ringwald         s32Sb=0;
166df25739fSMilanka Ringwald         while( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) )
167df25739fSMilanka Ringwald         {
168df25739fSMilanka Ringwald             if( (*(ps16GenArrPtr) >= 2) && (*(ps16GenArrPtr) < 16) )
169df25739fSMilanka Ringwald             {
170df25739fSMilanka Ringwald                 (*(ps16GenArrPtr))++;
171df25739fSMilanka Ringwald                 s32BitCount--;
172df25739fSMilanka Ringwald             }
173*c1ab6cc1SMatthias Ringwald             else if( (*(ps16GenBufPtr) == (s32BitSlice+1)) &&
174df25739fSMilanka Ringwald                 (s32BitCount > 1) )
175df25739fSMilanka Ringwald             {
176df25739fSMilanka Ringwald                 *(ps16GenArrPtr) = 2;
177df25739fSMilanka Ringwald                 s32BitCount -= 2;
178df25739fSMilanka Ringwald             }
179df25739fSMilanka Ringwald             s32Sb++;
180df25739fSMilanka Ringwald             ps16GenArrPtr++;
181df25739fSMilanka Ringwald             ps16GenBufPtr++;
182df25739fSMilanka Ringwald         }
183*c1ab6cc1SMatthias Ringwald         ps16GenArrPtr = pstrCodecParams->as16Bits+(s32Ch*s32NumOfSubBands);
184df25739fSMilanka Ringwald 
185df25739fSMilanka Ringwald 
186df25739fSMilanka Ringwald         s32Sb=0;
187df25739fSMilanka Ringwald         while( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) )
188df25739fSMilanka Ringwald         {
189df25739fSMilanka Ringwald             if( *(ps16GenArrPtr) < 16)
190df25739fSMilanka Ringwald             {
191df25739fSMilanka Ringwald                 (*(ps16GenArrPtr))++;
192df25739fSMilanka Ringwald                 s32BitCount--;
193df25739fSMilanka Ringwald             }
194df25739fSMilanka Ringwald             s32Sb++;
195df25739fSMilanka Ringwald             ps16GenArrPtr++;
196df25739fSMilanka Ringwald         }
197df25739fSMilanka Ringwald     }
198df25739fSMilanka Ringwald }
199df25739fSMilanka Ringwald /*End of BitAlloc() function*/
200