xref: /btstack/src/btstack_lc3_google.c (revision 9a19cd786042b1fc78813d984efdd045e84593df)
1*9a19cd78SMatthias Ringwald /*
2*9a19cd78SMatthias Ringwald  * Copyright (C) 2022 BlueKitchen GmbH
3*9a19cd78SMatthias Ringwald  *
4*9a19cd78SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*9a19cd78SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*9a19cd78SMatthias Ringwald  * are met:
7*9a19cd78SMatthias Ringwald  *
8*9a19cd78SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*9a19cd78SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*9a19cd78SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*9a19cd78SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*9a19cd78SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*9a19cd78SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*9a19cd78SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*9a19cd78SMatthias Ringwald  *    from this software without specific prior written permission.
16*9a19cd78SMatthias Ringwald  *
17*9a19cd78SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
18*9a19cd78SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9a19cd78SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20*9a19cd78SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
21*9a19cd78SMatthias Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22*9a19cd78SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23*9a19cd78SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24*9a19cd78SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25*9a19cd78SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26*9a19cd78SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27*9a19cd78SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*9a19cd78SMatthias Ringwald  * SUCH DAMAGE.
29*9a19cd78SMatthias Ringwald  *
30*9a19cd78SMatthias Ringwald  */
31*9a19cd78SMatthias Ringwald 
32*9a19cd78SMatthias Ringwald #define BTSTACK_FILE__ "btstack_lc3_google.c"
33*9a19cd78SMatthias Ringwald 
34*9a19cd78SMatthias Ringwald /**
35*9a19cd78SMatthias Ringwald  * @title LC3 Google Adapter
36*9a19cd78SMatthias Ringwald  */
37*9a19cd78SMatthias Ringwald 
38*9a19cd78SMatthias Ringwald #include "btstack_config.h"
39*9a19cd78SMatthias Ringwald #include "bluetooth.h"
40*9a19cd78SMatthias Ringwald 
41*9a19cd78SMatthias Ringwald #include "btstack_lc3_google.h"
42*9a19cd78SMatthias Ringwald #include "btstack_debug.h"
43*9a19cd78SMatthias Ringwald #include <string.h>
44*9a19cd78SMatthias Ringwald 
45*9a19cd78SMatthias Ringwald static uint16_t lc3_frame_duration_in_us(btstack_lc3_frame_duration_t frame_duration){
46*9a19cd78SMatthias Ringwald     switch (frame_duration) {
47*9a19cd78SMatthias Ringwald         case BTSTACK_LC3_FRAME_DURATION_7500US:
48*9a19cd78SMatthias Ringwald             return 7500;
49*9a19cd78SMatthias Ringwald         case BTSTACK_LC3_FRAME_DURATION_10000US:
50*9a19cd78SMatthias Ringwald             return 10000;
51*9a19cd78SMatthias Ringwald         default:
52*9a19cd78SMatthias Ringwald             return 0;
53*9a19cd78SMatthias Ringwald     }
54*9a19cd78SMatthias Ringwald }
55*9a19cd78SMatthias Ringwald 
56*9a19cd78SMatthias Ringwald /* Decoder implementation */
57*9a19cd78SMatthias Ringwald 
58*9a19cd78SMatthias Ringwald static uint8_t lc3_decoder_google_configure(void * context, uint32_t sample_rate, btstack_lc3_frame_duration_t frame_duration){
59*9a19cd78SMatthias Ringwald     btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context;
60*9a19cd78SMatthias Ringwald 
61*9a19cd78SMatthias Ringwald     // map frame duration
62*9a19cd78SMatthias Ringwald     uint16_t duration_us = lc3_frame_duration_in_us(frame_duration);
63*9a19cd78SMatthias Ringwald     if (duration_us == 0){
64*9a19cd78SMatthias Ringwald         return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
65*9a19cd78SMatthias Ringwald     }
66*9a19cd78SMatthias Ringwald 
67*9a19cd78SMatthias Ringwald     // store config
68*9a19cd78SMatthias Ringwald     instance->sample_rate = sample_rate;
69*9a19cd78SMatthias Ringwald     instance->frame_duration = frame_duration;
70*9a19cd78SMatthias Ringwald 
71*9a19cd78SMatthias Ringwald     // config decoder
72*9a19cd78SMatthias Ringwald     instance->decoder = lc3_setup_decoder(duration_us, sample_rate, 0, &instance->decoder_mem);
73*9a19cd78SMatthias Ringwald 
74*9a19cd78SMatthias Ringwald     if (instance->decoder == NULL) {
75*9a19cd78SMatthias Ringwald         return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
76*9a19cd78SMatthias Ringwald     }
77*9a19cd78SMatthias Ringwald 
78*9a19cd78SMatthias Ringwald     return ERROR_CODE_SUCCESS;
79*9a19cd78SMatthias Ringwald }
80*9a19cd78SMatthias Ringwald 
81*9a19cd78SMatthias Ringwald static uint16_t lc3_decoder_google_get_number_octets_for_bitrate(void * context, uint32_t bitrate){
82*9a19cd78SMatthias Ringwald     btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context;
83*9a19cd78SMatthias Ringwald     uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration);
84*9a19cd78SMatthias Ringwald     if (duration_us == 0){
85*9a19cd78SMatthias Ringwald         return 0;
86*9a19cd78SMatthias Ringwald     }
87*9a19cd78SMatthias Ringwald     return lc3_frame_bytes(duration_us, bitrate);
88*9a19cd78SMatthias Ringwald }
89*9a19cd78SMatthias Ringwald 
90*9a19cd78SMatthias Ringwald static uint16_t lc3_decoder_google_get_number_samples_per_frame(void * context){
91*9a19cd78SMatthias Ringwald     btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context;
92*9a19cd78SMatthias Ringwald     uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration);
93*9a19cd78SMatthias Ringwald     if (duration_us == 0){
94*9a19cd78SMatthias Ringwald         return 0;
95*9a19cd78SMatthias Ringwald     }
96*9a19cd78SMatthias Ringwald     return lc3_frame_samples(duration_us, instance->sample_rate);
97*9a19cd78SMatthias Ringwald }
98*9a19cd78SMatthias Ringwald 
99*9a19cd78SMatthias Ringwald static uint8_t lc3_decoder_google_decode(void * context, const uint8_t *bytes, uint16_t byte_count, uint8_t BFI,  enum lc3_pcm_format fmt, void * pcm_out, uint16_t stride, uint8_t * BEC_detect){
100*9a19cd78SMatthias Ringwald     btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context;
101*9a19cd78SMatthias Ringwald 
102*9a19cd78SMatthias Ringwald     if (BFI){
103*9a19cd78SMatthias Ringwald         // bit errors, trigger PLC by passing NULL as buffer
104*9a19cd78SMatthias Ringwald         *BEC_detect = 1;
105*9a19cd78SMatthias Ringwald         bytes = NULL;
106*9a19cd78SMatthias Ringwald     } else {
107*9a19cd78SMatthias Ringwald         // no bit errors, regular processing
108*9a19cd78SMatthias Ringwald         *BEC_detect = 0;
109*9a19cd78SMatthias Ringwald     }
110*9a19cd78SMatthias Ringwald 
111*9a19cd78SMatthias Ringwald     int result = lc3_decode(instance->decoder, (const void *) bytes, byte_count, fmt, pcm_out, stride);
112*9a19cd78SMatthias Ringwald     switch (result){
113*9a19cd78SMatthias Ringwald         case 0: // success
114*9a19cd78SMatthias Ringwald             return ERROR_CODE_SUCCESS;
115*9a19cd78SMatthias Ringwald         case -1: // PLC engaged
116*9a19cd78SMatthias Ringwald             *BEC_detect = 1;
117*9a19cd78SMatthias Ringwald             return ERROR_CODE_SUCCESS;
118*9a19cd78SMatthias Ringwald         default:
119*9a19cd78SMatthias Ringwald             return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
120*9a19cd78SMatthias Ringwald     }
121*9a19cd78SMatthias Ringwald }
122*9a19cd78SMatthias Ringwald 
123*9a19cd78SMatthias Ringwald static uint8_t lc3_decoder_google_decode_signed_16(void * context, const uint8_t *bytes, uint16_t byte_count, uint8_t BFI, int16_t* pcm_out, uint16_t stride, uint8_t * BEC_detect){
124*9a19cd78SMatthias Ringwald     return lc3_decoder_google_decode(context, bytes, byte_count, BFI, LC3_PCM_FORMAT_S16, (void *) pcm_out, stride, BEC_detect);
125*9a19cd78SMatthias Ringwald }
126*9a19cd78SMatthias Ringwald 
127*9a19cd78SMatthias Ringwald static uint8_t lc3_decoder_google_decode_signed_24(void * context, const uint8_t *bytes, uint16_t byte_count, uint8_t BFI, int32_t* pcm_out, uint16_t stride, uint8_t * BEC_detect) {
128*9a19cd78SMatthias Ringwald     return lc3_decoder_google_decode(context, bytes, byte_count, BFI, LC3_PCM_FORMAT_S24, (void *) pcm_out, stride, BEC_detect);
129*9a19cd78SMatthias Ringwald }
130*9a19cd78SMatthias Ringwald 
131*9a19cd78SMatthias Ringwald static const btstack_lc3_decoder_t btstack_l3c_decoder_google_instance = {
132*9a19cd78SMatthias Ringwald     lc3_decoder_google_configure,
133*9a19cd78SMatthias Ringwald     lc3_decoder_google_get_number_octets_for_bitrate,
134*9a19cd78SMatthias Ringwald     lc3_decoder_google_get_number_samples_per_frame,
135*9a19cd78SMatthias Ringwald     lc3_decoder_google_decode_signed_16,
136*9a19cd78SMatthias Ringwald     lc3_decoder_google_decode_signed_24
137*9a19cd78SMatthias Ringwald };
138*9a19cd78SMatthias Ringwald 
139*9a19cd78SMatthias Ringwald const btstack_lc3_decoder_t * btstack_lc3_decoder_google_init_instance(btstack_lc3_decoder_google_t * context){
140*9a19cd78SMatthias Ringwald     memset(context, 0, sizeof(btstack_lc3_decoder_google_t));
141*9a19cd78SMatthias Ringwald     return &btstack_l3c_decoder_google_instance;
142*9a19cd78SMatthias Ringwald }
143*9a19cd78SMatthias Ringwald 
144*9a19cd78SMatthias Ringwald /* Encoder implementation */
145*9a19cd78SMatthias Ringwald 
146*9a19cd78SMatthias Ringwald static uint8_t lc3_encoder_google_configure(void * context, uint32_t sample_rate, btstack_lc3_frame_duration_t frame_duration){
147*9a19cd78SMatthias Ringwald     btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context;
148*9a19cd78SMatthias Ringwald 
149*9a19cd78SMatthias Ringwald     // map frame duration
150*9a19cd78SMatthias Ringwald     uint16_t duration_us = lc3_frame_duration_in_us(frame_duration);
151*9a19cd78SMatthias Ringwald     if (duration_us == 0){
152*9a19cd78SMatthias Ringwald         return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
153*9a19cd78SMatthias Ringwald     }
154*9a19cd78SMatthias Ringwald 
155*9a19cd78SMatthias Ringwald     // store config
156*9a19cd78SMatthias Ringwald     instance->sample_rate = sample_rate;
157*9a19cd78SMatthias Ringwald     instance->frame_duration = frame_duration;
158*9a19cd78SMatthias Ringwald 
159*9a19cd78SMatthias Ringwald     // config encoder
160*9a19cd78SMatthias Ringwald     instance->encoder = lc3_setup_encoder(duration_us, sample_rate, 0, &instance->encoder_mem);
161*9a19cd78SMatthias Ringwald 
162*9a19cd78SMatthias Ringwald     if (instance->encoder == NULL) {
163*9a19cd78SMatthias Ringwald         return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
164*9a19cd78SMatthias Ringwald     }
165*9a19cd78SMatthias Ringwald 
166*9a19cd78SMatthias Ringwald     return ERROR_CODE_SUCCESS;
167*9a19cd78SMatthias Ringwald }
168*9a19cd78SMatthias Ringwald 
169*9a19cd78SMatthias Ringwald static uint32_t lc3_encoder_google_get_bitrate_for_number_of_octets(void * context, uint16_t number_of_octets){
170*9a19cd78SMatthias Ringwald     btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context;
171*9a19cd78SMatthias Ringwald     // map frame duration
172*9a19cd78SMatthias Ringwald     uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration);
173*9a19cd78SMatthias Ringwald     if (duration_us == 0){
174*9a19cd78SMatthias Ringwald         return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
175*9a19cd78SMatthias Ringwald     }
176*9a19cd78SMatthias Ringwald     return lc3_resolve_bitrate(duration_us, number_of_octets);
177*9a19cd78SMatthias Ringwald }
178*9a19cd78SMatthias Ringwald 
179*9a19cd78SMatthias Ringwald static uint16_t lc3_encoder_google_get_number_samples_per_frame(void * context){
180*9a19cd78SMatthias Ringwald     btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context;
181*9a19cd78SMatthias Ringwald     // map frame duration
182*9a19cd78SMatthias Ringwald     uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration);
183*9a19cd78SMatthias Ringwald     if (duration_us == 0){
184*9a19cd78SMatthias Ringwald         return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
185*9a19cd78SMatthias Ringwald     }
186*9a19cd78SMatthias Ringwald     return lc3_frame_samples(duration_us, instance->sample_rate);
187*9a19cd78SMatthias Ringwald }
188*9a19cd78SMatthias Ringwald static uint8_t lc3_encoder_google_encode_signed(void * context, enum lc3_pcm_format fmt, const void *pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count) {
189*9a19cd78SMatthias Ringwald     btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context;
190*9a19cd78SMatthias Ringwald     int result = lc3_encode(instance->encoder, fmt, pcm_in, stride, byte_count, (void*) bytes);
191*9a19cd78SMatthias Ringwald     switch (result){
192*9a19cd78SMatthias Ringwald         case 0:
193*9a19cd78SMatthias Ringwald             return ERROR_CODE_SUCCESS;
194*9a19cd78SMatthias Ringwald         default:
195*9a19cd78SMatthias Ringwald             return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
196*9a19cd78SMatthias Ringwald     }
197*9a19cd78SMatthias Ringwald }
198*9a19cd78SMatthias Ringwald 
199*9a19cd78SMatthias Ringwald static uint8_t lc3_encoder_google_encode_signed_16(void * context, const int16_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count){
200*9a19cd78SMatthias Ringwald     return lc3_encoder_google_encode_signed(context, LC3_PCM_FORMAT_S16, (const void *) pcm_in, stride, bytes, byte_count);
201*9a19cd78SMatthias Ringwald }
202*9a19cd78SMatthias Ringwald 
203*9a19cd78SMatthias Ringwald static uint8_t lc3_encoder_google_encode_signed_24(void * context, const int32_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count){
204*9a19cd78SMatthias Ringwald     return lc3_encoder_google_encode_signed(context, LC3_PCM_FORMAT_S24, (const void *) pcm_in, stride, bytes, byte_count);
205*9a19cd78SMatthias Ringwald }
206*9a19cd78SMatthias Ringwald 
207*9a19cd78SMatthias Ringwald static const btstack_lc3_encoder_t btstack_l3c_encoder_google_instance = {
208*9a19cd78SMatthias Ringwald         lc3_encoder_google_configure,
209*9a19cd78SMatthias Ringwald         lc3_encoder_google_get_bitrate_for_number_of_octets,
210*9a19cd78SMatthias Ringwald         lc3_encoder_google_get_number_samples_per_frame,
211*9a19cd78SMatthias Ringwald         lc3_encoder_google_encode_signed_16,
212*9a19cd78SMatthias Ringwald         lc3_encoder_google_encode_signed_24
213*9a19cd78SMatthias Ringwald };
214*9a19cd78SMatthias Ringwald 
215*9a19cd78SMatthias Ringwald const btstack_lc3_encoder_t * btstack_lc3_encoder_google_init_instance(btstack_lc3_encoder_google_t * context){
216*9a19cd78SMatthias Ringwald     memset(context, 0, sizeof(btstack_lc3_encoder_google_t));
217*9a19cd78SMatthias Ringwald     return &btstack_l3c_encoder_google_instance;
218*9a19cd78SMatthias Ringwald }
219*9a19cd78SMatthias Ringwald 
220