btstack_sbc: introduce btstack_sbc_channel_mode_t and btstack_sbc_allocation_method_t

This commit is contained in:
Milanka Ringwald 2020-11-19 13:25:14 +01:00
parent 79654d96bb
commit 79b02f79ab
9 changed files with 112 additions and 48 deletions

View File

@ -131,18 +131,18 @@ static char * sbc_filename = "av2dp_sink_demo.sbc";
typedef struct {
int reconfigure;
int num_channels;
int sampling_frequency;
int channel_mode;
int block_length;
int subbands;
int allocation_method;
int min_bitpool_value;
int max_bitpool_value;
int frames_per_buffer;
} avdtp_media_codec_configuration_sbc_t;
btstack_sbc_channel_mode_t channel_mode;
btstack_sbc_allocation_method_t allocation_method;
} media_codec_configuration_sbc_t;
static avdtp_media_codec_configuration_sbc_t sbc_configuration;
static media_codec_configuration_sbc_t sbc_configuration;
static int volume_percentage = 0;
#ifdef SUPPORT_VOLUME_CHANGE_NOTIFICATION
@ -378,7 +378,7 @@ static void handle_pcm_data(int16_t * data, int num_audio_frames, int num_channe
}
}
static int media_processing_init(avdtp_media_codec_configuration_sbc_t configuration){
static int media_processing_init(media_codec_configuration_sbc_t configuration){
if (media_initialized) return 0;
btstack_sbc_decoder_init(&state, mode, handle_pcm_data, NULL);
@ -569,7 +569,7 @@ static int read_media_data_header(uint8_t *packet, int size, int *offset, avdtp_
return 1;
}
static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t configuration){
static void dump_sbc_configuration(media_codec_configuration_sbc_t configuration){
printf(" - num_channels: %d\n", configuration.num_channels);
printf(" - sampling_frequency: %d\n", configuration.sampling_frequency);
printf(" - channel_mode: %d\n", configuration.channel_mode);
@ -857,6 +857,9 @@ static void a2dp_sink_packet_handler(uint8_t packet_type, uint16_t channel, uint
bd_addr_t address;
uint8_t status;
uint8_t channel_mode;
uint8_t allocation_method;
if (packet_type != HCI_EVENT_PACKET) return;
if (hci_event_packet_get_type(packet) != HCI_EVENT_A2DP_META) return;
@ -869,13 +872,35 @@ static void a2dp_sink_packet_handler(uint8_t packet_type, uint16_t channel, uint
sbc_configuration.reconfigure = a2dp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
sbc_configuration.num_channels = a2dp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet);
sbc_configuration.sampling_frequency = a2dp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
sbc_configuration.channel_mode = a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
sbc_configuration.block_length = a2dp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
sbc_configuration.subbands = a2dp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
sbc_configuration.allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
sbc_configuration.min_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet);
sbc_configuration.max_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
sbc_configuration.frames_per_buffer = sbc_configuration.subbands * sbc_configuration.block_length;
allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
channel_mode = a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
// Adapt Bluetooth spec definition to SBC Encoder expected input
sbc_configuration.allocation_method = (btstack_sbc_allocation_method_t)(allocation_method - 1);
sbc_configuration.num_channels = SBC_CHANNEL_MODE_STEREO;
switch (channel_mode){
case AVDTP_SBC_JOINT_STEREO:
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
break;
case AVDTP_SBC_STEREO:
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_STEREO;
break;
case AVDTP_SBC_DUAL_CHANNEL:
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
break;
case AVDTP_SBC_MONO:
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_MONO;
sbc_configuration.num_channels = 1;
break;
default:
btstack_assert(false);
break;
}
dump_sbc_configuration(sbc_configuration);
if (sbc_configuration.reconfigure){

View File

@ -150,16 +150,16 @@ static const int num_samples_sine_int16_48000 = sizeof(sine_int16_48000) / 2;
typedef struct {
int reconfigure;
int num_channels;
int sampling_frequency;
int channel_mode;
int block_length;
int subbands;
int allocation_method;
int min_bitpool_value;
int max_bitpool_value;
int frames_per_buffer;
} avdtp_media_codec_configuration_sbc_t;
btstack_sbc_channel_mode_t channel_mode;
btstack_sbc_allocation_method_t allocation_method;
} media_codec_configuration_sbc_t;
static btstack_packet_callback_registration_t hci_event_callback_registration;
@ -184,7 +184,7 @@ static uint8_t sdp_avrcp_target_service_buffer[200];
static uint8_t sdp_avrcp_controller_service_buffer[200];
static uint8_t device_id_sdp_service_buffer[100];
static avdtp_media_codec_configuration_sbc_t sbc_configuration;
static media_codec_configuration_sbc_t sbc_configuration;
static btstack_sbc_encoder_state_t sbc_encoder_state;
static uint8_t media_sbc_codec_configuration[4];
@ -510,7 +510,7 @@ static void a2dp_demo_timer_stop(a2dp_media_sending_context_t * context){
btstack_run_loop_remove_timer(&context->audio_timer);
}
static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t * configuration){
static void dump_sbc_configuration(media_codec_configuration_sbc_t * configuration){
printf("Received media codec configuration:\n");
printf(" - num_channels: %d\n", configuration->num_channels);
printf(" - sampling_frequency: %d\n", configuration->sampling_frequency);
@ -554,6 +554,9 @@ static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, ui
bd_addr_t address;
uint16_t cid;
uint8_t channel_mode;
uint8_t allocation_method;
if (packet_type != HCI_EVENT_PACKET) return;
if (hci_event_packet_get_type(packet) != HCI_EVENT_A2DP_META) return;
@ -583,33 +586,34 @@ static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, ui
sbc_configuration.reconfigure = a2dp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
sbc_configuration.num_channels = a2dp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet);
sbc_configuration.sampling_frequency = a2dp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
sbc_configuration.channel_mode = a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
sbc_configuration.block_length = a2dp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
sbc_configuration.subbands = a2dp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
sbc_configuration.allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
sbc_configuration.min_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet);
sbc_configuration.max_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
sbc_configuration.frames_per_buffer = sbc_configuration.subbands * sbc_configuration.block_length;
channel_mode = a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
printf("A2DP Source: Received SBC codec configuration, sampling frequency %u, a2dp_cid 0x%02x, local seid 0x%02x, remote seid 0x%02x.\n",
sbc_configuration.sampling_frequency, cid,
a2dp_subevent_signaling_media_codec_sbc_configuration_get_int_seid(packet),
a2dp_subevent_signaling_media_codec_sbc_configuration_get_acp_seid(packet));
// Adapt Bluetooth spec definition to SBC Encoder expected input
sbc_configuration.allocation_method -= 1;
sbc_configuration.num_channels = 2;
switch (sbc_configuration.channel_mode){
sbc_configuration.allocation_method = (btstack_sbc_allocation_method_t)(allocation_method - 1);
sbc_configuration.num_channels = SBC_CHANNEL_MODE_STEREO;
switch (channel_mode){
case AVDTP_SBC_JOINT_STEREO:
sbc_configuration.channel_mode = 3;
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
break;
case AVDTP_SBC_STEREO:
sbc_configuration.channel_mode = 2;
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_STEREO;
break;
case AVDTP_SBC_DUAL_CHANNEL:
sbc_configuration.channel_mode = 1;
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
break;
case AVDTP_SBC_MONO:
sbc_configuration.channel_mode = 0;
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_MONO;
sbc_configuration.num_channels = 1;
break;
default:

View File

@ -50,11 +50,23 @@
extern "C" {
#endif
typedef enum{
SBC_MODE_STANDARD,
typedef enum {
SBC_MODE_STANDARD = 0,
SBC_MODE_mSBC
} btstack_sbc_mode_t;
typedef enum {
SBC_CHANNEL_MODE_MONO = 0,
SBC_CHANNEL_MODE_DUAL_CHANNEL,
SBC_CHANNEL_MODE_STEREO,
SBC_CHANNEL_MODE_JOINT_STEREO
} btstack_sbc_channel_mode_t;
typedef enum {
SBC_ALLOCATION_METHOD_LOUDNESS = 0,
SBC_ALLOCATION_METHOD_SNR
} btstack_sbc_allocation_method_t;
typedef struct {
void * context;
void (*handle_pcm_data)(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context);
@ -126,7 +138,8 @@ int btstack_sbc_decoder_sample_rate(btstack_sbc_decoder_state_t * state);
* @param channel_mode
*/
void btstack_sbc_encoder_init(btstack_sbc_encoder_state_t * state, btstack_sbc_mode_t mode,
int blocks, int subbands, int allocation_method, int sample_rate, int bitpool, int channel_mode);
int blocks, int subbands, btstack_sbc_allocation_method_t allocation_method,
int sample_rate, int bitpool, btstack_sbc_channel_mode_t channel_mode);
/**
* @brief Encode PCM data

View File

@ -72,7 +72,8 @@ static bludroid_encoder_state_t bd_encoder_state;
void btstack_sbc_encoder_init(btstack_sbc_encoder_state_t * state, btstack_sbc_mode_t mode,
int blocks, int subbands, int allmethod, int sample_rate, int bitpool, int channel_mode){
int blocks, int subbands, btstack_sbc_allocation_method_t allocation_method,
int sample_rate, int bitpool, btstack_sbc_channel_mode_t channel_mode){
if (sbc_encoder_state_singleton && (sbc_encoder_state_singleton != state) ){
log_error("SBC encoder: different sbc decoder state is allready registered");
@ -90,10 +91,10 @@ void btstack_sbc_encoder_init(btstack_sbc_encoder_state_t * state, btstack_sbc_m
case SBC_MODE_STANDARD:
bd_encoder_state.context.s16NumOfBlocks = blocks;
bd_encoder_state.context.s16NumOfSubBands = subbands;
bd_encoder_state.context.s16AllocationMethod = allmethod;
bd_encoder_state.context.s16AllocationMethod = (uint8_t)allocation_method;
bd_encoder_state.context.s16BitPool = bitpool;
bd_encoder_state.context.mSBCEnabled = 0;
bd_encoder_state.context.s16ChannelMode = channel_mode;
bd_encoder_state.context.s16ChannelMode = (uint8_t)channel_mode;
bd_encoder_state.context.s16NumOfChannels = 2;
if (bd_encoder_state.context.s16ChannelMode == SBC_MONO){
bd_encoder_state.context.s16NumOfChannels = 1;

View File

@ -66,7 +66,7 @@ static uint8_t msbc_buffer[2*(MSBC_FRAME_SIZE + MSBC_EXTRA_SIZE)];
static int msbc_buffer_offset = 0;
void hfp_msbc_init(void){
btstack_sbc_encoder_init(&state, SBC_MODE_mSBC, 16, 8, 0, 16000, 26, 0);
btstack_sbc_encoder_init(&state, SBC_MODE_mSBC, 16, 8, SBC_ALLOCATION_METHOD_LOUDNESS, 16000, 26, SBC_CHANNEL_MODE_MONO);
msbc_buffer_offset = 0;
msbc_sequence_number = 0;
}

View File

@ -106,7 +106,7 @@ int btstack_main(int argc, const char * argv[]);
int btstack_main(int argc, const char * argv[]){
(void) argc;
(void) argv;
btstack_sbc_encoder_init(&sbc_encoder_state, SBC_MODE_STANDARD, 16, 8, 2, 44100, 53);
btstack_sbc_encoder_init(&sbc_encoder_state, SBC_MODE_STANDARD, 16, 8, SBC_ALLOCATION_METHOD_LOUDNESS, 44100, 53, SBC_CHANNEL_MODE_STEREO);
/* initialise sinusoidal wavetable */
int i;

View File

@ -224,7 +224,7 @@ int btstack_main(int argc, const char * argv[]){
(void) argc;
(void) argv;
local_stream_endpoint = avdtp_source_create_stream_endpoint(AVDTP_SOURCE, AVDTP_AUDIO);
btstack_sbc_encoder_init(&(local_stream_endpoint->sbc_encoder_state), SBC_MODE_STANDARD, 16, 8, 2, 44100, 53);
btstack_sbc_encoder_init(&(local_stream_endpoint->sbc_encoder_state), SBC_MODE_STANDARD, 16, 8, SBC_ALLOCATION_METHOD_LOUDNESS, 44100, 53, SBC_CHANNEL_MODE_STEREO);
/* initialise sinusoidal wavetable */
int i;

View File

@ -110,7 +110,7 @@ int btstack_main(int argc, const char * argv[]);
int btstack_main(int argc, const char * argv[]){
(void) argc;
(void) argv;
btstack_sbc_encoder_init(&sbc_encoder_state, SBC_MODE_STANDARD, 16, 8, 2, 44100, 53);
btstack_sbc_encoder_init(&sbc_encoder_state, SBC_MODE_STANDARD, 16, 8, SBC_ALLOCATION_METHOD_LOUDNESS, 44100, 53, SBC_CHANNEL_MODE_STEREO);
/* initialise sinusoidal wavetable */
int i;

View File

@ -209,16 +209,16 @@ typedef struct {
typedef struct {
int reconfigure;
int num_channels;
int sampling_frequency;
int channel_mode;
int block_length;
int subbands;
int allocation_method;
int min_bitpool_value;
int max_bitpool_value;
int frames_per_buffer;
} avdtp_media_codec_configuration_sbc_t;
btstack_sbc_channel_mode_t channel_mode;
btstack_sbc_allocation_method_t allocation_method;
} media_codec_configuration_sbc_t;
static uint8_t ertm_buffer[10000];
@ -329,7 +329,7 @@ avrcp_track_t tracks[] = {
};
int current_track_index;
avrcp_play_status_info_t play_info;
static avdtp_media_codec_configuration_sbc_t sbc_configuration;
static media_codec_configuration_sbc_t sbc_configuration;
static btstack_sbc_encoder_state_t sbc_encoder_state;
static uint8_t media_sbc_codec_configuration[4];
@ -398,6 +398,9 @@ static void avdtp_source_connection_establishment_packet_handler(uint8_t packet_
bd_addr_t address;
uint16_t cid;
uint8_t channel_mode;
uint8_t allocation_method;
if (packet_type != HCI_EVENT_PACKET) return;
switch (hci_event_packet_get_type(packet)){
case HCI_EVENT_PIN_CODE_REQUEST:
@ -450,24 +453,42 @@ static void avdtp_source_connection_establishment_packet_handler(uint8_t packet_
sbc_configuration.reconfigure = avdtp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
sbc_configuration.num_channels = avdtp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet);
sbc_configuration.sampling_frequency = avdtp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
sbc_configuration.channel_mode = avdtp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
sbc_configuration.block_length = avdtp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
sbc_configuration.subbands = avdtp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
sbc_configuration.allocation_method = avdtp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
sbc_configuration.min_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet);
sbc_configuration.max_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
sbc_configuration.frames_per_buffer = sbc_configuration.subbands * sbc_configuration.block_length;
allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
channel_mode = a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
// Adapt Bluetooth spec definition to SBC Encoder expected input
sbc_configuration.allocation_method = (btstack_sbc_allocation_method_t)(allocation_method - 1);
sbc_configuration.num_channels = SBC_CHANNEL_MODE_STEREO;
switch (channel_mode){
case AVDTP_SBC_JOINT_STEREO:
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
break;
case AVDTP_SBC_STEREO:
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_STEREO;
break;
case AVDTP_SBC_DUAL_CHANNEL:
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
break;
case AVDTP_SBC_MONO:
sbc_configuration.channel_mode = SBC_CHANNEL_MODE_MONO;
sbc_configuration.num_channels = 1;
break;
default:
btstack_assert(false);
break;
}
btstack_sbc_encoder_init(&sbc_encoder_state, SBC_MODE_STANDARD,
sbc_configuration.block_length, sbc_configuration.subbands,
sbc_configuration.allocation_method, sbc_configuration.sampling_frequency,
sbc_configuration.max_bitpool_value,
sbc_configuration.channel_mode);
// status = a2dp_source_establish_stream(device_addr, media_tracker.local_seid, &media_tracker.a2dp_cid);
// if (status != ERROR_CODE_SUCCESS){
// printf("Could not perform command, status 0x%2x\n", status);
// }
break;
}