⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aud_bt_a2dp.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    need_open_codec = KAL_FALSE;
    mute_phone = KAL_FALSE;
    codec_mutex = kal_create_mutex("a2dp_codec_mutex");
}

/*****************************************************************************
 * FUNCTION
 *  aud_bt_a2dp_is_mute_phone
 * DESCRIPTION
 *  
 * PARAMETERS
 *  void
 * RETURNS
 *  kal_bool
 *****************************************************************************/
kal_bool aud_bt_a2dp_is_mute_phone(void)
{
    return mute_phone;
}

/*****************************************************************************
 * FUNCTION
 *  aud_bt_a2dp_is_media_playing
 * DESCRIPTION
 *  
 * PARAMETERS
 *  void
 * RETURNS
 *  
 *****************************************************************************/
kal_bool aud_bt_a2dp_is_media_playing(void)
{
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    AUD_STATE_TRACE(aud_context_p->state);
    
    return (aud_context_p->state == AUD_MEDIA_PLAY || 
        aud_context_p->state == AUD_MEDIA_PLAY_FINISH);
}

/*****************************************************************************
 * FUNCTION
 *  aud_bt_a2dp_is_media_available
 * DESCRIPTION
 *  
 * PARAMETERS
 *  void
 * RETURNS
 *  
 *****************************************************************************/
kal_bool aud_bt_a2dp_is_media_available(void)
{
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    AUD_STATE_TRACE(aud_context_p->state);

    return (aud_context_p->state == AUD_MEDIA_PLAY || 
        aud_context_p->state == AUD_MEDIA_PLAY_PAUSED ||
        aud_context_p->state == AUD_MEDIA_PLAY_FINISH);
}

/*****************************************************************************
 * FUNCTION
 *  aud_bt_a2dp_set_mute_phone
 * DESCRIPTION
 *  
 * PARAMETERS
 *  on      [IN]        
 * RETURNS
 *  void
 *****************************************************************************/
void aud_bt_a2dp_set_mute_phone(kal_bool on)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint8 output_device;
    kal_uint8 audio_mode;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (on)
    {
        if (!mute_phone)
        {
            aud_melody_set_output_device(0);
        }
    }
    else
    {
        if (mute_phone)
        {
            switch (aud_context_p->audio_mode)
            {
                case AUD_MODE_NORMAL:
                case AUD_MODE_LOUDSPK:
            #ifdef TV_OUT_SUPPORT
                    if (audio_tv_cable_in)
                    {
                        if(audio_tv_loud_speaker ||
                           (aud_context_p->melody_output_device == AUDIO_DEVICE_SPEAKER_BOTH))
                        {
                            output_device = AUDIO_DEVICE_SPEAKER_BOTH;
                        }
                        else
                        {
                            output_device = AUDIO_DEVICE_SPEAKER2;
                        }
                    }
                    else
            #endif /* TV_OUT_SUPPORT */
                    {
                        output_device = AUDIO_DEVICE_LOUDSPEAKER;
                    }
                    break;
                case AUD_MODE_HEADSET:
                    output_device = aud_context_p->melody_output_device;
                    break;
                default:
                    output_device = 0;
                    ASSERT(0);
            }

            aud_melody_set_output_device(custom_cfg_hw_aud_output_path(output_device));

            if( aud_bt_a2dp_is_media_available() )
            {
                /* it is not redundant code becoz aud_set_meldoy_volume will check 
                  media_output_on */
                mute_phone = on;

            #ifdef TV_OUT_SUPPORT
                /* TV out is on, and audio output to TV only */
                if (audio_tv_cable_in && !audio_tv_loud_speaker)
                {
                    audio_mode = VOL_TV_OUT;
                }
                else
            #endif /* TV_OUT_SUPPORT */
                if (aud_context_p->audio_mode == AUD_MODE_HEADSET &&
                    aud_context_p->melody_output_device == AUDIO_DEVICE_SPEAKER_BOTH)
                {
                    audio_mode = VOL_NORMAL;
                }
                else
                {
                    audio_mode = aud_context_p->audio_mode;
                }

                aud_set_melody_volume(audio_mode, current_playing_melody_volume_level);
            }
        }
    }

    mute_phone = on;
}

/*****************************************************************************
 * FUNCTION
 *  aud_bt_a2dp_stream_qos_ind_hdlr
 * DESCRIPTION
 *  
 * PARAMETERS
 *  ilm_ptr     [?]     
 * RETURNS
 *  void
 *****************************************************************************/
void aud_bt_a2dp_stream_qos_ind_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    bt_a2dp_stream_qos_ind_struct *msg_p = (bt_a2dp_stream_qos_ind_struct*) ilm_ptr->local_para_ptr;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    AUD_BT_A2DP_FUNC_ENTRY(AUD_BT_A2DP_STREAM_QOS_IND_HDLR);

    if (codec != NULL)
    {
        codec->AdjustBitRateFromQos(msg_p->qos);
    }
}

/*****************************************************************************
 * FUNCTION
 *  aud_bt_a2dp_codec_callback
 * DESCRIPTION
 *  
 * PARAMETERS
 *  event       [IN]        
 *  param       [?]         
 * RETURNS
 *  void
 *****************************************************************************/
void aud_bt_a2dp_codec_callback(A2DP_Event event, void *param)
{
    A2DP_codec_struct* codec_p = (A2DP_codec_struct*)param;

    bt_a2dp_send_stream_data_send_req(MOD_L1SP, stream_handle, codec_p);
}

/*****************************************************************************
 * FUNCTION
 *  aud_bt_a2dp_open_codec
 * DESCRIPTION
 *  
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
void aud_bt_a2dp_open_codec(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (!need_open_codec)
        return;

    AUD_BT_A2DP_FUNC_ENTRY(AUD_BT_A2DP_OPEN_CODEC)

    ASSERT(codec == NULL);

    switch (audio_config.codec_type)
    {
        case BT_A2DP_SBC:
            codec = SBC_Open(aud_context_p->current_format,
                aud_bt_a2dp_codec_callback,
                &audio_config.codec_cap.sbc,
                buf,
                SBC_ENCODE_MEM_SIZE);
            break;
        case BT_A2DP_MP3:
            ASSERT(aud_context_p->current_format == MED_TYPE_DAF);

            codec = A2DP_DAF_Open(aud_context_p->last_mhdl_handle,
                aud_bt_a2dp_codec_callback,
                &audio_config.codec_cap.mp3,
                buf,
                MP3_ENCODE_MEM_SIZE);
            break;
        default:
            ASSERT(0);
    }
    need_open_codec = KAL_FALSE;

    aud_bt_a2dp_set_mute_phone(KAL_TRUE);
}

/*****************************************************************************
 * FUNCTION
 *  aud_bt_a2dp_close_codec
 * DESCRIPTION
 *  
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
void aud_bt_a2dp_close_codec(void)
{
    kal_bool playing;

    if (codec == NULL)
        return;

    AUD_BT_A2DP_FUNC_ENTRY(AUD_BT_A2DP_CLOSE_CODEC);

    playing = aud_bt_a2dp_is_media_playing();
    
    aud_bt_a2dp_lock_codec();

    switch (audio_config.codec_type)
    {
        case BT_A2DP_SBC:
            SBC_Close();
            break;
        case BT_A2DP_MP3:
            A2DP_DAF_Close(playing ? aud_context_p->last_mhdl_handle: NULL);
            break;
        default:
            ASSERT(0);
    }
    codec = NULL;

    aud_bt_a2dp_unlock_codec();

    aud_bt_a2dp_set_mute_phone(KAL_FALSE);
}

void aud_bt_a2dp_open_codec_req_hdlr(ilm_struct *ilm_ptr)
{
    media_bt_open_codec_req_struct *msg_p = (media_bt_open_codec_req_struct*)ilm_ptr->local_para_ptr;

    ASSERT(codec == NULL);
    ASSERT(!need_open_codec);

    stream_handle = msg_p->stream_handle;
    memcpy(&audio_config, &msg_p->cfg, sizeof(bt_a2dp_audio_cap_struct));
    need_open_codec = KAL_TRUE;

    if (msg_p->immediate && aud_bt_a2dp_is_media_playing())
        aud_bt_a2dp_open_codec();
}

void aud_bt_a2dp_close_codec_req_hdlr(ilm_struct *ilm_ptr)
{
    aud_bt_a2dp_close_codec();
    need_open_codec = KAL_FALSE;
}

#elif defined(__BTVCSR_HCI_BCHS__)

/* define queue status = cmds[0] | cmds[1] << 3 | cmds[2] << 6 */
#define AUD_BT_A2DP_CMD_QUEUE_EMPTY                   (AUD_BT_A2DP_CMD_NONE         |(AUD_BT_A2DP_CMD_NONE << 3)        |(AUD_BT_A2DP_CMD_NONE << 6))
#define AUD_BT_A2DP_CMD_QUEUE_ABORT                   (AUD_BT_A2DP_CMD_ABORT        |(AUD_BT_A2DP_CMD_NONE << 3)        |(AUD_BT_A2DP_CMD_NONE << 6))
#define AUD_BT_A2DP_CMD_QUEUE_CLOSE_STREAM               (AUD_BT_A2DP_CMD_CLOSE_STREAM |(AUD_BT_A2DP_CMD_NONE << 3)        |(AUD_BT_A2DP_CMD_NONE << 6))
#define AUD_BT_A2DP_CMD_QUEUE_RECONFIG_STREAM            (AUD_BT_A2DP_CMD_RECONFIG_STREAM|(AUD_BT_A2DP_CMD_NONE << 3)         |(AUD_BT_A2DP_CMD_NONE << 6))
#define AUD_BT_A2DP_CMD_QUEUE_START_STREAM               (AUD_BT_A2DP_CMD_START_STREAM |(AUD_BT_A2DP_CMD_NONE << 3)        |(AUD_BT_A2DP_CMD_NONE << 6))
#define AUD_BT_A2DP_CMD_QUEUE_PAUSE_STREAM               (AUD_BT_A2DP_CMD_PAUSE_STREAM |(AUD_BT_A2DP_CMD_NONE << 3)        |(AUD_BT_A2DP_CMD_NONE << 6))
#define AUD_BT_A2DP_CMD_QUEUE_RECONFIG_START_STREAM      (AUD_BT_A2DP_CMD_RECONFIG_STREAM|(AUD_BT_A2DP_CMD_START_STREAM << 3) |(AUD_BT_A2DP_CMD_NONE << 6))
#define AUD_BT_A2DP_CMD_QUEUE_PAUSE_RECONFIG_STREAM      (AUD_BT_A2DP_CMD_PAUSE_STREAM |(AUD_BT_A2DP_CMD_RECONFIG_STREAM << 3)   |(AUD_BT_A2DP_CMD_NONE << 6))
#define AUD_BT_A2DP_CMD_QUEUE_PAUSE_RECONFIG_START_STREAM   (AUD_BT_A2DP_CMD_PAUSE_STREAM |(AUD_BT_A2DP_CMD_RECONFIG_STREAM << 3)   |(AUD_BT_A2DP_CMD_START_STREAM << 6))

#define SBC_ENCODE_MEM_SIZE (8*1024)

typedef struct
{
    kal_uint8 count;
    kal_uint8 cmds[3];
} aud_bt_a2dp_cmd_queue_struct;

typedef struct
{
    module_type src_mod_id;
    kal_uint16 connect_id;
    aud_bt_a2dp_cmd_queue_struct cmd_queue;
    kal_uint8 state;
    kal_uint8 mode;
    kal_uint8 wait;
    kal_uint8 service_status;
    kal_uint8 result;
    kal_uint8 remote_seid;  /* 0 -> none, otherwise -> 0x01 - 0x3E */
    kal_uint8 local_seid;   /* 0x01 - 0x3E */
    kal_uint8 stream_handle;
    kal_uint8 audio_cap_num;
    kal_bool start_failed;
    kal_bool turn_on;
    kal_bool output_on;
    kal_bool media_output_on;
    kal_bool forced_streaming_handling;
    bt_a2dp_audio_cap_struct audio_cap_list[MAX_NUM_REMOTE_CAPABILITIES];
    bt_a2dp_audio_cap_struct audio_config;
    bt_a2dp_audio_cap_struct remote_audio_config;
    A2DP_codec_struct *codec;
    kal_uint8 buf[SBC_ENCODE_MEM_SIZE];
} aud_bt_a2dp_context_struct;

extern const bt_a2dp_sbc_codec_cap_struct sbc_cap[1];

extern aud_context_struct *aud_context_p;
extern STFSAL current_file_stream;
extern kal_uint8 current_playing_melody_volume_level;
#if defined(TV_OUT_SUPPORT)
extern kal_bool audio_tv_cable_in;
extern kal_bool audio_tv_loud_speaker;
#endif

aud_bt_a2dp_context_struct aud_bt_a2dp_ctx;
static const kal_int16 unsupported_media_types[] = 
{
    MED_TYPE_GSM_FR
    ,MED_TYPE_GSM_HR
    ,MED_TYPE_GSM_EFR
#ifdef __MED_VR_MOD__
    ,MED_TYPE_VR
#endif 
#ifdef __MED_VRSI_MOD__
    ,MED_TYPE_VRSI
#endif 
};

#define UNSUPPORTED_MEDIA_TYPES_NUM (sizeof(unsupported_media_types)/sizeof(kal_int16))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -