From 89c2c8a4af36ee8313a0459789e76b1ebf30ba2b Mon Sep 17 00:00:00 2001 From: magekkkk Date: Tue, 14 May 2024 12:27:27 +0000 Subject: [PATCH 01/10] hdi adapter manager add Signed-off-by: magekkkk --- .../hdiadapter/common/utils/ringbuffer.cpp | 26 +++++++++++ .../hdiadapter/common/utils/ringbuffer.h | 31 +++++++++++++ .../manager/hdi_adapter_manager.cpp | 38 ++++++++++++++++ .../hdiadapter/manager/hdi_adapter_manager.h | 45 +++++++++++++++++++ .../manager/hdi_adapter_manager_api.h | 39 ++++++++++++++++ 5 files changed, 179 insertions(+) create mode 100644 frameworks/native/hdiadapter/common/utils/ringbuffer.cpp create mode 100644 frameworks/native/hdiadapter/common/utils/ringbuffer.h create mode 100644 frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp create mode 100644 frameworks/native/hdiadapter/manager/hdi_adapter_manager.h create mode 100644 frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h diff --git a/frameworks/native/hdiadapter/common/utils/ringbuffer.cpp b/frameworks/native/hdiadapter/common/utils/ringbuffer.cpp new file mode 100644 index 0000000000..cd58774ef4 --- /dev/null +++ b/frameworks/native/hdiadapter/common/utils/ringbuffer.cpp @@ -0,0 +1,26 @@ +/* + * 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. + */ + +#include "ringbuffer.h" + +namespace OHOS { +namespace AudioStandard { + +RingBuffer::RingBuffer() +{ +} + +} +} diff --git a/frameworks/native/hdiadapter/common/utils/ringbuffer.h b/frameworks/native/hdiadapter/common/utils/ringbuffer.h new file mode 100644 index 0000000000..002f63e8b2 --- /dev/null +++ b/frameworks/native/hdiadapter/common/utils/ringbuffer.h @@ -0,0 +1,31 @@ +/* + * 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 RING_BUFFER_H +#define RING_BUFFER_H + +namespace OHOS { +namespace AudioStandard { + +class RingBuffer { +public: + +private: +}; + +} +} + +#endif // RING_BUFFER_H \ No newline at end of file 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 0000000000..ea6671a3f4 --- /dev/null +++ b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp @@ -0,0 +1,38 @@ +/* + * 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" + +#include "hdi_adapter_manager.h" + +#include "audio_log.h" +#include "audio_errors.h" + +namespace OHOS { +namespace AudioStandard { + +HdiAdapterManager::HdiAdapterManager() +{ + +} + +HdiAdapterManager::~HdiAdapterManager() +{ + +} + +} // namespace AudioStandard +} // namespace OHOS diff --git a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.h b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.h new file mode 100644 index 0000000000..be7b4c69b9 --- /dev/null +++ b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.h @@ -0,0 +1,45 @@ +/* + * 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 + +namespace OHOS { +namespace AudioStandard { + +class HdiAdapterManager { +public: + static std::shared_ptr GetInstance(); + + int32_t Init(); + int32_t LoadAdapter(const std::string &adapterName); + int32_t UnLoadAdapter(const std::string &adapterName); + int32_t CreateCapture(const std::string &adapterName, XXFormat format); + int32_t DestroyCapture(const std::string &adapterName, XXFormat format); + std::shared_ptr GetCapture(); + +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/hdi_adapter_manager_api.h b/frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h new file mode 100644 index 0000000000..aee61f1242 --- /dev/null +++ b/frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h @@ -0,0 +1,39 @@ +/* + * 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 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AudioBuffer { + float *bufIn; + float *bufOut; + int numChanIn; + int numChanOut; +} AudioBuffer; + +int32_t GetEcCaptureInstance(); +int32_t GetMicCaptureInstance(); + + +#ifdef __cplusplus +} +#endif +#endif // HDI_ADAPTER_MANAGER_API_H \ No newline at end of file -- Gitee From 69222dd4297ab1b7a9d495d2d3b843a6d56f60d0 Mon Sep 17 00:00:00 2001 From: magekkkk Date: Mon, 3 Jun 2024 04:02:08 +0000 Subject: [PATCH 02/10] add ec impl in same hal Signed-off-by: magekkkk --- .../source/common/capturer_source_adapter.c | 1 + .../source/common/i_audio_capturer_source.cpp | 18 +++++++ .../source/common/i_audio_capturer_source.h | 3 ++ .../common/i_audio_capturer_source_intf.h | 4 ++ .../fast/fast_audio_capturer_source.cpp | 11 ++++ .../file/audio_capturer_file_source.cpp | 8 +++ .../source/file/audio_capturer_file_source.h | 3 ++ .../source/primary/audio_capturer_source.cpp | 50 +++++++++++++++++++ .../remote/remote_audio_capturer_source.cpp | 11 ++++ .../remote_fast_audio_capturer_source.cpp | 11 ++++ .../pulseaudio/modules/hdi/hdi_source.c | 17 ++++++- 11 files changed, 136 insertions(+), 1 deletion(-) diff --git a/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c b/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c index 1e064739f7..6a79c07d5b 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 ba3dad1522..43934ef3cb 100644 --- a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp @@ -184,6 +184,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 a1c42908c4..1642b53162 100644 --- a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h +++ b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h @@ -72,6 +72,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 8b6f9c7d9e..1b5eac4eeb 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 3f6ef265db..73bc433e85 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 edc9259a01..18f18590b4 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 a88f19bc51..2c6ff1c7e4 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 904d4bc310..3554b9ea66 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -57,6 +57,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; @@ -166,6 +169,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; @@ -557,6 +563,21 @@ int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) param.startThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (param.frameSize); param.sourceType = static_cast(ConvertToHDIAudioInputType(attr_.sourceType)); + // for ec stream + if (attr_.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) { + param.ecSampleAttributes.ecInterleaved = true; + param.ecSampleAttributes.ecFormat = param.format; + param.ecSampleAttributes.ecSampleRate = param.sampleRate; + 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; deviceDesc.pins = PIN_IN_MIC; @@ -612,6 +633,27 @@ int32_t AudioCapturerSourceInner::CaptureFrame(char *frame, uint64_t requestByte return SUCCESS; } +int32_t AudioCapturerSourceInner::CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) +{ + CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); + + struct AudioCaptureFrameInfo frameInfo; + frameInfo.frame = frame; + frameInfo.frameSize = requestBytes; + frameInfo.frameEc = frame; + frameInfo.frameEcSize = requestBytesEc; + + int32_t ret = audioCapture_->CaptureFrameEc(audioCapture_, frameInfo); + CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_READ_FAILED, "Capture Frame Fail"); + + replyBytes = frameInfo.replyBytes; + replyBytesEc = frameInfo.replyBytesEc; + + return SUCCESS; +} + void AudioCapturerSourceInner::CheckUpdateState(char *frame, uint64_t replyBytes) { if (startUpdate_) { @@ -1339,6 +1381,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/remote/remote_audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/remote/remote_audio_capturer_source.cpp index cef667bb53..29984e4c5e 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 3a4a5afef4..a8b7acc151 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/hdi_source.c b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c index 1a884c1cbe..0e972ee59e 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c @@ -199,7 +199,10 @@ static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) { uint64_t requestBytes; uint64_t replyBytes = 0; + uint64_t requestBytesEc; + uint64_t replyBytesEc = 0; void *p = NULL; + void *pEc = NULL; chunk->length = u->buffer_size; AUDIO_DEBUG_LOG("HDI Source: chunk.length = u->buffer_size: %{public}zu", chunk->length); @@ -209,7 +212,19 @@ static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) pa_assert(p); requestBytes = pa_memblock_get_length(chunk->memblock); - u->sourceAdapter->CapturerSourceFrame(u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); + + // need allocat buffer for pEc and decide requestBytesEc here + requestBytesEc = requestBytes + + if (u->attrs.sourceType != SOURCE_TYPE_VOICE_COMMUNICATION) { + u->sourceAdapter->CapturerSourceFrame( + u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); + } else { + u->sourceAdapter->CapturerSourceFrameWithEc( + u->sourceAdapter->wapper, + (char *)p, (uint64_t)requestBytes, &replyBytes, + (char *)pEc, (uint64_t)requestBytesEc, &replyBytesEc); + } pa_memblock_release(chunk->memblock); AUDIO_DEBUG_LOG("HDI Source: request bytes: %{public}" PRIu64 ", replyBytes: %{public}" PRIu64, -- Gitee From ee84bc238b7a04bc15ee923d237c168abe59fa74 Mon Sep 17 00:00:00 2001 From: magekkkk Date: Tue, 4 Jun 2024 12:21:46 +0000 Subject: [PATCH 03/10] fix compiles Signed-off-by: magekkkk --- .../source/primary/audio_capturer_source.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 3554b9ea66..424fd1308f 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -572,10 +572,10 @@ int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) 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.ecIsSignedData = true; param.ecSampleAttributes.ecStartThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (param.frameSize); - param.ecSampleAttributes.ecStopThreshold = INT_32_MAX - param.ecSampleAttributes.ecSilenceThreshold = AUDIO_BUFF_SIZE + param.ecSampleAttributes.ecStopThreshold = INT_32_MAX; + param.ecSampleAttributes.ecSilenceThreshold = AUDIO_BUFF_SIZE; } struct AudioDeviceDescriptor deviceDesc; @@ -640,12 +640,12 @@ int32_t AudioCapturerSourceInner::CaptureFrameWithEc( CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); struct AudioCaptureFrameInfo frameInfo; - frameInfo.frame = frame; + frameInfo.frame = reinterpret_cast(frame); frameInfo.frameSize = requestBytes; - frameInfo.frameEc = frame; + frameInfo.frameEc = reinterpret_cast(frame); frameInfo.frameEcSize = requestBytesEc; - int32_t ret = audioCapture_->CaptureFrameEc(audioCapture_, frameInfo); + int32_t ret = audioCapture_->CaptureFrameEc(audioCapture_, &frameInfo); CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_READ_FAILED, "Capture Frame Fail"); replyBytes = frameInfo.replyBytes; -- Gitee From 1ff481234509d5eadfac9261c7c6b136991595f8 Mon Sep 17 00:00:00 2001 From: magekkkk Date: Thu, 27 Jun 2024 08:47:06 +0000 Subject: [PATCH 04/10] add ec policy part 1 Signed-off-by: magekkkk --- .../native/audiocommon/include/audio_effect.h | 7 +++++++ .../include/service/audio_policy_service.h | 2 ++ .../service/common/audio_module_info.h | 3 +++ .../src/service/audio_policy_service.cpp | 20 +++++++++++++++++++ 4 files changed, 32 insertions(+) diff --git a/interfaces/inner_api/native/audiocommon/include/audio_effect.h b/interfaces/inner_api/native/audiocommon/include/audio_effect.h index 8cb083d98b..bc9179c02d 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_effect.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_effect.h @@ -324,6 +324,13 @@ struct AudioRendererInfoForSpatialization { std::string deviceMacAddress; StreamUsage streamUsage; }; + +enum EcType { + NONE = 0, + SAME_ADAPTER, + DIFFERENT_ADAPTER +}; + } // namespace AudioStandard } // namespace OHOS 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 76e6362426..b0a47adbaf 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 2f7a52d649..7836aedadb 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 463b27f5b9..cd64d8c0f2 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) { -- Gitee From 571050f1dbc670c5f97bef73cd3bf65bca75a194 Mon Sep 17 00:00:00 2001 From: magekkkk Date: Tue, 25 Jun 2024 07:01:55 +0000 Subject: [PATCH 05/10] hdi adapter part Signed-off-by: magekkkk --- .../manager/hdi_adapter_manager_api.h | 22 ++++++--- .../pulseaudio/modules/hdi/hdi_source.c | 49 +++++++++++++++---- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h b/frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h index aee61f1242..83e3799cce 100644 --- a/frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h +++ b/frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h @@ -22,15 +22,23 @@ extern "C" { #endif -typedef struct AudioBuffer { - float *bufIn; - float *bufOut; - int numChanIn; - int numChanOut; -} AudioBuffer; +struct HdiCaptureHandle { + int32_t halType; + int32_t deviceType; + + int32_t (*Init)(const CaptureAttr *attr); + void (*Deinit)(); + int32_t (*Start)(); + int32_t (*Stop)(); + int32_t (*CaptureFrame)( + char *frame, uint64_t requestBytes, uint64_t *replyBytes); + int32_t (*CaptureFrameWithEc)( + char *frame, uint64_t requestBytes, uint64_t *replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t *replyBytesEc); +}; int32_t GetEcCaptureInstance(); -int32_t GetMicCaptureInstance(); +int32_t GetRefCaptureInstance(); #ifdef __cplusplus diff --git a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c index 0e972ee59e..327d65a2c2 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" @@ -197,33 +198,61 @@ static int SourceSetStateInIoThreadCb(pa_source *s, pa_source_state_t newState, static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) { + int32_t ecType = NONE; // TODO: can change this for debugging currently + int32_t auxiliaryRef = OFF; // TODO: can change this for debugging currently + 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); - // need allocat buffer for pEc and decide requestBytesEc here - requestBytesEc = requestBytes + // need allocate buffer for pEc & pRef and decide requestBytesEc & requestBytesRef here + requestBytesEc = requestBytes; + requestBytesRef = requestBytes; - if (u->attrs.sourceType != SOURCE_TYPE_VOICE_COMMUNICATION) { + if (u->attrs.sourceType != SOURCE_TYPE_VOICE_COMMUNICATION || ecType == NONE) { u->sourceAdapter->CapturerSourceFrame( u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); } else { - u->sourceAdapter->CapturerSourceFrameWithEc( - u->sourceAdapter->wapper, - (char *)p, (uint64_t)requestBytes, &replyBytes, - (char *)pEc, (uint64_t)requestBytesEc, &replyBytesEc); + if (ecType == SAME_ADAPTER) { + u->sourceAdapter->CapturerSourceFrameWithEc( + u->sourceAdapter->wapper, + (char *)p, (uint64_t)requestBytes, &replyBytes, + (char *)pEc, (uint64_t)requestBytesEc, &replyBytesEc); + } else if (ecType == DIFFERENT_ADAPTER) { + u->sourceAdapter->CapturerSourceFrame( + u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); + + // for ec source only pEc has data + u->ecSourceAadpter->CapturerSourceFrameWithEc( + u->ecSourceAadpter->wapper, + NULL, 0, NULL, + (char *)pEc, (uint64_t)requestBytesEc, &replyBytesEc); + } else { + AUDIO_WARNING_LOG("should not be here"); + } + + if (auxiliaryRef == ON) { + u->auxiliaryRefSourceAadpter->CapturerSourceFrame( + u->auxiliaryRefSourceAadpter->wapper, (char *)pRef, (uint64_t)requestBytesRef, &replyBytesRef); + } } pa_memblock_release(chunk->memblock); -- Gitee From dc884ac9178af3e6653a1d9d841024c80bcf73a0 Mon Sep 17 00:00:00 2001 From: magekkkk Date: Thu, 27 Jun 2024 06:32:28 +0000 Subject: [PATCH 06/10] add more impls Signed-off-by: magekkkk --- .../common/include/audio_hdiadapter_info.h | 27 + .../hdiadapter/common/utils/ringbuffer.cpp | 26 - frameworks/native/hdiadapter/manager/BUILD.gn | 77 ++ .../manager/hdi_adapter_manager.cpp | 119 ++- .../{ => include}/hdi_adapter_manager.h | 14 +- .../{ => include}/hdi_adapter_manager_api.h | 21 +- .../include/hdi_utils_ringbuffer.h} | 57 +- .../manager/utils/hdi_utils_ringbuffer.cpp | 198 ++++ frameworks/native/hdiadapter/source/BUILD.gn | 6 +- .../source/common/i_audio_capturer_source.cpp | 5 + .../source/common/i_audio_capturer_source.h | 2 + .../source/primary/audio_capturer_source.cpp | 866 +++++++++++------- .../source/primary/audio_capturer_source.h | 1 + .../native/pulseaudio/modules/hdi/BUILD.gn | 3 +- .../pulseaudio/modules/hdi/hdi_source.c | 88 +- .../audiocommon/include/audio_source_type.h | 4 +- 16 files changed, 1103 insertions(+), 411 deletions(-) delete mode 100644 frameworks/native/hdiadapter/common/utils/ringbuffer.cpp create mode 100644 frameworks/native/hdiadapter/manager/BUILD.gn rename frameworks/native/hdiadapter/manager/{ => include}/hdi_adapter_manager.h (69%) rename frameworks/native/hdiadapter/manager/{ => include}/hdi_adapter_manager_api.h (70%) rename frameworks/native/hdiadapter/{common/utils/ringbuffer.h => manager/include/hdi_utils_ringbuffer.h} (32%) create mode 100644 frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp diff --git a/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h b/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h index a2ea27c5c4..11d7a0a901 100644 --- a/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h +++ b/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h @@ -16,6 +16,8 @@ #ifndef AUDIO_HDIADAPTER_INFO_H #define AUDIO_HDIADAPTER_INFO_H +#include + #define MAX_MIX_CHANNELS 128 #define PA_MAX_OUTPUTS_PER_SOURCE 256 @@ -37,4 +39,29 @@ enum RenderCallbackType { CB_ERROR_OCCUR = 4, }; +enum EcType { + NONE = 0, + SAME_ADAPTER, + DIFFERENT_ADAPTER +}; + +enum AuxiliaryRefSwitch { + OFF = 0, + ON +}; + +struct CaptureAttr { + // usage attrs + int32_t sourceType; + // device attrs + const char *adapterName; + int32_t deviceType; + // common audio attrs + uint32_t sampleRate; + uint32_t channelCount; + uint64_t channelLayout; + enum HdiAdapterFormat format; + bool isBigEndian; +}; + #endif \ No newline at end of file diff --git a/frameworks/native/hdiadapter/common/utils/ringbuffer.cpp b/frameworks/native/hdiadapter/common/utils/ringbuffer.cpp deleted file mode 100644 index cd58774ef4..0000000000 --- a/frameworks/native/hdiadapter/common/utils/ringbuffer.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -#include "ringbuffer.h" - -namespace OHOS { -namespace AudioStandard { - -RingBuffer::RingBuffer() -{ -} - -} -} diff --git a/frameworks/native/hdiadapter/manager/BUILD.gn b/frameworks/native/hdiadapter/manager/BUILD.gn new file mode 100644 index 0000000000..96c40f8b36 --- /dev/null +++ b/frameworks/native/hdiadapter/manager/BUILD.gn @@ -0,0 +1,77 @@ +# 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", + "../../../../interfaces/inner_api/native/audiocommon/include", + ] + + sources = [ + "hdi_adapter_manager.cpp", + ] + + deps = [ + "../source:audio_capturer_source", + ] + + 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", + ] + + sources = [ + "utils/hdi_utils_ringbuffer.cpp", + ] + + external_deps = [ + "c_utils:utils", + ] + + 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 index ea6671a3f4..39958f6673 100644 --- a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp +++ b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp @@ -21,17 +21,132 @@ #include "audio_log.h" #include "audio_errors.h" +#include "include/hdi_adapter_manager_api.h" + +// 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"); + + return captureSource->DeInit(); +} + +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(); +} + +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, const 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; + } +} + +HdiAdapterManager *HdiAdapterManager::GetInstance() +{ + static HdiAdapterManager manager; + return &manager; } } // namespace AudioStandard diff --git a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.h b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager.h similarity index 69% rename from frameworks/native/hdiadapter/manager/hdi_adapter_manager.h rename to frameworks/native/hdiadapter/manager/include/hdi_adapter_manager.h index be7b4c69b9..b1116abbd9 100644 --- a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.h +++ b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager.h @@ -19,19 +19,18 @@ #include #include +#include "i_audio_capturer_source.h" + namespace OHOS { namespace AudioStandard { class HdiAdapterManager { public: - static std::shared_ptr GetInstance(); + static HdiAdapterManager *GetInstance(); + + IAudioCapturerSource *CreateCapture(CaptureAttr *attr); - int32_t Init(); - int32_t LoadAdapter(const std::string &adapterName); - int32_t UnLoadAdapter(const std::string &adapterName); - int32_t CreateCapture(const std::string &adapterName, XXFormat format); - int32_t DestroyCapture(const std::string &adapterName, XXFormat format); - std::shared_ptr GetCapture(); + int32_t ReleaseCapture(IAudioCapturerSource *capture); private: HdiAdapterManager(); @@ -41,5 +40,4 @@ private: } // namespace AudioStandard } // namespace OHOS - #endif // HDI_ADAPTER_MANAGER_H \ No newline at end of file diff --git a/frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h similarity index 70% rename from frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h rename to frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h index 83e3799cce..c48e0edc50 100644 --- a/frameworks/native/hdiadapter/manager/hdi_adapter_manager_api.h +++ b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h @@ -17,29 +17,28 @@ #define HDI_ADAPTER_MANAGER_API_H #include +#include "audio_hdiadapter_info.h" #ifdef __cplusplus extern "C" { #endif struct HdiCaptureHandle { - int32_t halType; - int32_t deviceType; - - int32_t (*Init)(const CaptureAttr *attr); - void (*Deinit)(); - int32_t (*Start)(); - int32_t (*Stop)(); - int32_t (*CaptureFrame)( + 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)( + int32_t (*CaptureFrameWithEc)(void *capture, char *frame, uint64_t requestBytes, uint64_t *replyBytes, char *frameEc, uint64_t requestBytesEc, uint64_t *replyBytesEc); }; -int32_t GetEcCaptureInstance(); -int32_t GetRefCaptureInstance(); +int32_t CreateCaptureHandle(HdiCaptureHandle **handle, const CaptureAttr *attr); +int32_t ReleaseCaptureHandle(HdiCaptureHandle *handle); #ifdef __cplusplus } diff --git a/frameworks/native/hdiadapter/common/utils/ringbuffer.h b/frameworks/native/hdiadapter/manager/include/hdi_utils_ringbuffer.h similarity index 32% rename from frameworks/native/hdiadapter/common/utils/ringbuffer.h rename to frameworks/native/hdiadapter/manager/include/hdi_utils_ringbuffer.h index 002f63e8b2..bb1e8ef0ee 100644 --- a/frameworks/native/hdiadapter/common/utils/ringbuffer.h +++ b/frameworks/native/hdiadapter/manager/include/hdi_utils_ringbuffer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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 @@ -13,19 +13,60 @@ * limitations under the License. */ -#ifndef RING_BUFFER_H -#define RING_BUFFER_H +#ifndef HDI_UTILS_RINGBUFFER_H +#define HDI_UTILS_RINGBUFFER_H + +#include +#include namespace OHOS { namespace AudioStandard { -class RingBuffer { +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_; +}; -#endif // RING_BUFFER_H \ No newline at end of file +} // 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 0000000000..aed81a41fa --- /dev/null +++ b/frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp @@ -0,0 +1,198 @@ +/* + * 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" + +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) float[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) float[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) float[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"); + } eles { + 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 57f8a4043e..454b948605 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_manager", + "../../audioutils:audio_utils", + ] external_deps = [ "c_utils:utils", 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 43934ef3cb..79ffb509a3 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 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 1642b53162..b32fa61af2 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() = 0; virtual bool IsInited(void) = 0; virtual void DeInit(void) = 0; diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 424fd1308f..3ce3e339fe 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,187 @@ #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: + case SOURCE_TYPE_MIC_REF: + 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; + 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 IsNonblockingSource(SourceType 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; @@ -87,6 +256,7 @@ public: int32_t UpdateAppsUid(const std::vector &appsUid) final; explicit AudioCapturerSourceInner(const std::string &halName = "primary"); + explicit AudioCapturerSourceInner(CaptureAttr *attr); ~AudioCapturerSourceInner(); private: @@ -100,7 +270,6 @@ private: 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(); @@ -110,7 +279,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; @@ -154,6 +325,9 @@ 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; }; class AudioCapturerSourceWakeup : public AudioCapturerSource { @@ -319,23 +493,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) { @@ -361,35 +520,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() @@ -408,51 +542,72 @@ 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; + // TODO: get hal name from adapterName in attr + 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; } -void AudioCapturerSourceInner::InitAttrsCapture(struct AudioSampleAttributes &attrs) +int32_t AudioCapturerSourceInner::InitWithoutAttr() +{ + // 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 = hdiAttr_->filePath; + // attr.deviceNetworkId = hdiAttr_->deviceNetworkId; + attr.deviceType = hdiAttr_->deviceType; + attr.sourceType = hdiAttr_->sourceType; + attr.channelLayout = hdiAttr_->channelLayout; + + Init(attr); + + ringBuffer_ = std::make_shared(); + ringBuffer_->Init(attr.sampleRate, attr.channel, GetByteSizeByFormat(attr.format)); +} + +void AudioCapturerSourceInner::InitAttrsCapture(struct AudioSampleAttributes &attrs) { /* Initialization of audio parameters for playback */ attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT; @@ -472,6 +627,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) { @@ -501,45 +671,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"); @@ -594,95 +725,74 @@ 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); - - int32_t ret = InitAdapterAndCapture(); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Init adapter and capture failed"); - - sourceInited_ = true; - - SetMute(muteState_); - - return SUCCESS; + return sourceInited_; } -int32_t AudioCapturerSourceInner::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) +void AudioCapturerSourceInner::DeInit() { - int64_t stamp = ClockTime::GetCurNano(); - int32_t ret; - CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); - - Trace trace("AudioCapturerSourceInner::CaptureFrame"); - uint32_t frameLen = static_cast(requestBytes); - ret = audioCapture_->CaptureFrame(audioCapture_, reinterpret_cast(frame), &frameLen, &replyBytes); - CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_READ_FAILED, "Capture Frame Fail"); - CheckLatencySignal(reinterpret_cast(frame), replyBytes); - - DumpFileUtil::WriteDumpFile(dumpFile_, frame, replyBytes); - CheckUpdateState(frame, requestBytes); + Trace trace("AudioCapturerSourceInner::DeInit"); + AudioXCollie sourceXCollie("AudioCapturerSourceInner::DeInit", DEINIT_TIME_OUT_SECONDS); + AUDIO_INFO_LOG("Start deinit of source inner"); + started_ = false; + sourceInited_ = false; - stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND; - if (logMode_) { - AUDIO_DEBUG_LOG("RenderFrame len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms", requestBytes, stamp); + if (audioAdapter_ != nullptr) { + audioAdapter_->DestroyCapture(audioAdapter_, captureId_); } - return SUCCESS; -} - -int32_t AudioCapturerSourceInner::CaptureFrameWithEc( - char *frame, uint64_t requestBytes, uint64_t &replyBytes, - char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) -{ - CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); - - struct AudioCaptureFrameInfo frameInfo; - frameInfo.frame = reinterpret_cast(frame); - frameInfo.frameSize = requestBytes; - frameInfo.frameEc = reinterpret_cast(frame); - frameInfo.frameEcSize = requestBytesEc; - - int32_t ret = audioCapture_->CaptureFrameEc(audioCapture_, &frameInfo); - CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_READ_FAILED, "Capture Frame Fail"); + captureInited_ = false; - replyBytes = frameInfo.replyBytes; - replyBytesEc = frameInfo.replyBytesEc; + IAudioSourceCallback* callback = nullptr; + { + std::lock_guard lck(wakeupClosecallbackMutex_); + callback = wakeupCloseCallback_; + } + if (callback != nullptr) { + callback->OnWakeupClose(); + } - return SUCCESS; -} + audioCapture_ = nullptr; + currentActiveDevice_ = DEVICE_TYPE_INVALID; // the current device must be rest when closing capturer. -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; - } + 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; } -} -float AudioCapturerSourceInner::GetMaxAmplitude() -{ - lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano(); - startUpdate_ = true; - return maxAmplitude_; + 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; + captureThread_ = std::make_unique(&AudioCapturerSourceInner::CaptureThreadLoop, this); + std::string threadName = "OS_Capture"; + threadName += (attr_.sourceType == SOURCE_TYPE_EC) ? "Ec" : "MicRef"; + pthread_setname_np(writeThread_->native_handle(), threadName.c_str()); + + } + return SUCCESS; + } + InitLatencyMeasurement(); #ifdef FEATURE_POWER_MANAGER std::shared_ptr keepRunningLock; @@ -731,6 +841,202 @@ int32_t AudioCapturerSourceInner::Start(void) 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(); + } + + 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; + + // for ec stream + if (attr_.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) { + param.ecSampleAttributes.ecInterleaved = true; + param.ecSampleAttributes.ecFormat = param.format; + param.ecSampleAttributes.ecSampleRate = param.sampleRate; + 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; + deviceDesc.pins = PIN_IN_MIC; + if (halName_ == "usb") { + deviceDesc.pins = PIN_IN_USB_HEADSET; + } + deviceDesc.desc = (char *)""; + + AUDIO_INFO_LOG("CreateCapture for audioAdapter_: audio sourceType %{public}d, hdi sourceType %{public}d", + attr_.sourceType, param.sourceType); + ret = audioAdapter_->CreateCapture(audioAdapter_, &deviceDesc, ¶m, &audioCapture_, &captureId_); + CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr && ret >= 0, ERR_NOT_STARTED, "Create capture failed"); + + 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!"); + + Trace trace("AudioCapturerSourceInner::CaptureFrame"); + uint32_t frameLen = static_cast(requestBytes); + ret = audioCapture_->CaptureFrame(audioCapture_, reinterpret_cast(frame), &frameLen, &replyBytes); + CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_READ_FAILED, "Capture Frame Fail"); + CheckLatencySignal(reinterpret_cast(frame), replyBytes); + + DumpFileUtil::WriteDumpFile(dumpFile_, frame, replyBytes); + CheckUpdateState(frame, requestBytes); + + stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND; + if (logMode_) { + AUDIO_DEBUG_LOG("RenderFrame len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms", requestBytes, stamp); + } + return SUCCESS; +} + +int32_t AudioCapturerSourceInner::CaptureFrameWithEc( + char *frame, uint64_t requestBytes, uint64_t &replyBytes, + char *frameEc, uint64_t requestBytesEc, uint64_t &replyBytesEc) +{ + CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); + + struct AudioCaptureFrameInfo frameInfo; + frameInfo.frame = reinterpret_cast(frame); + frameInfo.frameSize = requestBytes; + frameInfo.frameEc = reinterpret_cast(frame); + frameInfo.frameEcSize = requestBytesEc; + + int32_t ret = audioCapture_->CaptureFrameEc(audioCapture_, &frameInfo); + CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_READ_FAILED, "Capture Frame Fail"); + + replyBytes = frameInfo.replyBytes; + replyBytesEc = frameInfo.replyBytesEc; + + 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; + int32_t ret = audioCapture_->CaptureFrame( + audioCapture_, reinterpret_cast(buffer.data), &(buffer.length), &replyBytes); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("Capture frame failed"); + } + EnqueueInputBuffer(buffer); + } + } +} + int32_t AudioCapturerSourceInner::SetVolume(float left, float right) { float volume; @@ -809,67 +1115,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; @@ -962,6 +1207,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; @@ -989,81 +1259,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"); @@ -1095,19 +1290,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"); diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h index 48ff151b2c..e84aa4209a 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/pulseaudio/modules/hdi/BUILD.gn b/frameworks/native/pulseaudio/modules/hdi/BUILD.gn index 2b8e60e08d..5933a11635 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", @@ -111,7 +112,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 327d65a2c2..2607a204bb 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c @@ -72,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); @@ -124,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); } @@ -172,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"); } @@ -182,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"); } @@ -198,9 +228,6 @@ static int SourceSetStateInIoThreadCb(pa_source *s, pa_source_state_t newState, static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) { - int32_t ecType = NONE; // TODO: can change this for debugging currently - int32_t auxiliaryRef = OFF; // TODO: can change this for debugging currently - uint64_t requestBytes; uint64_t replyBytes = 0; uint64_t requestBytesEc; @@ -227,31 +254,32 @@ static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) requestBytesEc = requestBytes; requestBytesRef = requestBytes; - if (u->attrs.sourceType != SOURCE_TYPE_VOICE_COMMUNICATION || ecType == NONE) { + if (u->attrs.sourceType != SOURCE_TYPE_VOICE_COMMUNICATION || u->ecType == NONE) { u->sourceAdapter->CapturerSourceFrame( u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); } else { - if (ecType == SAME_ADAPTER) { + if (u->ecType == SAME_ADAPTER) { u->sourceAdapter->CapturerSourceFrameWithEc( u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes, (char *)pEc, (uint64_t)requestBytesEc, &replyBytesEc); - } else if (ecType == DIFFERENT_ADAPTER) { + } else if (u->ecType == DIFFERENT_ADAPTER) { u->sourceAdapter->CapturerSourceFrame( u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); // for ec source only pEc has data - u->ecSourceAadpter->CapturerSourceFrameWithEc( - u->ecSourceAadpter->wapper, + u->captureHandleEc->CaptureFrameWithEc( + u->captureHandleEc->capture, NULL, 0, NULL, (char *)pEc, (uint64_t)requestBytesEc, &replyBytesEc); } else { AUDIO_WARNING_LOG("should not be here"); } - if (auxiliaryRef == ON) { - u->auxiliaryRefSourceAadpter->CapturerSourceFrame( - u->auxiliaryRefSourceAadpter->wapper, (char *)pRef, (uint64_t)requestBytesRef, &replyBytesRef); + if (u->auxiliaryRef == ON) { + u->captureHandleRef->CapturerSourceFrame( + u->captureHandleRef->capture, + (char *)pRef, (uint64_t)requestBytesRef, &replyBytesRef); } } @@ -387,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)) { @@ -409,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, @@ -579,6 +621,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 = DIFFERENT_ADAPTER; + u->auxiliaryRef = ON; + if (u->attrs.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION && u->ecType == DIFFERENT_ADAPTER) { + CaptureAttr *attr = (struct CaptureAttr *)calloc(1, sizeof(CaptureAttr)); + // TODO: set target ec attr + int32_t res = CreateCaptureHandle(&u->captureHandleEc, attr); + if (res) { + AUDIO_ERR_LOG("create ec handle failed"); + } + } else { + u->captureHandleEc = NULL; + } + if (u->auxiliaryRef == ON) { + CaptureAttr *attr = (struct CaptureAttr *)calloc(1, sizeof(CaptureAttr)); + // TODO: set target mic ref 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_source_type.h b/interfaces/inner_api/native/audiocommon/include/audio_source_type.h index ba56934348..df7a8d2ebe 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 { -- Gitee From 93b1604d82e19a4e38e06ff1ae2969a4dc18a362 Mon Sep 17 00:00:00 2001 From: magekkkk Date: Sat, 22 Jun 2024 09:50:29 +0000 Subject: [PATCH 07/10] fix compile issues Signed-off-by: magekkkk --- .../common/include/audio_hdiadapter_info.h | 31 ++++++++----- frameworks/native/hdiadapter/manager/BUILD.gn | 6 +++ .../manager/hdi_adapter_manager.cpp | 13 ++++-- .../manager/include/hdi_adapter_manager_api.h | 6 +-- .../manager/utils/hdi_utils_ringbuffer.cpp | 16 ++++--- frameworks/native/hdiadapter/source/BUILD.gn | 2 +- .../source/common/i_audio_capturer_source.h | 2 +- .../source/primary/audio_capturer_source.cpp | 46 +++++-------------- .../native/pulseaudio/modules/hdi/BUILD.gn | 1 + .../pulseaudio/modules/hdi/hdi_source.c | 18 ++++---- .../native/audiocommon/include/audio_effect.h | 6 --- 11 files changed, 71 insertions(+), 76 deletions(-) diff --git a/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h b/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h index 11d7a0a901..6ac1f3dcd4 100644 --- a/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h +++ b/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h @@ -17,6 +17,7 @@ #define AUDIO_HDIADAPTER_INFO_H #include +#include #define MAX_MIX_CHANNELS 128 #define PA_MAX_OUTPUTS_PER_SOURCE 256 @@ -39,18 +40,22 @@ enum RenderCallbackType { CB_ERROR_OCCUR = 4, }; -enum EcType { - NONE = 0, - SAME_ADAPTER, - DIFFERENT_ADAPTER -}; +#ifdef __cplusplus +extern "C" { +#endif -enum AuxiliaryRefSwitch { - OFF = 0, - ON -}; +typedef enum EcType { + EC_NONE = 0, + EC_SAME_ADAPTER, + EC_DIFFERENT_ADAPTER +} EcType; + +typedef enum AuxiliaryRefSwitch { + REF_OFF = 0, + REF_ON +} AuxiliaryRefSwitch; -struct CaptureAttr { +typedef struct CaptureAttr { // usage attrs int32_t sourceType; // device attrs @@ -62,6 +67,10 @@ struct CaptureAttr { uint64_t channelLayout; 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 index 96c40f8b36..e10a96f455 100644 --- a/frameworks/native/hdiadapter/manager/BUILD.gn +++ b/frameworks/native/hdiadapter/manager/BUILD.gn @@ -28,6 +28,8 @@ ohos_shared_library("hdiadapter_manager") { include_dirs = [ "include", + "../common/include", + "../source/common", "../../../../interfaces/inner_api/native/audiocommon/include", ] @@ -36,7 +38,9 @@ ohos_shared_library("hdiadapter_manager") { ] deps = [ + ":hdiadapter_utils" "../source:audio_capturer_source", + "../source:capturer_source_adapter", ] external_deps = [ @@ -62,6 +66,7 @@ ohos_shared_library("hdiadapter_utils") { include_dirs = [ "include", + "../../../../interfaces/inner_api/audiocommon/include", ] sources = [ @@ -70,6 +75,7 @@ ohos_shared_library("hdiadapter_utils") { external_deps = [ "c_utils:utils", + "hilog:libhilog", ] part_name = "audio_framework" diff --git a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp index 39958f6673..78c0111bca 100644 --- a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp +++ b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp @@ -15,6 +15,8 @@ #ifndef LOG_TAG #define LOG_TAG "HdiAdapterManager" +#endif + #include "hdi_adapter_manager.h" @@ -23,6 +25,8 @@ #include "include/hdi_adapter_manager_api.h" +using namespace OHOS:AudioStandard; + // Capture handle funcs impl int32_t CaptureHandleInit(void *capture) { @@ -37,7 +41,9 @@ int32_t CaptureHandleDeinit(void *capture) IAudioCapturerSource *captureSource = static_cast(capture); CHECK_AND_RETURN_RET_LOG(captureSource != nullptr, ERR_INVALID_HANDLE, "wrong capture"); - return captureSource->DeInit(); + captureSource->DeInit(); + + return SUCCESS } int32_t CaptureHandleStart(void *capture) @@ -62,7 +68,7 @@ int32_t CaptureHandleCaptureFrame(void *capture, IAudioCapturerSource *captureSource = static_cast(capture); CHECK_AND_RETURN_RET_LOG(captureSource != nullptr, ERR_INVALID_HANDLE, "wrong capture"); - return captureSource->CaptureFrame(); + return captureSource->CaptureFrame(frame, requestBytes, *replyBytes); } int32_t CaptureHandleCaptureFrameWithEc(void *capture, @@ -78,7 +84,7 @@ int32_t CaptureHandleCaptureFrameWithEc(void *capture, } // public api impl -int32_t CreateCaptureHandle(HdiCaptureHandle **handle, const CaptureAttr *attr) +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"); @@ -141,6 +147,7 @@ int32_t HdiAdapterManager::ReleaseCapture(IAudioCapturerSource *capture) if (capture != nullptr) { delete capture; } + return SUCCESS; } HdiAdapterManager *HdiAdapterManager::GetInstance() diff --git a/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h index c48e0edc50..de06cca619 100644 --- a/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h +++ b/frameworks/native/hdiadapter/manager/include/hdi_adapter_manager_api.h @@ -23,7 +23,7 @@ extern "C" { #endif -struct HdiCaptureHandle { +typedef struct HdiCaptureHandle { void *capture; int32_t (*Init)(void *capture); int32_t (*Deinit)(void *capture); @@ -34,9 +34,9 @@ struct HdiCaptureHandle { 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, const CaptureAttr *attr); +int32_t CreateCaptureHandle(HdiCaptureHandle **handle, CaptureAttr *attr); int32_t ReleaseCaptureHandle(HdiCaptureHandle *handle); diff --git a/frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp b/frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp index aed81a41fa..276b0359fc 100644 --- a/frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp +++ b/frameworks/native/hdiadapter/manager/utils/hdi_utils_ringbuffer.cpp @@ -18,6 +18,8 @@ #include "hdi_utils_ringbuffer.h" #include "securec.h" +#include "audio_log.h" +#include "audio_errors.h" namespace OHOS { namespace AudioStandard { @@ -59,21 +61,21 @@ void HdiRingBuffer::Init(const int32_t sampleRate, const int32_t channelCount, c { perFrameLength_ = ((sampleRate * onceFrameNum) / 100) * channelCount * formatBytes; maxBufferSize_ = perFrameLength_ * maxFrameNum; - ringBuffer_.data = new (std::nothrow) float[maxBufferSize_]; + 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) float[perFrameLength_]; + 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) float[perFrameLength_]; + 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_); @@ -83,9 +85,9 @@ void HdiRingBuffer::Init(const int32_t sampleRate, const int32_t channelCount, c } enum RingBufferState HdiRingBuffer::GetRingBufferStatus() { - if (readFull) { + if (readFull_) { return RINGBUFFER_EMPTY; - } else if (writeFull) { + } else if (writeFull_) { return RINGBUFFER_FULL; } else { return RINGBUFFER_HALFFULL; @@ -165,7 +167,7 @@ int32_t HdiRingBuffer::ReleaseOutputBuffer(RingBuffer &item) if ((maxBufferSize_ - readIndex_) >= perFrameLength_ && GetRingBufferStatus() != RINGBUFFER_EMPTY) { ret = memmove_s(item.data, sizeof(uint8_t) * perFrameLength_, - ringBuffer_.data + readIndex, 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."); @@ -187,7 +189,7 @@ int32_t HdiRingBuffer::EnqueueInputBuffer(RingBuffer &item) 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"); - } eles { + } else { AUDIO_ERR_LOG("error: Not enough data to write."); } AddWriteIndex(perFrameLength_); diff --git a/frameworks/native/hdiadapter/source/BUILD.gn b/frameworks/native/hdiadapter/source/BUILD.gn index 454b948605..86d5cee8a9 100644 --- a/frameworks/native/hdiadapter/source/BUILD.gn +++ b/frameworks/native/hdiadapter/source/BUILD.gn @@ -36,7 +36,7 @@ ohos_shared_library("audio_capturer_source") { ] deps = [ - "../manager:hdiadapter_manager", + "../manager:hdiadapter_utils", "../../audioutils:audio_utils", ] 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 b32fa61af2..df26bea7f7 100644 --- a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h +++ b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h @@ -62,7 +62,7 @@ public: virtual ~IAudioCapturerSource() = default; virtual int32_t Init(const IAudioSourceAttr &attr) = 0; - virtual int32_t InitWithoutAttr() = 0; + virtual int32_t InitWithoutAttr() { return 0; } virtual bool IsInited(void) = 0; virtual void DeInit(void) = 0; diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 3ce3e339fe..4ff3ef0f72 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -78,6 +78,7 @@ static enum AudioInputType ConvertToHDIAudioInputType(const int32_t currSourceTy break; case SOURCE_TYPE_EC: hdiAudioInputType = AUDIO_INPUT_EC_TYPE; + break; default: hdiAudioInputType = AUDIO_INPUT_MIC_TYPE; break; @@ -207,7 +208,7 @@ static HdiAdapterFormat ParseAudioFormat(const std::string &format) } } -static IsNonblockingSource(SourceType type) { +static bool IsNonblockingSource(int32_t type) { return (type == SOURCE_TYPE_EC || type == SOURCE_TYPE_MIC_REF); } @@ -279,7 +280,7 @@ private: void CheckLatencySignal(uint8_t *frame, size_t replyBytes); void CheckUpdateState(char *frame, uint64_t replyBytes); - void CaptureThreadLoop() + void CaptureThreadLoop(); CaptureAttr *hdiAttr_; IAudioSourceAttr attr_ = {}; @@ -307,7 +308,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 @@ -605,6 +606,8 @@ int32_t AudioCapturerSourceInner::InitWithoutAttr() ringBuffer_ = std::make_shared(); ringBuffer_->Init(attr.sampleRate, attr.channel, GetByteSizeByFormat(attr.format)); + + return SUCCESS; } void AudioCapturerSourceInner::InitAttrsCapture(struct AudioSampleAttributes &attrs) @@ -787,7 +790,7 @@ int32_t AudioCapturerSourceInner::Start(void) captureThread_ = std::make_unique(&AudioCapturerSourceInner::CaptureThreadLoop, this); std::string threadName = "OS_Capture"; threadName += (attr_.sourceType == SOURCE_TYPE_EC) ? "Ec" : "MicRef"; - pthread_setname_np(writeThread_->native_handle(), threadName.c_str()); + pthread_setname_np(captureThread_->native_handle(), threadName.c_str()); } return SUCCESS; @@ -855,7 +858,7 @@ int32_t AudioCapturerSourceInner::Stop(void) if (started_ && audioCapture_ != nullptr) { int32_t ret = audioCapture_->Stop(audioCapture_); if (ret != SUCCESS) { - AUDIO_ERR_LOG("hdi stop capture failed") + AUDIO_ERR_LOG("hdi stop capture failed"); } } started_ = false; @@ -897,34 +900,6 @@ int32_t AudioCapturerSourceInner::Pause(void) } paused_ = true; - // for ec stream - if (attr_.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) { - param.ecSampleAttributes.ecInterleaved = true; - param.ecSampleAttributes.ecFormat = param.format; - param.ecSampleAttributes.ecSampleRate = param.sampleRate; - 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; - deviceDesc.pins = PIN_IN_MIC; - if (halName_ == "usb") { - deviceDesc.pins = PIN_IN_USB_HEADSET; - } - deviceDesc.desc = (char *)""; - - AUDIO_INFO_LOG("CreateCapture for audioAdapter_: audio sourceType %{public}d, hdi sourceType %{public}d", - attr_.sourceType, param.sourceType); - ret = audioAdapter_->CreateCapture(audioAdapter_, &deviceDesc, ¶m, &audioCapture_, &captureId_); - CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr && ret >= 0, ERR_NOT_STARTED, "Create capture failed"); - return SUCCESS; } @@ -1027,12 +1002,13 @@ void AudioCapturerSourceInner::CaptureThreadLoop() Trace trace("CaptureRefInput"); RingBuffer buffer = ringBuffer_->DequeueInputBuffer(); uint64_t replyBytes; + uint32_t requestBytes = buffer.length; int32_t ret = audioCapture_->CaptureFrame( - audioCapture_, reinterpret_cast(buffer.data), &(buffer.length), &replyBytes); + audioCapture_, reinterpret_cast(buffer.data), &requestBytes, &replyBytes); if (ret != SUCCESS) { AUDIO_ERR_LOG("Capture frame failed"); } - EnqueueInputBuffer(buffer); + ringBuffer_->EnqueueInputBuffer(buffer); } } } diff --git a/frameworks/native/pulseaudio/modules/hdi/BUILD.gn b/frameworks/native/pulseaudio/modules/hdi/BUILD.gn index 5933a11635..c197315d91 100644 --- a/frameworks/native/pulseaudio/modules/hdi/BUILD.gn +++ b/frameworks/native/pulseaudio/modules/hdi/BUILD.gn @@ -112,6 +112,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 2607a204bb..9994bb00af 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c @@ -254,16 +254,16 @@ static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) requestBytesEc = requestBytes; requestBytesRef = requestBytes; - if (u->attrs.sourceType != SOURCE_TYPE_VOICE_COMMUNICATION || u->ecType == NONE) { + 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 == SAME_ADAPTER) { + 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 == DIFFERENT_ADAPTER) { + } else if (u->ecType == EC_DIFFERENT_ADAPTER) { u->sourceAdapter->CapturerSourceFrame( u->sourceAdapter->wapper, (char *)p, (uint64_t)requestBytes, &replyBytes); @@ -276,8 +276,8 @@ static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) AUDIO_WARNING_LOG("should not be here"); } - if (u->auxiliaryRef == ON) { - u->captureHandleRef->CapturerSourceFrame( + if (u->auxiliaryRef == REF_ON) { + u->captureHandleRef->CaptureFrame( u->captureHandleRef->capture, (char *)pRef, (uint64_t)requestBytesRef, &replyBytesRef); } @@ -623,9 +623,9 @@ pa_source *PaHdiSourceNew(pa_module *m, pa_modargs *ma, const char *driver) } // decide whether to create ec or mic ref source here // TODO: decide by policy, change these for test - u->ecType = DIFFERENT_ADAPTER; - u->auxiliaryRef = ON; - if (u->attrs.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION && u->ecType == DIFFERENT_ADAPTER) { + 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)); // TODO: set target ec attr int32_t res = CreateCaptureHandle(&u->captureHandleEc, attr); @@ -635,7 +635,7 @@ pa_source *PaHdiSourceNew(pa_module *m, pa_modargs *ma, const char *driver) } else { u->captureHandleEc = NULL; } - if (u->auxiliaryRef == ON) { + if (u->auxiliaryRef == REF_ON) { CaptureAttr *attr = (struct CaptureAttr *)calloc(1, sizeof(CaptureAttr)); // TODO: set target mic ref attr int32_t res = CreateCaptureHandle(&u->captureHandleRef, attr); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_effect.h b/interfaces/inner_api/native/audiocommon/include/audio_effect.h index bc9179c02d..03e5c92b67 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_effect.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_effect.h @@ -325,12 +325,6 @@ struct AudioRendererInfoForSpatialization { StreamUsage streamUsage; }; -enum EcType { - NONE = 0, - SAME_ADAPTER, - DIFFERENT_ADAPTER -}; - } // namespace AudioStandard } // namespace OHOS -- Gitee From 4c5658520a2a23f3c318e64242e582a691ea67da Mon Sep 17 00:00:00 2001 From: magekkkk Date: Tue, 25 Jun 2024 07:00:10 +0000 Subject: [PATCH 08/10] add source params setting for new sources Signed-off-by: magekkkk --- .../common/include/audio_hdiadapter_info.h | 1 - frameworks/native/hdiadapter/manager/BUILD.gn | 4 +- .../manager/hdi_adapter_manager.cpp | 4 +- .../source/primary/audio_capturer_source.cpp | 51 ++++++++++++++----- .../pulseaudio/modules/hdi/hdi_source.c | 32 +++++++++++- 5 files changed, 73 insertions(+), 19 deletions(-) diff --git a/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h b/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h index 6ac1f3dcd4..d7593b1eba 100644 --- a/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h +++ b/frameworks/native/hdiadapter/common/include/audio_hdiadapter_info.h @@ -64,7 +64,6 @@ typedef struct CaptureAttr { // common audio attrs uint32_t sampleRate; uint32_t channelCount; - uint64_t channelLayout; enum HdiAdapterFormat format; bool isBigEndian; } CaptureAttr; diff --git a/frameworks/native/hdiadapter/manager/BUILD.gn b/frameworks/native/hdiadapter/manager/BUILD.gn index e10a96f455..5c79b448d5 100644 --- a/frameworks/native/hdiadapter/manager/BUILD.gn +++ b/frameworks/native/hdiadapter/manager/BUILD.gn @@ -38,7 +38,7 @@ ohos_shared_library("hdiadapter_manager") { ] deps = [ - ":hdiadapter_utils" + ":hdiadapter_utils", "../source:audio_capturer_source", "../source:capturer_source_adapter", ] @@ -66,7 +66,7 @@ ohos_shared_library("hdiadapter_utils") { include_dirs = [ "include", - "../../../../interfaces/inner_api/audiocommon/include", + "../../../../interfaces/inner_api/native/audiocommon/include", ] sources = [ diff --git a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp index 78c0111bca..e6490b3793 100644 --- a/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp +++ b/frameworks/native/hdiadapter/manager/hdi_adapter_manager.cpp @@ -25,7 +25,7 @@ #include "include/hdi_adapter_manager_api.h" -using namespace OHOS:AudioStandard; +using namespace OHOS::AudioStandard; // Capture handle funcs impl int32_t CaptureHandleInit(void *capture) @@ -43,7 +43,7 @@ int32_t CaptureHandleDeinit(void *capture) captureSource->DeInit(); - return SUCCESS + return SUCCESS; } int32_t CaptureHandleStart(void *capture) diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 4ff3ef0f72..47f06afea2 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -61,7 +61,6 @@ static enum AudioInputType ConvertToHDIAudioInputType(const int32_t currSourceTy case SOURCE_TYPE_MIC: case SOURCE_TYPE_PLAYBACK_CAPTURE: case SOURCE_TYPE_ULTRASONIC: - case SOURCE_TYPE_MIC_REF: hdiAudioInputType = AUDIO_INPUT_MIC_TYPE; break; case SOURCE_TYPE_WAKEUP: @@ -79,6 +78,9 @@ static enum AudioInputType ConvertToHDIAudioInputType(const int32_t currSourceTy 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; @@ -329,6 +331,7 @@ private: std::unique_ptr captureThread_ = nullptr; bool threadRunning_ = false; std::shared_ptr ringBuffer_ = nullptr; + int8_t *fakeSourceFrame_ = nullptr; }; class AudioCapturerSourceWakeup : public AudioCapturerSource { @@ -556,7 +559,6 @@ AudioCapturerSourceInner::AudioCapturerSourceInner(CaptureAttr *attr) leftVolume_(MAX_VOLUME_LEVEL), rightVolume_(MAX_VOLUME_LEVEL), openMic_(0), audioManager_(nullptr), audioAdapter_(nullptr), audioCapture_(nullptr) { - // TODO: get hal name from adapterName in attr halName_ = "primary"; hdiAttr_ = attr; attr_ = {}; @@ -586,21 +588,23 @@ int32_t AudioCapturerSourceInner::Init(const IAudioSourceAttr &attr) int32_t AudioCapturerSourceInner::InitWithoutAttr() { + // TODO: use this when testing usb + // halName_ = "usb"; + // build attr IAudioSourceAttr attr = {}; attr.adapterName = hdiAttr_->adapterName; - // attr.openMicSpeaker = true; + 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 = hdiAttr_->filePath; - // attr.deviceNetworkId = hdiAttr_->deviceNetworkId; - attr.deviceType = hdiAttr_->deviceType; + attr.filePath = ""; + attr.deviceNetworkId = "LocalDevice"; + attr.deviceType = DEVICE_TYPE_MIC; attr.sourceType = hdiAttr_->sourceType; - attr.channelLayout = hdiAttr_->channelLayout; Init(attr); @@ -691,6 +695,8 @@ 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; @@ -699,9 +705,11 @@ int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) // for ec 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; @@ -787,6 +795,7 @@ int32_t AudioCapturerSourceInner::Start(void) // 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"; @@ -854,6 +863,7 @@ int32_t AudioCapturerSourceInner::Stop(void) if (captureThread_ && captureThread_->joinable()) { captureThread_->join(); } + delete [] fakeSourceFrame_; if (started_ && audioCapture_ != nullptr) { int32_t ret = audioCapture_->Stop(audioCapture_); @@ -979,13 +989,15 @@ int32_t AudioCapturerSourceInner::CaptureFrameWithEc( { CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); + // Need compile with hdi + struct AudioFrameLen frameLen; + frameLen.frameLen = requestBytes; + frameLen.frameEcLen = requestBytesEc; struct AudioCaptureFrameInfo frameInfo; frameInfo.frame = reinterpret_cast(frame); - frameInfo.frameSize = requestBytes; frameInfo.frameEc = reinterpret_cast(frame); - frameInfo.frameEcSize = requestBytesEc; - int32_t ret = audioCapture_->CaptureFrameEc(audioCapture_, &frameInfo); + int32_t ret = audioCapture_->CaptureFrameEc(audioCapture_, &frameLen, &frameInfo); CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_READ_FAILED, "Capture Frame Fail"); replyBytes = frameInfo.replyBytes; @@ -1003,8 +1015,23 @@ void AudioCapturerSourceInner::CaptureThreadLoop() RingBuffer buffer = ringBuffer_->DequeueInputBuffer(); uint64_t replyBytes; uint32_t requestBytes = buffer.length; - int32_t ret = audioCapture_->CaptureFrame( - audioCapture_, reinterpret_cast(buffer.data), &requestBytes, &replyBytes); + 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"); } diff --git a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c index 9994bb00af..046f26984f 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c @@ -585,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; @@ -627,7 +655,7 @@ pa_source *PaHdiSourceNew(pa_module *m, pa_modargs *ma, const char *driver) 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)); - // TODO: set target ec attr + InitEcAttr(u, attr); int32_t res = CreateCaptureHandle(&u->captureHandleEc, attr); if (res) { AUDIO_ERR_LOG("create ec handle failed"); @@ -637,7 +665,7 @@ pa_source *PaHdiSourceNew(pa_module *m, pa_modargs *ma, const char *driver) } if (u->auxiliaryRef == REF_ON) { CaptureAttr *attr = (struct CaptureAttr *)calloc(1, sizeof(CaptureAttr)); - // TODO: set target mic ref attr + InitAuxiliaryRefAttr(u, attr); int32_t res = CreateCaptureHandle(&u->captureHandleRef, attr); if (res) { AUDIO_ERR_LOG("create ec handle failed"); -- Gitee From fa15bc758d71f09d40f8a271d86392c407ad3605 Mon Sep 17 00:00:00 2001 From: magekkkk Date: Thu, 27 Jun 2024 06:33:49 +0000 Subject: [PATCH 09/10] fix more issues for ec Signed-off-by: magekkkk --- .../native/hdiadapter/source/primary/audio_capturer_source.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 47f06afea2..81faa98f02 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -703,7 +703,7 @@ int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) param.startThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (param.frameSize); param.sourceType = static_cast(ConvertToHDIAudioInputType(attr_.sourceType)); - // for ec stream + // only for ec same adapter stream if (attr_.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) { // Need compile with hdi param.ecSampleAttributes.ecInterleaved = true; -- Gitee From 68b24a67ea70ad7646eb2dc75dab1e6181653d75 Mon Sep 17 00:00:00 2001 From: magekkkk Date: Thu, 27 Jun 2024 08:39:53 +0000 Subject: [PATCH 10/10] add streamid for new sources Signed-off-by: magekkkk --- .../source/primary/audio_capturer_source.cpp | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 81faa98f02..6e99bb9274 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -267,6 +267,8 @@ 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; @@ -702,6 +704,11 @@ int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) 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) { @@ -800,7 +807,6 @@ int32_t AudioCapturerSourceInner::Start(void) std::string threadName = "OS_Capture"; threadName += (attr_.sourceType == SOURCE_TYPE_EC) ? "Ec" : "MicRef"; pthread_setname_np(captureThread_->native_handle(), threadName.c_str()); - } return SUCCESS; } @@ -990,10 +996,10 @@ int32_t AudioCapturerSourceInner::CaptureFrameWithEc( CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!"); // Need compile with hdi - struct AudioFrameLen frameLen; + struct AudioFrameLen frameLen = {}; frameLen.frameLen = requestBytes; frameLen.frameEcLen = requestBytesEc; - struct AudioCaptureFrameInfo frameInfo; + struct AudioCaptureFrameInfo frameInfo = {}; frameInfo.frame = reinterpret_cast(frame); frameInfo.frameEc = reinterpret_cast(frame); @@ -1149,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 = { -- Gitee