• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2014 The Android Open Source Project
4  *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights
5  *                        reserved.
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at:
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS,
15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  *
19  ******************************************************************************/
20 
21 /*******************************************************************************
22   $Revision: #1 $
23  ******************************************************************************/
24 
25 /**
26 @file
27 
28 The functions in this file relate to the allocation of available bits to
29 subbands within the SBC/eSBC frame, along with support functions for computing
30 frame length and bitrate.
31 
32 @ingroup codec_internal
33 */
34 
35 /**
36 @addtogroup codec_internal
37 @{
38 */
39 
40 #include <oi_codec_sbc_private.h>
41 #include "oi_utils.h"
42 
OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO * frame)43 uint32_t OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO* frame) {
44   switch (frame->mode) {
45     case SBC_MONO:
46     case SBC_DUAL_CHANNEL:
47       return 16 * frame->nrof_subbands;
48     case SBC_STEREO:
49     case SBC_JOINT_STEREO:
50       return 32 * frame->nrof_subbands;
51   }
52 
53   ERROR(("Invalid frame mode %d", frame->mode));
54   OI_ASSERT(false);
55   return 0; /* Should never be reached */
56 }
57 
internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO * frame)58 PRIVATE uint16_t internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO* frame) {
59   uint16_t nbits = frame->nrof_blocks * frame->bitpool;
60   uint16_t nrof_subbands = frame->nrof_subbands;
61   uint16_t result = nbits;
62 
63   if (frame->mode == SBC_JOINT_STEREO) {
64     result += nrof_subbands + (8 * nrof_subbands);
65   } else {
66     if (frame->mode == SBC_DUAL_CHANNEL) {
67       result += nbits;
68     }
69     if (frame->mode == SBC_MONO) {
70       result += 4 * nrof_subbands;
71     } else {
72       result += 8 * nrof_subbands;
73     }
74   }
75   return SBC_HEADER_LEN + (result + 7) / 8;
76 }
77 
internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO * frame)78 PRIVATE uint32_t internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO* frame) {
79   OI_UINT blocksbands;
80   blocksbands = frame->nrof_subbands * frame->nrof_blocks;
81 
82   return DIVIDE(8 * internal_CalculateFramelen(frame) * frame->frequency,
83                 blocksbands);
84 }
85 
OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO * frame,OI_UINT * headerLen_)86 INLINE uint16_t OI_SBC_CalculateFrameAndHeaderlen(
87     OI_CODEC_SBC_FRAME_INFO* frame, OI_UINT* headerLen_) {
88   OI_UINT headerLen =
89       SBC_HEADER_LEN + frame->nrof_subbands * frame->nrof_channels / 2;
90 
91   if (frame->mode == SBC_JOINT_STEREO) {
92     headerLen++;
93   }
94 
95   *headerLen_ = headerLen;
96   return internal_CalculateFramelen(frame);
97 }
98 
99 #define MIN(x, y) ((x) < (y) ? (x) : (y))
100 
101 /*
102  * Computes the bit need for each sample and as also returns a counts of bit
103  * needs that are greater than one. This count is used in the first phase of bit
104  * allocation.
105  *
106  * We also compute a preferred bitpool value that this is the minimum bitpool
107  * needed to guarantee lossless representation of the audio data. The preferred
108  * bitpool may be larger than the bits actually required but the only input we
109  * have are the scale factors. For example, it takes 2 bits to represent values
110  * in the range -1 .. +1 but the scale factor is 0. To guarantee lossless
111  * representation we add 2 to each scale factor and sum them to come up with the
112  * preferred bitpool. This is not ideal because 0 requires 0 bits but we
113  * currently have no way of knowing this.
114  *
115  * @param bitneed       Array to return bitneeds for each subband
116  *
117  * @param ch            Channel 0 or 1
118  *
119  * @param preferredBitpool  Returns the number of reserved bits
120  *
121  * @return              The SBC bit need
122  *
123  */
computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT * common,uint8_t * bitneeds,OI_UINT ch,OI_UINT * preferredBitpool)124 OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT* common, uint8_t* bitneeds,
125                        OI_UINT ch, OI_UINT* preferredBitpool) {
126   static const int8_t offset4[4][4] = {
127       {-1, 0, 0, 0}, {-2, 0, 0, 1}, {-2, 0, 0, 1}, {-2, 0, 0, 1}};
128 
129   static const int8_t offset8[4][8] = {{-2, 0, 0, 0, 0, 0, 0, 1},
130                                        {-3, 0, 0, 0, 0, 0, 1, 2},
131                                        {-4, 0, 0, 0, 0, 0, 1, 2},
132                                        {-4, 0, 0, 0, 0, 0, 1, 2}};
133 
134   const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
135   OI_UINT sb;
136   int8_t* scale_factor = &common->scale_factor[ch ? nrof_subbands : 0];
137   OI_UINT bitcount = 0;
138   uint8_t maxBits = 0;
139   uint8_t prefBits = 0;
140 
141   if (common->frameInfo.alloc == SBC_SNR) {
142     for (sb = 0; sb < nrof_subbands; sb++) {
143       OI_INT bits = scale_factor[sb];
144       if (bits > maxBits) {
145         maxBits = bits;
146       }
147       bitneeds[sb] = bits;
148       if (bitneeds[sb] > 1) {
149         bitcount += bits;
150       }
151       prefBits += 2 + bits;
152     }
153   } else {
154     const int8_t* offset;
155     if (nrof_subbands == 4) {
156       offset = offset4[common->frameInfo.freqIndex];
157     } else {
158       offset = offset8[common->frameInfo.freqIndex];
159     }
160     for (sb = 0; sb < nrof_subbands; sb++) {
161       OI_INT bits = scale_factor[sb];
162       if (bits > maxBits) {
163         maxBits = bits;
164       }
165       prefBits += 2 + bits;
166       if (bits) {
167         bits -= offset[sb];
168         if (bits > 0) {
169           bits /= 2;
170         }
171         bits += 5;
172       }
173       bitneeds[sb] = bits;
174       if (bitneeds[sb] > 1) {
175         bitcount += bits;
176       }
177     }
178   }
179   common->maxBitneed = OI_MAX(maxBits, common->maxBitneed);
180   *preferredBitpool += prefBits;
181   return bitcount;
182 }
183 
184 /*
185  * Explanation of the adjustToFitBitpool inner loop.
186  *
187  * The inner loop computes the effect of adjusting the bit allocation up or
188  * down. Allocations must be 0 or in the range 2..16. This is accomplished by
189  * the following code:
190  *
191  *           for (s = bands - 1; s >= 0; --s) {
192  *              OI_INT bits = bitadjust + bitneeds[s];
193  *              bits = bits < 2 ? 0 : bits;
194  *              bits = bits > 16 ? 16 : bits;
195  *              count += bits;
196  *          }
197  *
198  * This loop can be optimized to perform 4 operations at a time as follows:
199  *
200  * Adjustment is computed as a 7 bit signed value and added to the bitneed.
201  *
202  * Negative allocations are zeroed by masking. (n & 0x40) >> 6 puts the
203  * sign bit into bit 0, adding this to 0x7F give us a mask of 0x80
204  * for -ve values and 0x7F for +ve values.
205  *
206  * n &= 0x7F + (n & 0x40) >> 6)
207  *
208  * Allocations greater than 16 are truncated to 16. Adjusted allocations are in
209  * the range 0..31 so we know that bit 4 indicates values >= 16. We use this bit
210  * to create a mask that zeroes bits 0 .. 3 if bit 4 is set.
211  *
212  * n &= (15 + (n >> 4))
213  *
214  * Allocations of 1 are disallowed. Add and shift creates a mask that
215  * eliminates the illegal value
216  *
217  * n &= ((n + 14) >> 4) | 0x1E
218  *
219  * These operations can be performed in 8 bits without overflowing so we can
220  * operate on 4 values at once.
221  */
222 
223 /*
224  * Encoder/Decoder
225  *
226  * Computes adjustment +/- of bitneeds to fill bitpool and returns overall
227  * adjustment and excess bits.
228  *
229  * @param bitpool   The bitpool we have to work within
230  *
231  * @param bitneeds  An array of bit needs (more acturately allocation
232  *                  prioritities) for each subband across all blocks in the SBC
233  *                  frame
234  *
235  * @param subbands  The number of subbands over which the adkustment is
236  *                  calculated. For mono and dual mode this is 4 or 8, for
237  *                  stereo or joint stereo this is 8 or 16.
238  *
239  * @param bitcount  A starting point for the adjustment
240  *
241  * @param excess    Returns the excess bits after the adjustment
242  *
243  * @return   The adjustment.
244  */
adjustToFitBitpool(const OI_UINT bitpool,uint32_t * bitneeds,const OI_UINT subbands,OI_UINT bitcount,OI_UINT * excess)245 OI_INT adjustToFitBitpool(const OI_UINT bitpool, uint32_t* bitneeds,
246                           const OI_UINT subbands, OI_UINT bitcount,
247                           OI_UINT* excess) {
248   OI_INT maxBitadjust = 0;
249   OI_INT bitadjust = (bitcount > bitpool) ? -8 : 8;
250   OI_INT chop = 8;
251 
252   /*
253    * This is essentially a binary search for the optimal adjustment value.
254    */
255   while ((bitcount != bitpool) && chop) {
256     uint32_t total = 0;
257     OI_UINT count;
258     uint32_t adjust4;
259     OI_INT i;
260 
261     adjust4 = bitadjust & 0x7F;
262     adjust4 |= (adjust4 << 8);
263     adjust4 |= (adjust4 << 16);
264 
265     for (i = (subbands / 4 - 1); i >= 0; --i) {
266       uint32_t mask;
267       uint32_t n = bitneeds[i] + adjust4;
268       mask = 0x7F7F7F7F + ((n & 0x40404040) >> 6);
269       n &= mask;
270       mask = 0x0F0F0F0F + ((n & 0x10101010) >> 4);
271       n &= mask;
272       mask = (((n + 0x0E0E0E0E) >> 4) | 0x1E1E1E1E);
273       n &= mask;
274       total += n;
275     }
276 
277     count = (total & 0xFFFF) + (total >> 16);
278     count = (count & 0xFF) + (count >> 8);
279 
280     chop >>= 1;
281     if (count > bitpool) {
282       bitadjust -= chop;
283     } else {
284       maxBitadjust = bitadjust;
285       bitcount = count;
286       bitadjust += chop;
287     }
288   }
289 
290   *excess = bitpool - bitcount;
291 
292   return maxBitadjust;
293 }
294 
295 /*
296  * The bit allocator trys to avoid single bit allocations except as a last
297  * resort. So in the case where a bitneed of 1 was passed over during the
298  * adsjustment phase 2 bits are now allocated.
299  */
allocAdjustedBits(uint8_t * dest,OI_INT bits,OI_INT excess)300 INLINE OI_INT allocAdjustedBits(uint8_t* dest, OI_INT bits, OI_INT excess) {
301   if (bits < 16) {
302     if (bits > 1) {
303       if (excess) {
304         ++bits;
305         --excess;
306       }
307     } else if ((bits == 1) && (excess > 1)) {
308       bits = 2;
309       excess -= 2;
310     } else {
311       bits = 0;
312     }
313   } else {
314     bits = 16;
315   }
316   *dest = (uint8_t)bits;
317   return excess;
318 }
319 
320 /*
321  * Excess bits not allocated by allocaAdjustedBits are allocated round-robin.
322  */
allocExcessBits(uint8_t * dest,OI_INT excess)323 INLINE OI_INT allocExcessBits(uint8_t* dest, OI_INT excess) {
324   if (*dest < 16) {
325     *dest += 1;
326     return excess - 1;
327   } else {
328     return excess;
329   }
330 }
331 
oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT * common,BITNEED_UNION1 * bitneeds,OI_UINT ch,OI_UINT bitcount)332 void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common,
333                              BITNEED_UNION1* bitneeds, OI_UINT ch,
334                              OI_UINT bitcount) {
335   const uint8_t nrof_subbands = common->frameInfo.nrof_subbands;
336   OI_UINT excess;
337   OI_UINT sb;
338   OI_INT bitadjust;
339   uint8_t RESTRICT* allocBits;
340 
341   {
342     OI_UINT ex;
343     bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds->uint32,
344                                    nrof_subbands, bitcount, &ex);
345     /* We want the compiler to put excess into a register */
346     excess = ex;
347   }
348 
349   /*
350    * Allocate adjusted bits
351    */
352   allocBits = &common->bits.uint8[ch ? nrof_subbands : 0];
353 
354   sb = 0;
355   while (sb < nrof_subbands) {
356     excess = allocAdjustedBits(&allocBits[sb], bitneeds->uint8[sb] + bitadjust,
357                                excess);
358     ++sb;
359   }
360   sb = 0;
361   while (excess) {
362     excess = allocExcessBits(&allocBits[sb], excess);
363     ++sb;
364   }
365 }
366 
monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT * common)367 void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) {
368   BITNEED_UNION1 bitneeds;
369   OI_UINT bitcount;
370   OI_UINT bitpoolPreference = 0;
371 
372   bitcount = computeBitneed(common, bitneeds.uint8, 0, &bitpoolPreference);
373 
374   oneChannelBitAllocation(common, &bitneeds, 0, bitcount);
375 }
376 
377 /**
378 @}
379 */
380