📄 hfp_audio.c
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004-2006
Part of BlueLab 3.4.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 "cvc_headset.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>
#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)
{
if (!SinkIsValid(app->sco_sink) || !SourceIsValid(StreamSourceFromSink(app->sco_sink)))
return FALSE;
if (isTonePlaying(app->pcm_audio_state))
{
setPcmState(app, pcm_tone_to_sco);
AUDIO_DEBUG(("AUDIO: Tone playing\n"));
return FALSE;
}
else
{
setPcmState(app, pcm_sco);
}
/* Make sure amp is powered on */
headsetPowerAmp(app, TRUE);
AUDIO_DEBUG(("AUDIO: Route SCO\n"));
/* Cancel the timer to shut down the audio amp */
MessageCancelAll(getAppTask(), APP_AMP_IDLE_IND);
#ifndef INCLUDE_CVC
/* Set volume to mute */
headsetUpdateVolume(app->codec_task, 0);
StreamDisconnect(StreamPcmSource(0), StreamPcmSink(0));
StreamDisconnect(StreamPcmSource(1), StreamPcmSink(1));
(void) PanicFalse(PcmClearRouting(0));
(void) PanicFalse(PcmClearRouting(1));
#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));
CodecConfigure(app->codec_task,0);
#else
(void) PanicFalse(PcmRateAndRoute(0, PCM_NO_SYNC, (uint32) 8000, (uint32) 8000, VM_PCM_INTERNAL_A_AND_B));
(void) PanicFalse(StreamConnect(StreamSourceFromSink(app->sco_sink), StreamPcmSink(0)));
if (!app->mic_mute_on)
(void) PanicFalse(StreamConnect(StreamPcmSource(0), app->sco_sink));
#endif
/* Set volume to required level */
headsetUpdateVolume(app->codec_task, app->speaker_volume.hfp_volume);
#else
CvcHeadsetConnect(app);
#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)
{
/* 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)
{
headsetRestartAV(app);
}
/* 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))
{
if ((app->hfp_state == headsetActiveCall) || (app->hfp_state == headsetIncomingCallEstablish))
headsetPlayTone(app, tone_type_call_end);
setHfpState(app, headsetConnected);
}
/* Start the timer to shut down the audio amp */
MessageSendLater(getAppTask(), APP_AMP_IDLE_IND, 0, AMP_IDLE_TIMER);
app->mic_mute_on = 0;
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.
*/
HfpAudioTransferConnection(app->hfp, dir, (sync_hv1 | sync_hv2 | sync_hv3), 0);
if (dir == hfp_audio_to_hfp)
/* Make sure amp is powered on */
headsetPowerAmp(app, TRUE);
}
/****************************************************************************/
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)
{
/* For now just accept the audio connection */
HfpAudioConnectResponse(active_hfp, 1, (sync_hv1 | sync_hv2 | sync_hv3), 0);
/* 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 + -