harmonyos--多路通话来电waiting声播放代码走读

本文围绕HarmonyOS展开,详细介绍了通话状态变化的处理,包括prestate和nextState。阐述了来电消息、单路和多路通话状态机的处理逻辑,如状态切换等。还说明了第二路通话来电消息处理及音频播放,如等待声的播放流程和资源加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//处理通话状态变化。其实通话状态变化分成两个部分,一部分处理prestate,可以理解为source(src),一部分处理nextState,可以理解为target(目标状态处理)
define:HandleCallStateUpdated

void AudioControlManager::HandleCallStateUpdated(
HandleNextState(callObjectPtr, nextState);

//来电消息处理
void AudioControlManager::HandleNextState(sptr &callObjectPtr, TelCallState nextState)
case TelCallState::CALL_STATUS_INCOMING:
event = AudioEvent::NEW_INCOMING_CALL;
DelayedSingleton::GetInstance()->ProcessEvent(event);

bool AudioSceneProcessor::ProcessEvent(AudioEvent event)
reportAudioStateChangeQueue.submit(= { ProcessEventInner(event); });

void AudioSceneProcessor::ProcessEventInner(AudioEvent event)
switch (event) {
case AudioEvent::NEW_INCOMING_CALL:
currentState_ = std::make_unique();
currentState_->ProcessEvent(event); //这个地方相当于是一个状态机,不同的状态处理同一个event,处理方式也不同

---------------------------可爱分隔线-------------------------------------

//单路通话 inactive_state处理NEW_INCOMING_CALL
bool InActiveState::ProcessEvent(int32_t event)
case AudioEvent::NEW_INCOMING_CALL:
result = DelayedSingleton::GetInstance()->ProcessEvent(AudioEvent::SWITCH_INCOMING_STATE); //会将状态机切到incoming_state

memberFuncMap_[AudioEvent::SWITCH_INCOMING_STATE] = &AudioSceneProcessor::SwitchIncoming;

bool AudioSceneProcessor::SwitchIncoming()
DelayedSingleton::GetInstance()->StopRingtone();

// play ringtone while incoming state
DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingtone();  //这个地方前边我们已经说明了来电响铃的逻辑,实际就是调用audioPlayer的播放

//多路通话 cs_call_state/ims_call_state/holding_state/incoming_state 上一路通话的状态可能是这几个状态机处理第二路来电消息

//处理上一路通话由incoming到active的时候
void AudioControlManager::HandleNewActiveCall(sptr &callObjectPtr)
case CallType::TYPE_IMS:
event = AudioEvent::NEW_ACTIVE_IMS_CALL;

bool AudioSceneProcessor::ProcessEvent(AudioEvent event)
reportAudioStateChangeQueue.submit(= { ProcessEventInner(event); });

void AudioSceneProcessor::ProcessEventInner(AudioEvent event)
case AudioEvent::NEW_ACTIVE_IMS_CALL:
currentState_->ProcessEvent(event); //currentState_ = IncomingState 来电

bool IncomingState::ProcessEvent(int32_t event)
case AudioEvent::NEW_ACTIVE_IMS_CALL:
result = DelayedSingleton::GetInstance()->ProcessEvent(
AudioEvent::SWITCH_IMS_CALL_STATE);

bool AudioSceneProcessor::ProcessEvent(AudioEvent event)
reportAudioStateChangeQueue.submit(= { ProcessEventInner(event); });

void AudioSceneProcessor::ProcessEventInner(AudioEvent event)
case AudioEvent::SWITCH_IMS_CALL_STATE:
SwitchState(event);

memberFuncMap_[AudioEvent::SWITCH_IMS_CALL_STATE] = &AudioSceneProcessor::SwitchIMS;

bool AudioSceneProcessor::SwitchState(AudioEvent event)
{
auto itFunc = memberFuncMap_.find(event);
if (itFunc != memberFuncMap_.end() && itFunc->second != nullptr) {
auto memberFunc = itFunc->second;
return (this->*memberFunc)();
}
return false;
}

//第一路通话active,状态机置为 IMSCallState。同理CS通话接听成功逻辑类似。通话hold也是一个逻辑,就不一一罗列了
bool AudioSceneProcessor::SwitchIMS()
currentState_ = std::make_unique();

goto:HandleCallStateUpdated
//第二路通话来电的消息处理—直接从消息处理说起
bool IMSCallState::ProcessEvent(int32_t event)
case AudioEvent::NEW_INCOMING_CALL:
result = DelayedSingleton::GetInstance()->PlayWaitingTone();

int32_t AudioControlManager::PlayWaitingTone()
{
return PlayCallTone(ToneDescriptor::TONE_WAITING);
}

int32_t AudioControlManager::PlayCallTone(ToneDescriptor type)
tone_ = std::make_unique(type); //初始化Tone,根据传入的ToneDescription,当前为TONE_WAITING
if (tone_->Play() != TELEPHONY_SUCCESS) {

int32_t Tone::Play()
//判断是否使用TonePlayer进行播放,历史上会铃声,等待声都是通话管理本地进行播放的,非调用音频框架进行播放。
if (IsUseTonePlayer(currentToneDescriptor_)) {
//初始化TonePlayer
if (!InitTonePlayer()) {
tonePlayer_->StartTone();

bool Tone::IsUseTonePlayer(ToneDescriptor tone)
case ToneDescriptor::TONE_RINGBACK:
case ToneDescriptor::TONE_WAITING:
ret = true;

bool Tone::InitTonePlayer()
//根据当前的description获取当前需要加载stream的类型
StreamUsage streamUsage = GetStreamUsageByToneType(currentToneDescriptor_);

https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-audio-kit/js-apis-audio.md#streamusage
STREAM_USAGE_VOICE_COMMUNICATION 2 语音通信。
//stream类型为通话类型
case ToneDescriptor::TONE_RINGBACK:
case ToneDescriptor::TONE_WAITING:
streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION;

    tonePlayer_ = TonePlayer::Create(rendererInfo);

//铃声类型为call_waiting 等待声
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-audio-kit/js-apis-audio-sys.md#tonetype9
TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING 106 呼叫监管音调,呼叫等待。
TONE_TYPE_COMMON_SUPERVISORY_RINGTONE 107 呼叫监管音调,铃声。

    ToneType toneType = ConvertToneDescriptorToToneType(currentToneDescriptor_);

AudioStandard::ToneType Tone::ConvertToneDescriptorToToneType(ToneDescriptor tone)
AudioStandard::ToneType Tone::ConvertCallToneDescriptorToToneType(ToneDescriptor tone)
case ToneDescriptor::TONE_WAITING:
tonType = ToneType::TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING;

//tonePlayer 根据Tone的类型去加载相应的资源文件,用于播放
if (!tonePlayer_->LoadTone(toneType)) {

//音频框架正式播放多路通话的waiting声音
tonePlayer_->StartTone();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值