mcu_hi3321_watch/tjd/ui/app/phone/phone_service/TjdPhoneAudio.cpp
2025-05-26 20:15:20 +08:00

458 lines
16 KiB
C++

/*----------------------------------------------------------------------------
* Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved.
*
* Description: TjdPhoneAudio.cpp
*
* Author: luziquan@ss-tjd.com
*
* Create: 2025-08-16
*--------------------------------------------------------------------------*/
#include "TjdPhoneAudio.h"
#include "TjdPhoneService.h"
#include "audio_errors.h"
#include "sys_config.h"
#define ENABLE_PRINT_INFO 1
#if ENABLE_PRINT_INFO
#define static_print_warn(...) sys_phone_log_w(__VA_ARGS__) // 警告信息打印一般常开
#define static_print_error(...) sys_phone_log_e(__VA_ARGS__) // 错误信息打印一般常开
#define static_print_debug(...) sys_phone_log_d(__VA_ARGS__) // 调试信息打印一般常开
#else
#define static_print_warn(...)
#define static_print_error(...)
#define static_print_debug(...)
#endif
class PhoneAudioInterruptListener : public Audio::InterruptListener
{
public:
PhoneAudioInterruptListener() {};
~PhoneAudioInterruptListener() {};
void OnInterrupt(int32_t type, int32_t hint) override
{
UNUSED(type);
UNUSED(hint);
static_print_debug("[PhoneAudioInterruptListener] OnInterrupt: type = %d, hint = %d", type, hint);
}
};
static std::shared_ptr<PhoneAudioInterruptListener> g_audioIntListener = nullptr;
int32_t TjdPhoneAudio::AudioInit(void)
{
bool ret = amInstance_.Initialize();
if (!ret) {
static_print_error("[%s] line:%d, audio manager init failed", __FUNCTION__, __LINE__);
return AUDIO_ERROR;
}
static_print_error("[%s] line:%d, success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioGetMinVolume(void) { return amInstance_.GetMinVolume(AUDIO_STREAM_VOICE_CALL_BT_SCO); }
int32_t TjdPhoneAudio::PhoneAudioGetMaxVolume(void) { return amInstance_.GetMaxVolume(AUDIO_STREAM_VOICE_CALL_BT_SCO); }
int32_t TjdPhoneAudio::PhoneAudioGetVolume(void) { return amInstance_.GetVolume(AUDIO_STREAM_VOICE_CALL_BT_SCO); }
bool TjdPhoneAudio::PhoneAudioSetVolume(int32_t volume)
{
return amInstance_.SetVolume(AUDIO_STREAM_VOICE_CALL_BT_SCO, volume);
}
// 设置通话speaker静音/取消静音
bool TjdPhoneAudio::PhoneAudioSetSpeakerMute(bool isMute)
{
bool ret;
static_print_debug("[PhoneAudioSetSpeakerMute] start");
ret = amInstance_.IsMute(AUDIO_STREAM_VOICE_CALL_BT_SCO);
if (ret == isMute) {
return true;
}
if (isMute) {
ret = amInstance_.Mute(AUDIO_STREAM_VOICE_CALL_BT_SCO);
} else {
ret = amInstance_.UnMute(AUDIO_STREAM_VOICE_CALL_BT_SCO);
}
static_print_debug("[PhoneAudioSetSpeakerMute] end! ret = %d", ret);
return ret;
}
// 设置通话mic静音/取消静音
bool TjdPhoneAudio::PhoneAudioSetMicMute(bool isMute)
{
bool ret;
static_print_debug("[PhoneAudioSetMicMute] start");
ret = amInstance_.IsMicrophoneMute();
if (ret == isMute) {
return true;
}
ret = amInstance_.SetMicrophoneMute(isMute);
static_print_debug("[PhoneAudioSetMicMute] end! ret = %d", ret);
return ret;
}
static bool CheckParam(int32_t instanceNum)
{
if (instanceNum == 0 || instanceNum == 1) {
return true;
}
return false;
}
int32_t TjdPhoneAudio::PhoneAudioManagerActInterrupt(AudioStreamType streamType)
{
/* request audio focus */
static_print_debug("[%s] streamType:0x%x", __FUNCTION__, streamType);
sessionId_ = amInstance_.MakeSessionId();
if (sessionId_ == AUDIO_SESSION_ID_NONE) {
static_print_error("[%s] line:%d, make session id failed", __FUNCTION__, __LINE__);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d, session id = %d", __FUNCTION__, __LINE__, sessionId_);
g_audioIntListener = std::make_shared<PhoneAudioInterruptListener>();
if (g_audioIntListener.get() == nullptr) {
static_print_error("[%s] line:%d, g_audioIntListener is null", __FUNCTION__, __LINE__);
return AUDIO_ERROR;
}
interrupt_ = {streamType, sessionId_, g_audioIntListener};
if (amInstance_.ActivateAudioInterrupt(interrupt_) == INTERRUPT_FAILED) {
static_print_error("[%s] line:%d, ActivateAudioInterrupt failed", __FUNCTION__, __LINE__);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d, success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioManagerSetDeviceConnState(AudioDeviceType deviceType,
AudioDeviceConnectState connectState)
{
int32_t ret = amInstance_.SetDeviceConnectionState(deviceType, connectState);
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d failed, deviceType = 0x%x connectState = %d ret = %d", __FUNCTION__, __LINE__,
deviceType, connectState, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d success, deviceType = 0x%x connectState = %d", __FUNCTION__, __LINE__, deviceType,
connectState);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamInInit(AudioLinkDirection linkDir)
{
int32_t instanceNum = INVALID_AUDIO_VALUE;
static_print_debug("[%s] linkDir:0x%x", __FUNCTION__, linkDir);
/* create ASI instance UP_LINK: index 0, DOWN_LINK: index 1 */
if (linkDir == AUDIO_UP_LINK) {
g_streamIn[0] = std::make_shared<AudioStreamIn>();
instanceNum = 0;
} else if (linkDir == AUDIO_DOWN_LINK) {
g_streamIn[1] = std::make_shared<AudioStreamIn>();
instanceNum = 1;
} else {
static_print_error("[%s] line:%d failed, invalid linkDir = %d", __FUNCTION__, __LINE__, linkDir);
return AUDIO_ERROR;
}
if (g_streamIn[instanceNum] == nullptr || g_streamIn[instanceNum].get() == nullptr) {
static_print_error("[%s] line:%d make_shared AudioStreamIn failed", __FUNCTION__, __LINE__);
return AUDIO_ERROR;
}
/* init ASI */
CapturerInputConfig captureConfig = {
.streamType = AUDIO_STREAM_VOICE_CALL_BT_SCO,
.sessionID = sessionId_,
.channelCount = AUDIO_CHANNEL_1,
.linkDir = linkDir,
};
captureConfig.audioFormat = (AudioCodecFormat)GetCallAudioCodec();
if (captureConfig.audioFormat == PCM) {
captureConfig.sampleRate = AUDIO_SAMPLE_RATE_8K;
} else if (captureConfig.audioFormat == mSBC) {
captureConfig.sampleRate = AUDIO_SAMPLE_RATE_16K;
}
int32_t ret = g_streamIn[instanceNum]->Init(captureConfig);
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamIn init failed, ret: 0x%x", __FUNCTION__, __LINE__, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d success, instanceNum = %d", __FUNCTION__, __LINE__, instanceNum);
return instanceNum;
}
int32_t TjdPhoneAudio::PhoneAudioStreamOutInit(AudioLinkDirection linkDir)
{
int32_t instanceNum = INVALID_AUDIO_VALUE;
static_print_debug("[%s] linkDir:0x%x", __FUNCTION__, linkDir);
/* create ASO instance UP_LINK: index 0, DOWN_LINK: index 1 */
if (linkDir == AUDIO_UP_LINK) {
g_streamOut[0] = std::make_shared<AudioStreamOut>();
instanceNum = 0;
} else if (linkDir == AUDIO_DOWN_LINK) {
g_streamOut[1] = std::make_shared<AudioStreamOut>();
instanceNum = 1;
} else {
static_print_error("[%s] line:%d failed, invalid linkDir = %d", __FUNCTION__, __LINE__, linkDir);
return AUDIO_ERROR;
}
if (g_streamOut[instanceNum] == nullptr || g_streamOut[instanceNum].get() == nullptr) {
static_print_error("[%s] line:%d make_shared AudioStreamOut failed", __FUNCTION__, __LINE__);
return AUDIO_ERROR;
}
/* init ASO */
AudioRendererConfig renderConfig = {
.streamType = AUDIO_STREAM_VOICE_CALL_BT_SCO,
.sessionID = sessionId_,
.channelCount = AUDIO_CHANNEL_1,
.linkDir = linkDir,
};
renderConfig.audioFormat = (AudioCodecFormat)GetCallAudioCodec();
if (renderConfig.audioFormat == PCM) {
renderConfig.sampleRate = AUDIO_SAMPLE_RATE_8K;
} else if (renderConfig.audioFormat == mSBC) {
renderConfig.sampleRate = AUDIO_SAMPLE_RATE_16K;
}
int32_t ret = g_streamOut[instanceNum]->Init(renderConfig);
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamOut init failed, ret: 0x%x", __FUNCTION__, __LINE__, ret);
return AUDIO_ERROR;
}
/* dump stream */
g_streamOut[instanceNum]->DumpInfo();
static_print_debug("[%s] line:%d success, instanceNum = %d", __FUNCTION__, __LINE__, instanceNum);
return instanceNum;
}
int32_t TjdPhoneAudio::PhoneAudioStreamInStart(int32_t instanceNum)
{
static_print_debug("[%s] instanceNum:0x%x", __FUNCTION__, instanceNum);
bool isValid = CheckParam(instanceNum);
if (!isValid) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* start ASI */
int32_t ret = g_streamIn[instanceNum]->Start();
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamIn Start failed ret: 0x%x", __FUNCTION__, __LINE__, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamOutStart(int32_t instanceNum)
{
static_print_debug("[%s] instanceNum:0x%x", __FUNCTION__, instanceNum);
bool isValid = CheckParam(instanceNum);
if (!isValid) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* start ASO */
int32_t ret = g_streamOut[instanceNum]->Play();
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamOut Play failed ret: 0x%x", __FUNCTION__, __LINE__, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamInGetChannelId(int32_t instanceNum, uint32_t *shmId)
{
bool isValid = CheckParam(instanceNum);
if (!isValid || shmId == nullptr) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* obtain ASI channel id(adp handle) */
uint32_t channelId;
int32_t ret = g_streamIn[instanceNum]->GetCurrentChannelId(channelId);
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamIn get Id failed ret: 0x%x", __FUNCTION__, __LINE__, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d stream in channelId: 0x%x", __FUNCTION__, __LINE__, channelId);
*shmId = channelId;
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamOutGetChannelId(int32_t instanceNum, uint32_t *shmId)
{
bool isValid = CheckParam(instanceNum);
if (!isValid || shmId == nullptr) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* obtain ASO channel id(adp handle) */
uint32_t channelId;
int32_t ret = g_streamOut[instanceNum]->GetCurrentChannelId(channelId);
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamOut get Id failed ret: 0x%x", __FUNCTION__, __LINE__, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d stream out channelId: 0x%x", __FUNCTION__, __LINE__, channelId);
*shmId = channelId;
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamInAttachBackend(int32_t instanceNum, uint32_t backendId)
{
bool isValid = CheckParam(instanceNum);
if (!isValid) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* ASI set shm id */
int32_t ret = g_streamIn[instanceNum]->AttachBackend(backendId);
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamIn AttachBackend failed backendId: 0x%x, ret: 0x%x", __FUNCTION__,
__LINE__, backendId, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d, stream in instanceNum: %d, backendId: 0x%x", __FUNCTION__, __LINE__, instanceNum,
backendId);
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamOutAttachFrontend(int32_t instanceNum, uint32_t frontendId)
{
bool isValid = CheckParam(instanceNum);
if (!isValid) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* ASO set shm id */
int32_t ret = g_streamOut[instanceNum]->AttachFrontend(frontendId);
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamOut AttachFrontend failed frontendId: 0x%x, ret: 0x%x", __FUNCTION__,
__LINE__, frontendId, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d, stream out instanceNum: %d, frontendId: 0x%x", __FUNCTION__, __LINE__,
instanceNum, frontendId);
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamInStop(int32_t instanceNum)
{
bool isValid = CheckParam(instanceNum);
if (!isValid) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* stop ASI */
int32_t ret = g_streamIn[instanceNum]->Stop();
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamIn Stop failed ret: 0x%x", __FUNCTION__, __LINE__, ret);
}
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamOutStop(int32_t instanceNum)
{
bool isValid = CheckParam(instanceNum);
if (!isValid) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* stop ASO */
int32_t ret = g_streamOut[instanceNum]->Stop();
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d streamOut Stop failed ret: 0x%x", __FUNCTION__, __LINE__, ret);
}
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamInDeinit(int32_t instanceNum)
{
bool isValid = CheckParam(instanceNum);
if (!isValid) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* deinit ASI */
if (g_streamIn[instanceNum] != nullptr) {
g_streamIn[instanceNum]->Release();
g_streamIn[instanceNum] = nullptr;
}
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioStreamOutDeinit(int32_t instanceNum)
{
bool isValid = CheckParam(instanceNum);
if (!isValid) {
static_print_error("[%s] line:%d instanceNum %d is invalid", __FUNCTION__, __LINE__, instanceNum);
return AUDIO_ERROR;
}
/* deinit ASO */
if (g_streamOut[instanceNum] != nullptr) {
g_streamOut[instanceNum]->Release();
g_streamOut[instanceNum] = nullptr;
}
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}
int32_t TjdPhoneAudio::PhoneAudioManagerDeactInterrupt(void)
{
/* release audio focus */
int32_t ret = amInstance_.DeactivateAudioInterrupt(interrupt_);
if (ret != AUDIO_SUCCESS) {
static_print_error("[%s] line:%d DeactivateAudioInterrupt failed ret = %d", __FUNCTION__, __LINE__, ret);
return AUDIO_ERROR;
}
static_print_debug("[%s] line:%d success", __FUNCTION__, __LINE__);
return AUDIO_SUCCESS;
}