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

📄 hfp_audio.c

📁 实现蓝牙立体声耳机功能。。可以接收并播放来自有蓝牙功能的手机
💻 C
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004-2006
Part of BlueLab 3.6.2-release

FILE NAME
    hfp_audio.c

DESCRIPTION
    Deals with SCO in the headset.

NOTES

*/


/****************************************************************************
    Header files
*/
#include "headset_private.h"
#include "hfp_audio.h"
#include "av_stream_control.h"
#include "headset_codec.h"
#include "headset_common.h"
#include "headset_power.h"
#include "headset_tones.h"
#include "headset_volume.h"

#include <codec.h>
#include <connection.h>
#include <hfp.h>
#include <pcm.h>
#include <panic.h>
#include <sink.h>
#include <source.h>
#include <stdlib.h>

#include <audio.h>
#include <csr_cvc_plugin.h>
#include <csr_no_dsp_plugin.h>
#include <csr_sco_dsp_plugin.h>


#ifdef DEBUG_AUDIO
#define AUDIO_DEBUG(x) DEBUG(x)
#else
#define AUDIO_DEBUG(x) 
#endif


/*****************************************************************************/
sync_pkt_type hfpGetBestScoPktType(const headsetTaskData *app)
{
    
    if (((app->supp_features_0 >>8) & 0xff) & 0x20)
        return sync_hv3;
    else if (((app->supp_features_0 >>8) & 0xff) & 0x10)
        return sync_hv2;
    else
        return sync_hv1;
}


/*****************************************************************************/
bool hfpSetupScoRouting(headsetTaskData *app)
{     
	
	AUDIO_MODE_T lMode = AUDIO_MODE_CONNECTED ;
    	/* Make sure amp is powered on */
    headsetPowerAmp(app, TRUE);
	
	DEBUG(("ScoSink:[%x]\n", (int)app->sco_sink)) ;
	
	PanicFalse(app->sco_sink) ;
	
	
	if (app->voice_recognition_enabled)
	{	
		lMode = AUDIO_MODE_MUTE_SPEAKER ;
	}
	
#ifdef INCLUDE_CVC	
	AudioConnect ( (TaskData*) &csr_cvc_plugin, app->sco_sink , app->codec_task , app->speaker_volume.hfp_volume , TRUE , lMode , NULL ) ;		
#else
	AudioConnect ( (TaskData*) &csr_no_dsp_plugin, app->sco_sink , app->codec_task , app->speaker_volume.hfp_volume , TRUE , lMode , NULL ) ;		
#endif
	   	
    return TRUE;
}


/*****************************************************************************/
void hfpHeadsetHandleAudioConnectCfm(headsetTaskData *app, const HFP_AUDIO_CONNECT_CFM_T *cfm)
{
    uint16 messages_cancelled = 0;
    bool sco_routed = FALSE;
    bool send_suspend = TRUE;
    
    /* A SCO connection has been opened to this device */
    if (cfm->status == hfp_audio_connect_success)
    {   
        /* If AG only supports HV1 SCO packets then close all connected AV streams. */
        if (hfpGetBestScoPktType(app) == sync_hv1)
        {
            A2dpCloseAll(app->a2dp);
            send_suspend = FALSE;
        }
        
        /* Don't want to restart music as we now have a SCO connection */
        messages_cancelled = MessageCancelAll(&app->task, APP_MUSIC_RESTART_IND); 
        if (!messages_cancelled && (app->a2dp_state == avHeadsetA2dpStreaming))
        {
            /* If the AV audio has not already been stopped then stop it now */
            avHeadsetAvStreamStop(app, send_suspend);
        }

        /* Store the sink associated with the SCO */
        app->sco_sink = cfm->audio_sink;

	
        /* Switch to hfp mode */
        app->active_profile = hfp_active;

        /* Route SCO to the PCM */
        sco_routed = hfpSetupScoRouting(app);
        
        /* If in HSP mode use sco set up as an indication of active call */
        if (app->profile_connected == hfp_headset_profile)
        {
            setHfpState(app, headsetActiveCall);

            /* The spec also requires us to send our current volume level so send it */
            HfpSendSpeakerVolume(app->hsp, (uint16)app->speaker_volume.hfp_volume);
        }
    }
}


/*****************************************************************************/
void hfpHeadsetHandleAudioDisconnectInd(headsetTaskData *app)
{
    /* Reset the SCO sink as its no longer valid */
    app->sco_sink = 0;
	
	AudioDisconnect() ;

    /* Power down the codec */
    CodecPowerDown(app->codec_task);
	
    /* Delay before re-starting music. Don't restart music if still an incoming call or an outgoing call */
    if ((app->hfp_state != headsetIncomingCallEstablish) && (app->hfp_state != headsetOutgoingCallEstablish))     
    {
        headsetRestartAV(app);
    }

	
    /* If in HSP mode use sco disconnect as an indication of a state change */
    if ((app->profile_connected == hfp_headset_profile) && (app->hfp_state != headsetReady))
    {
        if ((app->hfp_state == headsetActiveCall) || (app->hfp_state == headsetIncomingCallEstablish))
            headsetPlayTone(app, tone_type_call_end); 
        setHfpState(app, headsetConnected);
    }
	
	app->mic_mute_on = FALSE;
	MessageCancelAll( &app->task , APP_MUTE_REMINDER) ;
}


/*****************************************************************************/
void hfpHeadsetTransferAudio(headsetTaskData *app, hfp_audio_transfer_direction dir)
{
    /* 
        Decide what packet type to use based on the SCO packets supported by 
        the remote end and initiate the audio transfer.
    */
    #ifdef HFP_1_5
		if (app->profile_connected == hfp_headset_profile)
				HfpAudioTransferConnection(app->hfp, dir, (sync_all_sco), 0);
		else
			HfpAudioTransferConnection(app->hfp, dir, (sync_all_sco | sync_all_esco), 0);
	#else
		HfpAudioTransferConnection(app->hfp, dir, (sync_all_sco), 0);
	#endif

		
}


/****************************************************************************/
void hfpHeadsetHandleAudioConnectInd(headsetTaskData *app, const HFP_AUDIO_CONNECT_IND_T *ind)
{
    HFP *active_hfp = 0;
	
    /* Accept audio if its for a task we own */
    if ((ind->hfp == app->hfp) || (ind->hfp == app->hsp))
        active_hfp = ind->hfp;    

    if (active_hfp)
    {
        /* Accept the audio connection */
		#ifdef HFP_1_5
				if (app->profile_connected == hfp_headset_profile)
					HfpAudioConnectResponse(active_hfp, 1, (sync_all_sco), 0);
				else
					HfpAudioConnectResponse(active_hfp, 1, (sync_all_sco | sync_all_esco), 0);
		#else
				HfpAudioConnectResponse(active_hfp, 1, (sync_all_sco), 0);
		#endif
        /* Make sure amp is powered on */
/*        headsetPowerAmp(app, TRUE);*/
    }
    else
	{
        HfpAudioConnectResponse(active_hfp, 0, sync_hv1, 0);	
	}
}

⌨️ 快捷键说明

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