150a07fd2Sopenharmony_ci/* 250a07fd2Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 350a07fd2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 450a07fd2Sopenharmony_ci * you may not use this file except in compliance with the License. 550a07fd2Sopenharmony_ci * You may obtain a copy of the License at 650a07fd2Sopenharmony_ci * 750a07fd2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 850a07fd2Sopenharmony_ci * 950a07fd2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1050a07fd2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1150a07fd2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1250a07fd2Sopenharmony_ci * See the License for the specific language governing permissions and 1350a07fd2Sopenharmony_ci * limitations under the License. 1450a07fd2Sopenharmony_ci */ 1550a07fd2Sopenharmony_ci 1650a07fd2Sopenharmony_ci#include "dspeaker_client.h" 1750a07fd2Sopenharmony_ci 1850a07fd2Sopenharmony_ci#include "cJSON.h" 1950a07fd2Sopenharmony_ci 2050a07fd2Sopenharmony_ci#include "daudio_constants.h" 2150a07fd2Sopenharmony_ci#include "daudio_hisysevent.h" 2250a07fd2Sopenharmony_ci#include "daudio_sink_hidumper.h" 2350a07fd2Sopenharmony_ci#include "daudio_util.h" 2450a07fd2Sopenharmony_ci#include "daudio_sink_manager.h" 2550a07fd2Sopenharmony_ci 2650a07fd2Sopenharmony_ci#undef DH_LOG_TAG 2750a07fd2Sopenharmony_ci#define DH_LOG_TAG "DSpeakerClient" 2850a07fd2Sopenharmony_ci 2950a07fd2Sopenharmony_cinamespace OHOS { 3050a07fd2Sopenharmony_cinamespace DistributedHardware { 3150a07fd2Sopenharmony_ciDSpeakerClient::~DSpeakerClient() 3250a07fd2Sopenharmony_ci{ 3350a07fd2Sopenharmony_ci DHLOGD("Release speaker client."); 3450a07fd2Sopenharmony_ci} 3550a07fd2Sopenharmony_ci 3650a07fd2Sopenharmony_civoid DSpeakerClient::OnEngineTransEvent(const AVTransEvent &event) 3750a07fd2Sopenharmony_ci{ 3850a07fd2Sopenharmony_ci if (event.type == EventType::EVENT_START_SUCCESS) { 3950a07fd2Sopenharmony_ci OnStateChange(DATA_OPENED); 4050a07fd2Sopenharmony_ci } else if ((event.type == EventType::EVENT_STOP_SUCCESS) || 4150a07fd2Sopenharmony_ci (event.type == EventType::EVENT_CHANNEL_CLOSED) || 4250a07fd2Sopenharmony_ci (event.type == EventType::EVENT_START_FAIL)) { 4350a07fd2Sopenharmony_ci OnStateChange(DATA_CLOSED); 4450a07fd2Sopenharmony_ci } 4550a07fd2Sopenharmony_ci} 4650a07fd2Sopenharmony_ci 4750a07fd2Sopenharmony_civoid DSpeakerClient::OnEngineTransMessage(const std::shared_ptr<AVTransMessage> &message) 4850a07fd2Sopenharmony_ci{ 4950a07fd2Sopenharmony_ci CHECK_NULL_VOID(message); 5050a07fd2Sopenharmony_ci DHLOGI("On Engine message, type : %{public}s.", GetEventNameByType(message->type_).c_str()); 5150a07fd2Sopenharmony_ci DAudioSinkManager::GetInstance().HandleDAudioNotify(message->dstDevId_, message->dstDevId_, 5250a07fd2Sopenharmony_ci static_cast<int32_t>(message->type_), message->content_); 5350a07fd2Sopenharmony_ci} 5450a07fd2Sopenharmony_ci 5550a07fd2Sopenharmony_civoid DSpeakerClient::OnEngineTransDataAvailable(const std::shared_ptr<AudioData> &audioData) 5650a07fd2Sopenharmony_ci{ 5750a07fd2Sopenharmony_ci DHLOGI("On Engine Data available"); 5850a07fd2Sopenharmony_ci OnDecodeTransDataDone(audioData); 5950a07fd2Sopenharmony_ci} 6050a07fd2Sopenharmony_ci 6150a07fd2Sopenharmony_ciint32_t DSpeakerClient::InitReceiverEngine(IAVEngineProvider *providerPtr) 6250a07fd2Sopenharmony_ci{ 6350a07fd2Sopenharmony_ci DHLOGI("InitReceiverEngine enter."); 6450a07fd2Sopenharmony_ci if (speakerTrans_ == nullptr) { 6550a07fd2Sopenharmony_ci speakerTrans_ = std::make_shared<AVTransReceiverTransport>(devId_, shared_from_this()); 6650a07fd2Sopenharmony_ci } 6750a07fd2Sopenharmony_ci int32_t ret = speakerTrans_->InitEngine(providerPtr); 6850a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 6950a07fd2Sopenharmony_ci DHLOGE("Spk client initialize av receiver adapter failed."); 7050a07fd2Sopenharmony_ci return ERR_DH_AUDIO_NULLPTR; 7150a07fd2Sopenharmony_ci } 7250a07fd2Sopenharmony_ci return DH_SUCCESS; 7350a07fd2Sopenharmony_ci} 7450a07fd2Sopenharmony_ci 7550a07fd2Sopenharmony_ciint32_t DSpeakerClient::CreateAudioRenderer(const AudioParam ¶m) 7650a07fd2Sopenharmony_ci{ 7750a07fd2Sopenharmony_ci DHLOGD("Set up spk client: {sampleRate: %{public}d, bitFormat: %{public}d, channelMask: %{public}d," 7850a07fd2Sopenharmony_ci "frameSize: %{public}d, contentType: %{public}d, renderFlags: %{public}d, streamUsage: %{public}d}.", 7950a07fd2Sopenharmony_ci param.comParam.sampleRate, param.comParam.bitFormat, param.comParam.channelMask, param.comParam.frameSize, 8050a07fd2Sopenharmony_ci param.renderOpts.contentType, param.renderOpts.renderFlags, param.renderOpts.streamUsage); 8150a07fd2Sopenharmony_ci audioParam_ = param; 8250a07fd2Sopenharmony_ci AudioStandard::AudioRendererOptions rendererOptions = { 8350a07fd2Sopenharmony_ci { 8450a07fd2Sopenharmony_ci static_cast<AudioStandard::AudioSamplingRate>(audioParam_.comParam.sampleRate), 8550a07fd2Sopenharmony_ci AudioStandard::AudioEncodingType::ENCODING_PCM, 8650a07fd2Sopenharmony_ci static_cast<AudioStandard::AudioSampleFormat>(audioParam_.comParam.bitFormat), 8750a07fd2Sopenharmony_ci static_cast<AudioStandard::AudioChannel>(audioParam_.comParam.channelMask), 8850a07fd2Sopenharmony_ci }, 8950a07fd2Sopenharmony_ci { 9050a07fd2Sopenharmony_ci static_cast<AudioStandard::ContentType>(audioParam_.renderOpts.contentType), 9150a07fd2Sopenharmony_ci static_cast<AudioStandard::StreamUsage>(audioParam_.renderOpts.streamUsage), 9250a07fd2Sopenharmony_ci audioParam_.renderOpts.renderFlags == MMAP_MODE ? AudioStandard::STREAM_FLAG_FAST : 0, 9350a07fd2Sopenharmony_ci } 9450a07fd2Sopenharmony_ci }; 9550a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lck(devMtx_); 9650a07fd2Sopenharmony_ci audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions); 9750a07fd2Sopenharmony_ci CHECK_NULL_RETURN(audioRenderer_, ERR_DH_AUDIO_CLIENT_RENDER_CREATE_FAILED); 9850a07fd2Sopenharmony_ci 9950a07fd2Sopenharmony_ci audioRenderer_ ->SetRendererCallback(shared_from_this()); 10050a07fd2Sopenharmony_ci if (audioParam_.renderOpts.renderFlags != MMAP_MODE) { 10150a07fd2Sopenharmony_ci return DH_SUCCESS; 10250a07fd2Sopenharmony_ci } 10350a07fd2Sopenharmony_ci int32_t ret = audioRenderer_->SetRendererWriteCallback(shared_from_this()); 10450a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 10550a07fd2Sopenharmony_ci DHLOGE("Client save write callback failed."); 10650a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_RENDER_CREATE_FAILED; 10750a07fd2Sopenharmony_ci } 10850a07fd2Sopenharmony_ci return DH_SUCCESS; 10950a07fd2Sopenharmony_ci} 11050a07fd2Sopenharmony_ci 11150a07fd2Sopenharmony_civoid DSpeakerClient::OnWriteData(size_t length) 11250a07fd2Sopenharmony_ci{ 11350a07fd2Sopenharmony_ci AudioStandard::BufferDesc bufDesc; 11450a07fd2Sopenharmony_ci CHECK_NULL_VOID(audioRenderer_); 11550a07fd2Sopenharmony_ci if (audioRenderer_->GetBufferDesc(bufDesc) != DH_SUCCESS || bufDesc.bufLength == 0) { 11650a07fd2Sopenharmony_ci DHLOGE("Get buffer desc failed."); 11750a07fd2Sopenharmony_ci return; 11850a07fd2Sopenharmony_ci } 11950a07fd2Sopenharmony_ci CHECK_NULL_VOID(bufDesc.buffer); 12050a07fd2Sopenharmony_ci 12150a07fd2Sopenharmony_ci std::shared_ptr<AudioData> audioData = nullptr; 12250a07fd2Sopenharmony_ci { 12350a07fd2Sopenharmony_ci std::unique_lock<std::mutex> spkLck(dataQueueMtx_); 12450a07fd2Sopenharmony_ci if (dataQueue_.empty()) { 12550a07fd2Sopenharmony_ci audioData = std::make_shared<AudioData>(bufDesc.bufLength); 12650a07fd2Sopenharmony_ci DHLOGD("Pop spk data, dataQueue is empty. write empty data."); 12750a07fd2Sopenharmony_ci } else { 12850a07fd2Sopenharmony_ci audioData = dataQueue_.front(); 12950a07fd2Sopenharmony_ci dataQueue_.pop(); 13050a07fd2Sopenharmony_ci uint64_t queueSize = static_cast<uint64_t>(dataQueue_.size()); 13150a07fd2Sopenharmony_ci DHLOGD("Pop spk data, dataQueue size: %{public}" PRIu64, queueSize); 13250a07fd2Sopenharmony_ci } 13350a07fd2Sopenharmony_ci } 13450a07fd2Sopenharmony_ci if ((audioData != nullptr) && (audioData->Capacity() != bufDesc.bufLength)) { 13550a07fd2Sopenharmony_ci uint64_t capacity = static_cast<uint64_t>(audioData->Capacity()); 13650a07fd2Sopenharmony_ci uint64_t bufLength = static_cast<uint64_t>(bufDesc.bufLength); 13750a07fd2Sopenharmony_ci DHLOGE("Audio data length is not equal to buflength. datalength: %{public}" PRIu64 13850a07fd2Sopenharmony_ci ", bufLength: %{public}" PRIu64, capacity, bufLength); 13950a07fd2Sopenharmony_ci } 14050a07fd2Sopenharmony_ci if (memcpy_s(bufDesc.buffer, bufDesc.bufLength, audioData->Data(), audioData->Capacity()) != EOK) { 14150a07fd2Sopenharmony_ci DHLOGE("Copy audio data failed."); 14250a07fd2Sopenharmony_ci } 14350a07fd2Sopenharmony_ci audioRenderer_->Enqueue(bufDesc); 14450a07fd2Sopenharmony_ci} 14550a07fd2Sopenharmony_ci 14650a07fd2Sopenharmony_ciint32_t DSpeakerClient::SetUp(const AudioParam ¶m) 14750a07fd2Sopenharmony_ci{ 14850a07fd2Sopenharmony_ci int32_t ret = CreateAudioRenderer(param); 14950a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 15050a07fd2Sopenharmony_ci DHLOGE("Set up failed, Create Audio renderer failed."); 15150a07fd2Sopenharmony_ci return ret; 15250a07fd2Sopenharmony_ci } 15350a07fd2Sopenharmony_ci DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, DUMP_DAUDIO_SPK_AFTER_TRANS_NAME, &dumpFile_); 15450a07fd2Sopenharmony_ci CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR); 15550a07fd2Sopenharmony_ci ret = speakerTrans_->SetUp(audioParam_, audioParam_, shared_from_this(), CAP_SPK); 15650a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 15750a07fd2Sopenharmony_ci DHLOGE("Speaker trans setup failed."); 15850a07fd2Sopenharmony_ci return ret; 15950a07fd2Sopenharmony_ci } 16050a07fd2Sopenharmony_ci ret = speakerTrans_->Start(); 16150a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 16250a07fd2Sopenharmony_ci DHLOGE("Speaker trans start failed."); 16350a07fd2Sopenharmony_ci return ret; 16450a07fd2Sopenharmony_ci } 16550a07fd2Sopenharmony_ci auto pid = getprocpid(); 16650a07fd2Sopenharmony_ci ret = AudioStandard::AudioSystemManager::GetInstance()->RegisterVolumeKeyEventCallback(pid, shared_from_this()); 16750a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 16850a07fd2Sopenharmony_ci DHLOGE("Failed to register volume key event callback."); 16950a07fd2Sopenharmony_ci return ret; 17050a07fd2Sopenharmony_ci } 17150a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_READY; 17250a07fd2Sopenharmony_ci return DH_SUCCESS; 17350a07fd2Sopenharmony_ci} 17450a07fd2Sopenharmony_ci 17550a07fd2Sopenharmony_ciint32_t DSpeakerClient::Release() 17650a07fd2Sopenharmony_ci{ 17750a07fd2Sopenharmony_ci DHLOGI("Release spk client."); 17850a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lck(devMtx_); 17950a07fd2Sopenharmony_ci if (clientStatus_ != AudioStatus::STATUS_READY && clientStatus_ != AudioStatus::STATUS_STOP) { 18050a07fd2Sopenharmony_ci DHLOGE("Speaker status %{public}d is wrong.", (int32_t)clientStatus_); 18150a07fd2Sopenharmony_ci return ERR_DH_AUDIO_SA_STATUS_ERR; 18250a07fd2Sopenharmony_ci } 18350a07fd2Sopenharmony_ci bool isSucess = true; 18450a07fd2Sopenharmony_ci if (speakerTrans_ != nullptr) { 18550a07fd2Sopenharmony_ci if (speakerTrans_->Stop() != DH_SUCCESS) { 18650a07fd2Sopenharmony_ci DHLOGE("Speaker trans stop failed."); 18750a07fd2Sopenharmony_ci isSucess = false; 18850a07fd2Sopenharmony_ci } 18950a07fd2Sopenharmony_ci if (speakerTrans_->Release() != DH_SUCCESS) { 19050a07fd2Sopenharmony_ci DHLOGE("Speaker trans release failed."); 19150a07fd2Sopenharmony_ci isSucess = false; 19250a07fd2Sopenharmony_ci } 19350a07fd2Sopenharmony_ci speakerTrans_ = nullptr; 19450a07fd2Sopenharmony_ci } 19550a07fd2Sopenharmony_ci 19650a07fd2Sopenharmony_ci int32_t ret = AudioStandard::AudioSystemManager::GetInstance()->UnregisterVolumeKeyEventCallback(getprocpid()); 19750a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 19850a07fd2Sopenharmony_ci DHLOGE("Failed to unregister volume key event callback, error code %{public}d.", ret); 19950a07fd2Sopenharmony_ci isSucess = false; 20050a07fd2Sopenharmony_ci } 20150a07fd2Sopenharmony_ci if (audioRenderer_ != nullptr && !audioRenderer_->Release()) { 20250a07fd2Sopenharmony_ci DHLOGE("Audio renderer release failed."); 20350a07fd2Sopenharmony_ci isSucess = false; 20450a07fd2Sopenharmony_ci audioRenderer_ = nullptr; 20550a07fd2Sopenharmony_ci } 20650a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_IDLE; 20750a07fd2Sopenharmony_ci DumpFileUtil::CloseDumpFile(&dumpFile_); 20850a07fd2Sopenharmony_ci return isSucess ? DH_SUCCESS : ERR_DH_AUDIO_CLIENT_RENDER_RELEASE_FAILED; 20950a07fd2Sopenharmony_ci} 21050a07fd2Sopenharmony_ci 21150a07fd2Sopenharmony_ciint32_t DSpeakerClient::StartRender() 21250a07fd2Sopenharmony_ci{ 21350a07fd2Sopenharmony_ci DHLOGI("Start spk client."); 21450a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lck(devMtx_); 21550a07fd2Sopenharmony_ci CHECK_NULL_RETURN(audioRenderer_, ERR_DH_AUDIO_SA_STATUS_ERR); 21650a07fd2Sopenharmony_ci 21750a07fd2Sopenharmony_ci if (!audioRenderer_->Start()) { 21850a07fd2Sopenharmony_ci DHLOGE("Audio renderer start failed."); 21950a07fd2Sopenharmony_ci DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_STARTUP_FAILURE, 22050a07fd2Sopenharmony_ci "daudio renderer start failed."); 22150a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_RENDER_STARTUP_FAILURE; 22250a07fd2Sopenharmony_ci } 22350a07fd2Sopenharmony_ci if (audioParam_.renderOpts.renderFlags != MMAP_MODE) { 22450a07fd2Sopenharmony_ci isRenderReady_.store(true); 22550a07fd2Sopenharmony_ci renderDataThread_ = std::thread([this]() { this->PlayThreadRunning(); }); 22650a07fd2Sopenharmony_ci } 22750a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_START; 22850a07fd2Sopenharmony_ci return DH_SUCCESS; 22950a07fd2Sopenharmony_ci} 23050a07fd2Sopenharmony_ci 23150a07fd2Sopenharmony_ciint32_t DSpeakerClient::StopRender() 23250a07fd2Sopenharmony_ci{ 23350a07fd2Sopenharmony_ci DHLOGI("Stop spk client."); 23450a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lck(devMtx_); 23550a07fd2Sopenharmony_ci if (clientStatus_ != AudioStatus::STATUS_START) { 23650a07fd2Sopenharmony_ci DHLOGE("Renderer is not start or spk status wrong, status: %{public}d.", (int32_t)clientStatus_); 23750a07fd2Sopenharmony_ci DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_SA_STATUS_ERR, 23850a07fd2Sopenharmony_ci "daudio renderer is not start or spk status wrong."); 23950a07fd2Sopenharmony_ci return ERR_DH_AUDIO_SA_STATUS_ERR; 24050a07fd2Sopenharmony_ci } 24150a07fd2Sopenharmony_ci if (audioRenderer_ == nullptr) { 24250a07fd2Sopenharmony_ci DHLOGE("Audio renderer is nullptr."); 24350a07fd2Sopenharmony_ci DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_NULLPTR, 24450a07fd2Sopenharmony_ci "daudio renderer is nullptr."); 24550a07fd2Sopenharmony_ci return ERR_DH_AUDIO_NULLPTR; 24650a07fd2Sopenharmony_ci } 24750a07fd2Sopenharmony_ci 24850a07fd2Sopenharmony_ci if (audioParam_.renderOpts.renderFlags != MMAP_MODE) { 24950a07fd2Sopenharmony_ci if (isRenderReady_.load()) { 25050a07fd2Sopenharmony_ci isRenderReady_.store(false); 25150a07fd2Sopenharmony_ci if (renderDataThread_.joinable()) { 25250a07fd2Sopenharmony_ci renderDataThread_.join(); 25350a07fd2Sopenharmony_ci } 25450a07fd2Sopenharmony_ci } 25550a07fd2Sopenharmony_ci } 25650a07fd2Sopenharmony_ci 25750a07fd2Sopenharmony_ci if (!audioRenderer_->Stop()) { 25850a07fd2Sopenharmony_ci DHLOGE("Audio renderer stop failed"); 25950a07fd2Sopenharmony_ci DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_STOP_FAILED, 26050a07fd2Sopenharmony_ci "daudio renderer stop failed."); 26150a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_RENDER_STOP_FAILED; 26250a07fd2Sopenharmony_ci } 26350a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_STOP; 26450a07fd2Sopenharmony_ci return DH_SUCCESS; 26550a07fd2Sopenharmony_ci} 26650a07fd2Sopenharmony_ci 26750a07fd2Sopenharmony_civoid DSpeakerClient::PlayThreadRunning() 26850a07fd2Sopenharmony_ci{ 26950a07fd2Sopenharmony_ci DHLOGD("Start the renderer thread."); 27050a07fd2Sopenharmony_ci if (pthread_setname_np(pthread_self(), RENDERTHREAD) != DH_SUCCESS) { 27150a07fd2Sopenharmony_ci DHLOGE("Render data thread setname failed."); 27250a07fd2Sopenharmony_ci } 27350a07fd2Sopenharmony_ci 27450a07fd2Sopenharmony_ci FillJitterQueue(); 27550a07fd2Sopenharmony_ci while (audioRenderer_ != nullptr && isRenderReady_.load()) { 27650a07fd2Sopenharmony_ci int64_t startTime = GetNowTimeUs(); 27750a07fd2Sopenharmony_ci std::shared_ptr<AudioData> audioData = nullptr; 27850a07fd2Sopenharmony_ci { 27950a07fd2Sopenharmony_ci std::unique_lock<std::mutex> spkLck(dataQueueMtx_); 28050a07fd2Sopenharmony_ci dataQueueCond_.wait_for(spkLck, std::chrono::milliseconds(REQUEST_DATA_WAIT), 28150a07fd2Sopenharmony_ci [this]() { return !dataQueue_.empty(); }); 28250a07fd2Sopenharmony_ci if (dataQueue_.empty()) { 28350a07fd2Sopenharmony_ci continue; 28450a07fd2Sopenharmony_ci } 28550a07fd2Sopenharmony_ci audioData = dataQueue_.front(); 28650a07fd2Sopenharmony_ci dataQueue_.pop(); 28750a07fd2Sopenharmony_ci uint64_t queueSize = static_cast<uint64_t>(dataQueue_.size()); 28850a07fd2Sopenharmony_ci DHLOGD("Pop spk data, dataqueue size: %{public}" PRIu64, queueSize); 28950a07fd2Sopenharmony_ci } 29050a07fd2Sopenharmony_ci if (audioData == nullptr) { 29150a07fd2Sopenharmony_ci continue; 29250a07fd2Sopenharmony_ci } 29350a07fd2Sopenharmony_ci DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(audioData->Data()), audioData->Size()); 29450a07fd2Sopenharmony_ci int32_t writeOffSet = 0; 29550a07fd2Sopenharmony_ci while (writeOffSet < static_cast<int32_t>(audioData->Capacity())) { 29650a07fd2Sopenharmony_ci int32_t writeLen = audioRenderer_->Write(audioData->Data() + writeOffSet, 29750a07fd2Sopenharmony_ci static_cast<int32_t>(audioData->Capacity()) - writeOffSet); 29850a07fd2Sopenharmony_ci uint64_t capacity = static_cast<uint64_t>(audioData->Capacity()); 29950a07fd2Sopenharmony_ci DHLOGD("Write audio render, write len: %{public}d, raw len: %{public}" PRIu64", offset: %{public}d", 30050a07fd2Sopenharmony_ci writeLen, capacity, writeOffSet); 30150a07fd2Sopenharmony_ci if (writeLen < 0) { 30250a07fd2Sopenharmony_ci break; 30350a07fd2Sopenharmony_ci } 30450a07fd2Sopenharmony_ci writeOffSet += writeLen; 30550a07fd2Sopenharmony_ci } 30650a07fd2Sopenharmony_ci int64_t endTime = GetNowTimeUs(); 30750a07fd2Sopenharmony_ci if (IsOutDurationRange(startTime, endTime, lastPlayStartTime_)) { 30850a07fd2Sopenharmony_ci DHLOGE("This time play spend: %{public}" PRId64" us, The interval of play this time and " 30950a07fd2Sopenharmony_ci "the last time: %{public}" PRId64" us", endTime - startTime, startTime - lastPlayStartTime_); 31050a07fd2Sopenharmony_ci } 31150a07fd2Sopenharmony_ci lastPlayStartTime_ = startTime; 31250a07fd2Sopenharmony_ci } 31350a07fd2Sopenharmony_ci} 31450a07fd2Sopenharmony_ci 31550a07fd2Sopenharmony_civoid DSpeakerClient::FillJitterQueue() 31650a07fd2Sopenharmony_ci{ 31750a07fd2Sopenharmony_ci while (isRenderReady_.load()) { 31850a07fd2Sopenharmony_ci { 31950a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lock(dataQueueMtx_); 32050a07fd2Sopenharmony_ci if (dataQueue_.size() >= DATA_QUEUE_SIZE) { 32150a07fd2Sopenharmony_ci break; 32250a07fd2Sopenharmony_ci } 32350a07fd2Sopenharmony_ci } 32450a07fd2Sopenharmony_ci usleep(SLEEP_TIME); 32550a07fd2Sopenharmony_ci } 32650a07fd2Sopenharmony_ci} 32750a07fd2Sopenharmony_ci 32850a07fd2Sopenharmony_civoid DSpeakerClient::FlushJitterQueue() 32950a07fd2Sopenharmony_ci{ 33050a07fd2Sopenharmony_ci while (isRenderReady_.load()) { 33150a07fd2Sopenharmony_ci { 33250a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lock(dataQueueMtx_); 33350a07fd2Sopenharmony_ci if (dataQueue_.empty()) { 33450a07fd2Sopenharmony_ci break; 33550a07fd2Sopenharmony_ci } 33650a07fd2Sopenharmony_ci } 33750a07fd2Sopenharmony_ci usleep(SLEEP_TIME); 33850a07fd2Sopenharmony_ci } 33950a07fd2Sopenharmony_ci} 34050a07fd2Sopenharmony_ci 34150a07fd2Sopenharmony_ciint32_t DSpeakerClient::OnDecodeTransDataDone(const std::shared_ptr<AudioData> &audioData) 34250a07fd2Sopenharmony_ci{ 34350a07fd2Sopenharmony_ci DHLOGI("Write stream buffer."); 34450a07fd2Sopenharmony_ci int64_t startTime = GetNowTimeUs(); 34550a07fd2Sopenharmony_ci CHECK_NULL_RETURN(audioData, ERR_DH_AUDIO_NULLPTR); 34650a07fd2Sopenharmony_ci 34750a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lock(dataQueueMtx_); 34850a07fd2Sopenharmony_ci while (dataQueue_.size() > DATA_QUEUE_MAX_SIZE) { 34950a07fd2Sopenharmony_ci DHLOGD("Data queue overflow."); 35050a07fd2Sopenharmony_ci dataQueue_.pop(); 35150a07fd2Sopenharmony_ci } 35250a07fd2Sopenharmony_ci dataQueue_.push(audioData); 35350a07fd2Sopenharmony_ci dataQueueCond_.notify_all(); 35450a07fd2Sopenharmony_ci uint64_t queueSize = static_cast<uint64_t>(dataQueue_.size()); 35550a07fd2Sopenharmony_ci DHLOGD("Push new spk data, buf len: %{public}" PRIu64, queueSize); 35650a07fd2Sopenharmony_ci int64_t endTime = GetNowTimeUs(); 35750a07fd2Sopenharmony_ci if (IsOutDurationRange(startTime, endTime, lastReceiveStartTime_)) { 35850a07fd2Sopenharmony_ci DHLOGE("This time receivce data spend: %{public}" PRId64" us, Receivce data this time and " 35950a07fd2Sopenharmony_ci "the last time: %{public}" PRId64" us", endTime - startTime, startTime - lastReceiveStartTime_); 36050a07fd2Sopenharmony_ci } 36150a07fd2Sopenharmony_ci lastReceiveStartTime_ = startTime; 36250a07fd2Sopenharmony_ci return DH_SUCCESS; 36350a07fd2Sopenharmony_ci} 36450a07fd2Sopenharmony_ci 36550a07fd2Sopenharmony_ciint32_t DSpeakerClient::OnStateChange(const AudioEventType type) 36650a07fd2Sopenharmony_ci{ 36750a07fd2Sopenharmony_ci DHLOGD("On state change. type: %{public}d", type); 36850a07fd2Sopenharmony_ci AudioEvent event; 36950a07fd2Sopenharmony_ci switch (type) { 37050a07fd2Sopenharmony_ci case AudioEventType::DATA_OPENED: { 37150a07fd2Sopenharmony_ci event.type = AudioEventType::SPEAKER_OPENED; 37250a07fd2Sopenharmony_ci event.content = GetVolumeLevel(); 37350a07fd2Sopenharmony_ci break; 37450a07fd2Sopenharmony_ci } 37550a07fd2Sopenharmony_ci case AudioEventType::DATA_CLOSED: { 37650a07fd2Sopenharmony_ci event.type = AudioEventType::SPEAKER_CLOSED; 37750a07fd2Sopenharmony_ci event.content = GetCJsonString(KEY_DH_ID, std::to_string(dhId_).c_str()); 37850a07fd2Sopenharmony_ci break; 37950a07fd2Sopenharmony_ci } 38050a07fd2Sopenharmony_ci default: 38150a07fd2Sopenharmony_ci DHLOGE("Invalid parameter type: %{public}d.", type); 38250a07fd2Sopenharmony_ci return ERR_DH_AUDIO_NOT_SUPPORT; 38350a07fd2Sopenharmony_ci } 38450a07fd2Sopenharmony_ci 38550a07fd2Sopenharmony_ci std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock(); 38650a07fd2Sopenharmony_ci CHECK_NULL_RETURN(cbObj, ERR_DH_AUDIO_NULLPTR); 38750a07fd2Sopenharmony_ci cbObj->NotifyEvent(event); 38850a07fd2Sopenharmony_ci return DH_SUCCESS; 38950a07fd2Sopenharmony_ci} 39050a07fd2Sopenharmony_ci 39150a07fd2Sopenharmony_cistring DSpeakerClient::GetVolumeLevel() 39250a07fd2Sopenharmony_ci{ 39350a07fd2Sopenharmony_ci DHLOGD("Get the volume level."); 39450a07fd2Sopenharmony_ci AudioStandard::AudioStreamType streamType = AudioStandard::AudioStreamType::STREAM_DEFAULT; 39550a07fd2Sopenharmony_ci auto volumeType = static_cast<AudioStandard::AudioVolumeType>(1); 39650a07fd2Sopenharmony_ci int32_t volumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetVolume(volumeType); 39750a07fd2Sopenharmony_ci int32_t maxVolumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetMaxVolume(volumeType); 39850a07fd2Sopenharmony_ci int32_t minVolumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetMinVolume(volumeType); 39950a07fd2Sopenharmony_ci bool isUpdateUi = false; 40050a07fd2Sopenharmony_ci cJSON *jParam = cJSON_CreateObject(); 40150a07fd2Sopenharmony_ci CHECK_NULL_RETURN(jParam, ""); 40250a07fd2Sopenharmony_ci 40350a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str()); 40450a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_CHANGE_TYPE, FIRST_VOLUME_CHANAGE); 40550a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, AUDIO_STREAM_TYPE, std::to_string(streamType).c_str()); 40650a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, VOLUME_LEVEL.c_str(), std::to_string(volumeLevel).c_str()); 40750a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, IS_UPDATEUI, std::to_string(isUpdateUi).c_str()); 40850a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, MAX_VOLUME_LEVEL, std::to_string(maxVolumeLevel).c_str()); 40950a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, MIN_VOLUME_LEVEL, std::to_string(minVolumeLevel).c_str()); 41050a07fd2Sopenharmony_ci char *jsonData = cJSON_PrintUnformatted(jParam); 41150a07fd2Sopenharmony_ci if (jsonData == nullptr) { 41250a07fd2Sopenharmony_ci DHLOGE("Failed to create JSON data."); 41350a07fd2Sopenharmony_ci cJSON_Delete(jParam); 41450a07fd2Sopenharmony_ci return ""; 41550a07fd2Sopenharmony_ci } 41650a07fd2Sopenharmony_ci std::string str(jsonData); 41750a07fd2Sopenharmony_ci cJSON_Delete(jParam); 41850a07fd2Sopenharmony_ci cJSON_free(jsonData); 41950a07fd2Sopenharmony_ci DHLOGD("Get the volume level result, event: %{public}s.", str.c_str()); 42050a07fd2Sopenharmony_ci return str; 42150a07fd2Sopenharmony_ci} 42250a07fd2Sopenharmony_ci 42350a07fd2Sopenharmony_civoid DSpeakerClient::OnVolumeKeyEvent(AudioStandard::VolumeEvent volumeEvent) 42450a07fd2Sopenharmony_ci{ 42550a07fd2Sopenharmony_ci DHLOGD("Volume change event."); 42650a07fd2Sopenharmony_ci std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock(); 42750a07fd2Sopenharmony_ci CHECK_NULL_VOID(cbObj); 42850a07fd2Sopenharmony_ci 42950a07fd2Sopenharmony_ci cJSON *jParam = cJSON_CreateObject(); 43050a07fd2Sopenharmony_ci CHECK_NULL_VOID(jParam); 43150a07fd2Sopenharmony_ci 43250a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str()); 43350a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_CHANGE_TYPE, VOLUME_CHANAGE); 43450a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, AUDIO_STREAM_TYPE, std::to_string(volumeEvent.volumeType).c_str()); 43550a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, VOLUME_LEVEL.c_str(), std::to_string(volumeEvent.volume).c_str()); 43650a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, IS_UPDATEUI, std::to_string(volumeEvent.updateUi).c_str()); 43750a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, VOLUME_GROUP_ID, std::to_string(volumeEvent.volumeGroupId).c_str()); 43850a07fd2Sopenharmony_ci char *jsonData = cJSON_PrintUnformatted(jParam); 43950a07fd2Sopenharmony_ci if (jsonData == nullptr) { 44050a07fd2Sopenharmony_ci DHLOGE("Failed to create JSON data."); 44150a07fd2Sopenharmony_ci cJSON_Delete(jParam); 44250a07fd2Sopenharmony_ci return; 44350a07fd2Sopenharmony_ci } 44450a07fd2Sopenharmony_ci std::string str(jsonData); 44550a07fd2Sopenharmony_ci cJSON_Delete(jParam); 44650a07fd2Sopenharmony_ci cJSON_free(jsonData); 44750a07fd2Sopenharmony_ci DHLOGD("Volume change notification result, event: %{public}s.", str.c_str()); 44850a07fd2Sopenharmony_ci 44950a07fd2Sopenharmony_ci AudioEvent audioEvent(VOLUME_CHANGE, str); 45050a07fd2Sopenharmony_ci cbObj->NotifyEvent(audioEvent); 45150a07fd2Sopenharmony_ci} 45250a07fd2Sopenharmony_ci 45350a07fd2Sopenharmony_civoid DSpeakerClient::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent) 45450a07fd2Sopenharmony_ci{ 45550a07fd2Sopenharmony_ci DHLOGD("Audio focus interrupt event."); 45650a07fd2Sopenharmony_ci std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock(); 45750a07fd2Sopenharmony_ci CHECK_NULL_VOID(cbObj); 45850a07fd2Sopenharmony_ci 45950a07fd2Sopenharmony_ci cJSON *jParam = cJSON_CreateObject(); 46050a07fd2Sopenharmony_ci CHECK_NULL_VOID(jParam); 46150a07fd2Sopenharmony_ci 46250a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str()); 46350a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_CHANGE_TYPE, INTERRUPT_EVENT); 46450a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, VOLUME_EVENT_TYPE, std::to_string(interruptEvent.eventType).c_str()); 46550a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, FORCE_TYPE, std::to_string(interruptEvent.forceType).c_str()); 46650a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, HINT_TYPE, std::to_string(interruptEvent.hintType).c_str()); 46750a07fd2Sopenharmony_ci char *jsonData = cJSON_PrintUnformatted(jParam); 46850a07fd2Sopenharmony_ci if (jsonData == nullptr) { 46950a07fd2Sopenharmony_ci DHLOGE("Failed to create JSON data."); 47050a07fd2Sopenharmony_ci cJSON_Delete(jParam); 47150a07fd2Sopenharmony_ci return; 47250a07fd2Sopenharmony_ci } 47350a07fd2Sopenharmony_ci std::string str(jsonData); 47450a07fd2Sopenharmony_ci cJSON_Delete(jParam); 47550a07fd2Sopenharmony_ci cJSON_free(jsonData); 47650a07fd2Sopenharmony_ci DHLOGD("Audio focus oninterrupt notification result, event: %{public}s.", str.c_str()); 47750a07fd2Sopenharmony_ci 47850a07fd2Sopenharmony_ci AudioEvent audioEvent(AUDIO_FOCUS_CHANGE, str); 47950a07fd2Sopenharmony_ci cbObj->NotifyEvent(audioEvent); 48050a07fd2Sopenharmony_ci} 48150a07fd2Sopenharmony_ci 48250a07fd2Sopenharmony_civoid DSpeakerClient::OnStateChange(const AudioStandard::RendererState state, 48350a07fd2Sopenharmony_ci const AudioStandard::StateChangeCmdType __attribute__((unused)) cmdType) 48450a07fd2Sopenharmony_ci{ 48550a07fd2Sopenharmony_ci DHLOGD("On render state change. state: %{public}d", state); 48650a07fd2Sopenharmony_ci std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock(); 48750a07fd2Sopenharmony_ci CHECK_NULL_VOID(cbObj); 48850a07fd2Sopenharmony_ci 48950a07fd2Sopenharmony_ci cJSON *jParam = cJSON_CreateObject(); 49050a07fd2Sopenharmony_ci CHECK_NULL_VOID(jParam); 49150a07fd2Sopenharmony_ci 49250a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str()); 49350a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_CHANGE_TYPE, RENDER_STATE_CHANGE_EVENT); 49450a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_STATE, std::to_string(state).c_str()); 49550a07fd2Sopenharmony_ci char *jsonData = cJSON_PrintUnformatted(jParam); 49650a07fd2Sopenharmony_ci if (jsonData == nullptr) { 49750a07fd2Sopenharmony_ci DHLOGE("Failed to create JSON data."); 49850a07fd2Sopenharmony_ci cJSON_Delete(jParam); 49950a07fd2Sopenharmony_ci return; 50050a07fd2Sopenharmony_ci } 50150a07fd2Sopenharmony_ci std::string str(jsonData); 50250a07fd2Sopenharmony_ci cJSON_Delete(jParam); 50350a07fd2Sopenharmony_ci cJSON_free(jsonData); 50450a07fd2Sopenharmony_ci DHLOGD("Audio render state changes notification result, event: %{public}s.", str.c_str()); 50550a07fd2Sopenharmony_ci 50650a07fd2Sopenharmony_ci AudioEvent audioEvent(AUDIO_RENDER_STATE_CHANGE, str); 50750a07fd2Sopenharmony_ci cbObj->NotifyEvent(audioEvent); 50850a07fd2Sopenharmony_ci} 50950a07fd2Sopenharmony_ci 51050a07fd2Sopenharmony_ciint32_t DSpeakerClient::SetAudioParameters(const AudioEvent &event) 51150a07fd2Sopenharmony_ci{ 51250a07fd2Sopenharmony_ci DHLOGD("Set the volume, arg: %{public}s.", event.content.c_str()); 51350a07fd2Sopenharmony_ci 51450a07fd2Sopenharmony_ci int32_t audioVolumeType; 51550a07fd2Sopenharmony_ci int32_t ret = GetAudioParamInt(event.content, AUDIO_VOLUME_TYPE, audioVolumeType); 51650a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 51750a07fd2Sopenharmony_ci DHLOGE("Get audio volume type failed."); 51850a07fd2Sopenharmony_ci return ret; 51950a07fd2Sopenharmony_ci } 52050a07fd2Sopenharmony_ci auto volumeType = static_cast<AudioStandard::AudioVolumeType>(audioVolumeType); 52150a07fd2Sopenharmony_ci DHLOGD("Audio volume type, volumeType = %{public}d.", volumeType); 52250a07fd2Sopenharmony_ci if (event.type != VOLUME_SET) { 52350a07fd2Sopenharmony_ci DHLOGE("Invalid parameter."); 52450a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_PARAM_ERROR; 52550a07fd2Sopenharmony_ci } 52650a07fd2Sopenharmony_ci 52750a07fd2Sopenharmony_ci int32_t audioVolumeLevel; 52850a07fd2Sopenharmony_ci ret = GetAudioParamInt(event.content, VOLUME_LEVEL, audioVolumeLevel); 52950a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 53050a07fd2Sopenharmony_ci DHLOGE("Get audio volume level failed."); 53150a07fd2Sopenharmony_ci return ret; 53250a07fd2Sopenharmony_ci } 53350a07fd2Sopenharmony_ci DHLOGD("volume level = %{public}d.", audioVolumeLevel); 53450a07fd2Sopenharmony_ci ret = AudioStandard::AudioSystemManager::GetInstance()->SetVolume(volumeType, audioVolumeLevel); 53550a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 53650a07fd2Sopenharmony_ci DHLOGE("Voloume set failed."); 53750a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_SET_VOLUME_FAILED; 53850a07fd2Sopenharmony_ci } 53950a07fd2Sopenharmony_ci return DH_SUCCESS; 54050a07fd2Sopenharmony_ci} 54150a07fd2Sopenharmony_ci 54250a07fd2Sopenharmony_ciint32_t DSpeakerClient::SetMute(const AudioEvent &event) 54350a07fd2Sopenharmony_ci{ 54450a07fd2Sopenharmony_ci DHLOGD("Set mute, arg: %{public}s.", event.content.c_str()); 54550a07fd2Sopenharmony_ci int32_t audioVolumeType; 54650a07fd2Sopenharmony_ci int32_t ret = GetAudioParamInt(event.content, AUDIO_VOLUME_TYPE, audioVolumeType); 54750a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 54850a07fd2Sopenharmony_ci DHLOGE("Get audio volume type failed."); 54950a07fd2Sopenharmony_ci return ret; 55050a07fd2Sopenharmony_ci } 55150a07fd2Sopenharmony_ci 55250a07fd2Sopenharmony_ci bool muteStatus = false; 55350a07fd2Sopenharmony_ci ret = GetAudioParamBool(event.content, STREAM_MUTE_STATUS, muteStatus); 55450a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 55550a07fd2Sopenharmony_ci DHLOGE("Get mute status failed."); 55650a07fd2Sopenharmony_ci return ret; 55750a07fd2Sopenharmony_ci } 55850a07fd2Sopenharmony_ci 55950a07fd2Sopenharmony_ci auto volumeType = static_cast<AudioStandard::AudioVolumeType>(audioVolumeType); 56050a07fd2Sopenharmony_ci DHLOGD("Audio volume type, volumeType = %{public}d.", volumeType); 56150a07fd2Sopenharmony_ci if (event.type != VOLUME_MUTE_SET) { 56250a07fd2Sopenharmony_ci DHLOGE("Invalid parameter."); 56350a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_PARAM_ERROR; 56450a07fd2Sopenharmony_ci } 56550a07fd2Sopenharmony_ci ret = AudioStandard::AudioSystemManager::GetInstance()->SetMute(volumeType, muteStatus); 56650a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 56750a07fd2Sopenharmony_ci DHLOGE("Mute set failed."); 56850a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_SET_MUTE_FAILED; 56950a07fd2Sopenharmony_ci } 57050a07fd2Sopenharmony_ci return DH_SUCCESS; 57150a07fd2Sopenharmony_ci} 57250a07fd2Sopenharmony_ci 57350a07fd2Sopenharmony_civoid DSpeakerClient::Pause() 57450a07fd2Sopenharmony_ci{ 57550a07fd2Sopenharmony_ci DHLOGI("Pause and flush"); 57650a07fd2Sopenharmony_ci FlushJitterQueue(); 57750a07fd2Sopenharmony_ci if (audioParam_.renderOpts.renderFlags != MMAP_MODE) { 57850a07fd2Sopenharmony_ci isRenderReady_.store(false); 57950a07fd2Sopenharmony_ci if (renderDataThread_.joinable()) { 58050a07fd2Sopenharmony_ci renderDataThread_.join(); 58150a07fd2Sopenharmony_ci } 58250a07fd2Sopenharmony_ci } 58350a07fd2Sopenharmony_ci 58450a07fd2Sopenharmony_ci if (speakerTrans_ == nullptr || speakerTrans_->Pause() != DH_SUCCESS) { 58550a07fd2Sopenharmony_ci DHLOGE("Speaker trans Pause failed."); 58650a07fd2Sopenharmony_ci } 58750a07fd2Sopenharmony_ci if (audioRenderer_ != nullptr) { 58850a07fd2Sopenharmony_ci audioRenderer_->Flush(); 58950a07fd2Sopenharmony_ci audioRenderer_->Pause(); 59050a07fd2Sopenharmony_ci } 59150a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_START; 59250a07fd2Sopenharmony_ci isRenderReady_.store(true); 59350a07fd2Sopenharmony_ci} 59450a07fd2Sopenharmony_ci 59550a07fd2Sopenharmony_civoid DSpeakerClient::ReStart() 59650a07fd2Sopenharmony_ci{ 59750a07fd2Sopenharmony_ci DHLOGI("ReStart"); 59850a07fd2Sopenharmony_ci if (speakerTrans_ == nullptr || speakerTrans_->Restart(audioParam_, audioParam_) != DH_SUCCESS) { 59950a07fd2Sopenharmony_ci DHLOGE("Speaker trans Restart failed."); 60050a07fd2Sopenharmony_ci } 60150a07fd2Sopenharmony_ci if (audioParam_.renderOpts.renderFlags != MMAP_MODE) { 60250a07fd2Sopenharmony_ci isRenderReady_.store(true); 60350a07fd2Sopenharmony_ci renderDataThread_ = std::thread([this]() { this->PlayThreadRunning(); }); 60450a07fd2Sopenharmony_ci } 60550a07fd2Sopenharmony_ci if (audioRenderer_ != nullptr) { 60650a07fd2Sopenharmony_ci audioRenderer_->Start(); 60750a07fd2Sopenharmony_ci } 60850a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_START; 60950a07fd2Sopenharmony_ci} 61050a07fd2Sopenharmony_ci 61150a07fd2Sopenharmony_ciint32_t DSpeakerClient::SendMessage(uint32_t type, std::string content, std::string dstDevId) 61250a07fd2Sopenharmony_ci{ 61350a07fd2Sopenharmony_ci DHLOGD("Send message to remote."); 61450a07fd2Sopenharmony_ci if (type != static_cast<uint32_t>(NOTIFY_OPEN_SPEAKER_RESULT) && 61550a07fd2Sopenharmony_ci type != static_cast<uint32_t>(NOTIFY_OPEN_CTRL_RESULT) && 61650a07fd2Sopenharmony_ci type != static_cast<uint32_t>(NOTIFY_CLOSE_SPEAKER_RESULT) && 61750a07fd2Sopenharmony_ci type != static_cast<uint32_t>(VOLUME_CHANGE) && 61850a07fd2Sopenharmony_ci type != static_cast<uint32_t>(AUDIO_FOCUS_CHANGE) && 61950a07fd2Sopenharmony_ci type != static_cast<uint32_t>(AUDIO_RENDER_STATE_CHANGE)) { 62050a07fd2Sopenharmony_ci DHLOGE("event type is not NOTIFY_OPEN_SPK or NOTIFY_CLOSE_SPK or OPEN_CTRL. type:%{public}u", type); 62150a07fd2Sopenharmony_ci return ERR_DH_AUDIO_NULLPTR; 62250a07fd2Sopenharmony_ci } 62350a07fd2Sopenharmony_ci CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR); 62450a07fd2Sopenharmony_ci speakerTrans_->SendMessage(type, content, dstDevId); 62550a07fd2Sopenharmony_ci return DH_SUCCESS; 62650a07fd2Sopenharmony_ci} 62750a07fd2Sopenharmony_ci 62850a07fd2Sopenharmony_civoid DSpeakerClient::PlayStatusChange(const std::string &args) 62950a07fd2Sopenharmony_ci{ 63050a07fd2Sopenharmony_ci DHLOGI("Play status change, args: %{public}s.", args.c_str()); 63150a07fd2Sopenharmony_ci std::string changeType = ParseStringFromArgs(args, KEY_CHANGE_TYPE); 63250a07fd2Sopenharmony_ci if (changeType == AUDIO_EVENT_RESTART) { 63350a07fd2Sopenharmony_ci ReStart(); 63450a07fd2Sopenharmony_ci } else if (changeType == AUDIO_EVENT_PAUSE) { 63550a07fd2Sopenharmony_ci Pause(); 63650a07fd2Sopenharmony_ci } else { 63750a07fd2Sopenharmony_ci DHLOGE("Play status error."); 63850a07fd2Sopenharmony_ci } 63950a07fd2Sopenharmony_ci} 64050a07fd2Sopenharmony_ci 64150a07fd2Sopenharmony_civoid DSpeakerClient::SetAttrs(const std::string &devId, const std::shared_ptr<IAudioEventCallback> &callback) 64250a07fd2Sopenharmony_ci{ 64350a07fd2Sopenharmony_ci DHLOGE("Set attrs, not support yet."); 64450a07fd2Sopenharmony_ci} 64550a07fd2Sopenharmony_ci} // DistributedHardware 64650a07fd2Sopenharmony_ci} // OHOS 647