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