avdtp: use frequency in hz and general channel mode for sbc config

This commit is contained in:
Matthias Ringwald 2020-12-22 17:38:17 +01:00
parent 8226b499f4
commit 80dc008856
4 changed files with 68 additions and 39 deletions

View File

@ -369,13 +369,13 @@ static void a2dp_source_packet_handler_internal(uint8_t packet_type, uint16_t ch
// select SEP if none configured yet
if (a2dp_source_have_config == false){
// choose SBC config params
uint8_t sampling_frequency = avdtp_choose_sbc_sampling_frequency(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet));
uint8_t channel_mode = avdtp_choose_sbc_channel_mode(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet));
uint8_t block_length = avdtp_choose_sbc_block_length(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_block_length_bitmap(packet));
uint8_t subbands = avdtp_choose_sbc_subbands(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_subbands_bitmap(packet));
uint8_t allocation_method = avdtp_choose_sbc_allocation_method(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_allocation_method_bitmap(packet));
uint8_t max_bitpool_value = avdtp_choose_sbc_max_bitpool_value(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_max_bitpool_value(packet));
uint8_t min_bitpool_value = avdtp_choose_sbc_min_bitpool_value(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_min_bitpool_value(packet));
uint16_t sampling_frequency = avdtp_choose_sbc_sampling_frequency(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet));
avdtp_channel_mode_t channel_mode = avdtp_choose_sbc_channel_mode(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet));
uint8_t block_length = avdtp_choose_sbc_block_length(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_block_length_bitmap(packet));
uint8_t subbands = avdtp_choose_sbc_subbands(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_subbands_bitmap(packet));
avdtp_sbc_allocation_method_t allocation_method = avdtp_choose_sbc_allocation_method(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_allocation_method_bitmap(packet));
uint8_t max_bitpool_value = avdtp_choose_sbc_max_bitpool_value(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_max_bitpool_value(packet));
uint8_t min_bitpool_value = avdtp_choose_sbc_min_bitpool_value(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_min_bitpool_value(packet));
// and pre-select this (safe) endpoint
uint8_t local_seid = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
@ -810,9 +810,39 @@ uint8_t a2dp_source_stream_send_media_packet(uint16_t a2dp_cid, uint8_t local_se
return avdtp_source_stream_send_media_packet(a2dp_cid, local_seid, packet, size);
}
static void avdtp_config_sbc_store(uint8_t * config, uint16_t sampling_frequency, avdtp_sbc_channel_mode_t channel_mode, uint8_t block_length, uint8_t subbands,
static void avdtp_config_sbc_store(uint8_t * config, uint16_t sampling_frequency_hz, avdtp_channel_mode_t channel_mode, uint8_t block_length, uint8_t subbands,
avdtp_sbc_allocation_method_t allocation_method, uint8_t min_bitpool_value, uint8_t max_bitpool_value) {
config[0] = (sampling_frequency << 4) | channel_mode;
avdtp_sbc_sampling_frequency_t sampling_frequency;
switch (sampling_frequency_hz){
case 16000:
sampling_frequency = AVDTP_SBC_16000;
break;
case 32000:
sampling_frequency = AVDTP_SBC_32000;
break;
case 48000:
sampling_frequency = AVDTP_SBC_48000;
break;
default:
sampling_frequency = AVDTP_SBC_44100;
break;
}
avdtp_sbc_channel_mode_t sbc_channel_mode;
switch (channel_mode){
case AVDTP_CHANNEL_MODE_MONO:
sbc_channel_mode = AVDTP_SBC_MONO;
break;
case AVDTP_CHANNEL_MODE_DUAL_CHANNEL:
sbc_channel_mode = AVDTP_SBC_DUAL_CHANNEL;
break;
case AVDTP_CHANNEL_MODE_STEREO:
sbc_channel_mode = AVDTP_SBC_STEREO;
break;
default:
sbc_channel_mode = AVDTP_SBC_JOINT_STEREO;
break;
}
config[0] = (((uint8_t) sampling_frequency) << 4) | ((uint8_t) sbc_channel_mode);
config[1] = (block_length << 4) | (subbands << 2) | allocation_method;
config[2] = min_bitpool_value;
config[3] = max_bitpool_value;
@ -930,8 +960,8 @@ static void a2dp_source_config_init(uint8_t remote_seid, avdtp_media_codec_type_
a2dp_source_have_config = true;
}
uint8_t a2dp_source_set_config_sbc(uint16_t a2dp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t sampling_frequency, avdtp_sbc_channel_mode_t channel_mode,
uint8_t block_length, uint8_t subbands, avdtp_sbc_allocation_method_t allocation_method, uint8_t min_bitpool_value, uint8_t max_bitpool_value){
uint8_t a2dp_source_set_config_sbc(uint16_t a2dp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t sampling_frequency, avdtp_channel_mode_t channel_mode,
uint8_t block_length, uint8_t subbands, avdtp_sbc_allocation_method_t allocation_method, uint8_t min_bitpool_value, uint8_t max_bitpool_value){
UNUSED(local_seid);

View File

@ -198,7 +198,7 @@ uint8_t a2dp_source_stream_send_media_packet(uint16_t a2dp_cid, uint8_t local_se
* @param max_bitpool_value
* @return status
*/
uint8_t a2dp_source_set_config_sbc(uint16_t a2dp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t sampling_frequency, avdtp_sbc_channel_mode_t channel_mode,
uint8_t a2dp_source_set_config_sbc(uint16_t a2dp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t sampling_frequency, avdtp_channel_mode_t channel_mode,
uint8_t block_length, uint8_t subbands, avdtp_sbc_allocation_method_t allocation_method, uint8_t min_bitpool_value, uint8_t max_bitpool_value);
/**

View File

@ -1325,41 +1325,40 @@ void avdtp_set_preferred_channel_mode(avdtp_stream_endpoint_t * stream_endpoi
}
uint8_t avdtp_choose_sbc_channel_mode(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_channel_mode_bitmap){
avdtp_channel_mode_t avdtp_choose_sbc_channel_mode(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_channel_mode_bitmap){
uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information;
uint8_t channel_mode_bitmap = (media_codec[0] & 0x0F) & remote_channel_mode_bitmap;
uint8_t channel_mode = AVDTP_SBC_STEREO;
// use preferred channel mode if possible
if (stream_endpoint->preferred_channel_mode == AVDTP_SBC_JOINT_STEREO){
return AVDTP_SBC_JOINT_STEREO;
return AVDTP_CHANNEL_MODE_JOINT_STEREO;
}
if (stream_endpoint->preferred_channel_mode == AVDTP_SBC_STEREO){
return AVDTP_SBC_STEREO;
return AVDTP_CHANNEL_MODE_STEREO;
}
if (stream_endpoint->preferred_channel_mode == AVDTP_SBC_DUAL_CHANNEL){
return AVDTP_SBC_DUAL_CHANNEL;
return AVDTP_CHANNEL_MODE_DUAL_CHANNEL;
}
if (stream_endpoint->preferred_channel_mode == AVDTP_SBC_MONO){
return AVDTP_SBC_MONO;
return AVDTP_CHANNEL_MODE_MONO;
}
if (channel_mode_bitmap & AVDTP_SBC_JOINT_STEREO){
channel_mode = AVDTP_SBC_JOINT_STEREO;
return AVDTP_CHANNEL_MODE_JOINT_STEREO;
} else if (channel_mode_bitmap & AVDTP_SBC_STEREO){
channel_mode = AVDTP_SBC_STEREO;
return AVDTP_CHANNEL_MODE_STEREO;
} else if (channel_mode_bitmap & AVDTP_SBC_DUAL_CHANNEL){
channel_mode = AVDTP_SBC_DUAL_CHANNEL;
return AVDTP_CHANNEL_MODE_DUAL_CHANNEL;
} else if (channel_mode_bitmap & AVDTP_SBC_MONO){
channel_mode = AVDTP_SBC_MONO;
return AVDTP_CHANNEL_MODE_MONO;
}
return channel_mode;
return AVDTP_CHANNEL_MODE_JOINT_STEREO;
}
uint8_t avdtp_choose_sbc_allocation_method(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_allocation_method_bitmap){
avdtp_sbc_allocation_method_t avdtp_choose_sbc_allocation_method(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_allocation_method_bitmap){
uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information;
uint8_t allocation_method_bitmap = (media_codec[1] & 0x03) & remote_allocation_method_bitmap;
avdtp_sbc_allocation_method_t allocation_method_bitmap = (media_codec[1] & 0x03) & remote_allocation_method_bitmap;
uint8_t allocation_method = AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS;
if (allocation_method_bitmap & AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS){
@ -1406,39 +1405,39 @@ uint8_t avdtp_choose_sbc_block_length(avdtp_stream_endpoint_t * stream_endpoint,
return block_length;
}
uint8_t avdtp_choose_sbc_sampling_frequency(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_sampling_frequency_bitmap){
uint16_t avdtp_choose_sbc_sampling_frequency(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_sampling_frequency_bitmap){
if (!stream_endpoint) return 0;
uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information;
uint8_t supported_sampling_frequency_bitmap = (media_codec[0] >> 4) & remote_sampling_frequency_bitmap;
// use preferred sampling frequency if possible
if ((stream_endpoint->preferred_sampling_frequency == 48000) && (supported_sampling_frequency_bitmap & AVDTP_SBC_48000)){
return AVDTP_SBC_48000;
return stream_endpoint->preferred_sampling_frequency;
}
if ((stream_endpoint->preferred_sampling_frequency == 44100) && (supported_sampling_frequency_bitmap & AVDTP_SBC_44100)){
return AVDTP_SBC_44100;
return stream_endpoint->preferred_sampling_frequency;
}
if ((stream_endpoint->preferred_sampling_frequency == 32000) && (supported_sampling_frequency_bitmap & AVDTP_SBC_32000)){
return AVDTP_SBC_32000;
return stream_endpoint->preferred_sampling_frequency;
}
if ((stream_endpoint->preferred_sampling_frequency == 16000) && (supported_sampling_frequency_bitmap & AVDTP_SBC_16000)){
return AVDTP_SBC_16000;
return stream_endpoint->preferred_sampling_frequency;
}
// otherwise, use highest available
if (supported_sampling_frequency_bitmap & AVDTP_SBC_48000){
return AVDTP_SBC_48000;
return 48000;
}
if (supported_sampling_frequency_bitmap & AVDTP_SBC_44100){
return AVDTP_SBC_44100;
return 44100;
}
if (supported_sampling_frequency_bitmap & AVDTP_SBC_32000){
return AVDTP_SBC_32000;
return 32000;
}
if (supported_sampling_frequency_bitmap & AVDTP_SBC_16000){
return AVDTP_SBC_16000;
return 16000;
}
return AVDTP_SBC_44100; // some default
return 44100; // some default
}
uint8_t avdtp_choose_sbc_max_bitpool_value(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_max_bitpool_value){

View File

@ -629,9 +629,9 @@ void avdtp_set_preferred_channel_mode(avdtp_stream_endpoint_t * stream_endpoi
void avdtp_set_preferred_sbc_channel_mode(avdtp_stream_endpoint_t * stream_endpoint, uint32_t sampling_frequency);
uint8_t avdtp_choose_sbc_channel_mode(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_channel_mode_bitmap);
uint8_t avdtp_choose_sbc_allocation_method(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_allocation_method_bitmap);
uint8_t avdtp_choose_sbc_sampling_frequency(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_sampling_frequency_bitmap);
avdtp_channel_mode_t avdtp_choose_sbc_channel_mode(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_channel_mode_bitmap);
avdtp_sbc_allocation_method_t avdtp_choose_sbc_allocation_method(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_allocation_method_bitmap);
uint16_t avdtp_choose_sbc_sampling_frequency(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_sampling_frequency_bitmap);
uint8_t avdtp_choose_sbc_subbands(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_subbands_bitmap);
uint8_t avdtp_choose_sbc_block_length(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_block_length_bitmap);
uint8_t avdtp_choose_sbc_max_bitpool_value(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_max_bitpool_value);