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