xref: /btstack/src/classic/btstack_sbc_bluedroid.c (revision 09ac68ff64e4c11166ac4aaa00e7a5d75d953957)
1113ff2bcSMatthias Ringwald /*
2113ff2bcSMatthias Ringwald  * Copyright (C) 2023 BlueKitchen GmbH
3113ff2bcSMatthias Ringwald  *
4113ff2bcSMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5113ff2bcSMatthias Ringwald  * modification, are permitted provided that the following conditions
6113ff2bcSMatthias Ringwald  * are met:
7113ff2bcSMatthias Ringwald  *
8113ff2bcSMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9113ff2bcSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10113ff2bcSMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11113ff2bcSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12113ff2bcSMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13113ff2bcSMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14113ff2bcSMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15113ff2bcSMatthias Ringwald  *    from this software without specific prior written permission.
16113ff2bcSMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17113ff2bcSMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18113ff2bcSMatthias Ringwald  *    monetary gain.
19113ff2bcSMatthias Ringwald  *
20113ff2bcSMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21113ff2bcSMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22113ff2bcSMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23113ff2bcSMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24113ff2bcSMatthias Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25113ff2bcSMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26113ff2bcSMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27113ff2bcSMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28113ff2bcSMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29113ff2bcSMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30113ff2bcSMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31113ff2bcSMatthias Ringwald  * SUCH DAMAGE.
32113ff2bcSMatthias Ringwald  *
33113ff2bcSMatthias Ringwald  * Please inquire about commercial licensing options at
34113ff2bcSMatthias Ringwald  * [email protected]
35113ff2bcSMatthias Ringwald  *
36113ff2bcSMatthias Ringwald  */
37113ff2bcSMatthias Ringwald 
38113ff2bcSMatthias Ringwald #define BTSTACK_FILE__ "btstack_sbc_bluedroid.c"
39113ff2bcSMatthias Ringwald 
40113ff2bcSMatthias Ringwald #include "btstack_sbc_bluedroid.h"
41113ff2bcSMatthias Ringwald 
42113ff2bcSMatthias Ringwald #include "btstack_bool.h"
43113ff2bcSMatthias Ringwald #include "btstack_config.h"
44113ff2bcSMatthias Ringwald #include "btstack_debug.h"
45*09ac68ffSMatthias Ringwald #include "btstack_util.h"
46113ff2bcSMatthias Ringwald 
47113ff2bcSMatthias Ringwald #include <stdint.h>
48*09ac68ffSMatthias Ringwald #include <string.h>
49113ff2bcSMatthias Ringwald #include "bluetooth.h"
50113ff2bcSMatthias Ringwald 
51*09ac68ffSMatthias Ringwald // ENCODER
52*09ac68ffSMatthias Ringwald 
btstack_sbc_encoder_bluedroid_configure(void * context,btstack_sbc_mode_t mode,uint8_t blocks,uint8_t subbands,btstack_sbc_allocation_method_t allocation_method,uint16_t sample_rate,uint8_t bitpool,btstack_sbc_channel_mode_t channel_mode)53113ff2bcSMatthias Ringwald static uint8_t btstack_sbc_encoder_bluedroid_configure(void * context, btstack_sbc_mode_t mode,
54113ff2bcSMatthias Ringwald                      uint8_t blocks, uint8_t subbands, btstack_sbc_allocation_method_t allocation_method,
55113ff2bcSMatthias Ringwald                      uint16_t sample_rate, uint8_t bitpool, btstack_sbc_channel_mode_t channel_mode){
56113ff2bcSMatthias Ringwald 
57113ff2bcSMatthias Ringwald     btstack_sbc_encoder_bluedroid_t * instance = (btstack_sbc_encoder_bluedroid_t *) context;
58113ff2bcSMatthias Ringwald 
59113ff2bcSMatthias Ringwald     instance->mode = mode;
60113ff2bcSMatthias Ringwald 
61113ff2bcSMatthias Ringwald     switch (instance->mode){
62113ff2bcSMatthias Ringwald         case SBC_MODE_STANDARD:
63113ff2bcSMatthias Ringwald             instance->params.s16NumOfBlocks = blocks;
64113ff2bcSMatthias Ringwald             instance->params.s16NumOfSubBands = subbands;
65113ff2bcSMatthias Ringwald             instance->params.s16AllocationMethod = (uint8_t)allocation_method;
66113ff2bcSMatthias Ringwald             instance->params.s16BitPool = bitpool;
67113ff2bcSMatthias Ringwald             instance->params.mSBCEnabled = 0;
68113ff2bcSMatthias Ringwald             instance->params.s16ChannelMode = (uint8_t)channel_mode;
69113ff2bcSMatthias Ringwald             instance->params.s16NumOfChannels = 2;
70113ff2bcSMatthias Ringwald             if (instance->params.s16ChannelMode == SBC_MONO){
71113ff2bcSMatthias Ringwald                 instance->params.s16NumOfChannels = 1;
72113ff2bcSMatthias Ringwald             }
73113ff2bcSMatthias Ringwald             switch(sample_rate){
74113ff2bcSMatthias Ringwald                 case 16000: instance->params.s16SamplingFreq = SBC_sf16000; break;
75113ff2bcSMatthias Ringwald                 case 32000: instance->params.s16SamplingFreq = SBC_sf32000; break;
76113ff2bcSMatthias Ringwald                 case 44100: instance->params.s16SamplingFreq = SBC_sf44100; break;
77113ff2bcSMatthias Ringwald                 case 48000: instance->params.s16SamplingFreq = SBC_sf48000; break;
78113ff2bcSMatthias Ringwald                 default: instance->params.s16SamplingFreq = 0; break;
79113ff2bcSMatthias Ringwald             }
80113ff2bcSMatthias Ringwald             break;
81113ff2bcSMatthias Ringwald         case SBC_MODE_mSBC:
82113ff2bcSMatthias Ringwald             instance->params.s16NumOfBlocks    = 15;
83113ff2bcSMatthias Ringwald             instance->params.s16NumOfSubBands  = 8;
84113ff2bcSMatthias Ringwald             instance->params.s16AllocationMethod = SBC_LOUDNESS;
85113ff2bcSMatthias Ringwald             instance->params.s16BitPool   = 26;
86113ff2bcSMatthias Ringwald             instance->params.s16ChannelMode = SBC_MONO;
87113ff2bcSMatthias Ringwald             instance->params.s16NumOfChannels = 1;
88113ff2bcSMatthias Ringwald             instance->params.mSBCEnabled = 1;
89113ff2bcSMatthias Ringwald             instance->params.s16SamplingFreq = SBC_sf16000;
90113ff2bcSMatthias Ringwald             break;
91113ff2bcSMatthias Ringwald         default:
92113ff2bcSMatthias Ringwald             return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
93113ff2bcSMatthias Ringwald     }
94113ff2bcSMatthias Ringwald 
95113ff2bcSMatthias Ringwald     SBC_Encoder_Init(&instance->params);
96113ff2bcSMatthias Ringwald 
97113ff2bcSMatthias Ringwald     return ERROR_CODE_SUCCESS;
98113ff2bcSMatthias Ringwald }
99113ff2bcSMatthias Ringwald 
100113ff2bcSMatthias Ringwald /**
101113ff2bcSMatthias Ringwald  * @brief Return number of audio frames required for one SBC packet
102113ff2bcSMatthias Ringwald  * @param context
103113ff2bcSMatthias Ringwald  * @note  each audio frame contains 2 sample values in stereo modes
104113ff2bcSMatthias Ringwald  */
btstack_sbc_encoder_bluedroid_num_audio_frames(void * context)105113ff2bcSMatthias Ringwald static uint16_t btstack_sbc_encoder_bluedroid_num_audio_frames(void * context){
106113ff2bcSMatthias Ringwald     btstack_sbc_encoder_bluedroid_t * instance = (btstack_sbc_encoder_bluedroid_t *) context;
107113ff2bcSMatthias Ringwald     return instance->params.s16NumOfSubBands * instance->params.s16NumOfBlocks;
108113ff2bcSMatthias Ringwald }
109113ff2bcSMatthias Ringwald 
btstack_sbc_encoder_bluedroid_sbc_buffer_length(void * context)110113ff2bcSMatthias Ringwald static uint16_t btstack_sbc_encoder_bluedroid_sbc_buffer_length(void * context){
111113ff2bcSMatthias Ringwald     btstack_sbc_encoder_bluedroid_t * instance = (btstack_sbc_encoder_bluedroid_t *) context;
112113ff2bcSMatthias Ringwald     return instance->params.u16PacketLength;
113113ff2bcSMatthias Ringwald }
114113ff2bcSMatthias Ringwald 
115113ff2bcSMatthias Ringwald /**
116113ff2bcSMatthias Ringwald  * @brief Encode PCM data
117113ff2bcSMatthias Ringwald  * @param context
118113ff2bcSMatthias Ringwald  * @param pcm_in with samples in host endianess
119113ff2bcSMatthias Ringwald  * @param sbc_out
120113ff2bcSMatthias Ringwald  * @return status
121113ff2bcSMatthias Ringwald  */
btstack_sbc_encoder_bluedroid_encode_signed_16(void * context,const int16_t * pcm_in,uint8_t * sbc_out)122113ff2bcSMatthias Ringwald static uint8_t btstack_sbc_encoder_bluedroid_encode_signed_16(void * context, const int16_t* pcm_in, uint8_t * sbc_out){
123113ff2bcSMatthias Ringwald     btstack_sbc_encoder_bluedroid_t * instance = (btstack_sbc_encoder_bluedroid_t *) context;
124113ff2bcSMatthias Ringwald 
125113ff2bcSMatthias Ringwald     instance->params.ps16PcmBuffer = (int16_t *) pcm_in;
126113ff2bcSMatthias Ringwald     instance->params.pu8Packet =  sbc_out;
127113ff2bcSMatthias Ringwald     if (instance->params.mSBCEnabled){
128113ff2bcSMatthias Ringwald         instance->params.pu8Packet[0] = 0xad;
129113ff2bcSMatthias Ringwald     }
130113ff2bcSMatthias Ringwald     SBC_Encoder(&instance->params);
131113ff2bcSMatthias Ringwald     return ERROR_CODE_SUCCESS;
132113ff2bcSMatthias Ringwald }
133113ff2bcSMatthias Ringwald 
134113ff2bcSMatthias Ringwald static const btstack_sbc_encoder_t btstack_sbc_encoder_bluedroid = {
135113ff2bcSMatthias Ringwald     .configure         = btstack_sbc_encoder_bluedroid_configure,
136113ff2bcSMatthias Ringwald     .sbc_buffer_length = btstack_sbc_encoder_bluedroid_sbc_buffer_length,
137113ff2bcSMatthias Ringwald     .num_audio_frames  = btstack_sbc_encoder_bluedroid_num_audio_frames,
138113ff2bcSMatthias Ringwald     .encode_signed_16  = btstack_sbc_encoder_bluedroid_encode_signed_16
139113ff2bcSMatthias Ringwald };
140113ff2bcSMatthias Ringwald 
btstack_sbc_encoder_bluedroid_init_instance(btstack_sbc_encoder_bluedroid_t * context)141113ff2bcSMatthias Ringwald const btstack_sbc_encoder_t * btstack_sbc_encoder_bluedroid_init_instance(btstack_sbc_encoder_bluedroid_t * context){
142*09ac68ffSMatthias Ringwald     memset(context, 0, sizeof(btstack_sbc_encoder_bluedroid_t));
143113ff2bcSMatthias Ringwald     return &btstack_sbc_encoder_bluedroid;
144113ff2bcSMatthias Ringwald }
145*09ac68ffSMatthias Ringwald 
146*09ac68ffSMatthias Ringwald // DECODER
147*09ac68ffSMatthias Ringwald 
148*09ac68ffSMatthias Ringwald #include "btstack_config.h"
149*09ac68ffSMatthias Ringwald 
150*09ac68ffSMatthias Ringwald #include <stdint.h>
151*09ac68ffSMatthias Ringwald 
152*09ac68ffSMatthias Ringwald #include <stdlib.h>
153*09ac68ffSMatthias Ringwald #include <string.h>
154*09ac68ffSMatthias Ringwald #include "btstack_sbc_plc.h"
155*09ac68ffSMatthias Ringwald 
156*09ac68ffSMatthias Ringwald #include "oi_codec_sbc.h"
157*09ac68ffSMatthias Ringwald #include "oi_assert.h"
158*09ac68ffSMatthias Ringwald 
159*09ac68ffSMatthias Ringwald #ifdef LOG_FRAME_STATUS
160*09ac68ffSMatthias Ringwald #include <stdio.h>
161*09ac68ffSMatthias Ringwald #endif
162*09ac68ffSMatthias Ringwald 
163*09ac68ffSMatthias Ringwald #define mSBC_SYNCWORD 0xad
164*09ac68ffSMatthias Ringwald #define SBC_SYNCWORD 0x9c
165*09ac68ffSMatthias Ringwald #define SBC_MAX_CHANNELS 2
166*09ac68ffSMatthias Ringwald // #define LOG_FRAME_STATUS
167*09ac68ffSMatthias Ringwald 
168*09ac68ffSMatthias Ringwald // Testing only - START
169*09ac68ffSMatthias Ringwald static int plc_enabled = 1;
170*09ac68ffSMatthias Ringwald static int corrupt_frame_period = -1;
171*09ac68ffSMatthias Ringwald // Testing - STOP
172*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_bluedroid_test_set_plc_enabled(int enabled)173*09ac68ffSMatthias Ringwald void btstack_sbc_decoder_bluedroid_test_set_plc_enabled(int enabled){
174*09ac68ffSMatthias Ringwald     plc_enabled = enabled;
175*09ac68ffSMatthias Ringwald }
176*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_bluedroid_test_simulate_corrupt_frames(int period)177*09ac68ffSMatthias Ringwald void btstack_sbc_decoder_bluedroid_test_simulate_corrupt_frames(int period){
178*09ac68ffSMatthias Ringwald     corrupt_frame_period = period;
179*09ac68ffSMatthias Ringwald }
180*09ac68ffSMatthias Ringwald 
find_sequence_of_zeros(const OI_BYTE * frame_data,OI_UINT32 frame_bytes,int seq_length)181*09ac68ffSMatthias Ringwald static int find_sequence_of_zeros(const OI_BYTE *frame_data, OI_UINT32 frame_bytes, int seq_length){
182*09ac68ffSMatthias Ringwald     int zero_seq_count = 0;
183*09ac68ffSMatthias Ringwald     unsigned int i;
184*09ac68ffSMatthias Ringwald     for (i=0; i<frame_bytes; i++){
185*09ac68ffSMatthias Ringwald         if (frame_data[i] == 0) {
186*09ac68ffSMatthias Ringwald             zero_seq_count++;
187*09ac68ffSMatthias Ringwald             if (zero_seq_count >= seq_length) return zero_seq_count;
188*09ac68ffSMatthias Ringwald         } else {
189*09ac68ffSMatthias Ringwald             zero_seq_count = 0;
190*09ac68ffSMatthias Ringwald         }
191*09ac68ffSMatthias Ringwald     }
192*09ac68ffSMatthias Ringwald     return 0;
193*09ac68ffSMatthias Ringwald }
194*09ac68ffSMatthias Ringwald 
195*09ac68ffSMatthias Ringwald // returns position of mSBC sync word
find_h2_sync(const OI_BYTE * frame_data,OI_UINT32 frame_bytes,int * sync_word_nr)196*09ac68ffSMatthias Ringwald static int find_h2_sync(const OI_BYTE *frame_data, OI_UINT32 frame_bytes, int * sync_word_nr){
197*09ac68ffSMatthias Ringwald     int syncword = mSBC_SYNCWORD;
198*09ac68ffSMatthias Ringwald     uint8_t h2_first_byte = 0;
199*09ac68ffSMatthias Ringwald     uint8_t h2_second_byte = 0;
200*09ac68ffSMatthias Ringwald 
201*09ac68ffSMatthias Ringwald     unsigned int i;
202*09ac68ffSMatthias Ringwald     for (i=0; i<frame_bytes; i++){
203*09ac68ffSMatthias Ringwald         if (frame_data[i] == syncword) {
204*09ac68ffSMatthias Ringwald             // check: first byte == 1
205*09ac68ffSMatthias Ringwald             if (h2_first_byte == 1) {
206*09ac68ffSMatthias Ringwald                 // check lower nibble of second byte == 0x08
207*09ac68ffSMatthias Ringwald                 uint8_t ln = h2_second_byte & 0x0F;
208*09ac68ffSMatthias Ringwald                 if (ln == 8) {
209*09ac68ffSMatthias Ringwald                     // check if bits 0+2 == bits 1+3
210*09ac68ffSMatthias Ringwald                     uint8_t hn = h2_second_byte >> 4;
211*09ac68ffSMatthias Ringwald                     if  ( ((hn>>1) & 0x05) == (hn & 0x05) ) {
212*09ac68ffSMatthias Ringwald                         *sync_word_nr = ((hn & 0x04) >> 1) | (hn & 0x01);
213*09ac68ffSMatthias Ringwald                         return i;
214*09ac68ffSMatthias Ringwald                     }
215*09ac68ffSMatthias Ringwald                 }
216*09ac68ffSMatthias Ringwald             }
217*09ac68ffSMatthias Ringwald         }
218*09ac68ffSMatthias Ringwald         h2_first_byte = h2_second_byte;
219*09ac68ffSMatthias Ringwald         h2_second_byte = frame_data[i];
220*09ac68ffSMatthias Ringwald     }
221*09ac68ffSMatthias Ringwald     return -1;
222*09ac68ffSMatthias Ringwald }
223*09ac68ffSMatthias Ringwald 
224*09ac68ffSMatthias Ringwald #ifdef OI_DEBUG
OI_AssertFail(const char * file,int line,const char * reason)225*09ac68ffSMatthias Ringwald void OI_AssertFail(const char* file, int line, const char* reason){
226*09ac68ffSMatthias Ringwald     log_error("AssertFail file %s, line %d, reason %s", file, line, reason);
227*09ac68ffSMatthias Ringwald }
228*09ac68ffSMatthias Ringwald #endif
229*09ac68ffSMatthias Ringwald 
append_received_sbc_data(btstack_sbc_decoder_bluedroid_t * state,const uint8_t * buffer,int size)230*09ac68ffSMatthias Ringwald static void append_received_sbc_data(btstack_sbc_decoder_bluedroid_t * state, const uint8_t * buffer, int size){
231*09ac68ffSMatthias Ringwald     int numFreeBytes = sizeof(state->frame_buffer) - state->bytes_in_frame_buffer;
232*09ac68ffSMatthias Ringwald 
233*09ac68ffSMatthias Ringwald     if (size > numFreeBytes){
234*09ac68ffSMatthias Ringwald         log_error("SBC data: more bytes read %u than free bytes in buffer %u", size, numFreeBytes);
235*09ac68ffSMatthias Ringwald     }
236*09ac68ffSMatthias Ringwald 
237*09ac68ffSMatthias Ringwald     (void)memcpy(state->frame_buffer + state->bytes_in_frame_buffer, buffer,
238*09ac68ffSMatthias Ringwald                  size);
239*09ac68ffSMatthias Ringwald     state->bytes_in_frame_buffer += size;
240*09ac68ffSMatthias Ringwald }
241*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_bluedroid_simulate_error(const OI_BYTE * frame_data)242*09ac68ffSMatthias Ringwald static void btstack_sbc_decoder_bluedroid_simulate_error(const OI_BYTE *frame_data) {
243*09ac68ffSMatthias Ringwald     static int frame_count = 0;
244*09ac68ffSMatthias Ringwald     if (corrupt_frame_period > 0){
245*09ac68ffSMatthias Ringwald         frame_count++;
246*09ac68ffSMatthias Ringwald 
247*09ac68ffSMatthias Ringwald         if ((frame_count % corrupt_frame_period) == 0){
248*09ac68ffSMatthias Ringwald             *(uint8_t*)&frame_data[5] = 0;
249*09ac68ffSMatthias Ringwald             frame_count = 0;
250*09ac68ffSMatthias Ringwald         }
251*09ac68ffSMatthias Ringwald     }
252*09ac68ffSMatthias Ringwald }
253*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_deliver_pcm_data(btstack_sbc_decoder_bluedroid_t * state)254*09ac68ffSMatthias Ringwald static void btstack_sbc_decoder_deliver_pcm_data(btstack_sbc_decoder_bluedroid_t *state) {
255*09ac68ffSMatthias Ringwald     // deliver PCM data
256*09ac68ffSMatthias Ringwald     uint16_t num_samples_per_frame = state->decoder_context.common.frameInfo.nrof_blocks *
257*09ac68ffSMatthias Ringwald                                      state->decoder_context.common.frameInfo.nrof_subbands;
258*09ac68ffSMatthias Ringwald     uint8_t  num_channels = state->decoder_context.common.frameInfo.nrof_channels;
259*09ac68ffSMatthias Ringwald     uint16_t sample_rate = state->decoder_context.common.frameInfo.frequency;
260*09ac68ffSMatthias Ringwald     state->handle_pcm_data(state->pcm_data, num_samples_per_frame, num_channels, sample_rate, state->callback_context);
261*09ac68ffSMatthias Ringwald }
262*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_bluedroid_process_sbc_data(btstack_sbc_decoder_bluedroid_t * state,const uint8_t * buffer,int size)263*09ac68ffSMatthias Ringwald static void btstack_sbc_decoder_bluedroid_process_sbc_data(btstack_sbc_decoder_bluedroid_t * state, const uint8_t * buffer, int size){
264*09ac68ffSMatthias Ringwald     int input_bytes_to_process = size;
265*09ac68ffSMatthias Ringwald     int keep_decoding = 1;
266*09ac68ffSMatthias Ringwald 
267*09ac68ffSMatthias Ringwald     while (keep_decoding) {
268*09ac68ffSMatthias Ringwald         // Fill decoder_state->frame_buffer as much as possible.
269*09ac68ffSMatthias Ringwald         int bytes_free_in_frame_buffer = SBC_MAX_FRAME_LEN - state->bytes_in_frame_buffer;
270*09ac68ffSMatthias Ringwald         int bytes_to_append = btstack_min(input_bytes_to_process, bytes_free_in_frame_buffer);
271*09ac68ffSMatthias Ringwald         if (bytes_to_append){
272*09ac68ffSMatthias Ringwald             append_received_sbc_data(state, buffer, bytes_to_append);
273*09ac68ffSMatthias Ringwald             buffer += bytes_to_append;
274*09ac68ffSMatthias Ringwald             input_bytes_to_process -= bytes_to_append;
275*09ac68ffSMatthias Ringwald         }
276*09ac68ffSMatthias Ringwald 
277*09ac68ffSMatthias Ringwald         // Decode the next frame in decoder_state->frame_buffer.
278*09ac68ffSMatthias Ringwald         int bytes_in_frame_buffer_before_decoding = state->bytes_in_frame_buffer;
279*09ac68ffSMatthias Ringwald         const OI_BYTE *frame_data = state->frame_buffer;
280*09ac68ffSMatthias Ringwald         OI_UINT32 frame_data_len = state->bytes_in_frame_buffer;
281*09ac68ffSMatthias Ringwald         OI_STATUS status = OI_CODEC_SBC_DecodeFrame(&(state->decoder_context),
282*09ac68ffSMatthias Ringwald                                                     &frame_data,
283*09ac68ffSMatthias Ringwald                                                     &frame_data_len,
284*09ac68ffSMatthias Ringwald                                                     state->pcm_data,
285*09ac68ffSMatthias Ringwald                                                     &(state->pcm_bytes));
286*09ac68ffSMatthias Ringwald         uint16_t bytes_processed = bytes_in_frame_buffer_before_decoding - frame_data_len;
287*09ac68ffSMatthias Ringwald 
288*09ac68ffSMatthias Ringwald         // testing only - corrupt frame periodically
289*09ac68ffSMatthias Ringwald         btstack_sbc_decoder_bluedroid_simulate_error(frame_data);
290*09ac68ffSMatthias Ringwald 
291*09ac68ffSMatthias Ringwald         // Handle decoding result.
292*09ac68ffSMatthias Ringwald         switch(status){
293*09ac68ffSMatthias Ringwald             case OI_STATUS_SUCCESS:
294*09ac68ffSMatthias Ringwald             case OI_CODEC_SBC_PARTIAL_DECODE:
295*09ac68ffSMatthias Ringwald                 // deliver PCM data
296*09ac68ffSMatthias Ringwald                 btstack_sbc_decoder_deliver_pcm_data(state);
297*09ac68ffSMatthias Ringwald 
298*09ac68ffSMatthias Ringwald                 state->good_frames_nr++;
299*09ac68ffSMatthias Ringwald                 break;
300*09ac68ffSMatthias Ringwald 
301*09ac68ffSMatthias Ringwald             case OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA:
302*09ac68ffSMatthias Ringwald             case OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA:
303*09ac68ffSMatthias Ringwald             case OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA:
304*09ac68ffSMatthias Ringwald                 if (input_bytes_to_process > 0){
305*09ac68ffSMatthias Ringwald                     // Should never occur: The SBC codec claims there is not enough bytes in the frame_buffer,
306*09ac68ffSMatthias Ringwald                     // but the frame_buffer was full. (The frame_buffer is always full before decoding when input_bytes_to_process > 0.)
307*09ac68ffSMatthias Ringwald                     // Clear frame_buffer.
308*09ac68ffSMatthias Ringwald                     log_info("SBC decode: frame_buffer too small for frame");
309*09ac68ffSMatthias Ringwald                     bytes_processed = bytes_in_frame_buffer_before_decoding;
310*09ac68ffSMatthias Ringwald                 } else {
311*09ac68ffSMatthias Ringwald                     // Exit decode loop, because there is not enough data in frame_buffer to decode the next frame.
312*09ac68ffSMatthias Ringwald                     keep_decoding = 0;
313*09ac68ffSMatthias Ringwald                 }
314*09ac68ffSMatthias Ringwald                 break;
315*09ac68ffSMatthias Ringwald 
316*09ac68ffSMatthias Ringwald             case OI_CODEC_SBC_NO_SYNCWORD:
317*09ac68ffSMatthias Ringwald                 // This means the entire frame_buffer did not contain the syncword.
318*09ac68ffSMatthias Ringwald                 // Discard the frame_buffer contents.
319*09ac68ffSMatthias Ringwald                 log_info("SBC decode: no syncword found");
320*09ac68ffSMatthias Ringwald                 bytes_processed = bytes_in_frame_buffer_before_decoding;
321*09ac68ffSMatthias Ringwald                 break;
322*09ac68ffSMatthias Ringwald 
323*09ac68ffSMatthias Ringwald             case OI_CODEC_SBC_CHECKSUM_MISMATCH:
324*09ac68ffSMatthias Ringwald                 // The next frame is somehow corrupt.
325*09ac68ffSMatthias Ringwald                 log_info("SBC decode: checksum error");
326*09ac68ffSMatthias Ringwald                 // Did the codec consume any bytes?
327*09ac68ffSMatthias Ringwald                 if (bytes_processed > 0){
328*09ac68ffSMatthias Ringwald                     // Good. Nothing to do.
329*09ac68ffSMatthias Ringwald                 } else {
330*09ac68ffSMatthias Ringwald                     // Skip the bogus frame by skipping the header.
331*09ac68ffSMatthias Ringwald                     bytes_processed = 1;
332*09ac68ffSMatthias Ringwald                 }
333*09ac68ffSMatthias Ringwald                 break;
334*09ac68ffSMatthias Ringwald 
335*09ac68ffSMatthias Ringwald             case OI_STATUS_INVALID_PARAMETERS:
336*09ac68ffSMatthias Ringwald                 // This caused by corrupt frames.
337*09ac68ffSMatthias Ringwald                 // The codec apparently does not recover from this.
338*09ac68ffSMatthias Ringwald                 // Re-initialize the codec.
339*09ac68ffSMatthias Ringwald                 log_info("SBC decode: invalid parameters: resetting codec");
340*09ac68ffSMatthias Ringwald                 if (OI_CODEC_SBC_DecoderReset(&(state->decoder_context), state->decoder_data, sizeof(state->decoder_data), 2, 2, FALSE) != OI_STATUS_SUCCESS){
341*09ac68ffSMatthias Ringwald                     log_info("SBC decode: resetting codec failed");
342*09ac68ffSMatthias Ringwald 
343*09ac68ffSMatthias Ringwald                 }
344*09ac68ffSMatthias Ringwald                 break;
345*09ac68ffSMatthias Ringwald             default:
346*09ac68ffSMatthias Ringwald                 // Anything else went wrong.
347*09ac68ffSMatthias Ringwald                 // Skip a few bytes and try again.
348*09ac68ffSMatthias Ringwald                 bytes_processed = 1;
349*09ac68ffSMatthias Ringwald                 log_info("SBC decode: unknown status %d", status);
350*09ac68ffSMatthias Ringwald                 break;
351*09ac68ffSMatthias Ringwald         }
352*09ac68ffSMatthias Ringwald 
353*09ac68ffSMatthias Ringwald         // Remove decoded frame from decoder_state->frame_buffer.
354*09ac68ffSMatthias Ringwald         if (bytes_processed > bytes_in_frame_buffer_before_decoding) {
355*09ac68ffSMatthias Ringwald             bytes_processed = bytes_in_frame_buffer_before_decoding;
356*09ac68ffSMatthias Ringwald         }
357*09ac68ffSMatthias Ringwald         memmove(state->frame_buffer, state->frame_buffer + bytes_processed, bytes_in_frame_buffer_before_decoding - bytes_processed);
358*09ac68ffSMatthias Ringwald         state->bytes_in_frame_buffer -= bytes_processed;
359*09ac68ffSMatthias Ringwald     }
360*09ac68ffSMatthias Ringwald }
361*09ac68ffSMatthias Ringwald 
362*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_insert_missing_frames(btstack_sbc_decoder_bluedroid_t * state)363*09ac68ffSMatthias Ringwald static void btstack_sbc_decoder_insert_missing_frames(btstack_sbc_decoder_bluedroid_t *state) {
364*09ac68ffSMatthias Ringwald     const unsigned int MSBC_FRAME_SIZE = 60;
365*09ac68ffSMatthias Ringwald 
366*09ac68ffSMatthias Ringwald     while (state->first_good_frame_found && (state->msbc_bad_bytes >= MSBC_FRAME_SIZE)){
367*09ac68ffSMatthias Ringwald 
368*09ac68ffSMatthias Ringwald         state->msbc_bad_bytes -= MSBC_FRAME_SIZE;
369*09ac68ffSMatthias Ringwald         state->bad_frames_nr++;
370*09ac68ffSMatthias Ringwald 
371*09ac68ffSMatthias Ringwald         // prepare zero signal frame
372*09ac68ffSMatthias Ringwald         const OI_BYTE * frame_data  = btstack_sbc_plc_zero_signal_frame();
373*09ac68ffSMatthias Ringwald         OI_UINT32 bytes_in_frame_buffer = 57;
374*09ac68ffSMatthias Ringwald 
375*09ac68ffSMatthias Ringwald         // log_info("Trace bad frame generator, bad bytes %u", decoder_state->msbc_bad_bytes);
376*09ac68ffSMatthias Ringwald         OI_STATUS status = status = OI_CODEC_SBC_DecodeFrame(&(state->decoder_context),
377*09ac68ffSMatthias Ringwald                                                              &frame_data,
378*09ac68ffSMatthias Ringwald                                                              &bytes_in_frame_buffer,
379*09ac68ffSMatthias Ringwald                                                              state->pcm_plc_data,
380*09ac68ffSMatthias Ringwald                                                              &(state->pcm_bytes));
381*09ac68ffSMatthias Ringwald 
382*09ac68ffSMatthias Ringwald         if (status) {
383*09ac68ffSMatthias Ringwald             log_error("SBC decoder for ZIR frame: error %d\n", status);
384*09ac68ffSMatthias Ringwald         }
385*09ac68ffSMatthias Ringwald 
386*09ac68ffSMatthias Ringwald         if (bytes_in_frame_buffer){
387*09ac68ffSMatthias Ringwald             log_error("PLC: not all bytes of zero frame processed, left %u\n", (unsigned int) bytes_in_frame_buffer);
388*09ac68ffSMatthias Ringwald         }
389*09ac68ffSMatthias Ringwald 
390*09ac68ffSMatthias Ringwald         if (plc_enabled) {
391*09ac68ffSMatthias Ringwald             btstack_sbc_plc_bad_frame(&state->plc_state, state->pcm_plc_data, state->pcm_data);
392*09ac68ffSMatthias Ringwald         } else {
393*09ac68ffSMatthias Ringwald             (void)memcpy(state->pcm_data,
394*09ac68ffSMatthias Ringwald                          state->pcm_plc_data,
395*09ac68ffSMatthias Ringwald                          state->pcm_bytes);
396*09ac68ffSMatthias Ringwald         }
397*09ac68ffSMatthias Ringwald 
398*09ac68ffSMatthias Ringwald         // deliver PCM data
399*09ac68ffSMatthias Ringwald         btstack_sbc_decoder_deliver_pcm_data(state);
400*09ac68ffSMatthias Ringwald     }
401*09ac68ffSMatthias Ringwald }
402*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_drop_processed_bytes(btstack_sbc_decoder_bluedroid_t * state,uint16_t bytes_processed)403*09ac68ffSMatthias Ringwald static void btstack_sbc_decoder_drop_processed_bytes(btstack_sbc_decoder_bluedroid_t * state, uint16_t bytes_processed){
404*09ac68ffSMatthias Ringwald     memmove(state->frame_buffer, state->frame_buffer + bytes_processed, state->bytes_in_frame_buffer - bytes_processed);
405*09ac68ffSMatthias Ringwald     state->bytes_in_frame_buffer -= bytes_processed;
406*09ac68ffSMatthias Ringwald }
407*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_bluedroid_process_msbc_data(btstack_sbc_decoder_bluedroid_t * state,int packet_status_flag,const uint8_t * buffer,int size)408*09ac68ffSMatthias Ringwald static void btstack_sbc_decoder_bluedroid_process_msbc_data(btstack_sbc_decoder_bluedroid_t * state, int packet_status_flag, const uint8_t * buffer, int size){
409*09ac68ffSMatthias Ringwald     int input_bytes_to_process = size;
410*09ac68ffSMatthias Ringwald     const unsigned int MSBC_FRAME_SIZE = 60;
411*09ac68ffSMatthias Ringwald 
412*09ac68ffSMatthias Ringwald     while (input_bytes_to_process > 0){
413*09ac68ffSMatthias Ringwald 
414*09ac68ffSMatthias Ringwald         // Use PLC to insert missing frames (after first sync found)
415*09ac68ffSMatthias Ringwald         btstack_sbc_decoder_insert_missing_frames(state);
416*09ac68ffSMatthias Ringwald         // fill buffer with new data
417*09ac68ffSMatthias Ringwald         int bytes_missing_for_complete_msbc_frame = MSBC_FRAME_SIZE - state->bytes_in_frame_buffer;
418*09ac68ffSMatthias Ringwald         int bytes_to_append = btstack_min(input_bytes_to_process, bytes_missing_for_complete_msbc_frame);
419*09ac68ffSMatthias Ringwald         if (bytes_to_append) {
420*09ac68ffSMatthias Ringwald             append_received_sbc_data(state, buffer, bytes_to_append);
421*09ac68ffSMatthias Ringwald             buffer += bytes_to_append;
422*09ac68ffSMatthias Ringwald             input_bytes_to_process -= bytes_to_append;
423*09ac68ffSMatthias Ringwald         }
424*09ac68ffSMatthias Ringwald         // complete frame in  buffer?
425*09ac68ffSMatthias Ringwald         if (state->bytes_in_frame_buffer < MSBC_FRAME_SIZE) break;
426*09ac68ffSMatthias Ringwald 
427*09ac68ffSMatthias Ringwald         uint16_t bytes_in_frame_buffer_before_decoding = state->bytes_in_frame_buffer;
428*09ac68ffSMatthias Ringwald         uint16_t bytes_processed = 0;
429*09ac68ffSMatthias Ringwald         const OI_BYTE *frame_data = state->frame_buffer;
430*09ac68ffSMatthias Ringwald 
431*09ac68ffSMatthias Ringwald         // testing only - corrupt frame periodically
432*09ac68ffSMatthias Ringwald         btstack_sbc_decoder_bluedroid_simulate_error(frame_data);
433*09ac68ffSMatthias Ringwald 
434*09ac68ffSMatthias Ringwald         // assert frame looks like this: 01 x8 AD [rest of frame 56 bytes] 00
435*09ac68ffSMatthias Ringwald         int h2_syncword = 0;
436*09ac68ffSMatthias Ringwald         int h2_sync_pos = find_h2_sync(frame_data, state->bytes_in_frame_buffer, &h2_syncword);
437*09ac68ffSMatthias Ringwald         if (h2_sync_pos < 0){
438*09ac68ffSMatthias Ringwald             // no sync found, discard all but last 2 bytes
439*09ac68ffSMatthias Ringwald             bytes_processed = state->bytes_in_frame_buffer - 2;
440*09ac68ffSMatthias Ringwald             btstack_sbc_decoder_drop_processed_bytes(state, bytes_processed);
441*09ac68ffSMatthias Ringwald             // don't try PLC without at least a single good frame
442*09ac68ffSMatthias Ringwald             if (state->first_good_frame_found){
443*09ac68ffSMatthias Ringwald                 state->msbc_bad_bytes += bytes_processed;
444*09ac68ffSMatthias Ringwald             }
445*09ac68ffSMatthias Ringwald             continue;
446*09ac68ffSMatthias Ringwald         }
447*09ac68ffSMatthias Ringwald 
448*09ac68ffSMatthias Ringwald         state->h2_sequence_nr = h2_syncword;
449*09ac68ffSMatthias Ringwald 
450*09ac68ffSMatthias Ringwald         // drop data before it
451*09ac68ffSMatthias Ringwald         bytes_processed = h2_sync_pos - 2;
452*09ac68ffSMatthias Ringwald         if (bytes_processed > 0){
453*09ac68ffSMatthias Ringwald             memmove(state->frame_buffer, state->frame_buffer + bytes_processed, state->bytes_in_frame_buffer - bytes_processed);
454*09ac68ffSMatthias Ringwald             state->bytes_in_frame_buffer -= bytes_processed;
455*09ac68ffSMatthias Ringwald             // don't try PLC without at least a single good frame
456*09ac68ffSMatthias Ringwald             if (state->first_good_frame_found){
457*09ac68ffSMatthias Ringwald                 state->msbc_bad_bytes += bytes_processed;
458*09ac68ffSMatthias Ringwald             }
459*09ac68ffSMatthias Ringwald             continue;
460*09ac68ffSMatthias Ringwald         }
461*09ac68ffSMatthias Ringwald 
462*09ac68ffSMatthias Ringwald         int bad_frame = 0;
463*09ac68ffSMatthias Ringwald         int zero_seq_found = find_sequence_of_zeros(frame_data, state->bytes_in_frame_buffer, 20);
464*09ac68ffSMatthias Ringwald 
465*09ac68ffSMatthias Ringwald         // after first valid frame, zero sequences count as bad frames
466*09ac68ffSMatthias Ringwald         if (state->first_good_frame_found){
467*09ac68ffSMatthias Ringwald             bad_frame = zero_seq_found || packet_status_flag;
468*09ac68ffSMatthias Ringwald         }
469*09ac68ffSMatthias Ringwald 
470*09ac68ffSMatthias Ringwald         if (bad_frame){
471*09ac68ffSMatthias Ringwald             // stats
472*09ac68ffSMatthias Ringwald             if (zero_seq_found){
473*09ac68ffSMatthias Ringwald                 state->zero_frames_nr++;
474*09ac68ffSMatthias Ringwald             } else {
475*09ac68ffSMatthias Ringwald                 state->bad_frames_nr++;
476*09ac68ffSMatthias Ringwald             }
477*09ac68ffSMatthias Ringwald #ifdef LOG_FRAME_STATUS
478*09ac68ffSMatthias Ringwald             if (zero_seq_found){
479*09ac68ffSMatthias Ringwald                 printf("%d : ZERO FRAME\n", instance->h2_sequence_nr);
480*09ac68ffSMatthias Ringwald             } else {
481*09ac68ffSMatthias Ringwald                 printf("%d : BAD FRAME\n", instance->h2_sequence_nr);
482*09ac68ffSMatthias Ringwald             }
483*09ac68ffSMatthias Ringwald #endif
484*09ac68ffSMatthias Ringwald             // retry after dropping 3 byte sync
485*09ac68ffSMatthias Ringwald             bytes_processed = 3;
486*09ac68ffSMatthias Ringwald             btstack_sbc_decoder_drop_processed_bytes(state, bytes_processed);
487*09ac68ffSMatthias Ringwald             state->msbc_bad_bytes += bytes_processed;
488*09ac68ffSMatthias Ringwald             // log_info("Trace bad frame");
489*09ac68ffSMatthias Ringwald             continue;
490*09ac68ffSMatthias Ringwald         }
491*09ac68ffSMatthias Ringwald 
492*09ac68ffSMatthias Ringwald         //ready to decode frame
493*09ac68ffSMatthias Ringwald         OI_STATUS status = OI_CODEC_SBC_DecodeFrame(&(state->decoder_context),
494*09ac68ffSMatthias Ringwald                                                     &frame_data,
495*09ac68ffSMatthias Ringwald                                                     &(state->bytes_in_frame_buffer),
496*09ac68ffSMatthias Ringwald                                                     state->pcm_plc_data,
497*09ac68ffSMatthias Ringwald                                                     &(state->pcm_bytes));
498*09ac68ffSMatthias Ringwald 
499*09ac68ffSMatthias Ringwald         bytes_processed = bytes_in_frame_buffer_before_decoding - state->bytes_in_frame_buffer;
500*09ac68ffSMatthias Ringwald         // log_info("Trace decode status %u, processed %u (bad bytes %u), bytes in buffer %u", (int) status, bytes_processed, decoder_state->msbc_bad_bytes, decoder_state->bytes_in_frame_buffer);
501*09ac68ffSMatthias Ringwald 
502*09ac68ffSMatthias Ringwald         switch(status){
503*09ac68ffSMatthias Ringwald             case 0:
504*09ac68ffSMatthias Ringwald                 // synced
505*09ac68ffSMatthias Ringwald                 state->first_good_frame_found = 1;
506*09ac68ffSMatthias Ringwald 
507*09ac68ffSMatthias Ringwald                 // get rid of padding byte, not processed by SBC decoder
508*09ac68ffSMatthias Ringwald                 state->bytes_in_frame_buffer = 0;
509*09ac68ffSMatthias Ringwald 
510*09ac68ffSMatthias Ringwald                 // restart counting bad bytes
511*09ac68ffSMatthias Ringwald                 state->msbc_bad_bytes = 0;
512*09ac68ffSMatthias Ringwald 
513*09ac68ffSMatthias Ringwald                 // feed good frame into PLC history
514*09ac68ffSMatthias Ringwald                 btstack_sbc_plc_good_frame(&state->plc_state, state->pcm_plc_data, state->pcm_data);
515*09ac68ffSMatthias Ringwald 
516*09ac68ffSMatthias Ringwald                 // deliver PCM data
517*09ac68ffSMatthias Ringwald                 btstack_sbc_decoder_deliver_pcm_data(state);
518*09ac68ffSMatthias Ringwald 
519*09ac68ffSMatthias Ringwald                 // stats
520*09ac68ffSMatthias Ringwald                 state->good_frames_nr++;
521*09ac68ffSMatthias Ringwald                 continue;
522*09ac68ffSMatthias Ringwald 
523*09ac68ffSMatthias Ringwald             case OI_CODEC_SBC_CHECKSUM_MISMATCH:
524*09ac68ffSMatthias Ringwald                 // The next frame is somehow corrupt.
525*09ac68ffSMatthias Ringwald                 log_debug("OI_CODEC_SBC_CHECKSUM_MISMATCH");
526*09ac68ffSMatthias Ringwald                 // Did the codec consume any bytes?
527*09ac68ffSMatthias Ringwald                 if (bytes_processed > 0){
528*09ac68ffSMatthias Ringwald                     // Good. Nothing to do.
529*09ac68ffSMatthias Ringwald                 } else {
530*09ac68ffSMatthias Ringwald                     // Skip the bogus frame by skipping the header.
531*09ac68ffSMatthias Ringwald                     bytes_processed = 1;
532*09ac68ffSMatthias Ringwald                 }
533*09ac68ffSMatthias Ringwald                 break;
534*09ac68ffSMatthias Ringwald 
535*09ac68ffSMatthias Ringwald             case OI_STATUS_INVALID_PARAMETERS:
536*09ac68ffSMatthias Ringwald                 // This caused by corrupt frames.
537*09ac68ffSMatthias Ringwald                 // The codec apparently does not recover from this.
538*09ac68ffSMatthias Ringwald                 // Re-initialize the codec.
539*09ac68ffSMatthias Ringwald                 log_info("SBC decode: invalid parameters: resetting codec");
540*09ac68ffSMatthias Ringwald                 if (OI_CODEC_mSBC_DecoderReset(&(state->decoder_context), state->decoder_data, sizeof(state->decoder_data)) != OI_STATUS_SUCCESS){
541*09ac68ffSMatthias Ringwald                     log_info("SBC decode: resetting codec failed");
542*09ac68ffSMatthias Ringwald                 }
543*09ac68ffSMatthias Ringwald                 break;
544*09ac68ffSMatthias Ringwald             default:
545*09ac68ffSMatthias Ringwald                 log_info("Frame decode error: %d", status);
546*09ac68ffSMatthias Ringwald                 break;
547*09ac68ffSMatthias Ringwald         }
548*09ac68ffSMatthias Ringwald 
549*09ac68ffSMatthias Ringwald         // on success, while loop was restarted, so all processed bytes have been "bad"
550*09ac68ffSMatthias Ringwald         state->msbc_bad_bytes += bytes_processed;
551*09ac68ffSMatthias Ringwald 
552*09ac68ffSMatthias Ringwald         // drop processed bytes from frame buffer
553*09ac68ffSMatthias Ringwald         btstack_sbc_decoder_drop_processed_bytes(state, bytes_processed);
554*09ac68ffSMatthias Ringwald     }
555*09ac68ffSMatthias Ringwald }
556*09ac68ffSMatthias Ringwald 
557*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_bluedroid_configure(void * context,btstack_sbc_mode_t mode,void (* callback)(int16_t * data,int num_samples,int num_channels,int sample_rate,void * context),void * callback_context)558*09ac68ffSMatthias Ringwald static void btstack_sbc_decoder_bluedroid_configure(void * context, btstack_sbc_mode_t mode, void (*callback)(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context), void * callback_context){
559*09ac68ffSMatthias Ringwald     btstack_sbc_decoder_bluedroid_t * state = (btstack_sbc_decoder_bluedroid_t*) context;
560*09ac68ffSMatthias Ringwald     OI_STATUS status = OI_STATUS_SUCCESS;
561*09ac68ffSMatthias Ringwald     switch (mode){
562*09ac68ffSMatthias Ringwald         case SBC_MODE_STANDARD:
563*09ac68ffSMatthias Ringwald             // note: we always request stereo output, even for mono input
564*09ac68ffSMatthias Ringwald             status = OI_CODEC_SBC_DecoderReset(&state->decoder_context, state->decoder_data, sizeof(state->decoder_data), 2, 2, FALSE);
565*09ac68ffSMatthias Ringwald             break;
566*09ac68ffSMatthias Ringwald         case SBC_MODE_mSBC:
567*09ac68ffSMatthias Ringwald             status = OI_CODEC_mSBC_DecoderReset(&(state->decoder_context), state->decoder_data, sizeof(state->decoder_data));
568*09ac68ffSMatthias Ringwald             break;
569*09ac68ffSMatthias Ringwald         default:
570*09ac68ffSMatthias Ringwald             btstack_unreachable();
571*09ac68ffSMatthias Ringwald             break;
572*09ac68ffSMatthias Ringwald     }
573*09ac68ffSMatthias Ringwald 
574*09ac68ffSMatthias Ringwald     if (status != OI_STATUS_SUCCESS){
575*09ac68ffSMatthias Ringwald         log_error("SBC decoder: error during reset %d\n", status);
576*09ac68ffSMatthias Ringwald     }
577*09ac68ffSMatthias Ringwald 
578*09ac68ffSMatthias Ringwald     state->bytes_in_frame_buffer = 0;
579*09ac68ffSMatthias Ringwald     state->pcm_bytes = sizeof(state->pcm_data);
580*09ac68ffSMatthias Ringwald     state->h2_sequence_nr = -1;
581*09ac68ffSMatthias Ringwald     state->first_good_frame_found = 0;
582*09ac68ffSMatthias Ringwald 
583*09ac68ffSMatthias Ringwald     state->handle_pcm_data = callback;
584*09ac68ffSMatthias Ringwald     state->callback_context = callback_context;
585*09ac68ffSMatthias Ringwald     state->mode = mode;
586*09ac68ffSMatthias Ringwald     btstack_sbc_plc_init(&state->plc_state);
587*09ac68ffSMatthias Ringwald }
588*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_bluedroid_decode_signed_16(void * context,uint8_t packet_status_flag,const uint8_t * buffer,uint16_t size)589*09ac68ffSMatthias Ringwald static void btstack_sbc_decoder_bluedroid_decode_signed_16(void * context, uint8_t packet_status_flag, const uint8_t * buffer, uint16_t size){
590*09ac68ffSMatthias Ringwald     btstack_sbc_decoder_bluedroid_t * state = (btstack_sbc_decoder_bluedroid_t*) context;
591*09ac68ffSMatthias Ringwald     if (state->mode == SBC_MODE_mSBC){
592*09ac68ffSMatthias Ringwald         btstack_sbc_decoder_bluedroid_process_msbc_data(state, packet_status_flag, buffer, size);
593*09ac68ffSMatthias Ringwald     } else {
594*09ac68ffSMatthias Ringwald         btstack_sbc_decoder_bluedroid_process_sbc_data(state, buffer, size);
595*09ac68ffSMatthias Ringwald     }
596*09ac68ffSMatthias Ringwald }
597*09ac68ffSMatthias Ringwald 
598*09ac68ffSMatthias Ringwald static const btstack_sbc_decoder_t btstack_sbc_decoder_bluedroid = {
599*09ac68ffSMatthias Ringwald     .configure         = btstack_sbc_decoder_bluedroid_configure,
600*09ac68ffSMatthias Ringwald     .decode_signed_16  = btstack_sbc_decoder_bluedroid_decode_signed_16
601*09ac68ffSMatthias Ringwald };
602*09ac68ffSMatthias Ringwald 
btstack_sbc_decoder_bluedroid_init_instance(btstack_sbc_decoder_bluedroid_t * context)603*09ac68ffSMatthias Ringwald const btstack_sbc_decoder_t * btstack_sbc_decoder_bluedroid_init_instance(btstack_sbc_decoder_bluedroid_t * context){
604*09ac68ffSMatthias Ringwald     memset(context, 0, sizeof(btstack_sbc_encoder_bluedroid_t));
605*09ac68ffSMatthias Ringwald     return &btstack_sbc_decoder_bluedroid;
606*09ac68ffSMatthias Ringwald }
607