From 9b9478570b17b17a7daa8928a66ca051c3a3b440 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 21 Apr 2022 12:30:28 +0200 Subject: [PATCH] lc3: provide separate functions for 16 vs. 24 bit PCM samples --- src/btstack_lc3.h | 33 +++++++++++++++++++--- src/btstack_lc3_ehima.cpp | 34 ++++++++++++++++++++--- test/lc3/lc3_decoder_ehima.c | 2 +- test/lc3/lc3_encoder_ehima.c | 2 +- test/le_audio/le_audio_broadcast_sink.c | 2 +- test/le_audio/le_audio_broadcast_source.c | 2 +- test/le_audio/le_audio_unicast_sink.c | 2 +- test/le_audio/le_audio_unicast_source.c | 2 +- 8 files changed, 65 insertions(+), 14 deletions(-) diff --git a/src/btstack_lc3.h b/src/btstack_lc3.h index af67f9caf..2a43d9b97 100644 --- a/src/btstack_lc3.h +++ b/src/btstack_lc3.h @@ -80,7 +80,7 @@ typedef struct { uint16_t (*get_number_samples_per_frame)(void * context); /** - * Decode LC3 Frame + * Decode LC3 Frame into signed 16-bit samples * @param context * @param bytes * @param byte_count @@ -90,9 +90,23 @@ typedef struct { * @param BEC_detect Bit Error Detected flag * @return status */ - uint8_t (*decode)(void * context, const uint8_t *bytes, uint16_t byte_count, uint8_t BFI, + uint8_t (*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); + /** + * Decode LC3 Frame into signed 24-bit samples, sign-extended to 32-bit + * @param context + * @param bytes + * @param byte_count + * @param BFI Bad Frame Indication flags + * @param pcm_out buffer for decoded PCM samples + * @param stride count between two consecutive samples + * @param BEC_detect Bit Error Detected flag + * @return status + */ + uint8_t (*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); + } btstack_lc3_decoder_t; typedef struct { @@ -122,7 +136,7 @@ typedef struct { uint16_t (*get_number_samples_per_frame)(void * context); /** - * Encode LC3 Frame + * Encode LC3 Frame with 16-bit signed PCM samples * @param context * @param pcm_in buffer for decoded PCM samples * @param stride count between two consecutive samples @@ -130,7 +144,18 @@ typedef struct { * @param byte_count * @return status */ - uint8_t (*encode)(void * context, const int16_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count); + uint8_t (*encode_signed_16)(void * context, const int16_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count); + + /** + * Encode LC3 Frame with 24-bit signed PCM samples, sign-extended to 32 bit + * @param context + * @param pcm_in buffer for decoded PCM samples + * @param stride count between two consecutive samples + * @param bytes + * @param byte_count + * @return status + */ + uint8_t (*encode_signed_24)(void * context, const int32_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count); } btstack_lc3_encoder_t; diff --git a/src/btstack_lc3_ehima.cpp b/src/btstack_lc3_ehima.cpp index 3d8ca4635..39ada1846 100644 --- a/src/btstack_lc3_ehima.cpp +++ b/src/btstack_lc3_ehima.cpp @@ -41,6 +41,7 @@ #ifdef HAVE_LC3_EHIMA #include "btstack_lc3_ehima.h" +#include "btstack_debug.h" #include #include #include @@ -90,19 +91,32 @@ static uint16_t lc3_decoder_ehima_get_number_samples_per_frame(void * context){ return decoder->lc3Config.NF; } -static uint8_t lc3_decoder_ehima_decode(void * context, const uint8_t *bytes, uint16_t byte_count, uint8_t BFI, int16_t* pcm_out, uint16_t stride, uint8_t * BEC_detect){ +static uint8_t lc3_decoder_ehima_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){ (void)stride; lc3_decoder_ehima_t * instance = static_cast(context); Lc3Decoder * decoder = static_cast(instance->decoder); uint8_t res = decoder->run(bytes, byte_count, BFI, pcm_out, decoder->lc3Config.NF, *BEC_detect); return ERROR_CODE_SUCCESS; } +static uint8_t lc3_decoder_ehima_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) { + (void)context; + (void)bytes; + (void)byte_count; + (void)BFI; + (void)pcm_out; + (void)stride; + (void)BEC_detect; + // not implemented yet + btstack_assert(false); + return ERROR_CODE_COMMAND_DISALLOWED; +} static const btstack_lc3_decoder_t l3c_decoder_ehima_instance = { lc3_decoder_ehima_configure, lc3_decoder_ehima_get_number_octets_for_bitrate, lc3_decoder_ehima_get_number_samples_per_frame, - lc3_decoder_ehima_decode + lc3_decoder_ehima_decode_signed_16, + lc3_decoder_ehima_decode_signed_24 }; const btstack_lc3_decoder_t * lc3_decoder_ehima_init_instance(lc3_decoder_ehima_t * context){ @@ -158,7 +172,7 @@ static uint16_t lc3_encoder_ehima_get_number_samples_per_frame(void * context){ return encoder->lc3Config.NF; } -static uint8_t lc3_encoder_ehima_encode(void * context, const int16_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count){ +static uint8_t lc3_encoder_ehima_encode_signed_16(void * context, const int16_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count){ (void)stride; lc3_encoder_ehima_t * instance = static_cast(context); Lc3Encoder * encoder = static_cast(instance->encoder); @@ -166,11 +180,23 @@ static uint8_t lc3_encoder_ehima_encode(void * context, const int16_t* pcm_in, u return ERROR_CODE_SUCCESS; } +static uint8_t lc3_encoder_ehima_encode_signed_24(void * context, const int32_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count){ + (void)context; + (void)pcm_in; + (void)stride; + (void)bytes; + (void)byte_count; + // not implemented + btstack_assert(false); + return ERROR_CODE_COMMAND_DISALLOWED; +} + static const btstack_lc3_encoder_t l3c_encoder_ehima_instance = { lc3_encoder_ehima_configure, lc3_encoder_ehima_get_bitrate_for_number_of_octets, lc3_encoder_ehima_get_number_samples_per_frame, - lc3_encoder_ehima_encode + lc3_encoder_ehima_encode_signed_16, + lc3_encoder_ehima_encode_signed_24 }; const btstack_lc3_encoder_t * lc3_encoder_ehima_init_instance(lc3_encoder_ehima_t * context){ diff --git a/test/lc3/lc3_decoder_ehima.c b/test/lc3/lc3_decoder_ehima.c index a777c6ba9..d74c44e7c 100644 --- a/test/lc3/lc3_decoder_ehima.c +++ b/test/lc3/lc3_decoder_ehima.c @@ -212,7 +212,7 @@ int main (int argc, const char * argv[]){ uint8_t tmp_BEC_detect; uint8_t BFI = 0; - uint8_t status = lc3_decoder->decode(&decoder_contexts[channel], read_buffer, bytes_per_frame, BFI, &pcm[channel * MAX_SAMPLES_PER_FRAME], 1, &tmp_BEC_detect); + uint8_t status = lc3_decoder->decode_signed_16(&decoder_contexts[channel], read_buffer, bytes_per_frame, BFI, &pcm[channel * MAX_SAMPLES_PER_FRAME], 1, &tmp_BEC_detect); if (status != ERROR_CODE_SUCCESS){ printf("Error %u\n", status); done = true; diff --git a/test/lc3/lc3_encoder_ehima.c b/test/lc3/lc3_encoder_ehima.c index 619f4f443..924faabbc 100644 --- a/test/lc3/lc3_encoder_ehima.c +++ b/test/lc3/lc3_encoder_ehima.c @@ -168,7 +168,7 @@ int main (int argc, const char * argv[]){ for (sample = 0 ; sample < number_samples_per_frame ; sample++){ frame_buffer[sample] = samples_buffer[ sample * num_channels + channel]; } - status = lc3_encoder->encode(&encoder_contexts[channel], frame_buffer, 1, write_buffer, bytes_per_frame); + status = lc3_encoder->encode_signed_16(&encoder_contexts[channel], frame_buffer, 1, write_buffer, bytes_per_frame); if (status != ERROR_CODE_SUCCESS){ printf("Error %u\n", status); break; diff --git a/test/le_audio/le_audio_broadcast_sink.c b/test/le_audio/le_audio_broadcast_sink.c index a3400da3a..15c8f4621 100644 --- a/test/le_audio/le_audio_broadcast_sink.c +++ b/test/le_audio/le_audio_broadcast_sink.c @@ -598,7 +598,7 @@ static void iso_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p // decode codec frame uint8_t tmp_BEC_detect; uint8_t BFI = 0; - (void) lc3_decoder->decode(&decoder_contexts[bis_channel], &packet[offset], iso_sdu_length, BFI, + (void) lc3_decoder->decode_signed_16(&decoder_contexts[bis_channel], &packet[offset], iso_sdu_length, BFI, &pcm[bis_channel * MAX_SAMPLES_PER_FRAME], 1, &tmp_BEC_detect); diff --git a/test/le_audio/le_audio_broadcast_source.c b/test/le_audio/le_audio_broadcast_source.c index 7031625e5..18f7e583b 100644 --- a/test/le_audio/le_audio_broadcast_source.c +++ b/test/le_audio/le_audio_broadcast_source.c @@ -446,7 +446,7 @@ static void encode_and_send(uint8_t bis_index){ memset(&buffer[9], iso_frame_counter, octets_per_frame - 1); #else // encode as lc3 - lc3_encoder->encode(&encoder_contexts[bis_index], &pcm[bis_index * MAX_SAMPLES_PER_FRAME], 1, &buffer[8], octets_per_frame); + lc3_encoder->encode_signed_16(&encoder_contexts[bis_index], &pcm[bis_index * MAX_SAMPLES_PER_FRAME], 1, &buffer[8], octets_per_frame); #endif // send hci_send_iso_packet_buffer(4 + 0 + 4 + octets_per_frame); diff --git a/test/le_audio/le_audio_unicast_sink.c b/test/le_audio/le_audio_unicast_sink.c index 5cf80c354..5c30f6007 100644 --- a/test/le_audio/le_audio_unicast_sink.c +++ b/test/le_audio/le_audio_unicast_sink.c @@ -581,7 +581,7 @@ static void iso_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p // decode codec frame uint8_t tmp_BEC_detect; uint8_t BFI = 0; - (void) lc3_decoder->decode(&decoder_contexts[channel], &packet[offset], octets_per_frame, BFI, + (void) lc3_decoder->decode_signed_16(&decoder_contexts[channel], &packet[offset], octets_per_frame, BFI, &pcm[channel * MAX_SAMPLES_PER_FRAME], 1, &tmp_BEC_detect); offset += octets_per_frame; diff --git a/test/le_audio/le_audio_unicast_source.c b/test/le_audio/le_audio_unicast_source.c index 377959a06..0cd5810aa 100644 --- a/test/le_audio/le_audio_unicast_source.c +++ b/test/le_audio/le_audio_unicast_source.c @@ -366,7 +366,7 @@ static void encode_and_send(uint8_t cis_index){ uint8_t channel; uint16_t offset = 8; for (channel = 0; channel < num_channels; channel++){ - lc3_encoder->encode(&encoder_contexts[channel], &pcm[channel * MAX_SAMPLES_PER_FRAME], 1, &buffer[offset], octets_per_frame); + lc3_encoder->encode_signed_16(&encoder_contexts[channel], &pcm[channel * MAX_SAMPLES_PER_FRAME], 1, &buffer[offset], octets_per_frame); offset += octets_per_frame; } #endif