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 "dmic_client.h" 1750a07fd2Sopenharmony_ci 1850a07fd2Sopenharmony_ci#include <chrono> 1950a07fd2Sopenharmony_ci 2050a07fd2Sopenharmony_ci#include "cJSON.h" 2150a07fd2Sopenharmony_ci 2250a07fd2Sopenharmony_ci#include "daudio_constants.h" 2350a07fd2Sopenharmony_ci#include "daudio_hisysevent.h" 2450a07fd2Sopenharmony_ci#include "daudio_sink_hidumper.h" 2550a07fd2Sopenharmony_ci#include "daudio_sink_manager.h" 2650a07fd2Sopenharmony_ci 2750a07fd2Sopenharmony_ci#undef DH_LOG_TAG 2850a07fd2Sopenharmony_ci#define DH_LOG_TAG "DMicClient" 2950a07fd2Sopenharmony_ci 3050a07fd2Sopenharmony_cinamespace OHOS { 3150a07fd2Sopenharmony_cinamespace DistributedHardware { 3250a07fd2Sopenharmony_ciDMicClient::~DMicClient() 3350a07fd2Sopenharmony_ci{ 3450a07fd2Sopenharmony_ci if (micTrans_ != nullptr) { 3550a07fd2Sopenharmony_ci DHLOGI("Release mic client."); 3650a07fd2Sopenharmony_ci StopCapture(); 3750a07fd2Sopenharmony_ci } 3850a07fd2Sopenharmony_ci} 3950a07fd2Sopenharmony_ci 4050a07fd2Sopenharmony_civoid DMicClient::OnEngineTransEvent(const AVTransEvent &event) 4150a07fd2Sopenharmony_ci{ 4250a07fd2Sopenharmony_ci if (event.type == EventType::EVENT_START_SUCCESS) { 4350a07fd2Sopenharmony_ci OnStateChange(DATA_OPENED); 4450a07fd2Sopenharmony_ci } else if ((event.type == EventType::EVENT_STOP_SUCCESS) || 4550a07fd2Sopenharmony_ci (event.type == EventType::EVENT_CHANNEL_CLOSED) || 4650a07fd2Sopenharmony_ci (event.type == EventType::EVENT_START_FAIL)) { 4750a07fd2Sopenharmony_ci OnStateChange(DATA_CLOSED); 4850a07fd2Sopenharmony_ci } 4950a07fd2Sopenharmony_ci} 5050a07fd2Sopenharmony_ci 5150a07fd2Sopenharmony_civoid DMicClient::OnEngineTransMessage(const std::shared_ptr<AVTransMessage> &message) 5250a07fd2Sopenharmony_ci{ 5350a07fd2Sopenharmony_ci CHECK_NULL_VOID(message); 5450a07fd2Sopenharmony_ci DHLOGI("On Engine message, type : %{public}s.", GetEventNameByType(message->type_).c_str()); 5550a07fd2Sopenharmony_ci DAudioSinkManager::GetInstance().HandleDAudioNotify(message->dstDevId_, message->dstDevId_, 5650a07fd2Sopenharmony_ci static_cast<int32_t>(message->type_), message->content_); 5750a07fd2Sopenharmony_ci} 5850a07fd2Sopenharmony_ci 5950a07fd2Sopenharmony_ciint32_t DMicClient::InitSenderEngine(IAVEngineProvider *providerPtr) 6050a07fd2Sopenharmony_ci{ 6150a07fd2Sopenharmony_ci DHLOGI("Init SenderEngine"); 6250a07fd2Sopenharmony_ci if (micTrans_ == nullptr) { 6350a07fd2Sopenharmony_ci micTrans_ = std::make_shared<AVTransSenderTransport>(devId_, shared_from_this()); 6450a07fd2Sopenharmony_ci } 6550a07fd2Sopenharmony_ci int32_t ret = micTrans_->InitEngine(providerPtr); 6650a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 6750a07fd2Sopenharmony_ci DHLOGE("Mic client initialize av sender adapter failed."); 6850a07fd2Sopenharmony_ci return ERR_DH_AUDIO_NULLPTR; 6950a07fd2Sopenharmony_ci } 7050a07fd2Sopenharmony_ci return DH_SUCCESS; 7150a07fd2Sopenharmony_ci} 7250a07fd2Sopenharmony_ci 7350a07fd2Sopenharmony_ciint32_t DMicClient::OnStateChange(const AudioEventType type) 7450a07fd2Sopenharmony_ci{ 7550a07fd2Sopenharmony_ci DHLOGD("On state change type: %{public}d.", type); 7650a07fd2Sopenharmony_ci AudioEvent event; 7750a07fd2Sopenharmony_ci cJSON *jParam = cJSON_CreateObject(); 7850a07fd2Sopenharmony_ci CHECK_NULL_RETURN(jParam, ERR_DH_AUDIO_NULLPTR); 7950a07fd2Sopenharmony_ci 8050a07fd2Sopenharmony_ci cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str()); 8150a07fd2Sopenharmony_ci char *jsonData = cJSON_PrintUnformatted(jParam); 8250a07fd2Sopenharmony_ci if (jsonData == nullptr) { 8350a07fd2Sopenharmony_ci DHLOGE("Failed to create JSON data."); 8450a07fd2Sopenharmony_ci cJSON_Delete(jParam); 8550a07fd2Sopenharmony_ci return ERR_DH_AUDIO_NULLPTR; 8650a07fd2Sopenharmony_ci } 8750a07fd2Sopenharmony_ci event.content = std::string(jsonData); 8850a07fd2Sopenharmony_ci cJSON_Delete(jParam); 8950a07fd2Sopenharmony_ci cJSON_free(jsonData); 9050a07fd2Sopenharmony_ci switch (type) { 9150a07fd2Sopenharmony_ci case AudioEventType::DATA_OPENED: { 9250a07fd2Sopenharmony_ci isBlocking_.store(true); 9350a07fd2Sopenharmony_ci if (audioParam_.captureOpts.capturerFlags != MMAP_MODE) { 9450a07fd2Sopenharmony_ci isCaptureReady_.store(true); 9550a07fd2Sopenharmony_ci captureDataThread_ = std::thread([this]() { this->CaptureThreadRunning(); }); 9650a07fd2Sopenharmony_ci } 9750a07fd2Sopenharmony_ci event.type = AudioEventType::MIC_OPENED; 9850a07fd2Sopenharmony_ci break; 9950a07fd2Sopenharmony_ci } 10050a07fd2Sopenharmony_ci case AudioEventType::DATA_CLOSED: { 10150a07fd2Sopenharmony_ci event.type = AudioEventType::MIC_CLOSED; 10250a07fd2Sopenharmony_ci break; 10350a07fd2Sopenharmony_ci } 10450a07fd2Sopenharmony_ci default: 10550a07fd2Sopenharmony_ci DHLOGE("Invalid parameter type: %{public}d.", type); 10650a07fd2Sopenharmony_ci return ERR_DH_AUDIO_NOT_SUPPORT; 10750a07fd2Sopenharmony_ci } 10850a07fd2Sopenharmony_ci 10950a07fd2Sopenharmony_ci std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock(); 11050a07fd2Sopenharmony_ci CHECK_NULL_RETURN(cbObj, ERR_DH_AUDIO_NULLPTR); 11150a07fd2Sopenharmony_ci cbObj->NotifyEvent(event); 11250a07fd2Sopenharmony_ci return DH_SUCCESS; 11350a07fd2Sopenharmony_ci} 11450a07fd2Sopenharmony_ci 11550a07fd2Sopenharmony_ciint32_t DMicClient::AudioFwkClientSetUp() 11650a07fd2Sopenharmony_ci{ 11750a07fd2Sopenharmony_ci AudioStandard::AudioCapturerOptions capturerOptions = { 11850a07fd2Sopenharmony_ci { 11950a07fd2Sopenharmony_ci static_cast<AudioStandard::AudioSamplingRate>(audioParam_.comParam.sampleRate), 12050a07fd2Sopenharmony_ci AudioStandard::AudioEncodingType::ENCODING_PCM, 12150a07fd2Sopenharmony_ci static_cast<AudioStandard::AudioSampleFormat>(audioParam_.comParam.bitFormat), 12250a07fd2Sopenharmony_ci static_cast<AudioStandard::AudioChannel>(audioParam_.comParam.channelMask), 12350a07fd2Sopenharmony_ci }, 12450a07fd2Sopenharmony_ci { 12550a07fd2Sopenharmony_ci static_cast<AudioStandard::SourceType>(audioParam_.captureOpts.sourceType), 12650a07fd2Sopenharmony_ci audioParam_.captureOpts.capturerFlags == MMAP_MODE ? AudioStandard::STREAM_FLAG_FAST : 0, 12750a07fd2Sopenharmony_ci } 12850a07fd2Sopenharmony_ci }; 12950a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lck(devMtx_); 13050a07fd2Sopenharmony_ci audioCapturer_ = AudioStandard::AudioCapturer::Create(capturerOptions); 13150a07fd2Sopenharmony_ci CHECK_NULL_RETURN(audioCapturer_, ERR_DH_AUDIO_CLIENT_CAPTURER_CREATE_FAILED); 13250a07fd2Sopenharmony_ci if (audioParam_.captureOpts.capturerFlags == MMAP_MODE) { 13350a07fd2Sopenharmony_ci int32_t ret = audioCapturer_->SetCapturerReadCallback(shared_from_this()); 13450a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 13550a07fd2Sopenharmony_ci DHLOGE("Client save read callback failed."); 13650a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_CAPTURER_CREATE_FAILED; 13750a07fd2Sopenharmony_ci } 13850a07fd2Sopenharmony_ci } 13950a07fd2Sopenharmony_ci return TransSetUp(); 14050a07fd2Sopenharmony_ci} 14150a07fd2Sopenharmony_ci 14250a07fd2Sopenharmony_ciint32_t DMicClient::TransSetUp() 14350a07fd2Sopenharmony_ci{ 14450a07fd2Sopenharmony_ci CHECK_NULL_RETURN(micTrans_, ERR_DH_AUDIO_NULLPTR); 14550a07fd2Sopenharmony_ci int32_t ret = micTrans_->SetUp(audioParam_, audioParam_, shared_from_this(), CAP_MIC); 14650a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 14750a07fd2Sopenharmony_ci DHLOGE("Mic trans setup failed."); 14850a07fd2Sopenharmony_ci return ret; 14950a07fd2Sopenharmony_ci } 15050a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_READY; 15150a07fd2Sopenharmony_ci return DH_SUCCESS; 15250a07fd2Sopenharmony_ci} 15350a07fd2Sopenharmony_ci 15450a07fd2Sopenharmony_ciint32_t DMicClient::SetUp(const AudioParam ¶m) 15550a07fd2Sopenharmony_ci{ 15650a07fd2Sopenharmony_ci DHLOGI("Set up mic client, param: {sampleRate: %{public}d, bitFormat: %{public}d," 15750a07fd2Sopenharmony_ci "channelMask: %{public}d, sourceType: %{public}d, capturerFlags: %{public}d, frameSize: %{public}d}.", 15850a07fd2Sopenharmony_ci param.comParam.sampleRate, param.comParam.bitFormat, param.comParam.channelMask, param.captureOpts.sourceType, 15950a07fd2Sopenharmony_ci param.captureOpts.capturerFlags, param.comParam.frameSize); 16050a07fd2Sopenharmony_ci audioParam_ = param; 16150a07fd2Sopenharmony_ci DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, DUMP_DAUDIO_MIC_BEFORE_TRANS_NAME, &dumpFile_); 16250a07fd2Sopenharmony_ci return AudioFwkClientSetUp(); 16350a07fd2Sopenharmony_ci} 16450a07fd2Sopenharmony_ci 16550a07fd2Sopenharmony_ciint32_t DMicClient::SendMessage(uint32_t type, std::string content, std::string dstDevId) 16650a07fd2Sopenharmony_ci{ 16750a07fd2Sopenharmony_ci DHLOGD("Send message to remote."); 16850a07fd2Sopenharmony_ci if (type != static_cast<uint32_t>(NOTIFY_OPEN_MIC_RESULT) && 16950a07fd2Sopenharmony_ci type != static_cast<uint32_t>(NOTIFY_OPEN_CTRL_RESULT) && 17050a07fd2Sopenharmony_ci type != static_cast<uint32_t>(NOTIFY_CLOSE_MIC_RESULT) && 17150a07fd2Sopenharmony_ci type != static_cast<uint32_t>(CLOSE_MIC)) { 17250a07fd2Sopenharmony_ci DHLOGE("event type is not NOTIFY_OPEN_MIC or NOTIFY_CLOSE_MIC or" 17350a07fd2Sopenharmony_ci "CLOSE_MIC or OPEN_CTRL. type: %{public}u", type); 17450a07fd2Sopenharmony_ci return ERR_DH_AUDIO_NULLPTR; 17550a07fd2Sopenharmony_ci } 17650a07fd2Sopenharmony_ci CHECK_NULL_RETURN(micTrans_, ERR_DH_AUDIO_NULLPTR); 17750a07fd2Sopenharmony_ci micTrans_->SendMessage(type, content, dstDevId); 17850a07fd2Sopenharmony_ci return DH_SUCCESS; 17950a07fd2Sopenharmony_ci} 18050a07fd2Sopenharmony_ci 18150a07fd2Sopenharmony_ciint32_t DMicClient::Release() 18250a07fd2Sopenharmony_ci{ 18350a07fd2Sopenharmony_ci DHLOGI("Release mic client."); 18450a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lck(devMtx_); 18550a07fd2Sopenharmony_ci CHECK_NULL_RETURN(micTrans_, ERR_DH_AUDIO_SA_STATUS_ERR); 18650a07fd2Sopenharmony_ci if (clientStatus_ != AudioStatus::STATUS_READY && clientStatus_ != AudioStatus::STATUS_STOP) { 18750a07fd2Sopenharmony_ci DHLOGE("Mic status is wrong, %{public}d.", (int32_t)clientStatus_); 18850a07fd2Sopenharmony_ci return ERR_DH_AUDIO_SA_STATUS_ERR; 18950a07fd2Sopenharmony_ci } 19050a07fd2Sopenharmony_ci bool isReleaseError = false; 19150a07fd2Sopenharmony_ci if (audioCapturer_ == nullptr || !audioCapturer_->Release()) { 19250a07fd2Sopenharmony_ci DHLOGE("Audio capturer release failed."); 19350a07fd2Sopenharmony_ci isReleaseError = true; 19450a07fd2Sopenharmony_ci } 19550a07fd2Sopenharmony_ci int32_t ret = micTrans_->Release(); 19650a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 19750a07fd2Sopenharmony_ci DHLOGE("Mic trans release failed."); 19850a07fd2Sopenharmony_ci isReleaseError = true; 19950a07fd2Sopenharmony_ci } 20050a07fd2Sopenharmony_ci micTrans_ = nullptr; 20150a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_IDLE; 20250a07fd2Sopenharmony_ci if (isReleaseError) { 20350a07fd2Sopenharmony_ci return ERR_DH_AUDIO_FAILED; 20450a07fd2Sopenharmony_ci } 20550a07fd2Sopenharmony_ci DumpFileUtil::CloseDumpFile(&dumpFile_); 20650a07fd2Sopenharmony_ci return DH_SUCCESS; 20750a07fd2Sopenharmony_ci} 20850a07fd2Sopenharmony_ci 20950a07fd2Sopenharmony_ciint32_t DMicClient::StartCapture() 21050a07fd2Sopenharmony_ci{ 21150a07fd2Sopenharmony_ci DHLOGI("Start capturer."); 21250a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lck(devMtx_); 21350a07fd2Sopenharmony_ci CHECK_NULL_RETURN(micTrans_, ERR_DH_AUDIO_SA_STATUS_ERR); 21450a07fd2Sopenharmony_ci CHECK_NULL_RETURN(audioCapturer_, ERR_DH_AUDIO_NULLPTR); 21550a07fd2Sopenharmony_ci 21650a07fd2Sopenharmony_ci if (clientStatus_ != AudioStatus::STATUS_READY) { 21750a07fd2Sopenharmony_ci DHLOGE("Audio capturer init failed or mic status wrong, status: %{public}d.", (int32_t)clientStatus_); 21850a07fd2Sopenharmony_ci DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_SA_STATUS_ERR, 21950a07fd2Sopenharmony_ci "daudio init failed or mic status wrong."); 22050a07fd2Sopenharmony_ci return ERR_DH_AUDIO_SA_STATUS_ERR; 22150a07fd2Sopenharmony_ci } 22250a07fd2Sopenharmony_ci if (!audioCapturer_->Start()) { 22350a07fd2Sopenharmony_ci DHLOGE("Audio capturer start failed."); 22450a07fd2Sopenharmony_ci audioCapturer_->Release(); 22550a07fd2Sopenharmony_ci DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, 22650a07fd2Sopenharmony_ci ERR_DH_AUDIO_CLIENT_CAPTURER_START_FAILED, "daudio capturer start failed."); 22750a07fd2Sopenharmony_ci return ERR_DH_AUDIO_CLIENT_CAPTURER_START_FAILED; 22850a07fd2Sopenharmony_ci } 22950a07fd2Sopenharmony_ci int32_t ret = micTrans_->Start(); 23050a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 23150a07fd2Sopenharmony_ci DHLOGE("Mic trans start failed."); 23250a07fd2Sopenharmony_ci micTrans_->Release(); 23350a07fd2Sopenharmony_ci DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ret, "daudio mic trans start failed."); 23450a07fd2Sopenharmony_ci return ret; 23550a07fd2Sopenharmony_ci } 23650a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_START; 23750a07fd2Sopenharmony_ci return DH_SUCCESS; 23850a07fd2Sopenharmony_ci} 23950a07fd2Sopenharmony_ci 24050a07fd2Sopenharmony_civoid DMicClient::AudioFwkCaptureData() 24150a07fd2Sopenharmony_ci{ 24250a07fd2Sopenharmony_ci std::shared_ptr<AudioData> audioData = std::make_shared<AudioData>(audioParam_.comParam.frameSize); 24350a07fd2Sopenharmony_ci size_t bytesRead = 0; 24450a07fd2Sopenharmony_ci bool errorFlag = false; 24550a07fd2Sopenharmony_ci int64_t startTime = GetNowTimeUs(); 24650a07fd2Sopenharmony_ci CHECK_NULL_VOID(audioCapturer_); 24750a07fd2Sopenharmony_ci 24850a07fd2Sopenharmony_ci while (bytesRead < audioParam_.comParam.frameSize) { 24950a07fd2Sopenharmony_ci int32_t len = audioCapturer_->Read(*(audioData->Data() + bytesRead), 25050a07fd2Sopenharmony_ci audioParam_.comParam.frameSize - bytesRead, isBlocking_.load()); 25150a07fd2Sopenharmony_ci if (len >= 0) { 25250a07fd2Sopenharmony_ci bytesRead += static_cast<size_t>(len); 25350a07fd2Sopenharmony_ci } else { 25450a07fd2Sopenharmony_ci errorFlag = true; 25550a07fd2Sopenharmony_ci break; 25650a07fd2Sopenharmony_ci } 25750a07fd2Sopenharmony_ci int64_t endTime = GetNowTimeUs(); 25850a07fd2Sopenharmony_ci if (IsOutDurationRange(startTime, endTime, lastCaptureStartTime_)) { 25950a07fd2Sopenharmony_ci DHLOGE("This time capture spend: %{public}" PRId64" us, The interval of capture this time and " 26050a07fd2Sopenharmony_ci "the last time: %{public}" PRId64" us", endTime - startTime, startTime - lastCaptureStartTime_); 26150a07fd2Sopenharmony_ci } 26250a07fd2Sopenharmony_ci lastCaptureStartTime_ = startTime; 26350a07fd2Sopenharmony_ci } 26450a07fd2Sopenharmony_ci if (errorFlag) { 26550a07fd2Sopenharmony_ci DHLOGE("Bytes read failed."); 26650a07fd2Sopenharmony_ci return; 26750a07fd2Sopenharmony_ci } 26850a07fd2Sopenharmony_ci if (isPauseStatus_.load()) { 26950a07fd2Sopenharmony_ci memset_s(audioData->Data(), audioData->Size(), 0, audioData->Size()); 27050a07fd2Sopenharmony_ci } 27150a07fd2Sopenharmony_ci DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(audioData->Data()), audioData->Size()); 27250a07fd2Sopenharmony_ci int64_t startTransTime = GetNowTimeUs(); 27350a07fd2Sopenharmony_ci CHECK_NULL_VOID(micTrans_); 27450a07fd2Sopenharmony_ci int32_t ret = micTrans_->FeedAudioData(audioData); 27550a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 27650a07fd2Sopenharmony_ci DHLOGE("Failed to send data."); 27750a07fd2Sopenharmony_ci } 27850a07fd2Sopenharmony_ci int64_t endTransTime = GetNowTimeUs(); 27950a07fd2Sopenharmony_ci if (IsOutDurationRange(startTransTime, endTransTime, lastTransStartTime_)) { 28050a07fd2Sopenharmony_ci DHLOGE("This time send data spend: %{public}" PRId64" us, The interval of send data this time and " 28150a07fd2Sopenharmony_ci "the last time: %{public}" PRId64" us", 28250a07fd2Sopenharmony_ci endTransTime - startTransTime, startTransTime - lastTransStartTime_); 28350a07fd2Sopenharmony_ci } 28450a07fd2Sopenharmony_ci lastTransStartTime_ = startTransTime; 28550a07fd2Sopenharmony_ci} 28650a07fd2Sopenharmony_ci 28750a07fd2Sopenharmony_civoid DMicClient::CaptureThreadRunning() 28850a07fd2Sopenharmony_ci{ 28950a07fd2Sopenharmony_ci DHLOGD("Start the capturer thread."); 29050a07fd2Sopenharmony_ci if (pthread_setname_np(pthread_self(), CAPTURETHREAD) != DH_SUCCESS) { 29150a07fd2Sopenharmony_ci DHLOGE("Capture data thread setname failed."); 29250a07fd2Sopenharmony_ci } 29350a07fd2Sopenharmony_ci while (isCaptureReady_.load()) { 29450a07fd2Sopenharmony_ci AudioFwkCaptureData(); 29550a07fd2Sopenharmony_ci } 29650a07fd2Sopenharmony_ci} 29750a07fd2Sopenharmony_ci 29850a07fd2Sopenharmony_ciint32_t DMicClient::OnDecodeTransDataDone(const std::shared_ptr<AudioData> &audioData) 29950a07fd2Sopenharmony_ci{ 30050a07fd2Sopenharmony_ci (void)audioData; 30150a07fd2Sopenharmony_ci return DH_SUCCESS; 30250a07fd2Sopenharmony_ci} 30350a07fd2Sopenharmony_ci 30450a07fd2Sopenharmony_civoid DMicClient::OnReadData(size_t length) 30550a07fd2Sopenharmony_ci{ 30650a07fd2Sopenharmony_ci AudioStandard::BufferDesc bufDesc; 30750a07fd2Sopenharmony_ci CHECK_NULL_VOID(audioCapturer_); 30850a07fd2Sopenharmony_ci 30950a07fd2Sopenharmony_ci if (audioCapturer_->GetBufferDesc(bufDesc) != DH_SUCCESS || bufDesc.bufLength == 0) { 31050a07fd2Sopenharmony_ci DHLOGE("Get buffer desc failed."); 31150a07fd2Sopenharmony_ci return; 31250a07fd2Sopenharmony_ci } 31350a07fd2Sopenharmony_ci CHECK_NULL_VOID(bufDesc.buffer); 31450a07fd2Sopenharmony_ci 31550a07fd2Sopenharmony_ci std::shared_ptr<AudioData> audioData = std::make_shared<AudioData>(audioParam_.comParam.frameSize); 31650a07fd2Sopenharmony_ci if (audioData->Capacity() != bufDesc.bufLength) { 31750a07fd2Sopenharmony_ci uint64_t capacity = static_cast<uint64_t>(audioData->Capacity()); 31850a07fd2Sopenharmony_ci uint64_t bufLength = static_cast<uint64_t>(bufDesc.bufLength); 31950a07fd2Sopenharmony_ci DHLOGE("Audio data length is not equal to buflength. datalength: %{public}" PRIu64 32050a07fd2Sopenharmony_ci ", bufLength: %{public}" PRIu64, capacity, bufLength); 32150a07fd2Sopenharmony_ci } 32250a07fd2Sopenharmony_ci if (memcpy_s(audioData->Data(), audioData->Capacity(), bufDesc.buffer, bufDesc.bufLength) != EOK) { 32350a07fd2Sopenharmony_ci DHLOGE("Copy audio data failed."); 32450a07fd2Sopenharmony_ci } 32550a07fd2Sopenharmony_ci 32650a07fd2Sopenharmony_ci if (isPauseStatus_.load()) { 32750a07fd2Sopenharmony_ci memset_s(audioData->Data(), audioData->Size(), 0, audioData->Size()); 32850a07fd2Sopenharmony_ci } 32950a07fd2Sopenharmony_ci audioCapturer_->Enqueue(bufDesc); 33050a07fd2Sopenharmony_ci 33150a07fd2Sopenharmony_ci CHECK_NULL_VOID(micTrans_); 33250a07fd2Sopenharmony_ci if (micTrans_->FeedAudioData(audioData) != DH_SUCCESS) { 33350a07fd2Sopenharmony_ci DHLOGE("Failed to send data."); 33450a07fd2Sopenharmony_ci } 33550a07fd2Sopenharmony_ci} 33650a07fd2Sopenharmony_ci 33750a07fd2Sopenharmony_ciint32_t DMicClient::StopCapture() 33850a07fd2Sopenharmony_ci{ 33950a07fd2Sopenharmony_ci DHLOGI("Stop capturer."); 34050a07fd2Sopenharmony_ci std::lock_guard<std::mutex> lck(devMtx_); 34150a07fd2Sopenharmony_ci if (clientStatus_ != AudioStatus::STATUS_START) { 34250a07fd2Sopenharmony_ci DHLOGE("Capturee is not start or mic status wrong, status: %{public}d.", (int32_t)clientStatus_); 34350a07fd2Sopenharmony_ci DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_SA_STATUS_ERR, 34450a07fd2Sopenharmony_ci "daudio capturer is not start or mic status wrong."); 34550a07fd2Sopenharmony_ci return ERR_DH_AUDIO_SA_STATUS_ERR; 34650a07fd2Sopenharmony_ci } 34750a07fd2Sopenharmony_ci CHECK_NULL_RETURN(micTrans_, ERR_DH_AUDIO_NULLPTR); 34850a07fd2Sopenharmony_ci 34950a07fd2Sopenharmony_ci isBlocking_.store(false); 35050a07fd2Sopenharmony_ci if (audioParam_.captureOpts.capturerFlags != MMAP_MODE && isCaptureReady_.load()) { 35150a07fd2Sopenharmony_ci isCaptureReady_.store(false); 35250a07fd2Sopenharmony_ci if (captureDataThread_.joinable()) { 35350a07fd2Sopenharmony_ci captureDataThread_.join(); 35450a07fd2Sopenharmony_ci } 35550a07fd2Sopenharmony_ci } 35650a07fd2Sopenharmony_ci 35750a07fd2Sopenharmony_ci bool status = true; 35850a07fd2Sopenharmony_ci int32_t ret = micTrans_->Stop(); 35950a07fd2Sopenharmony_ci if (ret != DH_SUCCESS) { 36050a07fd2Sopenharmony_ci DHLOGE("Mic trans stop failed."); 36150a07fd2Sopenharmony_ci status = false; 36250a07fd2Sopenharmony_ci } 36350a07fd2Sopenharmony_ci if (audioCapturer_ == nullptr || !audioCapturer_->Stop()) { 36450a07fd2Sopenharmony_ci DHLOGE("Audio capturer stop failed."); 36550a07fd2Sopenharmony_ci status = false; 36650a07fd2Sopenharmony_ci } 36750a07fd2Sopenharmony_ci clientStatus_ = AudioStatus::STATUS_STOP; 36850a07fd2Sopenharmony_ci if (!status) { 36950a07fd2Sopenharmony_ci return ERR_DH_AUDIO_FAILED; 37050a07fd2Sopenharmony_ci } 37150a07fd2Sopenharmony_ci return DH_SUCCESS; 37250a07fd2Sopenharmony_ci} 37350a07fd2Sopenharmony_ci 37450a07fd2Sopenharmony_civoid DMicClient::SetAttrs(const std::string &devId, const std::shared_ptr<IAudioEventCallback> &callback) 37550a07fd2Sopenharmony_ci{ 37650a07fd2Sopenharmony_ci DHLOGE("Set attrs, not support yet."); 37750a07fd2Sopenharmony_ci} 37850a07fd2Sopenharmony_ci 37950a07fd2Sopenharmony_ciint32_t DMicClient::PauseCapture() 38050a07fd2Sopenharmony_ci{ 38150a07fd2Sopenharmony_ci DHLOGI("Pause capture."); 38250a07fd2Sopenharmony_ci isPauseStatus_.store(true); 38350a07fd2Sopenharmony_ci return DH_SUCCESS; 38450a07fd2Sopenharmony_ci} 38550a07fd2Sopenharmony_ci 38650a07fd2Sopenharmony_ciint32_t DMicClient::ResumeCapture() 38750a07fd2Sopenharmony_ci{ 38850a07fd2Sopenharmony_ci DHLOGI("Resume capture."); 38950a07fd2Sopenharmony_ci isPauseStatus_.store(false); 39050a07fd2Sopenharmony_ci return DH_SUCCESS; 39150a07fd2Sopenharmony_ci} 39250a07fd2Sopenharmony_ci} // DistributedHardware 39350a07fd2Sopenharmony_ci} // OHOS 394