📄 aud_bt_a2dp.c
字号:
/* function prototypes */
kal_bool aud_bt_a2dp_is_media_type_supported(kal_int16 format);
kal_bool aud_bt_a2dp_is_media_playing(void);
kal_bool aud_bt_a2dp_is_media_available(void);
void aud_bt_a2dp_media_reset_output(kal_bool on);
void aud_bt_a2dp_set_output_on(kal_bool on);
kal_bool aud_bt_a2dp_cmp_audio_config(bt_a2dp_audio_cap_struct *aud_cfg1, bt_a2dp_audio_cap_struct *aud_cfg2);
kal_bool aud_bt_a2dp_get_audio_config(
bt_a2dp_audio_cap_struct *audio_config,
kal_uint8 audio_cap_num,
bt_a2dp_audio_cap_struct *audio_cap_list);
kal_uint8 aud_bt_a2dp_select_remote_seid(kal_uint8 sep_num, bt_sep_info_struct *sep_list);
kal_uint16 aud_bt_a2dp_stream_config_and_open_req(void);
void aud_bt_a2dp_cmd_queue_init(aud_bt_a2dp_cmd_queue_struct *cmd_queue);
void aud_bt_a2dp_cmd_queue_clear(aud_bt_a2dp_cmd_queue_struct *cmd_queue);
kal_uint8 aud_bt_a2dp_cmd_queue_pop(aud_bt_a2dp_cmd_queue_struct *cmd_queue);
void aud_bt_a2dp_cmd_queue_add(aud_bt_a2dp_cmd_queue_struct *cmd_queue, kal_uint8 cmd0, kal_uint8 cmd1);
void aud_bt_a2dp_open_codec(void);
void aud_bt_a2dp_close_codec(void);
void aud_bt_a2dp_reset_state(void);
void aud_bt_a2dp_stream_abort_req(void);
void aud_bt_a2dp_stream_close_req(void);
kal_uint16 aud_bt_a2dp_stream_reconfig_req(void);
void aud_bt_a2dp_stream_start_req(void);
void aud_bt_a2dp_sbc_callback(A2DP_Event event, void *param);
void aud_bt_a2dp_stream_pause_req(void);
void aud_bt_a2dp_open_result(kal_uint16 result);
void aud_bt_a2dp_close_result(kal_uint8 service_status, kal_uint16 mod_id, kal_uint16 result);
kal_bool aud_bt_a2dp_process_cmd(void);
/*****************************************************************************
* FUNCTION
* aud_bt_a2dp_adjust_audio_cap_list
* DESCRIPTION
*
* PARAMETERS
* audio_config [?]
* RETURNS
* void
*****************************************************************************/
void aud_bt_a2dp_adjust_audio_cap_list(bt_a2dp_audio_cap_struct *audio_config)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_uint8 i;
bt_a2dp_sbc_codec_cap_struct *sbc_config, *sbc_cap;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (audio_config->codec_type == BT_A2DP_SBC)
{
sbc_config = &audio_config->codec_cap.sbc;
for (i = 0; i < aud_bt_a2dp_ctx.audio_cap_num; i++)
{
if (aud_bt_a2dp_ctx.audio_cap_list[i].codec_type == BT_A2DP_SBC)
{
sbc_cap = &aud_bt_a2dp_ctx.audio_cap_list[i].codec_cap.sbc;
/* if the bit pool range is exaclty one value, then enlarge our range
* otherwise, copy the bit pool range to ours
*/
if( sbc_cap->min_bit_pool != sbc_cap->max_bit_pool )
{
sbc_cap->min_bit_pool = sbc_config->min_bit_pool;
sbc_cap->max_bit_pool = sbc_config->max_bit_pool;
}
else
{
if( sbc_cap->min_bit_pool > sbc_config->min_bit_pool )
sbc_cap->min_bit_pool = sbc_config->min_bit_pool;
if( sbc_cap->max_bit_pool < sbc_config->max_bit_pool )
sbc_cap->max_bit_pool = sbc_config->max_bit_pool;
}
}
}
}
}
/*****************************************************************************
* FUNCTION
* findFirstValid
* DESCRIPTION
*
* PARAMETERS
* a [IN]
* n [IN]
* RETURNS
*
*****************************************************************************/
static kal_uint32 findFirstValid(kal_uint32 a, int n)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
int I;
kal_uint32 Value = 1;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
for (I = n; I > 0; I--, Value <<= 1)
if (0 != (Value & a))
{
break;
}
ASSERT(I > 0);
return (Value);
}
/*****************************************************************************
* FUNCTION
* aud_bt_a2dp_audio_cap_to_config
* DESCRIPTION
*
* PARAMETERS
* audio_cap [?]
* audio_cfg [?]
* RETURNS
* void
*****************************************************************************/
void aud_bt_a2dp_audio_cap_to_config(bt_a2dp_audio_cap_struct *audio_cap, bt_a2dp_audio_cap_struct *audio_cfg)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
audio_cfg->codec_type = audio_cap->codec_type;
switch (audio_cap->codec_type)
{
case BT_A2DP_SBC:
{
bt_a2dp_sbc_codec_cap_struct *sbc_cap = &audio_cap->codec_cap.sbc;
bt_a2dp_sbc_codec_cap_struct *sbc_cfg = &audio_cfg->codec_cap.sbc;
sbc_cfg->sample_rate = (kal_uint8) findFirstValid(sbc_cap->sample_rate, 4);
sbc_cfg->channel_mode = (kal_uint8) findFirstValid(sbc_cap->channel_mode, 4);
sbc_cfg->block_len = (kal_uint8) findFirstValid(sbc_cap->block_len, 4);
sbc_cfg->subband_num = (kal_uint8) findFirstValid(sbc_cap->subband_num, 2);
sbc_cfg->alloc_method = (kal_uint8) findFirstValid(sbc_cap->alloc_method, 2);
sbc_cfg->min_bit_pool = sbc_cap->min_bit_pool;
sbc_cfg->max_bit_pool = sbc_cap->max_bit_pool;
break;
}
case BT_A2DP_MP3:
{
bt_a2dp_mp3_codec_cap_struct *mp3_cap = &audio_cap->codec_cap.mp3;
bt_a2dp_mp3_codec_cap_struct *mp3_cfg = &audio_cfg->codec_cap.mp3;
mp3_cfg->layer = (kal_uint8) findFirstValid(mp3_cap->layer, 3);
mp3_cfg->CRC = mp3_cap->CRC;
mp3_cfg->channel_mode = (kal_uint8) findFirstValid(mp3_cap->channel_mode, 4);
mp3_cfg->MPF = mp3_cap->MPF;
mp3_cfg->sample_rate = (kal_uint8) findFirstValid(mp3_cap->sample_rate, 6);
mp3_cfg->VBR = mp3_cap->VBR;
mp3_cfg->bit_rate = (kal_uint16) findFirstValid(mp3_cap->bit_rate, 15);
break;
}
case BT_A2DP_AAC:
{
bt_a2dp_aac_codec_cap_struct *aac_cap = &audio_cap->codec_cap.aac;
bt_a2dp_aac_codec_cap_struct *aac_cfg = &audio_cfg->codec_cap.aac;
aac_cfg->object_type = (kal_uint8) findFirstValid(aac_cap->object_type, 8);
aac_cfg->sample_rate = (kal_uint16) findFirstValid(aac_cap->sample_rate, 12);
aac_cfg->channels = (kal_uint8) findFirstValid(aac_cap->channels, 2);
aac_cfg->VBR = aac_cap->VBR;
aac_cfg->bit_rate = 0; /* unknown */
break;
}
case BT_A2DP_ATRAC:
{
bt_a2dp_atrac_codec_cap_struct *atrac_cap = &audio_cap->codec_cap.atrac;
bt_a2dp_atrac_codec_cap_struct *atrac_cfg = &audio_cfg->codec_cap.atrac;
atrac_cfg->version = atrac_cap->version;
atrac_cfg->channel_mode = (kal_uint8) findFirstValid(atrac_cap->channel_mode, 3);
atrac_cfg->sample_rate = (kal_uint8) findFirstValid(atrac_cap->sample_rate, 2);
atrac_cfg->VBR = atrac_cap->VBR;
atrac_cfg->bit_rate = (kal_uint32) findFirstValid(atrac_cap->bit_rate, 19);
atrac_cfg->max_sul = atrac_cap->max_sul;
break;
}
default:
{
break;
}
}
}
/*****************************************************************************
* FUNCTION
* aud_bt_a2dp_calc_audio_config
* DESCRIPTION
*
* PARAMETERS
* aud_fmt [IN]
* codec_type [IN]
* stereo [IN]
* samplerate [IN]
* aud_cfg [?]
* RETURNS
*
*****************************************************************************/
kal_bool aud_bt_a2dp_calc_audio_config(
Media_Format aud_fmt,
kal_uint8 codec_type,
kal_bool stereo,
kal_uint32 samplerate,
bt_a2dp_audio_cap_struct *aud_cfg)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
aud_cfg->codec_type = codec_type;
if (codec_type == BT_A2DP_SBC)
{ /* SBC transcoding is necessary */
bt_a2dp_sbc_codec_cap_struct *sbc = &aud_cfg->codec_cap.sbc;
samplerate /= 1000;
switch (samplerate)
{
case 7:
case 8:
case 15:
case 16:
sbc->sample_rate = 0x8; /* convert to 16000 sps */
break;
case 31:
case 32:
sbc->sample_rate = 0x4; /* convert to 16000 sps */
break;
case 10:
case 11:
case 21:
case 22:
case 43:
case 44:
sbc->sample_rate = 0x2; /* convert to 16000 sps */
break;
case 12:
case 23:
case 24:
case 47:
case 48:
sbc->sample_rate = 0x1; /* convert to 16000 sps */
break;
default:
return KAL_FALSE;
}
#if 1 /* defined(L1SBC_SUPPORT_MONO) */
if (stereo == KAL_FALSE)
{
sbc->channel_mode = 0x8; /* mono */
}
else
#endif /* 1 */
sbc->channel_mode = 0x1; /* default: joint-stereo */
sbc->block_len = 0x1; /* 16: fixed */
sbc->subband_num = 0x1; /* 8: fixed */
sbc->alloc_method = 0x1; /* loudness: fixed */
SBC_InitiateBitPool(sbc->channel_mode, sbc->sample_rate, &sbc->min_bit_pool, &sbc->max_bit_pool);
}
else
{ /* not support transcoding here, media format shall be the same with codec type */
if (codec_type == BT_A2DP_MP3 && aud_fmt == MEDIA_FORMAT_DAF)
{ /* MP3 streaming */
/* bt_a2dp_mp3_codec_cap_struct *mp3 = &aud_cfg->codec_cap.mp3; */
return KAL_FALSE; /* not support now */
}
else if (codec_type == BT_A2DP_AAC && aud_fmt == MEDIA_FORMAT_AAC)
{ /* AAC streaming */
/* bt_a2dp_aac_codec_cap_struct *aac = &aud_cfg->codec_cap.aac; */
return KAL_FALSE; /* not support now */
}
else
{ /* not supported streaming codec */
return KAL_FALSE;
}
}
return KAL_TRUE;
}
/*****************************************************************************
* FUNCTION
* aud_bt_a2dp_cmp_audio_config
* DESCRIPTION
*
* PARAMETERS
* aud_cfg1 [?]
* aud_cfg2 [?]
* RETURNS
*
*****************************************************************************/
kal_bool aud_bt_a2dp_cmp_audio_config(bt_a2dp_audio_cap_struct *aud_cfg1, bt_a2dp_audio_cap_struct *aud_cfg2)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_bool result = KAL_FALSE;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (aud_cfg1->codec_type == aud_cfg2->codec_type)
{
switch (aud_cfg1->codec_type)
{
case BT_A2DP_SBC:
result = (memcmp(
(const void*)&aud_cfg1->codec_cap.sbc,
(const void*)&aud_cfg2->codec_cap.sbc,
sizeof(bt_a2dp_sbc_codec_cap_struct)) == 0);
break;
case BT_A2DP_MP3:
result = (memcmp(
(const void*)&aud_cfg1->codec_cap.mp3,
(const void*)&aud_cfg2->codec_cap.mp3,
sizeof(bt_a2dp_mp3_codec_cap_struct)) == 0);
break;
case BT_A2DP_AAC:
result = (memcmp(
(const void*)&aud_cfg1->codec_cap.aac,
(const void*)&aud_cfg2->codec_cap.aac,
sizeof(bt_a2dp_aac_codec_cap_struct)) == 0);
break;
case BT_A2DP_ATRAC:
result = (memcmp(
(const void*)&aud_cfg1->codec_cap.atrac,
(const void*)&aud_cfg2->codec_cap.atrac,
sizeof(bt_a2dp_atrac_codec_cap_struct)) == 0);
break;
default:
ASSERT(0);
}
}
return result;
}
/*****************************************************************************
* FUNCTION
* aud_bt_a2dp_get_audio_config
* DESCRIPTION
*
* PARAMETERS
* audio_config [?]
* audio_cap_num [IN]
* audio_cap_list [?]
* RETURNS
*
*****************************************************************************/
kal_bool aud_bt_a2dp_get_audio_config(
bt_a2dp_audio_cap_struct *audio_config,
kal_uint8 audio_cap_num,
bt_a2dp_audio_cap_struct *audio_cap_list)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_int16 i;
kal_uint16 result;
STFSAL file;
Media_Status(*get_aud_info_func) (STFSAL * pstFSAL, audInfoStruct * contentInfo, void *param) = NULL;
bt_a2dp_audio_cap_struct cfg;
audInfoStruct aud_info;
kal_uint32 samplerate = 0;
kal_bool stereo = KAL_FALSE;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
ASSERT(audio_cap_num != 0);
if (aud_bt_a2dp_is_media_available())
{
switch (aud_context_p->current_format)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -