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){ 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 71 // config decoder 72 instance->decoder = lc3_setup_decoder(duration_us, sample_rate, 0, &instance->decoder_mem); 73 74 if (instance->decoder == NULL) { 75 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 76 } 77 78 return ERROR_CODE_SUCCESS; 79 } 80 81 static uint16_t lc3_decoder_google_get_number_octets_for_bitrate(void * context, uint32_t bitrate){ 82 btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context; 83 uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration); 84 if (duration_us == 0){ 85 return 0; 86 } 87 return lc3_frame_bytes(duration_us, bitrate); 88 } 89 90 static uint16_t lc3_decoder_google_get_number_samples_per_frame(void * context){ 91 btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context; 92 uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration); 93 if (duration_us == 0){ 94 return 0; 95 } 96 return lc3_frame_samples(duration_us, instance->sample_rate); 97 } 98 99 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 btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context; 101 102 if (BFI){ 103 // bit errors, trigger PLC by passing NULL as buffer 104 *BEC_detect = 1; 105 bytes = NULL; 106 } else { 107 // no bit errors, regular processing 108 *BEC_detect = 0; 109 } 110 111 int result = lc3_decode(instance->decoder, (const void *) bytes, byte_count, fmt, pcm_out, stride); 112 switch (result){ 113 case 0: // success 114 return ERROR_CODE_SUCCESS; 115 case -1: // PLC engaged 116 *BEC_detect = 1; 117 return ERROR_CODE_SUCCESS; 118 default: 119 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 120 } 121 } 122 123 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 return lc3_decoder_google_decode(context, bytes, byte_count, BFI, LC3_PCM_FORMAT_S16, (void *) pcm_out, stride, BEC_detect); 125 } 126 127 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 return lc3_decoder_google_decode(context, bytes, byte_count, BFI, LC3_PCM_FORMAT_S24, (void *) pcm_out, stride, BEC_detect); 129 } 130 131 static const btstack_lc3_decoder_t btstack_l3c_decoder_google_instance = { 132 lc3_decoder_google_configure, 133 lc3_decoder_google_get_number_octets_for_bitrate, 134 lc3_decoder_google_get_number_samples_per_frame, 135 lc3_decoder_google_decode_signed_16, 136 lc3_decoder_google_decode_signed_24 137 }; 138 139 const btstack_lc3_decoder_t * btstack_lc3_decoder_google_init_instance(btstack_lc3_decoder_google_t * context){ 140 memset(context, 0, sizeof(btstack_lc3_decoder_google_t)); 141 return &btstack_l3c_decoder_google_instance; 142 } 143 144 /* Encoder implementation */ 145 146 static uint8_t lc3_encoder_google_configure(void * context, uint32_t sample_rate, btstack_lc3_frame_duration_t frame_duration){ 147 btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context; 148 149 // map frame duration 150 uint16_t duration_us = lc3_frame_duration_in_us(frame_duration); 151 if (duration_us == 0){ 152 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 153 } 154 155 // store config 156 instance->sample_rate = sample_rate; 157 instance->frame_duration = frame_duration; 158 159 // config encoder 160 instance->encoder = lc3_setup_encoder(duration_us, sample_rate, 0, &instance->encoder_mem); 161 162 if (instance->encoder == NULL) { 163 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 164 } 165 166 return ERROR_CODE_SUCCESS; 167 } 168 169 static uint32_t lc3_encoder_google_get_bitrate_for_number_of_octets(void * context, uint16_t number_of_octets){ 170 btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context; 171 // map frame duration 172 uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration); 173 if (duration_us == 0){ 174 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 175 } 176 return lc3_resolve_bitrate(duration_us, number_of_octets); 177 } 178 179 static uint16_t lc3_encoder_google_get_number_samples_per_frame(void * context){ 180 btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context; 181 // map frame duration 182 uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration); 183 if (duration_us == 0){ 184 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 185 } 186 return lc3_frame_samples(duration_us, instance->sample_rate); 187 } 188 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 btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context; 190 int result = lc3_encode(instance->encoder, fmt, pcm_in, stride, byte_count, (void*) bytes); 191 switch (result){ 192 case 0: 193 return ERROR_CODE_SUCCESS; 194 default: 195 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 196 } 197 } 198 199 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 return lc3_encoder_google_encode_signed(context, LC3_PCM_FORMAT_S16, (const void *) pcm_in, stride, bytes, byte_count); 201 } 202 203 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 return lc3_encoder_google_encode_signed(context, LC3_PCM_FORMAT_S24, (const void *) pcm_in, stride, bytes, byte_count); 205 } 206 207 static const btstack_lc3_encoder_t btstack_l3c_encoder_google_instance = { 208 lc3_encoder_google_configure, 209 lc3_encoder_google_get_bitrate_for_number_of_octets, 210 lc3_encoder_google_get_number_samples_per_frame, 211 lc3_encoder_google_encode_signed_16, 212 lc3_encoder_google_encode_signed_24 213 }; 214 215 const btstack_lc3_encoder_t * btstack_lc3_encoder_google_init_instance(btstack_lc3_encoder_google_t * context){ 216 memset(context, 0, sizeof(btstack_lc3_encoder_google_t)); 217 return &btstack_l3c_encoder_google_instance; 218 } 219 220