1. 程式人生 > >關於藍芽耳機通話,切換聲音路徑

關於藍芽耳機通話,切換聲音路徑

今天遇到一個問題,不大不小:

1.聲音從本機切換到藍芽耳機
 (1)如果此時靜音功能關閉,切換到BT耳機後,靜音功能仍關閉,[靜音]選單顯示正常,之後開啟、關閉操作也正常;
 (2)如果此時靜音功能開啟,切換到BT耳機後,靜音功能被關閉,但是[靜音]選單的顯示仍然是開啟,即:切換聲音路徑到BT耳機時,自動關閉了靜音功能,但是[靜音]選單的顯示沒有響應的變化,導致錯誤。2.聲音從藍芽耳機切換到本機
 現象類似。

一路追蹤程式碼,過程如下:
1. [靜音]選單的操作函式:mmi_ucm_set_mute()

2.切換聲音路徑的操作:
(1)mmi_ucm_bt_set_audio_path()-->
(2)mmi_bt_switch_voice_path_incall( )-->
(3)(*g_mmi_bt_scr_cntx.stack_cb_tbl.mmi_bt_switch_voice_path_incall) (is_on);   is_on=1表示切換聲音到藍芽耳機。這是個函式指標,在函式
mmi_bt_init_stack_cb()中呼叫mmi_bt_reg_stack_cb()註冊的即:
(4)mmi_bth_switch_voice_path_incall()-->
(4-1)mmi_profiles_bt_connect_req(MMI_PROFILES_BT_HFP_SCO);     切換到藍芽耳機
   mdi_audio_bt_open_stream()-->
 aud_send_bt_audio_open_req( )-->
 aud_send_msg_to_med( MSG_ID_MEDIA_BT_AUDIO_OPEN_REQ)

 底層aud_bt_main()函式接收到這個訊息後,執行:
 aud_bt_audio_open_req_hdlr()-->
 aud_bt_hfp_open_req_hdlr()--> 執行if分支:
 aud_bt_hfp_sco_connect_req( )-->
 aud_bt_hfp_set_audio_path_on( )-->設定音訊輸出路徑
 bt_hfg_send_sco_connect_req(MOD_MED, aud_bt_hfp_ctx.connect_id); 傳送訊息:MSG_ID_BT_HFG_SCO_CONNECT_REQ

 藍芽返回MSG_ID_BT_HFG_SCO_CONNECT_CNF,在aud_bt_main()中被捕捉到,進入:
 aud_bt_hfp_sco_connect_cnf_hdlr() -->
 aud_send_bt_audio_open_ind( )-->
  aud_send_msg_from_med(MSG_ID_MEDIA_BT_AUDIO_OPEN_IND),進入函式:
  mdi_audio_bt_open_stream_ind()--即:(5)中所註冊的回撥函式
 aud_bt_hfp_set_audio_path(KAL_TRUE); 比較關鍵的函式
  aud_bt_hfp_set_audio_path_on();
              aud_bt_hfp_set_speech_path_on(); 先呼叫L1SP_MuteMicrophone(KAL_TRUE);開啟靜音,然後啟動一定時器,定時器響應關閉靜音!


(4-2) mmi_profiles_bt_disconnect_req(MMI_PROFILES_BT_HFP_SCO); 切換到本機
 mdi_audio_bt_close_stream( )-->
 media_aud_bt_audio_close( )-->
 aud_send_bt_audio_close_req( )-->
 aud_send_msg_to_med(MSG_ID_MEDIA_BT_AUDIO_CLOSE_REQ )

 底層aud_bt_main()函式接收到這個訊息後,執行:
 aud_bt_audio_close_req_hdlr()-->
 aud_bt_hfp_close_req_hdlr( )-->
 aud_bt_hfp_set_audio_path( FALSE)--> 比較關鍵的函式!!!
  aud_bt_hfp_set_audio_path_off();
              aud_bt_hfp_set_speech_path_off();-->L1SP_MuteMicrophone(KAL_FALSE);  關閉靜音功能!!!!!
 aud_send_bt_audio_close_cnf()-->
 aud_send_msg_from_med(MSG_ID_MEDIA_BT_AUDIO_CLOSE_CNF),進入函式:
 mdi_audio_bt_close_stream_cnf()--即:(5)中所註冊的回撥函式


(5)在函式mdi_audio_init_event_hdlrs()中註冊了:
    SetProtocolEventHandler(mdi_audio_bt_close_stream_cnf, MSG_ID_MEDIA_BT_AUDIO_CLOSE_CNF);
    SetProtocolEventHandler(mdi_audio_bt_close_stream_ind, MSG_ID_MEDIA_BT_AUDIO_CLOSE_IND);
    SetProtocolEventHandler(mdi_audio_bt_open_stream_cnf, MSG_ID_MEDIA_BT_AUDIO_OPEN_CNF);
    SetProtocolEventHandler(mdi_audio_bt_open_stream_ind, MSG_ID_MEDIA_BT_AUDIO_OPEN_IND);
    以上4個響應函式都呼叫mdi_audio_bt_cntx.close_hdlr[profile]註冊的函式。而這個函式的註冊是在:InitProfileApp()-->
 mdi_audio_bt_init(BT_HFP, mmi_profiles_bt_open_stream_callback, mmi_profiles_bt_close_stream_callback);來完成的。
    即:mmi_profiles_bt_open_stream_callback( ),mmi_profiles_bt_close_stream_callback( )這2個函式是切換聲音路徑最後呼叫的函式。

(6-1) mmi_profiles_bt_open_stream_callback()--> 切換到BT耳機
 mmi_profiles_bt_connect_callback(MMI_PROFILES_BT_HFP_SCO, MMI_PROFILES_BT_RSP, res);-->
 mmi_bth_sco_connect_ind_hdler( )
  (*g_mmi_bth_cntx.scr_cb_tbl.mmi_bt_scr_cb_sco_ind)( ) 函式指標,即:mmi_bt_sco_ind(res)。res=1表示切換到BT耳機。
   如果當前開啟擴音,則把擴音關閉;顯示提示資訊:聲音轉至免持裝置。   
 然後啟動定時器mmi_profiles_bt_sco_timeout(),定期檢查藍芽耳機是否斷開,是的話執行mmi_profiles_bt_disconnect_sco()。

 (6-2)mmi_profiles_bt_close_stream_callback()--> 切換到本機
 mmi_profiles_bt_disconnect_callback(MMI_PROFILES_BT_HFP_SCO, MMI_PROFILES_BT_RSP, MMI_PROFILES_BT_OK);-->
 mmi_bth_sco_disconnect_ind_hdler()
  (*g_mmi_bth_cntx.scr_cb_tbl.mmi_bt_scr_cb_sco_ind)( ) 函式指標,即:mmi_bt_sco_ind(res)
   提示資訊:聲音轉回手機端

   即:切換聲音完成之後,都會進入函式mmi_bt_sco_ind()中,顯示提示資訊。