xref: /btstack/3rd-party/bluedroid/decoder/srce/decoder-sbc.c (revision df25739fc3ea5a0a90f0f5925e6461d653697d2e)
1 /******************************************************************************
2  *
3  *  Copyright (C) 2014 The Android Open Source Project
4  *  Copyright 2006 Open Interface North America, Inc. All rights reserved.
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at:
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  ******************************************************************************/
19 
20 /**********************************************************************************
21   $Revision: #1 $
22  ***********************************************************************************/
23 
24 /** @file
25 @ingroup codec_internal
26 */
27 
28 /**@addtogroup codec_internal */
29 /**@{*/
30 
31 #include "oi_codec_sbc_private.h"
32 #include "oi_bitstream.h"
33 
34 #define SPECIALIZE_READ_SAMPLES_JOINT
35 
36 /**
37  * Scans through a buffer looking for a codec syncword. If the decoder has been
38  * set for enhanced operation using OI_CODEC_SBC_DecoderReset(), it will search
39  * for both a standard and an enhanced syncword.
40  */
41 PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
42                                const OI_BYTE **frameData,
43                                OI_UINT32 *frameBytes)
44 {
45 #ifdef SBC_ENHANCED
46     OI_BYTE search1 = OI_SBC_SYNCWORD;
47     OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
48 #endif // SBC_ENHANCED
49 
50     if (*frameBytes == 0) {
51         return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
52     }
53 
54 #ifdef SBC_ENHANCED
55     if (context->limitFrameFormat && context->enhancedEnabled){
56         /* If the context is restricted, only search for specified SYNCWORD */
57         search1 = search2;
58     } else if (context->enhancedEnabled == FALSE) {
59         /* If enhanced is not enabled, only search for classic SBC SYNCWORD*/
60         search2 = search1;
61     }
62     while (*frameBytes && (**frameData != search1) && (**frameData != search2)) {
63         (*frameBytes)--;
64         (*frameData)++;
65     }
66     if (*frameBytes) {
67         /* Syncword found, *frameData points to it, and *frameBytes correctly
68          * reflects the number of bytes available to read, including the
69          * syncword. */
70         context->common.frameInfo.enhanced = (**frameData == OI_SBC_ENHANCED_SYNCWORD);
71         return OI_OK;
72     } else {
73         /* No syncword was found anywhere in the provided input data.
74          * *frameData points past the end of the original input, and
75          * *frameBytes is 0. */
76         return OI_CODEC_SBC_NO_SYNCWORD;
77     }
78 #else  // SBC_ENHANCED
79     while (*frameBytes && (**frameData != OI_SBC_SYNCWORD)) {
80         (*frameBytes)--;
81         (*frameData)++;
82     }
83 
84     if (*frameBytes) {
85         /* Syncword found, *frameData points to it, and *frameBytes correctly
86          * reflects the number of bytes available to read, including the
87          * syncword. */
88         context->common.frameInfo.enhanced = FALSE;
89         return OI_OK;
90     } else {
91         /* No syncword was found anywhere in the provided input data.
92          * *frameData points past the end of the original input, and
93          * *frameBytes is 0. */
94         return OI_CODEC_SBC_NO_SYNCWORD;
95     }
96 #endif // SBC_ENHANCED
97 }
98 
99 
100 static OI_STATUS DecodeBody(OI_CODEC_SBC_DECODER_CONTEXT *context,
101                             const OI_BYTE *bodyData,
102                             OI_INT16 *pcmData,
103                             OI_UINT32 *pcmBytes,
104                             OI_BOOL allowPartial)
105 {
106     OI_BITSTREAM bs;
107     OI_UINT frameSamples = context->common.frameInfo.nrof_blocks * context->common.frameInfo.nrof_subbands;
108     OI_UINT decode_block_count;
109 
110     /*
111      * Based on the header data, make sure that there is enough room to write the output samples.
112      */
113     if (*pcmBytes < (sizeof(OI_INT16) * frameSamples * context->common.pcmStride) && !allowPartial) {
114         /* If we're not allowing partial decodes, we need room for the entire
115          * codec frame */
116         TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA"));
117         return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
118     } else if (*pcmBytes < sizeof (OI_INT16) * context->common.frameInfo.nrof_subbands * context->common.pcmStride) {
119         /* Even if we're allowing partials, we can still only decode on a frame
120          * boundary */
121         return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
122     }
123 
124     if (context->bufferedBlocks == 0) {
125         TRACE(("Reading scalefactors"));
126         OI_SBC_ReadScalefactors(&context->common, bodyData, &bs);
127 
128         TRACE(("Computing bit allocation"));
129         OI_SBC_ComputeBitAllocation(&context->common);
130 
131         TRACE(("Reading samples"));
132         if (context->common.frameInfo.mode == SBC_JOINT_STEREO) {
133             OI_SBC_ReadSamplesJoint(context, &bs);
134         } else {
135             OI_SBC_ReadSamples(context, &bs);
136         }
137 
138         context->bufferedBlocks = context->common.frameInfo.nrof_blocks;
139     }
140 
141     if (allowPartial) {
142         decode_block_count = *pcmBytes / sizeof(OI_INT16) / context->common.pcmStride / context->common.frameInfo.nrof_subbands;
143 
144         if (decode_block_count > context->bufferedBlocks) {
145             decode_block_count = context->bufferedBlocks;
146         }
147 
148     } else {
149         decode_block_count = context->common.frameInfo.nrof_blocks;
150     }
151 
152     TRACE(("Synthesizing frame"));
153     {
154         OI_UINT start_block = context->common.frameInfo.nrof_blocks - context->bufferedBlocks;
155         OI_SBC_SynthFrame(context, pcmData, start_block, decode_block_count);
156     }
157 
158     OI_ASSERT(context->bufferedBlocks >= decode_block_count);
159     context->bufferedBlocks -= decode_block_count;
160 
161     frameSamples = decode_block_count * context->common.frameInfo.nrof_subbands;
162 
163     /*
164      * When decoding mono into a stride-2 array, copy pcm data to second channel
165      */
166     if (context->common.frameInfo.nrof_channels == 1 && context->common.pcmStride == 2) {
167         OI_UINT i;
168         for (i = 0; i < frameSamples; ++i) {
169             pcmData[2*i+1] = pcmData[2*i];
170         }
171     }
172 
173     /*
174      * Return number of pcm bytes generated by the decode operation.
175      */
176     *pcmBytes = frameSamples * sizeof(OI_INT16) * context->common.pcmStride;
177 
178     if (context->bufferedBlocks > 0) {
179         return OI_CODEC_SBC_PARTIAL_DECODE;
180     } else {
181         return OI_OK;
182     }
183 }
184 
185 PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
186                                      OI_UINT8 bitpool,
187                                      const OI_BYTE **frameData,
188                                      OI_UINT32 *frameBytes,
189                                      OI_INT16 *pcmData,
190                                      OI_UINT32 *pcmBytes)
191 {
192     OI_STATUS status;
193     OI_UINT bodyLen;
194 
195     TRACE(("+OI_CODEC_SBC_DecodeRaw"));
196 
197     if (context->bufferedBlocks == 0) {
198         /*
199          * The bitallocator needs to know the bitpool value.
200          */
201         context->common.frameInfo.bitpool = bitpool;
202         /*
203          * Compute the frame length and check we have enough frame data to proceed
204          */
205         bodyLen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo) - SBC_HEADER_LEN;
206         if (*frameBytes < bodyLen) {
207             TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
208             return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
209         }
210     } else {
211         bodyLen = 0;
212     }
213     /*
214      * Decode the SBC data. Pass TRUE to DecodeBody to allow partial decoding of
215      * tones.
216      */
217     status = DecodeBody(context, *frameData, pcmData, pcmBytes, TRUE);
218     if (OI_SUCCESS(status) || status == OI_CODEC_SBC_PARTIAL_DECODE) {
219         *frameData += bodyLen;
220         *frameBytes -= bodyLen;
221     }
222     TRACE(("-OI_CODEC_SBC_DecodeRaw: %d", status));
223     return status;
224 }
225 
226 OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
227                                     OI_UINT32 *decoderData,
228                                     OI_UINT32 decoderDataBytes,
229                                     OI_UINT8 maxChannels,
230                                     OI_UINT8 pcmStride,
231                                     OI_BOOL enhanced)
232 {
233     return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride, enhanced);
234 }
235 
236 OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
237                                    const OI_BYTE **frameData,
238                                    OI_UINT32 *frameBytes,
239                                    OI_INT16 *pcmData,
240                                    OI_UINT32 *pcmBytes)
241 {
242     OI_STATUS status;
243     OI_UINT framelen;
244     OI_UINT8 crc;
245 
246     TRACE(("+OI_CODEC_SBC_DecodeFrame"));
247 
248     TRACE(("Finding syncword"));
249 
250     status = FindSyncword(context, frameData, frameBytes);
251     if (!OI_SUCCESS(status)) {
252         return status;
253     }
254     /* Make sure enough data remains to read the header. */
255     if (*frameBytes < SBC_HEADER_LEN) {
256         TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA"));
257         return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
258     }
259 
260     TRACE(("Reading Header"));
261     OI_SBC_ReadHeader(&context->common, *frameData);
262 
263     /*
264      * Some implementations load the decoder into RAM and use overlays for 4 vs 8 subbands. We need
265      * to ensure that the SBC parameters for this frame are compatible with the restrictions imposed
266      * by the loaded overlays.
267      */
268     if (context->limitFrameFormat && (context->common.frameInfo.subbands != context->restrictSubbands)) {
269         ERROR(("SBC parameters incompatible with loaded overlay"));
270         return OI_STATUS_INVALID_PARAMETERS;
271     }
272     TRACE(("Frame: "));
273 
274     if (context->common.frameInfo.nrof_channels > context->common.maxChannels) {
275         ERROR(("SBC parameters incompatible with number of channels specified during reset"));
276         return OI_STATUS_INVALID_PARAMETERS;
277     }
278 
279     if (context->common.pcmStride < 1 || context->common.pcmStride > 2) {
280         ERROR(("PCM stride not set correctly during reset"));
281         return OI_STATUS_INVALID_PARAMETERS;
282     }
283 
284     /*
285      * At this point a header has been read. However, it's possible that we found a false syncword,
286      * so the header data might be invalid. Make sure we have enough bytes to read in the
287      * CRC-protected header, but don't require we have the whole frame. That way, if it turns out
288      * that we're acting on bogus header data, we don't stall the decoding process by waiting for
289      * data that we don't actually need.
290      */
291     framelen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo);
292     if (*frameBytes < framelen) {
293         TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
294         return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
295     }
296     TRACE(("frame len %d\n", framelen));
297 
298     TRACE(("Calculating checksum"));
299 
300     crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
301     if (crc != context->common.frameInfo.crc) {
302         TRACE(("CRC Mismatch:  calc=%02x read=%02x\n", crc, context->common.frameInfo.crc));
303         TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_CHECKSUM_MISMATCH"));
304         return OI_CODEC_SBC_CHECKSUM_MISMATCH;
305     }
306 
307 #ifdef OI_DEBUG
308     /*
309      * Make sure the bitpool values are sane.
310      */
311     if ((context->common.frameInfo.bitpool < SBC_MIN_BITPOOL) && !context->common.frameInfo.enhanced) {
312         ERROR(("Bitpool too small: %d (must be >= 2)", context->common.frameInfo.bitpool));
313         return OI_STATUS_INVALID_PARAMETERS;
314     }
315     if (context->common.frameInfo.bitpool > OI_SBC_MaxBitpool(&context->common.frameInfo)) {
316         ERROR(("Bitpool too large: %d (must be <= %ld)", context->common.frameInfo.bitpool, OI_SBC_MaxBitpool(&context->common.frameInfo)));
317         return OI_STATUS_INVALID_PARAMETERS;
318     }
319 #endif
320 
321     /*
322      * Now decode the SBC data. Partial decode is not yet implemented for an SBC
323      * stream, so pass FALSE to decode body to have it enforce the old rule that
324      * you have to decode a whole packet at a time.
325      */
326     status = DecodeBody(context, *frameData + SBC_HEADER_LEN, pcmData, pcmBytes, FALSE);
327     if (OI_SUCCESS(status)) {
328         *frameData += framelen;
329         *frameBytes -= framelen;
330     }
331     TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
332 
333     return status;
334 }
335 
336 OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
337                                  const OI_BYTE **frameData,
338                                  OI_UINT32 *frameBytes)
339 {
340     OI_STATUS status;
341     OI_UINT framelen;
342     OI_UINT headerlen;
343     OI_UINT8 crc;
344 
345     status = FindSyncword(context, frameData, frameBytes);
346     if (!OI_SUCCESS(status)) {
347         return status;
348     }
349     if (*frameBytes < SBC_HEADER_LEN) {
350         return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
351     }
352     OI_SBC_ReadHeader(&context->common, *frameData);
353     framelen = OI_SBC_CalculateFrameAndHeaderlen(&context->common.frameInfo, &headerlen);
354     if (*frameBytes < headerlen) {
355         return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
356     }
357     crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
358     if (crc != context->common.frameInfo.crc) {
359         return OI_CODEC_SBC_CHECKSUM_MISMATCH;
360     }
361     if (*frameBytes < framelen) {
362         return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
363     }
364     context->bufferedBlocks = 0;
365     *frameData += framelen;
366     *frameBytes -= framelen;
367     return OI_OK;
368 }
369 
370 OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE  *frameData,
371                                  OI_UINT32 frameBytes)
372 {
373     OI_UINT8 mode;
374     OI_UINT8 blocks;
375     OI_UINT8 subbands;
376     OI_UINT8 frameCount = 0;
377     OI_UINT  frameLen;
378 
379     while (frameBytes){
380         while (frameBytes && ((frameData[0] & 0xFE) != 0x9C)){
381             frameData++;
382             frameBytes--;
383         }
384 
385         if (frameBytes < SBC_HEADER_LEN) {
386             return frameCount;
387         }
388 
389         /* Extract and translate required fields from Header */
390         subbands = mode = blocks = frameData[1];;
391         mode = (mode & (BIT3 | BIT2)) >> 2;
392         blocks = block_values[(blocks & (BIT5 | BIT4)) >> 4];
393         subbands = band_values[(subbands & BIT0)];
394 
395         /* Inline logic to avoid corrupting context */
396         frameLen = blocks * frameData[2];
397         switch (mode){
398             case SBC_JOINT_STEREO:
399                 frameLen += subbands + (8 * subbands);
400                 break;
401 
402             case SBC_DUAL_CHANNEL:
403                 frameLen *= 2;
404                 /* fall through */
405 
406             default:
407                 if (mode == SBC_MONO){
408                     frameLen += 4*subbands;
409                 } else {
410                     frameLen += 8*subbands;
411                 }
412         }
413 
414         frameCount++;
415         frameLen = SBC_HEADER_LEN + (frameLen + 7) / 8;
416         if (frameBytes > frameLen){
417             frameBytes -= frameLen;
418             frameData += frameLen;
419         } else {
420             frameBytes = 0;
421         }
422     }
423     return frameCount;
424 }
425 
426 /** Read quantized subband samples from the input bitstream and expand them. */
427 
428 #ifdef SPECIALIZE_READ_SAMPLES_JOINT
429 
430 PRIVATE void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
431 {
432 #define NROF_SUBBANDS 4
433 #include "readsamplesjoint.inc"
434 #undef NROF_SUBBANDS
435 }
436 
437 PRIVATE void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
438 {
439 #define NROF_SUBBANDS 8
440 #include "readsamplesjoint.inc"
441 #undef NROF_SUBBANDS
442 }
443 
444 typedef void (*READ_SAMPLES)(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs);
445 
446 static const READ_SAMPLES SpecializedReadSamples[] = {
447     OI_SBC_ReadSamplesJoint4,
448     OI_SBC_ReadSamplesJoint8
449 };
450 
451 #endif /* SPECIALIZE_READ_SAMPLES_JOINT */
452 
453 
454 PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
455 {
456     OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
457     OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
458 #ifdef SPECIALIZE_READ_SAMPLES_JOINT
459     OI_ASSERT((nrof_subbands >> 3u) <= 1u);
460     SpecializedReadSamples[nrof_subbands >> 3](context, global_bs);
461 #else
462 
463 #define NROF_SUBBANDS nrof_subbands
464 #include "readsamplesjoint.inc"
465 #undef NROF_SUBBANDS
466 #endif /* SPECIALIZE_READ_SAMPLES_JOINT */
467 }
468 
469 /**@}*/
470 
471