diff --git a/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h b/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h index a2ea27c5c42e3ff0d6f2ce651b441722c960821b..d7593b1eba8179dabbaf4f3072ab947b6d593893 100644 --- a/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h +++ b/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h @@ -16,6 +16,9 @@ #ifndef AUDIO_HDIADAPTER_INFO_H #define AUDIO_HDIADAPTER_INFO_H +#include +#include + #define MAX_MIX_CHANNELS 128 #define PA_MAX_OUTPUTS_PER_SOURCE 256 @@ -37,4 +40,36 @@ enum RenderCallbackType { CB_ERROR_OCCUR = 4, }; +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum EcType { + EC_NONE = 0, + EC_SAME_ADAPTER, + EC_DIFFERENT_ADAPTER +} EcType; + +typedef enum AuxiliaryRefSwitch { + REF_OFF = 0, + REF_ON +} AuxiliaryRefSwitch; + +typedef struct CaptureAttr { + // usage attrs + int32_t sourceType; + // device attrs + const char *adapterName; + int32_t deviceType; + // common audio attrs + uint32_t sampleRate; + uint32_t channelCount; + enum HdiAdapterFormat format; + bool isBigEndian; +} CaptureAttr; + +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/frameworks/native/hdiadapter/manager/BUILD.gn b/frameworks/native/hdiadapter/manager/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..5c79b448d5de28ebdf28eafed65f81285c6c2472 --- /dev/null +++ b/frameworks/native/hdiadapter/manager/BUILD.gn @@ -0,0 +1,83 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("../../../../config.gni") + +ohos_shared_library("hdiadapter_manager") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + install_enable = true + + cflags = [ "-fPIC" ] + cflags += [ "-Wall" ] + cflags_cc = cflags + + include_dirs = [ + "include", + "../common/include", + "../source/common", + "../../../../interfaces/inner_api/native/audiocommon/include", + ] + + sources = [ + "hdi_adapter_manager.cpp", + ] + + deps = [ + ":hdiadapter_utils", + "../source:audio_capturer_source", + "../source:capturer_source_adapter", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + part_name = "audio_framework" + subsystem_name = "multimedia" +} + +ohos_shared_library("hdiadapter_utils") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + install_enable = true + + cflags = [ "-fPIC" ] + cflags += [ "-Wall" ] + cflags_cc = cflags + + include_dirs = [ + "include", + "../../../../interfaces/inner_api/native/audiocommon/include", + ] + + sources = [ + "utils/hdi_utils_ringbuffer.cpp", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + part_name = "audio_framework" + subsystem_name = "multimedia" +} diff --git a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e6490b37936df04259cae2ee4a1da1b319557d02 --- /dev/null +++ b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LOG_TAG +#define LOG_TAG "HdiAdapterManager" +#endif + + +#include "hdi_adapter_manager.h" + +#include "audio_log.h" +#include "audio_errors.h" + +#include "include/hdi_adapter_manager_api.h" + +using namespace OHOS::AudioStandard; + +// Capture handle funcs impl +int32_t CaptureHandleInit(void *capture) +{ + IAudioCapturerSource *captureSource = static_cast(capture); + CHECK_AND_RETURN_RET_LOG(captureSource != nullptr, ERR_INVALID_HANDLE, "wrong capture"); + + return captureSource->InitWithoutAttr(); +} + +int32_t CaptureHandleDeinit(void *capture) +{ + IAudioCapturerSource *captureSource = static_cast(capture); + CHECK_AND_RETURN_RET_LOG(captureSource != nullptr, ERR_INVALID_HANDLE, "wrong capture"); + + captureSource->DeInit(); + + return SUCCESS; +} + +int32_t CaptureHandleStart(void *capture) +{ + IAudioCapturerSource *captureSource = static_cast(capture); + CHECK_AND_RETURN_RET_LOG(captureSource != nullptr, ERR_INVALID_HANDLE, "wrong capture"); + + return captureSource->Start(); +} + +int32_t CaptureHandleStop(void *capture) +{ + IAudioCapturerSource *captureSource = static_cast(capture); + CHECK_AND_RETURN_RET_LOG(captureSource != nullptr, ERR_INVALID_HANDLE, "wrong capture"); + + return captureSource->Stop(); +} + +int32_t CaptureHandleCaptureFrame(void *capture, + char *frame, uint64_t requestBytes, uint64_t *replyBytes) +{ + IAudioCapturerSource *captureSource = static_cast(capture); + CHECK_AND_RETURN_RET_LOG(captureSource != nullptr, ERR_INVALID_HANDLE, "wrong capture"); + + return captureSource->CaptureFrame(frame, requestBytes, *replyBytes); +} + +int32_t CaptureHandleCaptureFrameWithEc(void *capture, + char *frame, uint64_t requestBytes, uint64_t *replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t *replyBytesEc) +{ + IAudioCapturerSource *captureSource = static_cast(capture); + CHECK_AND_RETURN_RET_LOG(captureSource != nullptr, ERR_INVALID_HANDLE, "wrong capture"); + + return captureSource->CaptureFrameWithEc( + frame, requestBytes, *replyBytes, + frameEc, requestBytesEc, *replyBytesEc); +} + +// public api impl +int32_t CreateCaptureHandle(HdiCaptureHandle **handle, CaptureAttr *attr) +{ + OHOS::AudioStandard::HdiAdapterManager *manager = OHOS::AudioStandard::HdiAdapterManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(manager != nullptr, ERR_INVALID_HANDLE, "hdi adapter manager is null"); + + struct HdiCaptureHandle *captureHandle = (struct HdiCaptureHandle *)calloc(1, sizeof(*captureHandle)); + if (captureHandle == nullptr) { + AUDIO_ERR_LOG("allocate handle failed"); + return ERR_INVALID_HANDLE; + } + + IAudioCapturerSource *capture = manager->CreateCapture(attr); + captureHandle->capture = reinterpret_cast(capture); + + captureHandle->Init = CaptureHandleInit; + captureHandle->Deinit = CaptureHandleDeinit; + captureHandle->Start = CaptureHandleStart; + captureHandle->Stop = CaptureHandleStop; + captureHandle->CaptureFrame = CaptureHandleCaptureFrame; + captureHandle->CaptureFrameWithEc = CaptureHandleCaptureFrameWithEc; + + *handle = captureHandle; + + return SUCCESS; +} + +int32_t ReleaseCaptureHandle(HdiCaptureHandle *handle) +{ + if (handle != nullptr) { + // delete instance saved in handle + IAudioCapturerSource *capture = reinterpret_cast(handle->capture); + delete capture; + + free(handle); + } + + return SUCCESS; +} + +namespace OHOS { +namespace AudioStandard { + +HdiAdapterManager::HdiAdapterManager() +{ + // nothing to do now +} + +HdiAdapterManager::~HdiAdapterManager() +{ + // nothing to do now +} + +IAudioCapturerSource *HdiAdapterManager::CreateCapture(CaptureAttr *attr) +{ + IAudioCapturerSource *capture = IAudioCapturerSource::Create(attr); + return capture; +} + +int32_t HdiAdapterManager::ReleaseCapture(IAudioCapturerSource *capture) +{ + if (capture != nullptr) { + delete capture; + } + return SUCCESS; +} + +HdiAdapterManager *HdiAdapterManager::GetInstance() +{ + static HdiAdapterManager manager; + return &manager; +} + +} // namespace AudioStandard +} // namespace OHOS diff --git a/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager.h b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..b1116abbd9e46ec4446ed04c905060e4576ad77d --- /dev/null +++ b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HDI_ADAPTER_MANAGER_H +#define HDI_ADAPTER_MANAGER_H + +#include +#include + +#include "i_audio_capturer_source.h" + +namespace OHOS { +namespace AudioStandard { + +class HdiAdapterManager { +public: + static HdiAdapterManager *GetInstance(); + + IAudioCapturerSource *CreateCapture(CaptureAttr *attr); + + int32_t ReleaseCapture(IAudioCapturerSource *capture); + +private: + HdiAdapterManager(); + virtual ~HdiAdapterManager(); + +}; + +} // namespace AudioStandard +} // namespace OHOS +#endif // HDI_ADAPTER_MANAGER_H \ No newline at end of file diff --git a/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h new file mode 100644 index 0000000000000000000000000000000000000000..de06cca619839f13dce2515059c3b5042cc88d94 --- /dev/null +++ b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HDI_ADAPTER_MANAGER_API_H +#define HDI_ADAPTER_MANAGER_API_H + +#include +#include "audio_hdiadapter_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct HdiCaptureHandle { + void *capture; + int32_t (*Init)(void *capture); + int32_t (*Deinit)(void *capture); + int32_t (*Start)(void *capture); + int32_t (*Stop)(void *capture); + int32_t (*CaptureFrame)(void *capture, + char *frame, uint64_t requestBytes, uint64_t *replyBytes); + int32_t (*CaptureFrameWithEc)(void *capture, + char *frame, uint64_t requestBytes, uint64_t *replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t *replyBytesEc); +} HdiCaptureHandle; + +int32_t CreateCaptureHandle(HdiCaptureHandle **handle, CaptureAttr *attr); + +int32_t ReleaseCaptureHandle(HdiCaptureHandle *handle); + +#ifdef __cplusplus +} +#endif +#endif // HDI_ADAPTER_MANAGER_API_H \ No newline at end of file diff --git a/frameworks/native/hdiadapter/manager/include/hdi_utils_ringbuffer.h b/frameworks/native/hdiadapter/manager/include/hdi_utils_ringbuffer.h new file mode 100644 index 0000000000000000000000000000000000000000..bb1e8ef0ee6dbbe392bb7986e1579734248b7cdb --- /dev/null +++ b/frameworks/native/hdiadapter/manager/include/hdi_utils_ringbuffer.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HDI_UTILS_RINGBUFFER_H +#define HDI_UTILS_RINGBUFFER_H + +#include +#include + +namespace OHOS { +namespace AudioStandard { + +enum RingBufferState { + RINGBUFFER_EMPTY = 0, + RINGBUFFER_FULL, + RINGBUFFER_HALFFULL +}; + +typedef struct RingBuffer { + uint8_t *data; // BYTE + int length; +} RingBuffer; + +class HdiRingBuffer { +public: + HdiRingBuffer(); + ~HdiRingBuffer(); + + void Init(const int32_t sampleRate, const int32_t channelCount, const int32_t formatBytes, + const int32_t onceFrameNum = 2, const int32_t maxFrameNum = 5); + // read + RingBuffer AcquireOutputBuffer(); + int32_t ReleaseOutputBuffer(RingBuffer &item); + + // write + RingBuffer DequeueInputBuffer(); + int32_t EnqueueInputBuffer(RingBuffer &item); + +private: + enum RingBufferState GetRingBufferStatus(); + int32_t GetRingBufferDataLen(); + void AddWriteIndex(const int32_t &length); + void AddReadIndex(const int32_t &length); + +private: + RingBuffer ringBuffer_; + RingBuffer outputBuffer_; + RingBuffer inputBuffer_; + int32_t readIndex_; + bool readFull_; + int32_t writeIndex_; + bool writeFull_; + int32_t maxBufferSize_; + int32_t perFrameLength_; + std::mutex mtx_; +}; + +} // namespace AudioStandard +} // namespace OHOS +#endif // HDI_UTILS_RINGBUFFER_H diff --git a/frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp b/frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..276b0359fc9fec134a4d4025b0f95e988905f350 --- /dev/null +++ b/frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#undef LOG_TAG +#define LOG_TAG "HdiUtilsRingBuffer" + +#include "hdi_utils_ringbuffer.h" + +#include "securec.h" +#include "audio_log.h" +#include "audio_errors.h" + +namespace OHOS { +namespace AudioStandard { + +HdiRingBuffer::HdiRingBuffer() +{ + ringBuffer_.data = nullptr; + ringBuffer_.length = 0; + outputBuffer_.data = nullptr; + outputBuffer_.length = 0; + inputBuffer_.data = nullptr; + inputBuffer_.length = 0; + readIndex_ = 0; + readFull_ = false; + writeIndex_ = 0; + writeFull_ = false; + maxBufferSize_ = 0; + perFrameLength_ = 0; +} +HdiRingBuffer::~HdiRingBuffer() +{ + std::lock_guard lock(mtx_); + if (ringBuffer_.data != nullptr) { + delete [] ringBuffer_.data; + ringBuffer_.data = nullptr; + } + if (outputBuffer_.data != nullptr) { + delete [] outputBuffer_.data; + outputBuffer_.data = nullptr; + } + if (inputBuffer_.data != nullptr) { + delete [] inputBuffer_.data; + inputBuffer_.data = nullptr; + } +} + +void HdiRingBuffer::Init(const int32_t sampleRate, const int32_t channelCount, const int32_t formatBytes, + const int32_t onceFrameNum, const int32_t maxFrameNum) +{ + perFrameLength_ = ((sampleRate * onceFrameNum) / 100) * channelCount * formatBytes; + maxBufferSize_ = perFrameLength_ * maxFrameNum; + ringBuffer_.data = new (std::nothrow) uint8_t[maxBufferSize_]; + if (ringBuffer_.data != nullptr) { + memset_s(static_cast(ringBuffer_.data), sizeof(uint8_t) * maxBufferSize_, + 0, sizeof(uint8_t) * maxBufferSize_); + } else { + AUDIO_ERR_LOG("error: new ringBuffer_ data failed."); + } + outputBuffer_.data = new (std::nothrow) uint8_t[perFrameLength_]; + if (outputBuffer_.data != nullptr) { + memset_s(static_cast(outputBuffer_.data), sizeof(uint8_t) * perFrameLength_, + 0, sizeof(uint8_t) * perFrameLength_); + } else { + AUDIO_ERR_LOG("error: new outputBuffer_ data failed."); + } + inputBuffer_.data = new (std::nothrow) uint8_t[perFrameLength_]; + if (inputBuffer_.data != nullptr) { + memset_s(static_cast(inputBuffer_.data), sizeof(uint8_t) * perFrameLength_, + 0, sizeof(uint8_t) * perFrameLength_); + } else { + AUDIO_ERR_LOG("error: new inputBuffer_ data failed."); + } +} +enum RingBufferState HdiRingBuffer::GetRingBufferStatus() +{ + if (readFull_) { + return RINGBUFFER_EMPTY; + } else if (writeFull_) { + return RINGBUFFER_FULL; + } else { + return RINGBUFFER_HALFFULL; + } +} +int32_t HdiRingBuffer::GetRingBufferDataLen() +{ + switch (GetRingBufferStatus()) { + case RINGBUFFER_EMPTY: { + return 0; + } + case RINGBUFFER_FULL: { + return maxBufferSize_; + } + case RINGBUFFER_HALFFULL: + default: { + if (writeIndex_ > readIndex_){ + return writeIndex_ - readIndex_; + } else { + return maxBufferSize_ - (readIndex_ - writeIndex_); + } + } + } +} +void HdiRingBuffer::AddWriteIndex(const int32_t &length) +{ + if ((writeIndex_ + length) == maxBufferSize_) { + writeFull_ = true; + writeIndex_ = 0; + } else { + writeIndex_ += length; + writeFull_ = false; + } + readFull_ = false; +} +void HdiRingBuffer::AddReadIndex(const int32_t &length) +{ + if ((readIndex_ + length) == maxBufferSize_) { + readFull_ = true; + readIndex_ = 0; + } else { + readIndex_ += length; + readFull_ = false; + } +} +RingBuffer HdiRingBuffer::DequeueInputBuffer() +{ + std::lock_guard lock(mtx_); + inputBuffer_.length = perFrameLength_; + if (inputBuffer_.data != nullptr) { + memset_s(static_cast(inputBuffer_.data), sizeof(uint8_t) * perFrameLength_, + 0, sizeof(uint8_t) * perFrameLength_); + } else { + AUDIO_ERR_LOG("error: Dequeue InputBuffer failed."); + } + return inputBuffer_; +} + +RingBuffer HdiRingBuffer::AcquireOutputBuffer() +{ + std::lock_guard lock(mtx_); + outputBuffer_.length = perFrameLength_; + if (outputBuffer_.data != nullptr) { + memset_s(static_cast(outputBuffer_.data), sizeof(uint8_t) * perFrameLength_, + 0, sizeof(uint8_t) * perFrameLength_); + } else { + AUDIO_ERR_LOG("error: Acquire outpurtBuffer failed."); + } + return outputBuffer_; +} + +int32_t HdiRingBuffer::ReleaseOutputBuffer(RingBuffer &item) +{ + int32_t ret = 0; + std::lock_guard lock(mtx_); + // Onlyfixed-length(perFrameLength_) data is processed。 + if ((maxBufferSize_ - readIndex_) >= perFrameLength_ + && GetRingBufferStatus() != RINGBUFFER_EMPTY) { + ret = memmove_s(item.data, sizeof(uint8_t) * perFrameLength_, + ringBuffer_.data + readIndex_, sizeof(uint8_t) * perFrameLength_); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_READ_BUFFER, "copy ringbuffer fail"); + } else { + AUDIO_ERR_LOG("error: Not enough data to return."); + } + AddReadIndex(perFrameLength_); + return ret; +} + +int32_t HdiRingBuffer::EnqueueInputBuffer(RingBuffer &item) +{ + int32_t ret = 0; + std::lock_guard lock(mtx_); + int32_t leftSize = maxBufferSize_ - GetRingBufferDataLen(); + if (leftSize == 0) { + ret = memmove_s(ringBuffer_.data, sizeof(uint8_t) * perFrameLength_, + item.data, sizeof(uint8_t) * perFrameLength_); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_WRITE_BUFFER, "write ringbuffer from begin fail"); + } else if (leftSize >= perFrameLength_) { + ret = memmove_s(ringBuffer_.data + writeIndex_, sizeof(uint8_t) * perFrameLength_, + item.data, sizeof(uint8_t) * perFrameLength_); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_WRITE_BUFFER, "write ringbuffer from writeIndex fail"); + } else { + AUDIO_ERR_LOG("error: Not enough data to write."); + } + AddWriteIndex(perFrameLength_); + return ret; +}; + +} // namespace AudioStandard +} // namespace OHOS diff --git a/frameworks/native/hdiadapter/source/BUILD.gn b/frameworks/native/hdiadapter/source/BUILD.gn index 57f8a4043e3cd304f4ba14c476d982d91f03b5b6..86d5cee8a90c939af0c94940c316a28cc4c047d2 100644 --- a/frameworks/native/hdiadapter/source/BUILD.gn +++ b/frameworks/native/hdiadapter/source/BUILD.gn @@ -30,11 +30,15 @@ ohos_shared_library("audio_capturer_source") { include_dirs = [ "common", "../common/include", + "../manager/include", "../../audioutils/include", "../../../../interfaces/inner_api/native/audiocommon/include", ] - deps = [ "../../audioutils:audio_utils" ] + deps = [ + "../manager:hdiadapter_utils", + "../../audioutils:audio_utils", + ] external_deps = [ "c_utils:utils", diff --git a/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c b/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c index 1e064739f7a4d5540355d2682893a4f61445130b..6a79c07d5b3d062b8c1d1ea58e78369a0207f7ad 100644 --- a/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c +++ b/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c @@ -81,6 +81,7 @@ int32_t LoadSourceAdapter(const char *device, const char *deviceNetworkId, const adapter->CapturerSourceSetMute = IAudioCapturerSourceSetMute; adapter->CapturerSourceIsMuteRequired = IAudioCapturerSourceIsMuteRequired; adapter->CapturerSourceFrame = IAudioCapturerSourceFrame; + adapter->CapturerSourceFrameWithEc = IAudioCapturerSourceFrameWithEc; adapter->CapturerSourceSetVolume = IAudioCapturerSourceSetVolume; adapter->CapturerSourceGetVolume = IAudioCapturerSourceGetVolume; adapter->CapturerSourceAppsUid = IAudioCapturerSourceUpdateAppsUid; diff --git a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp index ba3dad15226ffd1bdf06451e6d2a3bb80b97c39c..79ffb509a35240a82765089d80dee9b56348a2bd 100644 --- a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp @@ -78,6 +78,11 @@ void IAudioCapturerSource::GetAllInstance(std::vector &a allInstance.push_back(AudioCapturerSource::GetInstance()); } +IAudioCapturerSource *IAudioCapturerSource::Create(CaptureAttr *attr) +{ + return AudioCapturerSource::Create(attr); +} + } // namespace AudioStandard } // namesapce OHOS @@ -184,6 +189,24 @@ int32_t IAudioCapturerSourceFrame(void *wapper, char *frame, uint64_t requestByt return ret; } +int32_t IAudioCapturerSourceFrameWithEc(void *wapper, + char *frame, uint64_t requestBytes, uint64_t *replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t *replyBytesEc) +{ + int32_t ret; + IAudioCapturerSource *iAudioCapturerSource = static_cast(wapper); + CHECK_AND_RETURN_RET_LOG(iAudioCapturerSource != nullptr, ERR_INVALID_HANDLE, "null audioCapturerSource"); + bool isInited = iAudioCapturerSource->IsInited(); + CHECK_AND_RETURN_RET_LOG(isInited, ERR_DEVICE_INIT, + "audioCapturer Not Inited! Init the capturer first\n"); + + ret = iAudioCapturerSource->CaptureFrameWithEc( + frame, requestBytes, *replyBytes, + frameEc, requestBytesEc, *replyBytesEc); + + return ret; +} + int32_t IAudioCapturerSourceSetVolume(void *wapper, float left, float right) { int32_t ret; diff --git a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h index a1c42908c45dceea92d96db14d3cbc5f4925ee47..df26bea7f7bfb0337e043614f67ce86443c7d799 100644 --- a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h +++ b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h @@ -57,10 +57,12 @@ class IAudioCapturerSource { public: static IAudioCapturerSource *GetInstance(const char *deviceClass, const char *deviceNetworkId, const SourceType sourceType = SourceType::SOURCE_TYPE_MIC, const char *sourceName = "Built_in_wakeup"); + static IAudioCapturerSource *Create(CaptureAttr *attr); static void GetAllInstance(std::vector &allInstance); virtual ~IAudioCapturerSource() = default; virtual int32_t Init(const IAudioSourceAttr &attr) = 0; + virtual int32_t InitWithoutAttr() { return 0; } virtual bool IsInited(void) = 0; virtual void DeInit(void) = 0; @@ -72,6 +74,9 @@ public: virtual int32_t Resume(void) = 0; virtual int32_t CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) = 0; + virtual int32_t CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) = 0; virtual int32_t SetVolume(float left, float right) = 0; virtual int32_t GetVolume(float &left, float &right) = 0; diff --git a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source_intf.h b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source_intf.h index 8b6f9c7d9eb07d4ada3c1d3447c75f99c6848fc6..1b5eac4eeb29348603e955cfd78bf62606d99039 100644 --- a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source_intf.h +++ b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source_intf.h @@ -50,6 +50,8 @@ struct CapturerSourceAdapter { bool (*CapturerSourceIsMuteRequired)(void *wapper); int32_t (*CapturerSourceStop)(void *wapper); int32_t (*CapturerSourceFrame)(void *wapper, char *frame, uint64_t requestBytes, uint64_t *replyBytes); + int32_t (*CapturerSourceFrameWithEc)(void *wapper, char *frame, uint64_t requestBytes, uint64_t *replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t *replyBytesEc); int32_t (*CapturerSourceSetVolume)(void *wapper, float left, float right); int32_t (*CapturerSourceGetVolume)(void *wapper, float *left, float *right); int32_t (*CapturerSourceAppsUid) (void *wapper, const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], @@ -63,6 +65,8 @@ void IAudioCapturerSourceDeInit(void *wapper); int32_t IAudioCapturerSourceStart(void *wapper); int32_t IAudioCapturerSourceStop(void *wapper); int32_t IAudioCapturerSourceFrame(void *wapper, char *frame, uint64_t requestBytes, uint64_t *replyBytes); +int32_t IAudioCapturerSourceFrameWithEc(void *wapper, char *frame, uint64_t requestBytes, uint64_t *replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t *replyBytesEc); int32_t IAudioCapturerSourceSetVolume(void *wapper, float left, float right); bool IAudioCapturerSourceIsMuteRequired(void *wapper); int32_t IAudioCapturerSourceSetMute(void *wapper, bool isMute); diff --git a/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.cpp index 3f6ef265dbc780f2ae969e5468fd3750f413a790..73bc433e85ca8a1171e8117b73336920b40ef3b2 100644 --- a/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.cpp @@ -47,6 +47,9 @@ public: int32_t Pause(void) override; int32_t Resume(void) override; int32_t CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) override; + int32_t CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; int32_t SetMute(bool isMute) override; @@ -455,6 +458,14 @@ int32_t FastAudioCapturerSourceInner::CaptureFrame(char *frame, uint64_t request return ERR_DEVICE_NOT_SUPPORTED; } +int32_t FastAudioCapturerSourceInner::CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) +{ + AUDIO_ERR_LOG("not supported!"); + return ERR_DEVICE_NOT_SUPPORTED; +} + int32_t FastAudioCapturerSourceInner::CheckPositionTime() { int32_t tryCount = 10; diff --git a/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.cpp b/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.cpp index edc9259a0152cbd17d451b34922e4aa41430225d..18f18590b487c3ca4311a2165f5e9855da9b2c77 100644 --- a/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.cpp +++ b/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.cpp @@ -167,6 +167,14 @@ int32_t AudioCapturerFileSource::CaptureFrame(char *frame, uint64_t requestBytes return SUCCESS; } +int32_t AudioCapturerFileSource::CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) +{ + AUDIO_ERR_LOG("not supported!"); + return ERR_DEVICE_NOT_SUPPORTED; +} + int32_t AudioCapturerFileSource::Start(void) { return SUCCESS; diff --git a/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.h b/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.h index a88f19bc511cadaf1c4d9e53938369bfea7634fd..2c6ff1c7e47c5215b5bffdf12313fbaec271ae74 100644 --- a/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.h +++ b/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.h @@ -38,6 +38,9 @@ public: int32_t Pause(void) override; int32_t Resume(void) override; int32_t CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) override; + int32_t CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; int32_t SetMute(bool isMute) override; diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 904d4bc3109f534d5591459e4a532d6549419fc2..6e99bb92747e23dd091f91590f5903d69ad900e4 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -21,8 +21,10 @@ #include #include #include +#include #include "securec.h" +#include "parameters.h" #ifdef FEATURE_POWER_MANAGER #include "power_mgr_client.h" #include "running_lock.h" @@ -33,20 +35,190 @@ #include "audio_log.h" #include "audio_errors.h" #include "audio_utils.h" -#include "parameters.h" + +#include "hdi_utils_ringbuffer.h" using namespace std; namespace OHOS { namespace AudioStandard { namespace { - const int64_t SECOND_TO_NANOSECOND = 1000000000; - const unsigned int DEINIT_TIME_OUT_SECONDS = 5; - const uint16_t GET_MAX_AMPLITUDE_FRAMES_THRESHOLD = 10; +const int64_t SECOND_TO_NANOSECOND = 1000000000; +const unsigned int DEINIT_TIME_OUT_SECONDS = 5; +const uint16_t GET_MAX_AMPLITUDE_FRAMES_THRESHOLD = 10; +} +#ifdef FEATURE_POWER_MANAGER +constexpr int32_t RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING = -1; +#endif + +static enum AudioInputType ConvertToHDIAudioInputType(const int32_t currSourceType) +{ + enum AudioInputType hdiAudioInputType; + switch (currSourceType) { + case SOURCE_TYPE_INVALID: + hdiAudioInputType = AUDIO_INPUT_DEFAULT_TYPE; + break; + case SOURCE_TYPE_MIC: + case SOURCE_TYPE_PLAYBACK_CAPTURE: + case SOURCE_TYPE_ULTRASONIC: + hdiAudioInputType = AUDIO_INPUT_MIC_TYPE; + break; + case SOURCE_TYPE_WAKEUP: + hdiAudioInputType = AUDIO_INPUT_SPEECH_WAKEUP_TYPE; + break; + case SOURCE_TYPE_VOICE_COMMUNICATION: + hdiAudioInputType = AUDIO_INPUT_VOICE_COMMUNICATION_TYPE; + break; + case SOURCE_TYPE_VOICE_RECOGNITION: + hdiAudioInputType = AUDIO_INPUT_VOICE_RECOGNITION_TYPE; + break; + case SOURCE_TYPE_VOICE_CALL: + hdiAudioInputType = AUDIO_INPUT_VOICE_CALL_TYPE; + break; + case SOURCE_TYPE_EC: + hdiAudioInputType = AUDIO_INPUT_EC_TYPE; + break; + case SOURCE_TYPE_MIC_REF: + hdiAudioInputType = AUDIO_INPUT_NOISE_REDUCTION_TYPE; + break; + default: + hdiAudioInputType = AUDIO_INPUT_MIC_TYPE; + break; + } + return hdiAudioInputType; +} + +static AudioCategory GetAudioCategory(AudioScene audioScene) +{ + AudioCategory audioCategory; + switch (audioScene) { + case AUDIO_SCENE_PHONE_CALL: + audioCategory = AUDIO_IN_CALL; + break; + case AUDIO_SCENE_PHONE_CHAT: + audioCategory = AUDIO_IN_COMMUNICATION; + break; + case AUDIO_SCENE_RINGING: + case AUDIO_SCENE_VOICE_RINGING: + audioCategory = AUDIO_IN_RINGTONE; + break; + case AUDIO_SCENE_DEFAULT: + audioCategory = AUDIO_IN_MEDIA; + break; + default: + audioCategory = AUDIO_IN_MEDIA; + break; + } + AUDIO_DEBUG_LOG("Audio category returned is: %{public}d", audioCategory); + + return audioCategory; +} + +static int32_t SetInputPortPin(DeviceType inputDevice, AudioRouteNode &source) +{ + int32_t ret = SUCCESS; + + switch (inputDevice) { + case DEVICE_TYPE_MIC: + case DEVICE_TYPE_EARPIECE: + case DEVICE_TYPE_SPEAKER: + source.ext.device.type = PIN_IN_MIC; + source.ext.device.desc = (char *)"pin_in_mic"; + break; + case DEVICE_TYPE_WIRED_HEADSET: + source.ext.device.type = PIN_IN_HS_MIC; + source.ext.device.desc = (char *)"pin_in_hs_mic"; + break; + case DEVICE_TYPE_USB_ARM_HEADSET: + source.ext.device.type = PIN_IN_USB_HEADSET; + source.ext.device.desc = (char *)"pin_in_usb_headset"; + break; + case DEVICE_TYPE_USB_HEADSET: + source.ext.device.type = PIN_IN_USB_EXT; + source.ext.device.desc = (char *)"pin_in_usb_ext"; + break; + case DEVICE_TYPE_BLUETOOTH_SCO: + source.ext.device.type = PIN_IN_BLUETOOTH_SCO_HEADSET; + source.ext.device.desc = (char *)"pin_in_bluetooth_sco_headset"; + break; + default: + ret = ERR_NOT_SUPPORTED; + break; + } + + return ret; +} + +static AudioFormat ConvertToHdiFormat(HdiAdapterFormat format) +{ + AudioFormat hdiFormat; + switch (format) { + case SAMPLE_U8: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT; + break; + case SAMPLE_S16: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT; + break; + case SAMPLE_S24: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT; + break; + case SAMPLE_S32: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT; + break; + default: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT; + break; + } + + return hdiFormat; +} + +static int32_t GetByteSizeByFormat(HdiAdapterFormat format) +{ + int32_t byteSize = 0; + switch (format) { + case SAMPLE_U8: + byteSize = 1; + break; + case SAMPLE_S16: + byteSize = 2; + break; + case SAMPLE_S24: + byteSize = 3; + break; + case SAMPLE_S32: + byteSize = 4; + break; + default: + byteSize = 2; + break; + } + + return byteSize; +} + +static HdiAdapterFormat ParseAudioFormat(const std::string &format) +{ + if (format == "AUDIO_FORMAT_PCM_16_BIT") { + return HdiAdapterFormat::SAMPLE_S16; + } else if (format == "AUDIO_FORMAT_PCM_24_BIT") { + return HdiAdapterFormat::SAMPLE_S24; + } else if (format == "AUDIO_FORMAT_PCM_32_BIT") { + return HdiAdapterFormat::SAMPLE_S32; + } else { + return HdiAdapterFormat::SAMPLE_S16; + } } + +static bool IsNonblockingSource(int32_t type) { + return (type == SOURCE_TYPE_EC || type == SOURCE_TYPE_MIC_REF); +} + +// inner class definations class AudioCapturerSourceInner : public AudioCapturerSource { public: int32_t Init(const IAudioSourceAttr &attr) override; + int32_t InitWithoutAttr() override; bool IsInited(void) override; void DeInit(void) override; @@ -57,6 +229,9 @@ public: int32_t Pause(void) override; int32_t Resume(void) override; int32_t CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) override; + int32_t CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; int32_t SetMute(bool isMute) override; @@ -84,6 +259,7 @@ public: int32_t UpdateAppsUid(const std::vector &appsUid) final; explicit AudioCapturerSourceInner(const std::string &halName = "primary"); + explicit AudioCapturerSourceInner(CaptureAttr *attr); ~AudioCapturerSourceInner(); private: @@ -91,13 +267,14 @@ private: static constexpr uint32_t MAX_AUDIO_ADAPTER_NUM = 5; static constexpr float MAX_VOLUME_LEVEL = 15.0f; static constexpr uint32_t PRIMARY_INPUT_STREAM_ID = 14; // 14 + 0 * 8 + static constexpr uint32_t MICREF_INPUT_STREAM_ID = 46; // 14 + 0 * 8 + static constexpr uint32_t EC_INPUT_STREAM_ID = 54; // 14 + 0 * 8 static constexpr uint32_t USB_DEFAULT_BUFFERSIZE = 3840; static constexpr uint32_t STEREO_CHANNEL_COUNT = 2; int32_t CreateCapture(struct AudioPort &capturePort); int32_t InitAudioManager(); void InitAttrsCapture(struct AudioSampleAttributes &attrs); - AudioFormat ConvertToHdiFormat(HdiAdapterFormat format); int32_t UpdateUsbAttrs(const std::string &usbInfoStr); int32_t InitManagerAndAdapter(); @@ -107,7 +284,9 @@ private: void CheckLatencySignal(uint8_t *frame, size_t replyBytes); void CheckUpdateState(char *frame, uint64_t replyBytes); + void CaptureThreadLoop(); + CaptureAttr *hdiAttr_; IAudioSourceAttr attr_ = {}; bool sourceInited_ = false; bool captureInited_ = false; @@ -133,7 +312,7 @@ private: std::atomic adapterLoaded_ = false; struct IAudioAdapter *audioAdapter_ = nullptr; struct IAudioCapture *audioCapture_ = nullptr; - const std::string halName_ = ""; + std::string halName_ = ""; struct AudioAdapterDescriptor adapterDesc_ = {}; struct AudioPort audioPort_ = {}; #ifdef FEATURE_POWER_MANAGER @@ -151,6 +330,10 @@ private: bool signalDetected_ = false; std::shared_ptr signalDetectAgent_ = nullptr; std::mutex managerAndAdapterMutex_; + std::unique_ptr captureThread_ = nullptr; + bool threadRunning_ = false; + std::shared_ptr ringBuffer_ = nullptr; + int8_t *fakeSourceFrame_ = nullptr; }; class AudioCapturerSourceWakeup : public AudioCapturerSource { @@ -166,6 +349,9 @@ public: int32_t Pause(void) override; int32_t Resume(void) override; int32_t CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) override; + int32_t CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; int32_t SetMute(bool isMute) override; @@ -313,23 +499,8 @@ private: static inline AudioCapturerSourceInner audioCapturerSource_; }; -#ifdef FEATURE_POWER_MANAGER -constexpr int32_t RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING = -1; -#endif - -AudioCapturerSourceInner::AudioCapturerSourceInner(const std::string &halName) - : sourceInited_(false), captureInited_(false), started_(false), paused_(false), - leftVolume_(MAX_VOLUME_LEVEL), rightVolume_(MAX_VOLUME_LEVEL), openMic_(0), - audioManager_(nullptr), audioAdapter_(nullptr), audioCapture_(nullptr), halName_(halName) -{ - attr_ = {}; -} - -AudioCapturerSourceInner::~AudioCapturerSourceInner() -{ - AUDIO_WARNING_LOG("~AudioCapturerSourceInner"); -} +// class function impls AudioCapturerSource *AudioCapturerSource::GetInstance(const std::string &halName, const SourceType sourceType, const char *sourceName) { @@ -355,35 +526,10 @@ AudioCapturerSource *AudioCapturerSource::GetInstance(const std::string &halName } } -static enum AudioInputType ConvertToHDIAudioInputType(const int32_t currSourceType) +AudioCapturerSource *AudioCapturerSource::Create(CaptureAttr *attr) { - enum AudioInputType hdiAudioInputType; - switch (currSourceType) { - case SOURCE_TYPE_INVALID: - hdiAudioInputType = AUDIO_INPUT_DEFAULT_TYPE; - break; - case SOURCE_TYPE_MIC: - case SOURCE_TYPE_PLAYBACK_CAPTURE: - case SOURCE_TYPE_ULTRASONIC: - hdiAudioInputType = AUDIO_INPUT_MIC_TYPE; - break; - case SOURCE_TYPE_WAKEUP: - hdiAudioInputType = AUDIO_INPUT_SPEECH_WAKEUP_TYPE; - break; - case SOURCE_TYPE_VOICE_COMMUNICATION: - hdiAudioInputType = AUDIO_INPUT_VOICE_COMMUNICATION_TYPE; - break; - case SOURCE_TYPE_VOICE_RECOGNITION: - hdiAudioInputType = AUDIO_INPUT_VOICE_RECOGNITION_TYPE; - break; - case SOURCE_TYPE_VOICE_CALL: - hdiAudioInputType = AUDIO_INPUT_VOICE_CALL_TYPE; - break; - default: - hdiAudioInputType = AUDIO_INPUT_MIC_TYPE; - break; - } - return hdiAudioInputType; + AudioCapturerSource *captureSource = new AudioCapturerSourceInner(attr); + return captureSource; } AudioCapturerSource *AudioCapturerSource::GetMicInstance() @@ -402,49 +548,73 @@ AudioCapturerSource *AudioCapturerSource::GetWakeupInstance(bool isMirror) return &audioCapturer; } -bool AudioCapturerSourceInner::IsInited(void) +AudioCapturerSourceInner::AudioCapturerSourceInner(const std::string &halName) + : sourceInited_(false), captureInited_(false), started_(false), paused_(false), + leftVolume_(MAX_VOLUME_LEVEL), rightVolume_(MAX_VOLUME_LEVEL), openMic_(0), + audioManager_(nullptr), audioAdapter_(nullptr), audioCapture_(nullptr), halName_(halName) { - return sourceInited_; + attr_ = {}; } -void AudioCapturerSourceInner::DeInit() +AudioCapturerSourceInner::AudioCapturerSourceInner(CaptureAttr *attr) + : sourceInited_(false), captureInited_(false), started_(false), paused_(false), + leftVolume_(MAX_VOLUME_LEVEL), rightVolume_(MAX_VOLUME_LEVEL), openMic_(0), + audioManager_(nullptr), audioAdapter_(nullptr), audioCapture_(nullptr) { - Trace trace("AudioCapturerSourceInner::DeInit"); - AudioXCollie sourceXCollie("AudioCapturerSourceInner::DeInit", DEINIT_TIME_OUT_SECONDS); - AUDIO_INFO_LOG("Start deinit of source inner"); - started_ = false; - sourceInited_ = false; + halName_ = "primary"; + hdiAttr_ = attr; + attr_ = {}; +} - if (audioAdapter_ != nullptr) { - audioAdapter_->DestroyCapture(audioAdapter_, captureId_); - } - captureInited_ = false; +AudioCapturerSourceInner::~AudioCapturerSourceInner() +{ + AUDIO_WARNING_LOG("~AudioCapturerSourceInner"); +} - IAudioSourceCallback* callback = nullptr; - { - std::lock_guard lck(wakeupClosecallbackMutex_); - callback = wakeupCloseCallback_; - } - if (callback != nullptr) { - callback->OnWakeupClose(); - } +int32_t AudioCapturerSourceInner::Init(const IAudioSourceAttr &attr) +{ + attr_ = attr; + adapterNameCase_ = attr_.adapterName; + openMic_ = attr_.openMicSpeaker; + logMode_ = system::GetIntParameter("persist.multimedia.audiolog.switch", 0); - audioCapture_ = nullptr; - currentActiveDevice_ = DEVICE_TYPE_INVALID; // the current device must be rest when closing capturer. + int32_t ret = InitAdapterAndCapture(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Init adapter and capture failed"); - std::lock_guard lock(managerAndAdapterMutex_); - // Only the usb hal needs to be unloadadapter at the moment. - if (halName_ == "usb") { - adapterLoaded_ = false; - if (audioManager_ != nullptr) { - audioManager_->UnloadAdapter(audioManager_, adapterDesc_.adapterName); - } - audioAdapter_ = nullptr; - audioManager_ = nullptr; - } + sourceInited_ = true; - DumpFileUtil::CloseDumpFile(&dumpFile_); -} + SetMute(muteState_); + + return SUCCESS; +} + +int32_t AudioCapturerSourceInner::InitWithoutAttr() +{ + // TODO: use this when testing usb + // halName_ = "usb"; + + // build attr + IAudioSourceAttr attr = {}; + attr.adapterName = hdiAttr_->adapterName; + attr.openMicSpeaker = true; + attr.format = hdiAttr_->format; + attr.sampleRate = hdiAttr_->sampleRate; + attr.channel = hdiAttr_->channelCount; + // attr.volume = 1.0; + attr.bufferSize = USB_DEFAULT_BUFFERSIZE; + attr.isBigEndian = hdiAttr_->isBigEndian; + attr.filePath = ""; + attr.deviceNetworkId = "LocalDevice"; + attr.deviceType = DEVICE_TYPE_MIC; + attr.sourceType = hdiAttr_->sourceType; + + Init(attr); + + ringBuffer_ = std::make_shared(); + ringBuffer_->Init(attr.sampleRate, attr.channel, GetByteSizeByFormat(attr.format)); + + return SUCCESS; +} void AudioCapturerSourceInner::InitAttrsCapture(struct AudioSampleAttributes &attrs) { @@ -466,6 +636,21 @@ void AudioCapturerSourceInner::InitAttrsCapture(struct AudioSampleAttributes &at attrs.sourceType = SOURCE_TYPE_MIC; } +int32_t AudioCapturerSourceInner::InitAudioManager() +{ + AUDIO_INFO_LOG("Initialize audio proxy manager"); + + if (audioManager_ == nullptr) { + audioManager_ = IAudioManagerGet(false); + } + + if (audioManager_ == nullptr) { + return ERR_INVALID_HANDLE; + } + + return 0; +} + int32_t SwitchAdapterCapture(struct AudioAdapterDescriptor *descs, uint32_t size, const std::string &adapterNameCase, enum AudioPortDirection portFlag, struct AudioPort &capturePort) { @@ -495,45 +680,6 @@ int32_t SwitchAdapterCapture(struct AudioAdapterDescriptor *descs, uint32_t size return ERR_INVALID_INDEX; } -int32_t AudioCapturerSourceInner::InitAudioManager() -{ - AUDIO_INFO_LOG("Initialize audio proxy manager"); - - if (audioManager_ == nullptr) { - audioManager_ = IAudioManagerGet(false); - } - - if (audioManager_ == nullptr) { - return ERR_INVALID_HANDLE; - } - - return 0; -} - -AudioFormat AudioCapturerSourceInner::ConvertToHdiFormat(HdiAdapterFormat format) -{ - AudioFormat hdiFormat; - switch (format) { - case SAMPLE_U8: - hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT; - break; - case SAMPLE_S16: - hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT; - break; - case SAMPLE_S24: - hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT; - break; - case SAMPLE_S32: - hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT; - break; - default: - hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT; - break; - } - - return hdiFormat; -} - int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) { Trace trace("AudioCapturerSourceInner:CreateCapture"); @@ -551,11 +697,35 @@ int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) param.channelLayout = CH_LAYOUT_STEREO; } else if (param.channelCount == CHANNEL_4) { param.channelLayout = CH_LAYOUT_QUAD; + } else if (param.channelCount == CHANNEL_8) { + param.channelLayout = CH_LAYOUT_7POINT1; } param.silenceThreshold = attr_.bufferSize; param.frameSize = param.format * param.channelCount; param.startThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (param.frameSize); param.sourceType = static_cast(ConvertToHDIAudioInputType(attr_.sourceType)); + if (attr_.sourceType == SOURCE_TYPE_EC) { + param.streamId = EC_INPUT_STREAM_ID; + } else if (attr_.sourceType == SOURCE_TYPE_MIC_REF) { + param.streamId = MICREF_INPUT_STREAM_ID; + } + + // only for ec same adapter stream + if (attr_.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) { + // Need compile with hdi + param.ecSampleAttributes.ecInterleaved = true; + param.ecSampleAttributes.ecFormat = param.format; + param.ecSampleAttributes.ecSampleRate = param.sampleRate; + param.ecSampleAttributes.ecChannelLayout = param.channelLayout; + param.ecSampleAttributes.ecChannelCount = param.channelCount; + param.ecSampleAttributes.ecPeriod = DEEP_BUFFER_CAPTURE_PERIOD_SIZE; + param.ecSampleAttributes.ecFrameSize = PCM_16_BIT * param.channelCount / PCM_8_BIT; + param.ecSampleAttributes.ecIsBigEndian = false; + param.ecSampleAttributes.ecIsSignedData = true; + param.ecSampleAttributes.ecStartThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (param.frameSize); + param.ecSampleAttributes.ecStopThreshold = INT_32_MAX; + param.ecSampleAttributes.ecSilenceThreshold = AUDIO_BUFF_SIZE; + } struct AudioDeviceDescriptor deviceDesc; deviceDesc.portId = capturePort.portId; @@ -573,25 +743,232 @@ int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) return 0; } -int32_t AudioCapturerSourceInner::Init(const IAudioSourceAttr &attr) +bool AudioCapturerSourceInner::IsInited(void) { - attr_ = attr; - adapterNameCase_ = attr_.adapterName; - openMic_ = attr_.openMicSpeaker; - logMode_ = system::GetIntParameter("persist.multimedia.audiolog.switch", 0); + return sourceInited_; +} - int32_t ret = InitAdapterAndCapture(); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Init adapter and capture failed"); +void AudioCapturerSourceInner::DeInit() +{ + Trace trace("AudioCapturerSourceInner::DeInit"); + AudioXCollie sourceXCollie("AudioCapturerSourceInner::DeInit", DEINIT_TIME_OUT_SECONDS); + AUDIO_INFO_LOG("Start deinit of source inner"); + started_ = false; + sourceInited_ = false; - sourceInited_ = true; + if (audioAdapter_ != nullptr) { + audioAdapter_->DestroyCapture(audioAdapter_, captureId_); + } + captureInited_ = false; - SetMute(muteState_); + IAudioSourceCallback* callback = nullptr; + { + std::lock_guard lck(wakeupClosecallbackMutex_); + callback = wakeupCloseCallback_; + } + if (callback != nullptr) { + callback->OnWakeupClose(); + } + + audioCapture_ = nullptr; + currentActiveDevice_ = DEVICE_TYPE_INVALID; // the current device must be rest when closing capturer. + + std::lock_guard lock(managerAndAdapterMutex_); + // Only the usb hal needs to be unloadadapter at the moment. + if (halName_ == "usb") { + adapterLoaded_ = false; + if (audioManager_ != nullptr) { + audioManager_->UnloadAdapter(audioManager_, adapterDesc_.adapterName); + } + audioAdapter_ = nullptr; + audioManager_ = nullptr; + } + + DumpFileUtil::CloseDumpFile(&dumpFile_); +} + +int32_t AudioCapturerSourceInner::Start(void) +{ + Trace trace("AudioCapturerSourceInner::Start"); + AUDIO_INFO_LOG("Enter"); + + if (IsNonblockingSource(attr_.sourceType)) { + if (!started_) { + int32_t ret = audioCapture_->Start(audioCapture_); + if (ret < 0) { + return ERR_NOT_STARTED; + } + started_ = true; + + // start self capture frame thread + threadRunning_ = true; + fakeSourceFrame_ = new int8_t[attr_.bufferSize]; + captureThread_ = std::make_unique(&AudioCapturerSourceInner::CaptureThreadLoop, this); + std::string threadName = "OS_Capture"; + threadName += (attr_.sourceType == SOURCE_TYPE_EC) ? "Ec" : "MicRef"; + pthread_setname_np(captureThread_->native_handle(), threadName.c_str()); + } + return SUCCESS; + } + + InitLatencyMeasurement(); +#ifdef FEATURE_POWER_MANAGER + std::shared_ptr keepRunningLock; + if (runningLockManager_ == nullptr) { + switch (attr_.sourceType) { + case SOURCE_TYPE_WAKEUP: + keepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioWakeupCapturer", + PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO); + break; + case SOURCE_TYPE_MIC: + default: + keepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioPrimaryCapturer", + PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO); + } + if (keepRunningLock) { + runningLockManager_ = std::make_shared> (keepRunningLock); + } + } + if (runningLockManager_ != nullptr) { + AUDIO_INFO_LOG("keepRunningLock lock result: %{public}d", + runningLockManager_->Lock(RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING)); // -1 for lasting. + } else { + AUDIO_WARNING_LOG("keepRunningLock is null, capture can not work well!"); + } +#endif + // eg: primary_0_44100_2_1_20240527202236189_source.pcm + std::string dumpName = halName_ + '_' + std::to_string(attr_.sourceType) + '_' + + std::to_string(attr_.sampleRate) + '_' + std::to_string(attr_.channel) + '_' + + std::to_string(attr_.format) + '_' + + GetTime() + "_source.pcm"; + DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, dumpName, &dumpFile_); + + int32_t ret; + if (!started_) { + if (audioCapturerSourceCallback_ != nullptr) { + audioCapturerSourceCallback_->OnCapturerState(true); + } + + ret = audioCapture_->Start(audioCapture_); + if (ret < 0) { + return ERR_NOT_STARTED; + } + started_ = true; + } + + return SUCCESS; +} + +int32_t AudioCapturerSourceInner::Stop(void) +{ + Trace trace("AudioCapturerSourceInner::Stop"); + AUDIO_INFO_LOG("Enter"); + + if (IsNonblockingSource(attr_.sourceType)) { + threadRunning_ = false; + if (captureThread_ && captureThread_->joinable()) { + captureThread_->join(); + } + delete [] fakeSourceFrame_; + + if (started_ && audioCapture_ != nullptr) { + int32_t ret = audioCapture_->Stop(audioCapture_); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("hdi stop capture failed"); + } + } + started_ = false; + + return SUCCESS; + } + + DeinitLatencyMeasurement(); + +#ifdef FEATURE_POWER_MANAGER + if (runningLockManager_ != nullptr) { + AUDIO_INFO_LOG("keepRunningLock unlock"); + runningLockManager_->UnLock(); + } else { + AUDIO_WARNING_LOG("keepRunningLock is null, stop can not work well!"); + } +#endif + int32_t ret; + if (started_ && audioCapture_ != nullptr) { + ret = audioCapture_->Stop(audioCapture_); + CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_OPERATION_FAILED, "Stop capture Failed"); + } + started_ = false; + + if (audioCapturerSourceCallback_ != nullptr) { + audioCapturerSourceCallback_->OnCapturerState(false); + } + + return SUCCESS; +} + +int32_t AudioCapturerSourceInner::Pause(void) +{ + Trace trace("AudioCapturerSourceInner::Pause"); + int32_t ret; + if (started_ && audioCapture_ != nullptr) { + ret = audioCapture_->Pause(audioCapture_); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "pause capture Failed"); + } + paused_ = true; + + return SUCCESS; +} + +int32_t AudioCapturerSourceInner::Resume(void) +{ + Trace trace("AudioCapturerSourceInner::Resume"); + int32_t ret; + if (paused_ && audioCapture_ != nullptr) { + ret = audioCapture_->Resume(audioCapture_); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "resume capture Failed"); + } + paused_ = false; + + return SUCCESS; +} + +int32_t AudioCapturerSourceInner::Reset(void) +{ + Trace trace("AudioCapturerSourceInner::Reset"); + if (started_ && audioCapture_ != nullptr) { + audioCapture_->Flush(audioCapture_); + } + + return SUCCESS; +} + +int32_t AudioCapturerSourceInner::Flush(void) +{ + Trace trace("AudioCapturerSourceInner::Flush"); + if (started_ && audioCapture_ != nullptr) { + audioCapture_->Flush(audioCapture_); + } return SUCCESS; } int32_t AudioCapturerSourceInner::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) { + // for ec or mic ref + if (IsNonblockingSource(attr_.sourceType)) { + if (ringBuffer_ != nullptr) { + Trace trace("CaptureRefOutput"); + RingBuffer buffer = ringBuffer_->AcquireOutputBuffer(); + replyBytes = buffer.length; + if (memcpy_s(frame, requestBytes, buffer.data, requestBytes)) { + AUDIO_ERR_LOG("memcpy error"); + } + ringBuffer_->ReleaseOutputBuffer(buffer); + } + + return SUCCESS; + } + int64_t stamp = ClockTime::GetCurNano(); int32_t ret; CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); @@ -612,81 +989,61 @@ int32_t AudioCapturerSourceInner::CaptureFrame(char *frame, uint64_t requestByte return SUCCESS; } -void AudioCapturerSourceInner::CheckUpdateState(char *frame, uint64_t replyBytes) +int32_t AudioCapturerSourceInner::CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) { - if (startUpdate_) { - if (capFrameNum_ == 0) { - last10FrameStartTime_ = ClockTime::GetCurNano(); - } - capFrameNum_++; - maxAmplitude_ = UpdateMaxAmplitude(static_cast(attr_.format), frame, replyBytes); - if (capFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) { - capFrameNum_ = 0; - if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) { - startUpdate_ = false; - maxAmplitude_ = 0; - } - } - } -} + CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); -float AudioCapturerSourceInner::GetMaxAmplitude() -{ - lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano(); - startUpdate_ = true; - return maxAmplitude_; -} + // Need compile with hdi + struct AudioFrameLen frameLen = {}; + frameLen.frameLen = requestBytes; + frameLen.frameEcLen = requestBytesEc; + struct AudioCaptureFrameInfo frameInfo = {}; + frameInfo.frame = reinterpret_cast(frame); + frameInfo.frameEc = reinterpret_cast(frame); -int32_t AudioCapturerSourceInner::Start(void) -{ - Trace trace("AudioCapturerSourceInner::Start"); - AUDIO_INFO_LOG("Enter"); - InitLatencyMeasurement(); -#ifdef FEATURE_POWER_MANAGER - std::shared_ptr keepRunningLock; - if (runningLockManager_ == nullptr) { - switch (attr_.sourceType) { - case SOURCE_TYPE_WAKEUP: - keepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioWakeupCapturer", - PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO); - break; - case SOURCE_TYPE_MIC: - default: - keepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioPrimaryCapturer", - PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO); - } - if (keepRunningLock) { - runningLockManager_ = std::make_shared> (keepRunningLock); - } - } - if (runningLockManager_ != nullptr) { - AUDIO_INFO_LOG("keepRunningLock lock result: %{public}d", - runningLockManager_->Lock(RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING)); // -1 for lasting. - } else { - AUDIO_WARNING_LOG("keepRunningLock is null, capture can not work well!"); - } -#endif - // eg: primary_0_44100_2_1_20240527202236189_source.pcm - std::string dumpName = halName_ + '_' + std::to_string(attr_.sourceType) + '_' - + std::to_string(attr_.sampleRate) + '_' + std::to_string(attr_.channel) + '_' - + std::to_string(attr_.format) + '_' - + GetTime() + "_source.pcm"; - DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, dumpName, &dumpFile_); + int32_t ret = audioCapture_->CaptureFrameEc(audioCapture_, &frameLen, &frameInfo); + CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_READ_FAILED, "Capture Frame Fail"); - int32_t ret; - if (!started_) { - if (audioCapturerSourceCallback_ != nullptr) { - audioCapturerSourceCallback_->OnCapturerState(true); - } + replyBytes = frameInfo.replyBytes; + replyBytesEc = frameInfo.replyBytesEc; - ret = audioCapture_->Start(audioCapture_); - if (ret < 0) { - return ERR_NOT_STARTED; + return SUCCESS; +} + +void AudioCapturerSourceInner::CaptureThreadLoop() +{ + AUDIO_INFO_LOG("Auxiliary capture thread start"); + while (threadRunning_) { + if (ringBuffer_ != nullptr) { + Trace trace("CaptureRefInput"); + RingBuffer buffer = ringBuffer_->DequeueInputBuffer(); + uint64_t replyBytes; + uint32_t requestBytes = buffer.length; + int32_t ret = 0; + if (attr_.sourceType == SOURCE_TYPE_MIC_REF) { + ret = audioCapture_->CaptureFrame( + audioCapture_, reinterpret_cast(buffer.data), &requestBytes, &replyBytes); + } else { + // Need compile with hdi + // mic frame just used for check, ec frame must be right + struct AudioFrameLen frameLen; + frameLen.frameLen = buffer.length; + frameLen.frameEcLen = buffer.length; + struct AudioCaptureFrameInfo frameInfo; + frameInfo.frame = fakeSourceFrame_; + frameInfo.frameEc = reinterpret_cast(buffer.data); + ret = audioCapture_->CaptureFrameEc(audioCapture_, &frameLen, &frameInfo); + replyBytes = frameInfo.replyBytes; + // replyBytesEc = frameInfo.replyBytesEc; + } + if (ret != SUCCESS) { + AUDIO_ERR_LOG("Capture frame failed"); + } + ringBuffer_->EnqueueInputBuffer(buffer); } - started_ = true; } - - return SUCCESS; } int32_t AudioCapturerSourceInner::SetVolume(float left, float right) @@ -767,67 +1124,6 @@ int32_t AudioCapturerSourceInner::GetMute(bool &isMute) return SUCCESS; } -static AudioCategory GetAudioCategory(AudioScene audioScene) -{ - AudioCategory audioCategory; - switch (audioScene) { - case AUDIO_SCENE_PHONE_CALL: - audioCategory = AUDIO_IN_CALL; - break; - case AUDIO_SCENE_PHONE_CHAT: - audioCategory = AUDIO_IN_COMMUNICATION; - break; - case AUDIO_SCENE_RINGING: - case AUDIO_SCENE_VOICE_RINGING: - audioCategory = AUDIO_IN_RINGTONE; - break; - case AUDIO_SCENE_DEFAULT: - audioCategory = AUDIO_IN_MEDIA; - break; - default: - audioCategory = AUDIO_IN_MEDIA; - break; - } - AUDIO_DEBUG_LOG("Audio category returned is: %{public}d", audioCategory); - - return audioCategory; -} - -static int32_t SetInputPortPin(DeviceType inputDevice, AudioRouteNode &source) -{ - int32_t ret = SUCCESS; - - switch (inputDevice) { - case DEVICE_TYPE_MIC: - case DEVICE_TYPE_EARPIECE: - case DEVICE_TYPE_SPEAKER: - source.ext.device.type = PIN_IN_MIC; - source.ext.device.desc = (char *)"pin_in_mic"; - break; - case DEVICE_TYPE_WIRED_HEADSET: - source.ext.device.type = PIN_IN_HS_MIC; - source.ext.device.desc = (char *)"pin_in_hs_mic"; - break; - case DEVICE_TYPE_USB_ARM_HEADSET: - source.ext.device.type = PIN_IN_USB_HEADSET; - source.ext.device.desc = (char *)"pin_in_usb_headset"; - break; - case DEVICE_TYPE_USB_HEADSET: - source.ext.device.type = PIN_IN_USB_EXT; - source.ext.device.desc = (char *)"pin_in_usb_ext"; - break; - case DEVICE_TYPE_BLUETOOTH_SCO: - source.ext.device.type = PIN_IN_BLUETOOTH_SCO_HEADSET; - source.ext.device.desc = (char *)"pin_in_bluetooth_sco_headset"; - break; - default: - ret = ERR_NOT_SUPPORTED; - break; - } - - return ret; -} - int32_t AudioCapturerSourceInner::SetInputRoute(DeviceType inputDevice) { AudioPortPin inputPortPin = PIN_IN_MIC; @@ -859,7 +1155,13 @@ int32_t AudioCapturerSourceInner::SetInputRoute(DeviceType inputDevice, AudioPor sink.role = AUDIO_PORT_SINK_ROLE; sink.type = AUDIO_PORT_MIX_TYPE; sink.ext.mix.moduleId = 0; - sink.ext.mix.streamId = PRIMARY_INPUT_STREAM_ID; + if (attr_.sourceType == SOURCE_TYPE_EC) { + sink.ext.mix.streamId = EC_INPUT_STREAM_ID; + } else if (attr_.sourceType == SOURCE_TYPE_MIC_REF) { + sink.ext.mix.streamId = MICREF_INPUT_STREAM_ID; + } else { + sink.ext.mix.streamId = PRIMARY_INPUT_STREAM_ID; + } sink.ext.device.desc = (char *)""; AudioRoute route = { @@ -920,6 +1222,31 @@ uint64_t AudioCapturerSourceInner::GetTransactionId() return reinterpret_cast(audioCapture_); } +void AudioCapturerSourceInner::CheckUpdateState(char *frame, uint64_t replyBytes) +{ + if (startUpdate_) { + if (capFrameNum_ == 0) { + last10FrameStartTime_ = ClockTime::GetCurNano(); + } + capFrameNum_++; + maxAmplitude_ = UpdateMaxAmplitude(static_cast(attr_.format), frame, replyBytes); + if (capFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) { + capFrameNum_ = 0; + if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) { + startUpdate_ = false; + maxAmplitude_ = 0; + } + } + } +} + +float AudioCapturerSourceInner::GetMaxAmplitude() +{ + lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano(); + startUpdate_ = true; + return maxAmplitude_; +} + int32_t AudioCapturerSourceInner::GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec) { int32_t ret; @@ -947,81 +1274,6 @@ int32_t AudioCapturerSourceInner::GetPresentationPosition(uint64_t& frames, int6 return ret; } -int32_t AudioCapturerSourceInner::Stop(void) -{ - Trace trace("AudioCapturerSourceInner::Stop"); - AUDIO_INFO_LOG("Enter"); - - DeinitLatencyMeasurement(); - -#ifdef FEATURE_POWER_MANAGER - if (runningLockManager_ != nullptr) { - AUDIO_INFO_LOG("keepRunningLock unlock"); - runningLockManager_->UnLock(); - } else { - AUDIO_WARNING_LOG("keepRunningLock is null, stop can not work well!"); - } -#endif - int32_t ret; - if (started_ && audioCapture_ != nullptr) { - ret = audioCapture_->Stop(audioCapture_); - CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_OPERATION_FAILED, "Stop capture Failed"); - } - started_ = false; - - if (audioCapturerSourceCallback_ != nullptr) { - audioCapturerSourceCallback_->OnCapturerState(false); - } - - return SUCCESS; -} - -int32_t AudioCapturerSourceInner::Pause(void) -{ - Trace trace("AudioCapturerSourceInner::Pause"); - int32_t ret; - if (started_ && audioCapture_ != nullptr) { - ret = audioCapture_->Pause(audioCapture_); - CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "pause capture Failed"); - } - paused_ = true; - - return SUCCESS; -} - -int32_t AudioCapturerSourceInner::Resume(void) -{ - Trace trace("AudioCapturerSourceInner::Resume"); - int32_t ret; - if (paused_ && audioCapture_ != nullptr) { - ret = audioCapture_->Resume(audioCapture_); - CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "resume capture Failed"); - } - paused_ = false; - - return SUCCESS; -} - -int32_t AudioCapturerSourceInner::Reset(void) -{ - Trace trace("AudioCapturerSourceInner::Reset"); - if (started_ && audioCapture_ != nullptr) { - audioCapture_->Flush(audioCapture_); - } - - return SUCCESS; -} - -int32_t AudioCapturerSourceInner::Flush(void) -{ - Trace trace("AudioCapturerSourceInner::Flush"); - if (started_ && audioCapture_ != nullptr) { - audioCapture_->Flush(audioCapture_); - } - - return SUCCESS; -} - void AudioCapturerSourceInner::RegisterWakeupCloseCallback(IAudioSourceCallback *callback) { AUDIO_INFO_LOG("Register WakeupClose Callback"); @@ -1053,19 +1305,6 @@ int32_t AudioCapturerSourceInner::Preload(const std::string &usbInfoStr) return SUCCESS; } -static HdiAdapterFormat ParseAudioFormat(const std::string &format) -{ - if (format == "AUDIO_FORMAT_PCM_16_BIT") { - return HdiAdapterFormat::SAMPLE_S16; - } else if (format == "AUDIO_FORMAT_PCM_24_BIT") { - return HdiAdapterFormat::SAMPLE_S24; - } else if (format == "AUDIO_FORMAT_PCM_32_BIT") { - return HdiAdapterFormat::SAMPLE_S32; - } else { - return HdiAdapterFormat::SAMPLE_S16; - } -} - int32_t AudioCapturerSourceInner::UpdateUsbAttrs(const std::string &usbInfoStr) { CHECK_AND_RETURN_RET_LOG(usbInfoStr != "", ERR_INVALID_PARAM, "usb info string error"); @@ -1339,6 +1578,14 @@ int32_t AudioCapturerSourceWakeup::CaptureFrame(char *frame, uint64_t requestByt return res; } +int32_t AudioCapturerSourceWakeup::CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) +{ + AUDIO_ERR_LOG("not supported!"); + return ERR_DEVICE_NOT_SUPPORTED; +} + int32_t AudioCapturerSourceWakeup::SetVolume(float left, float right) { return audioCapturerSource_.SetVolume(left, right); diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h index 48ff151b2c04ffbdb93358f5a06ad787eb778a91..e84aa4209a95d27ade03b63b3e60f3c3ee6117a7 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h @@ -41,6 +41,7 @@ public: const char *sourceName = "Built_in_wakeup"); static AudioCapturerSource *GetMicInstance(void); static AudioCapturerSource *GetWakeupInstance(bool isMirror = false); + static AudioCapturerSource *Create(CaptureAttr *attr); protected: AudioCapturerSource() = default; diff --git a/frameworks/native/hdiadapter/source/remote/remote_audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/remote/remote_audio_capturer_source.cpp index cef667bb538d93c25b06062e6407415d8d863a5d..29984e4c5e21313b7de3aa13eaace4d50fef47d4 100644 --- a/frameworks/native/hdiadapter/source/remote/remote_audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/remote/remote_audio_capturer_source.cpp @@ -71,6 +71,9 @@ public: int32_t Pause(void) override; int32_t Resume(void) override; int32_t CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) override; + int32_t CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; int32_t SetMute(bool isMute) override; @@ -331,6 +334,14 @@ int32_t RemoteAudioCapturerSourceInner::CaptureFrame(char *frame, uint64_t reque return SUCCESS; } +int32_t RemoteAudioCapturerSourceInner::CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) +{ + AUDIO_ERR_LOG("not supported!"); + return ERR_DEVICE_NOT_SUPPORTED; +} + void RemoteAudioCapturerSourceInner::CheckUpdateState(char *frame, uint64_t replyBytes) { if (startUpdate_) { diff --git a/frameworks/native/hdiadapter/source/remote_fast/remote_fast_audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/remote_fast/remote_fast_audio_capturer_source.cpp index 3a4a5afef4e2cff25d6f61ab5b1a49b42b5c81ba..a8b7acc151c05dc3b0eca04129fd749a1cfd1fcc 100644 --- a/frameworks/native/hdiadapter/source/remote_fast/remote_fast_audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/remote_fast/remote_fast_audio_capturer_source.cpp @@ -67,6 +67,9 @@ public: int32_t Pause(void) override; int32_t Resume(void) override; int32_t CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) override; + int32_t CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; int32_t SetMute(bool isMute) override; @@ -441,6 +444,14 @@ int32_t RemoteFastAudioCapturerSourceInner::CaptureFrame(char *frame, uint64_t r return SUCCESS; } +int32_t RemoteFastAudioCapturerSourceInner::CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) +{ + AUDIO_ERR_LOG("not supported!"); + return ERR_DEVICE_NOT_SUPPORTED; +} + int32_t RemoteFastAudioCapturerSourceInner::CheckPositionTime() { int32_t tryCount = 10; diff --git a/frameworks/native/pulseaudio/modules/hdi/BUILD.gn b/frameworks/native/pulseaudio/modules/hdi/BUILD.gn index 2b8e60e08d71ee41b4ce129300cc3f4deb21b152..c197315d91f8a4720a30c13b3953bf6d5740f2a3 100644 --- a/frameworks/native/pulseaudio/modules/hdi/BUILD.gn +++ b/frameworks/native/pulseaudio/modules/hdi/BUILD.gn @@ -22,6 +22,7 @@ config("hdi_config") { ".", "../../../audioschedule/include", "../../../hdiadapter/common/include", + "../../../hdiadapter/manager/include", "../../../hdiadapter/sink/bluetooth", "../../../hdiadapter/sink/common", "../../../hdiadapter/sink/file", @@ -112,6 +113,7 @@ ohos_shared_library("module-hdi-source") { deps = [ "../../../audioeffect:audio_effect", "../../../audioutils:audio_utils", + "../../../hdiadapter/manager:hdiadapter_manager", "../../../hdiadapter/source:capturer_source_adapter", ] diff --git a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c index 1a884c1cbe4178a24e875ce330687d7d1c3983bf..046f26984f545500b6352f1a7546ab3088f793b3 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c @@ -33,13 +33,14 @@ #include #include -#include "audio_hdiadapter_info.h" +#include "v3_0/audio_types.h" +#include "v3_0/iaudio_manager.h" #include "audio_log.h" #include "audio_source_type.h" #include "audio_utils_c.h" +#include "audio_hdiadapter_info.h" +#include "hdi_adapter_manager_api.h" #include "capturer_source_adapter.h" -#include "v3_0/audio_types.h" -#include "v3_0/iaudio_manager.h" #define DEFAULT_SOURCE_NAME "hdi_input" #define DEFAULT_DEVICE_CLASS "primary" @@ -71,8 +72,12 @@ struct Userdata { pa_usec_t timestamp; SourceAttr attrs; bool IsCapturerStarted; + EcType ecType; + AuxiliaryRefSwitch auxiliaryRef; struct CapturerSourceAdapter *sourceAdapter; pa_usec_t delayTime; + HdiCaptureHandle *captureHandleEc; + HdiCaptureHandle *captureHandleRef; }; static int PaHdiCapturerInit(struct Userdata *u); @@ -123,6 +128,14 @@ static void UserdataFree(struct Userdata *u) if (u->sourceAdapter) { u->sourceAdapter->CapturerSourceStop(u->sourceAdapter->wapper); u->sourceAdapter->CapturerSourceDeInit(u->sourceAdapter->wapper); + if (u->captureHandleEc != NULL) { + u->captureHandleEc->Stop(u->captureHandleEc->capture); + u->captureHandleEc->Deinit(u->captureHandleEc->capture); + } + if (u->captureHandleRef != NULL) { + u->captureHandleRef->Stop(u->captureHandleRef->capture); + u->captureHandleRef->Deinit(u->captureHandleRef->capture); + } UnLoadSourceAdapter(u->sourceAdapter); } @@ -171,6 +184,12 @@ static int SourceSetStateInIoThreadCb(pa_source *s, pa_source_state_t newState, AUDIO_ERR_LOG("HDI capturer start failed"); return -PA_ERR_IO; } + if (u->captureHandleEc != NULL) { + u->captureHandleEc->Start(u->captureHandleEc->capture); + } + if (u->captureHandleRef != NULL) { + u->captureHandleRef->Start(u->captureHandleRef->capture); + } u->IsCapturerStarted = true; AUDIO_DEBUG_LOG("Successfully started HDI capturer"); } @@ -181,12 +200,24 @@ static int SourceSetStateInIoThreadCb(pa_source *s, pa_source_state_t newState, u->IsCapturerStarted = false; AUDIO_DEBUG_LOG("Stopped HDI capturer"); } + if (u->captureHandleEc != NULL) { + u->captureHandleEc->Stop(u->captureHandleEc->capture); + } + if (u->captureHandleRef != NULL) { + u->captureHandleRef->Stop(u->captureHandleRef->capture); + } } else if (newState == PA_SOURCE_RUNNING && !u->IsCapturerStarted) { AUDIO_DEBUG_LOG("Idle to Running starting HDI capturing device"); if (u->sourceAdapter->CapturerSourceStart(u->sourceAdapter->wapper)) { AUDIO_ERR_LOG("Idle to Running HDI capturer start failed"); return -PA_ERR_IO; } + if (u->captureHandleEc != NULL) { + u->captureHandleEc->Start(u->captureHandleEc->capture); + } + if (u->captureHandleRef != NULL) { + u->captureHandleRef->Start(u->captureHandleRef->capture); + } u->IsCapturerStarted = true; AUDIO_DEBUG_LOG("Idle to Running: Successfully reinitialized HDI renderer"); } @@ -199,17 +230,58 @@ static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) { uint64_t requestBytes; uint64_t replyBytes = 0; + uint64_t requestBytesEc; + uint64_t replyBytesEc = 0; + uint64_t requestBytesRef; + uint64_t replyBytesRef = 0; + void *p = NULL; + void *pEc = NULL; + void *pRef = NULL; chunk->length = u->buffer_size; AUDIO_DEBUG_LOG("HDI Source: chunk.length = u->buffer_size: %{public}zu", chunk->length); + chunk->memblock = pa_memblock_new(u->core->mempool, chunk->length); pa_assert(chunk->memblock); + p = pa_memblock_acquire(chunk->memblock); pa_assert(p); requestBytes = pa_memblock_get_length(chunk->memblock); - u->sourceAdapter->CapturerSourceFrame(u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); + + // need allocate buffer for pEc & pRef and decide requestBytesEc & requestBytesRef here + requestBytesEc = requestBytes; + requestBytesRef = requestBytes; + + if (u->attrs.sourceType != SOURCE_TYPE_VOICE_COMMUNICATION || u->ecType == EC_NONE) { + u->sourceAdapter->CapturerSourceFrame( + u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); + } else { + if (u->ecType == EC_SAME_ADAPTER) { + u->sourceAdapter->CapturerSourceFrameWithEc( + u->sourceAdapter->wapper, + (char *)p, (uint64_t)requestBytes, &replyBytes, + (char *)pEc, (uint64_t)requestBytesEc, &replyBytesEc); + } else if (u->ecType == EC_DIFFERENT_ADAPTER) { + u->sourceAdapter->CapturerSourceFrame( + u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); + + // for ec source only pEc has data + u->captureHandleEc->CaptureFrameWithEc( + u->captureHandleEc->capture, + NULL, 0, NULL, + (char *)pEc, (uint64_t)requestBytesEc, &replyBytesEc); + } else { + AUDIO_WARNING_LOG("should not be here"); + } + + if (u->auxiliaryRef == REF_ON) { + u->captureHandleRef->CaptureFrame( + u->captureHandleRef->capture, + (char *)pRef, (uint64_t)requestBytesRef, &replyBytesRef); + } + } pa_memblock_release(chunk->memblock); AUDIO_DEBUG_LOG("HDI Source: request bytes: %{public}" PRIu64 ", replyBytes: %{public}" PRIu64, @@ -343,6 +415,12 @@ static int PaHdiCapturerInit(struct Userdata *u) AUDIO_ERR_LOG("Audio capturer init failed!"); return ret; } + if (u->captureHandleEc != NULL) { + u->captureHandleEc->Init(u->captureHandleEc->capture); + } + if (u->captureHandleRef != NULL) { + u->captureHandleRef->Init(u->captureHandleRef->capture); + } // No start test for remote device. if (strcmp(GetDeviceClass(u->sourceAdapter->deviceClass), DEVICE_CLASS_REMOTE)) { @@ -365,6 +443,14 @@ static void PaHdiCapturerExit(struct Userdata *u) { u->sourceAdapter->CapturerSourceStop(u->sourceAdapter->wapper); u->sourceAdapter->CapturerSourceDeInit(u->sourceAdapter->wapper); + if (u->captureHandleEc != NULL) { + u->captureHandleEc->Stop(u->captureHandleEc->capture); + u->captureHandleEc->Deinit(u->captureHandleEc->capture); + } + if (u->captureHandleRef != NULL) { + u->captureHandleRef->Stop(u->captureHandleRef->capture); + u->captureHandleRef->Deinit(u->captureHandleRef->capture); + } } static int PaSetSourceProperties(pa_module *m, pa_modargs *ma, const pa_sample_spec *ss, const pa_channel_map *map, @@ -499,6 +585,34 @@ static void InitUserdataAttrs(pa_modargs *ma, struct Userdata *u, const pa_sampl u->attrs.openMicSpeaker = u->open_mic_speaker; } +static void InitEcAttr(struct Userdata *u, CaptureAttr *attr) +{ + // set attr for different adapter ec + attr->sourceType = SOURCE_TYPE_EC; + // device attrs + attr->adapterName = "dp"; + attr->deviceType = DEVICE_TYPE_MIC; // not needed, updateAudioRoute later + // common audio attrs + attr->sampleRate = u->attrs.sampleRate; + attr->channelCount = 8; // TODO: change according to output, 2 : 2; > 4 : 8 + attr->format = u->attrs.format; + attr->isBigEndian = u->attrs.isBigEndian; +} + +static void InitAuxiliaryRefAttr(struct Userdata *u, CaptureAttr *attr) +{ + // set attr for mic ref + attr->sourceType = SOURCE_TYPE_MIC_REF; + // device attrs + attr->adapterName = "primary"; + attr->deviceType = DEVICE_TYPE_MIC; + // common audio attrs + attr->sampleRate = u->attrs.sampleRate; + attr->channelCount = 4; // TODO: change according to device config + attr->format = u->attrs.format; + attr->isBigEndian = u->attrs.isBigEndian; +} + pa_source *PaHdiSourceNew(pa_module *m, pa_modargs *ma, const char *driver) { int ret; @@ -535,6 +649,30 @@ pa_source *PaHdiSourceNew(pa_module *m, pa_modargs *ma, const char *driver) AUDIO_ERR_LOG("Load adapter failed"); goto fail; } + // decide whether to create ec or mic ref source here + // TODO: decide by policy, change these for test + u->ecType = EC_DIFFERENT_ADAPTER; + u->auxiliaryRef = REF_ON; + if (u->attrs.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION && u->ecType == EC_DIFFERENT_ADAPTER) { + CaptureAttr *attr = (struct CaptureAttr *)calloc(1, sizeof(CaptureAttr)); + InitEcAttr(u, attr); + int32_t res = CreateCaptureHandle(&u->captureHandleEc, attr); + if (res) { + AUDIO_ERR_LOG("create ec handle failed"); + } + } else { + u->captureHandleEc = NULL; + } + if (u->auxiliaryRef == REF_ON) { + CaptureAttr *attr = (struct CaptureAttr *)calloc(1, sizeof(CaptureAttr)); + InitAuxiliaryRefAttr(u, attr); + int32_t res = CreateCaptureHandle(&u->captureHandleRef, attr); + if (res) { + AUDIO_ERR_LOG("create ec handle failed"); + } + } else { + u->captureHandleRef = NULL; + } if (PaSetSourceProperties(m, ma, &ss, &map, u) != 0) { AUDIO_ERR_LOG("Failed to PaSetSourceProperties"); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_effect.h b/interfaces/inner_api/native/audiocommon/include/audio_effect.h index 8cb083d98b5d3983f37f795ce666e2a2bdf853eb..03e5c92b67b40a5df7f99642e12fb1c9f4dd8a73 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_effect.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_effect.h @@ -324,6 +324,7 @@ struct AudioRendererInfoForSpatialization { std::string deviceMacAddress; StreamUsage streamUsage; }; + } // namespace AudioStandard } // namespace OHOS diff --git a/interfaces/inner_api/native/audiocommon/include/audio_source_type.h b/interfaces/inner_api/native/audiocommon/include/audio_source_type.h index ba569343482dac88c4a251e4c982b648ced6e356..df7a8d2ebe0c57df4bbeffc62557467b2e57ccc1 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_source_type.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_source_type.h @@ -35,7 +35,9 @@ enum SourceType { SOURCE_TYPE_VIRTUAL_CAPTURE = 9, // only for voice call SOURCE_TYPE_VOICE_MESSAGE = 10, SOURCE_TYPE_REMOTE_CAST = 11, - SOURCE_TYPE_MAX = SOURCE_TYPE_REMOTE_CAST + SOURCE_TYPE_EC = 13, + SOURCE_TYPE_MIC_REF = 14, + SOURCE_TYPE_MAX = SOURCE_TYPE_MIC_REF }; typedef enum { diff --git a/services/audio_policy/server/include/service/audio_policy_service.h b/services/audio_policy/server/include/service/audio_policy_service.h index 76e63624267dc35836bf0111141f1a20bd80c98e..b0a47adbaf4427920f04a43844f6a9711dd78c3c 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -931,6 +931,8 @@ private: void SetAbsVolumeSceneAsync(const std::string &macAddress, const bool support); + void UpdateModuleInfoForRecording(); + bool isUpdateRouteSupported_ = true; bool isCurrentRemoteRenderer = false; bool remoteCapturerSwitch_ = false; diff --git a/services/audio_policy/server/include/service/common/audio_module_info.h b/services/audio_policy/server/include/service/common/audio_module_info.h index 2f7a52d64966e323333eda380963dc9e1d0190c9..7836aedadb446e959275d079f125f3fba2766599 100644 --- a/services/audio_policy/server/include/service/common/audio_module_info.h +++ b/services/audio_policy/server/include/service/common/audio_module_info.h @@ -106,6 +106,9 @@ public: std::string sceneName; std::string sourceType; std::string offloadEnable; + std::string openEc; + std::string ecAdapter; + std::string openBuiltinMic; std::list ports; }; diff --git a/services/audio_policy/server/src/service/audio_policy_service.cpp b/services/audio_policy/server/src/service/audio_policy_service.cpp index 463b27f5b982c6597da08dfe1ad2a8661cb473a2..cd64d8c0f2f6076952565341a8e976e99517e4fc 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -6518,8 +6518,15 @@ int32_t AudioPolicyService::OnCapturerSessionAdded(uint64_t sessionID, SessionIn RectifyModuleInfo(moduleInfo, moduleInfoList, targetInfo); break; } + + // for ec or builtin-mic ref + if (sessionInfo.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) { + UpdateModuleInfoForRecording(moduleInfo); + } + AUDIO_INFO_LOG("rate:%{public}s, channels:%{public}s, bufferSize:%{public}s", moduleInfo.rate.c_str(), moduleInfo.channels.c_str(), moduleInfo.bufferSize.c_str()); + auto ioHandle = OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo); audioPolicyManager_.SetDeviceActive(ioHandle, currentActiveInputDevice_.deviceType_, moduleInfo.name, true, INPUT_DEVICES_FLAG); @@ -6535,6 +6542,19 @@ int32_t AudioPolicyService::OnCapturerSessionAdded(uint64_t sessionID, SessionIn return SUCCESS; } +void AudioPolicyService::UpdateModuleInfoForRecording(AudioModuleInfo &moduleInfo) +{ + // get voip input and output device, check if need to open ec input in output hal (input/output in different hal) + unique_ptr outputDesc = audioRouterCenter_.FetchOutputDevice(STREAM_USAGE_VOICE_COMMUNICATION, -1); + unique_ptr inputDesc = audioRouterCenter_.FetchInputDevice(SOURCE_TYPE_VOICE_COMMUNICATION, -1); + EcType ecType = GetEcStrategy(); + moduleInfo.ecType = ""; // same_adapter/diff_adapter/none + moduleInfo.ecAdapter = GetHalNameForDevice(outputDesc); + + // get voip input device, if is headset and pnr feature open, open builtin mic input + moduleInfo.openBuiltinMic = ""; +} + void AudioPolicyService::RectifyModuleInfo(AudioModuleInfo &moduleInfo, std::list &moduleInfoList, SourceInfo &targetInfo) {