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

📄 hfp_headset_sco.c

📁 CSR蓝牙芯片 无线蓝牙耳机的语音网关程序 蓝牙耳机程序已经上传
💻 C
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004

FILE NAME
    hfp_headset_sco.c

DESCRIPTION
    

NOTES

*/


/****************************************************************************
    Header files
*/
#include "headset_private.h"
#include "hfp_headset_sco.h"
#include "av_headset_controls.h"
#include "av_headset_kalimba.h"
#include "cvc_headset.h"
#include <codec.h>
#include <connection.h>
#include <hfp.h>
#include <pcm.h>
#include <panic.h>
#include <sink.h>
#include <source.h>


/****************************************************************************
NAME    
    hfpGetBestScoPktType
    
DESCRIPTION
    This function looks at the supported features of the remote device and
    returns the most appropriate packet type depending on what packets the other
    end can support. If the remote end supports HV3 then this is the type 
    returned. Failing that it checks if HV2 is supported and if so returns that.
    Otherwise it returns the default packet type that all devices must support
    HV1.

RETURNS
    sco_pkt_type
*/
sco_pkt_type hfpGetBestScoPktType(const headsetTaskData *app)
{
    
    if (((app->supp_features_0 >>8) & 0xff) & 0x20)
        return sco_hv3;
    else if (((app->supp_features_0 >>8) & 0xff) & 0x10)
        return sco_hv2;
    else
        return sco_hv1;
}


/****************************************************************************
NAME    
    hfpSetupScoRouting
    
DESCRIPTION
    Set up the SCO routing to the PCM.

RETURNS
    bool
*/
bool hfpSetupScoRouting(headsetTaskData *app)
{
   if (!SinkIsValid(app->sco_sink) || !SourceIsValid(StreamSourceFromSink(app->sco_sink)))
       return FALSE;
   
#ifndef INCLUDE_CVC
   StreamDisconnect(StreamPcmSource(0), StreamPcmSink(0)); 
   StreamDisconnect(StreamPcmSource(1), StreamPcmSink(1)); 
   (void) PanicFalse(PcmRoute(0,VM_PCM_NONE,PCM_NO_SYNC));
   (void) PanicFalse(PcmRoute(1,VM_PCM_NONE,PCM_NO_SYNC));

#ifdef WOLFSON_CODEC
   (void) PanicFalse(PcmRateAndRoute(0, PCM_NO_SYNC, 8000, 8000, VM_PCM_EXTERNAL_I2S));
   (void) PanicFalse(PcmRateAndRoute(1, PCM_NO_SYNC, 8000, 8000, VM_PCM_EXTERNAL_I2S));
   (void) PanicFalse(StreamConnect(StreamSourceFromSink(app->sco_sink), StreamPcmSink(0)));
   (void) PanicFalse(StreamConnect(StreamPcmSource(0), app->sco_sink)); 
  
   {
       codec_config_params codec_settings;
       codec_settings.inputs = mic_input;
       codec_settings.outputs = 0x1;
       codec_settings.adc_sample_rate = 8000;
       codec_settings.dac_sample_rate = 8000;
       CodecConfigure(app->codec_task,&codec_settings);
   }
#else
   (void) PanicFalse(PcmRateAndRoute(0, PCM_NO_SYNC, 8000, 8000, VM_PCM_INTERNAL_A_AND_B));
   (void) PanicFalse(StreamConnect(StreamSourceFromSink(app->sco_sink), StreamPcmSink(0)));
   (void) PanicFalse(StreamConnect(StreamPcmSource(0), app->sco_sink)); 
#endif
#endif

   return TRUE;
}


/****************************************************************************
NAME    
    hfpHeadsetHandleScoConnectInd
    
DESCRIPTION
    Indication of the AG opening a SCO to the headset.

RETURNS
    void
*/
void hfpHeadsetHandleScoConnectInd(headsetTaskData *app, const HFP_SCO_CONNECT_IND_T *ind)
{
    uint16 messages_cancelled = 0;
    bool sco_routed = FALSE;
    bool send_suspend = TRUE;
    
    /* A SCO connection has been opened to this device */
    
    /* TODO: B-4373 how do we support multiple instances */
    
    if (ind->status == hfp_success)
    {
        /* 
            Cancel any audio transfer messages. This deals with the case where the AG 
            opens a SCO before the SLC is completed.
        */
        (void) MessageCancelAll(&app->task, BUTTON_PLAY_PAUSE_REL);
        (void) MessageCancelAll(&app->task, BUTTON_PLAY_PAUSE_LONG);
        
        /* If AG only supports HV1 SCO packets then close all connected AV streams. */
        if (hfpGetBestScoPktType(app) == sco_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 = ind->sco_sink;
        /* Switch to hfp mode */
        app->active_profile = hfp_active;

        /* Route SCO to the PCM */
        app->pcm_audio_state = pcm_sco;
        sco_routed = hfpSetupScoRouting(app);
        
        if (sco_routed)
        {
            /* Update the headset volume */
#ifdef INCLUDE_CVC
			CvcHeadsetVolume(app->speaker_volume);
#else
            avHeadsetUpdateHfVolume(app->codec_task, app->speaker_volume);
#endif
            /* Request to change the SCO packet type to the best we can change it to */
            ConnectionScoChangePktType(ind->sco_sink, hfpGetBestScoPktType(app));
        }

        /* If in HSP mode use sco set up as an indication of active call */
        if (app->profile_connected == hfp_headset_profile)
        {
            app->hfp_state = headsetActiveCall;

            /* The spec also requires us to send our current volume level so send it */
            HfpSendSpeakerVolume(app->hsp, app->speaker_volume >> VOLUME_SHIFT);
        }
#ifdef INCLUDE_CVC
        CvcHeadsetConnect(app);
#endif
    }
}

/****************************************************************************
NAME    
    hfpHeadsetHandleScoDisconnectInd
    
DESCRIPTION
    Indication that the SCO connection has been released.

RETURNS
    void
*/
void hfpHeadsetHandleScoDisconnectInd(headsetTaskData *app, const HFP_SCO_DISCONNECT_IND_T *ind)
{
    ind = ind;

    /* Power down the codec */
    CodecPowerDown(app->codec_task);

    /* Delay before re-starting music. Don't restart music if still an incoming call. */
    if (app->hfp_state != headsetIncomingCallEstablish)
    {
        (void) MessageCancelAll(getAppTask(), APP_MUSIC_RESTART_IND);
        MessageSendLater(getAppTask(), APP_MUSIC_RESTART_IND, 0, (uint32) MUSIC_RESTART_DELAY);
    }

    /* Reset the SCO sink as its no longer valid */
    app->sco_sink = 0;

    /* 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))
        app->hfp_state = headsetConnected;
}

⌨️ 快捷键说明

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