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 &param)
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