diff --git a/services/audio_engine/plugin/channel_converter/include/down_mixer.h b/services/audio_engine/plugin/channel_converter/include/down_mixer.h index 63c13350f5321afb46ed5f33b5669953c15627b7..2faa46befd37cf88a812482fc96a4eb941f9a876 100644 --- a/services/audio_engine/plugin/channel_converter/include/down_mixer.h +++ b/services/audio_engine/plugin/channel_converter/include/down_mixer.h @@ -45,6 +45,7 @@ public: int32_t SetParam(AudioChannelInfo inChannelInfo_, AudioChannelInfo outChannelInfo_, uint32_t formatSize, bool mixLfe); void Reset(); + static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels); private: AudioChannelLayout inLayout_ = CH_LAYOUT_UNKNOWN; uint32_t inChannels_ = 0; diff --git a/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp b/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp index 3ac3f1500b7eb0ed7d2bd8ef780dae40239e52ce..a82bf222923a466908a89b6ed1f4e46026c4aeea 100644 --- a/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp +++ b/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp @@ -77,9 +77,13 @@ static constexpr uint64_t MASK_BOTTOM = BOTTOM_FRONT_CENTER static constexpr uint64_t MASK_LFE = LOW_FREQUENCY | LOW_FREQUENCY_2; +static const uint64_t MASK_HOA = + CH_LAYOUT_HOA_ORDER1_ACN_N3D | CH_LAYOUT_HOA_ORDER1_ACN_SN3D | CH_LAYOUT_HOA_ORDER1_FUMA | + CH_LAYOUT_HOA_ORDER2_ACN_N3D | CH_LAYOUT_HOA_ORDER2_ACN_SN3D | CH_LAYOUT_HOA_ORDER2_FUMA | + CH_LAYOUT_HOA_ORDER3_ACN_N3D | CH_LAYOUT_HOA_ORDER3_ACN_SN3D | CH_LAYOUT_HOA_ORDER3_FUMA; + static uint32_t BitCounts(uint64_t bits); static bool IsValidChLayout(AudioChannelLayout &chLayout, uint32_t chCounts); -static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels); // 改成默认构造 DownMixer::DownMixer() @@ -129,7 +133,15 @@ int32_t DownMixer::Process(uint32_t frameLen, float* in, uint32_t inLen, float* expectInLen, inLen, expectOutLen, outLen); return DMIX_ERR_ALLOC_FAILED; } - AUDIO_DEBUG_LOG("Downmixing: frameLen: %{public}d,", frameLen); + // For HOA, copy the first channel into all output channels + if (inLayout_ & MASK_HOA) { + for (uint32_t i = 0; i < frameLen; i++) { + for (uint32_t c = 0; c < outChannels_; c++) { + out[outChannels_ * i + c] = in[inChannels_ * i]; + } + } + return DMIX_ERR_SUCCESS; + } float a; for (; frameLen > 0; frameLen--) { for (uint32_t i = 0; i < outChannels_; i++) { @@ -1056,12 +1068,12 @@ static bool IsValidChLayout(AudioChannelLayout &chLayout, uint32_t chCounts) return false; } if (chLayout == CH_LAYOUT_UNKNOWN || BitCounts(chLayout) != chCounts) { - chLayout = SetDefaultChannelLayout((AudioChannel)chCounts); + chLayout = DownMixer::SetDefaultChannelLayout((AudioChannel)chCounts); } return true; } -static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels) +AudioChannelLayout DownMixer::SetDefaultChannelLayout(AudioChannel channels) { if (channels < MONO || channels > CHANNEL_16) { return CH_LAYOUT_UNKNOWN; @@ -1083,6 +1095,8 @@ static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels) return CH_LAYOUT_6POINT1; case CHANNEL_8: return CH_LAYOUT_5POINT1POINT2; + case CHANNEL_9: + return CH_LAYOUT_HOA_ORDER2_ACN_N3D; case CHANNEL_10: return CH_LAYOUT_7POINT1POINT2; case CHANNEL_12: diff --git a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp index 99d0e0b33b5f8dd907c05e87b2c2476cdbbc9b78..a67177386d7c6b75eb4304987c18dabd9a55db7b 100644 --- a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp +++ b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp @@ -49,8 +49,11 @@ int32_t ProResampler::Process(const float *inBuffer, uint32_t *inFrameSize, floa AUDIO_WARNING_LOG("ProResampler process failed with error %{public}s", ErrCodeToString(ret).c_str()); } uint32_t fillZeroSize = expectedOutFrameSize - *outFrameSize > 0 ? expectedOutFrameSize - *outFrameSize : 0; - ret += memset_s(outBuffer, expectedOutFrameSize * channels_ * sizeof(float), 0, - fillZeroSize * channels_ * sizeof(float)); + for (uint32_t i = 0; i < fillZeroSize; i++) { + for (uint32_t c = 0; c < channels_; c++) { + outBuffer[channels_ * i + c] = tmpOutBuf[c]; + } + } ret += memcpy_s(outBuffer + fillZeroSize * channels_, (expectedOutFrameSize - fillZeroSize) * channels_ * sizeof(float), tmpOutBuf.data(), *outFrameSize * channels_ * sizeof(float)); diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index f93bd2aaff3b56248d86449ee5dd600f3133d799..477ef3f861310177693622fa387fd7ca2b87da44 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -396,6 +396,10 @@ audio_ohos_library("audio_process_service") { } configs = [ ":audio_service_config" ] + + include_dirs = [ + "../../services/audio_engine/plugin/channel_converter/include", + ] deps = [ ":audio_common", @@ -405,6 +409,7 @@ audio_ohos_library("audio_process_service") { "../../frameworks/native/audioutils:audio_utils", "../../frameworks/native/hdiadapter_new:hdiadapter_new", "../audio_engine:audio_engine_manager", + "../audio_engine:audio_engine_plugins", "../audio_policy:audio_foundation", ] diff --git a/services/audio_service/common/include/limiter/audio_limiter.h b/services/audio_service/common/include/limiter/audio_limiter.h index 249bf3a8c61565443ca54ed12c6286cbc1ceef62..c4e323e1c1581106363d351f695461fc57832a40 100644 --- a/services/audio_service/common/include/limiter/audio_limiter.h +++ b/services/audio_service/common/include/limiter/audio_limiter.h @@ -45,6 +45,8 @@ private: float gainAttack_; float gainRelease_; float *bufHis_; + uint32_t sampleRate_; + uint32_t channels_; FILE *dumpFileInput_ = nullptr; FILE *dumpFileOutput_ = nullptr; std::string dumpFileNameIn_ = ""; diff --git a/services/audio_service/common/src/limiter/audio_limiter.cpp b/services/audio_service/common/src/limiter/audio_limiter.cpp index a2a371a7bf269ececc3d2a844f01311ab74ee810..e3aeb904da88c8b4d3cade464c9b68e2776750d5 100644 --- a/services/audio_service/common/src/limiter/audio_limiter.cpp +++ b/services/audio_service/common/src/limiter/audio_limiter.cpp @@ -83,7 +83,8 @@ int32_t AudioLimiter::SetConfig(int32_t maxRequest, int32_t biteSize, int32_t sa maxRequest, biteSize, sampleRate, channels, algoFrameLen_, latency_); bufHis_ = new (std::nothrow) float[algoFrameLen_](); CHECK_AND_RETURN_RET_LOG(bufHis_ != nullptr, ERROR, "allocate limit algorithm buffer failed"); - + sampleRate_ = sampleRate; + channels_ = channels; dumpFileNameIn_ = std::to_string(sinkIndex_) + "_limiter_in_" + GetTime() + "_" + std::to_string(sampleRate) + "_" + std::to_string(channels) + "_" + std::to_string(format_) + ".pcm"; DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileNameIn_, &dumpFileInput_); @@ -99,6 +100,18 @@ int32_t AudioLimiter::Process(int32_t frameLen, float *inBuffer, float *outBuffe CHECK_AND_RETURN_RET_LOG(algoFrameLen_ * PROC_COUNT == frameLen, ERROR, "error, algoFrameLen_ = %{public}d, frameLen = %{public}d", algoFrameLen_, frameLen); int32_t ptrIndex = 0; + if (dumpFileInput_ == nullptr) { + dumpFileNameIn_ = std::to_string(sinkIndex_) + "_limiter_in_" + GetTime() + "_" + + std::to_string(sampleRate_) + "_" + std::to_string(channels_) + "_" + std::to_string(format_) + ".pcm"; + DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileNameIn_, &dumpFileInput_); + AUDIO_DEBUG_LOG("Reopen dump file: %{public}s", dumpFileNameIn_.c_str()); + } + if (dumpFileOutput_ == nullptr) { + dumpFileNameOut_ = std::to_string(sinkIndex_) + "_limiter_out_" + GetTime() + "_" + + std::to_string(sampleRate_) + "_" + std::to_string(channels_) + "_" + std::to_string(format_) + ".pcm"; + DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileNameOut_, &dumpFileOutput_); + AUDIO_DEBUG_LOG("Reopen dump file: %{public}s", dumpFileNameOut_.c_str()); + } DumpFileUtil::WriteDumpFile(dumpFileInput_, static_cast(inBuffer), frameLen * sizeof(float)); for (int32_t i = 0; i < PROC_COUNT; i++) { ProcessAlgo(algoFrameLen_, inBuffer + ptrIndex, outBuffer + ptrIndex); diff --git a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp index a7f3f4ddd5d7828071c76c2ed8eef147b8651e0a..eb32290c0fd00ec8fc0ba674171703749272b4bd 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -31,6 +31,7 @@ #include "i_hpae_manager.h" #include "audio_stream_info.h" #include "audio_effect_map.h" +#include "down_mixer.h" using namespace OHOS::AudioStandard::HPAE; namespace OHOS { @@ -39,7 +40,6 @@ namespace AudioStandard { const int32_t MIN_BUFFER_SIZE = 2; const int32_t FRAME_LEN_10MS = 2; const int32_t TENMS_PER_SEC = 100; -static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels); static std::shared_ptr GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId); HpaeRendererStreamImpl::HpaeRendererStreamImpl(AudioProcessConfig processConfig) { @@ -59,8 +59,9 @@ int32_t HpaeRendererStreamImpl::InitParams(const std::string &deviceName) streamInfo.channels = processConfig_.streamInfo.channels; streamInfo.samplingRate = processConfig_.streamInfo.samplingRate; streamInfo.format = processConfig_.streamInfo.format; - if (processConfig_.streamInfo.channelLayout == CH_LAYOUT_UNKNOWN) { - streamInfo.channelLayout = SetDefaultChannelLayout(streamInfo.channels); + streamInfo.channelLayout = processConfig_.streamInfo.channelLayout; + if (streamInfo.channelLayout == CH_LAYOUT_UNKNOWN) { + streamInfo.channelLayout = DownMixer::SetDefaultChannelLayout((AudioChannel)streamInfo.channels); } streamInfo.frameLen = spanSizeInFrame_; streamInfo.sessionId = processConfig_.originalSessionId; @@ -447,41 +448,6 @@ int32_t HpaeRendererStreamImpl::SetClientVolume(float clientVolume) return SUCCESS; } -static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels) -{ - if (channels < MONO || channels > CHANNEL_16) { - return CH_LAYOUT_UNKNOWN; - } - switch (channels) { - case MONO: - return CH_LAYOUT_MONO; - case STEREO: - return CH_LAYOUT_STEREO; - case CHANNEL_3: - return CH_LAYOUT_SURROUND; - case CHANNEL_4: - return CH_LAYOUT_3POINT1; - case CHANNEL_5: - return CH_LAYOUT_4POINT1; - case CHANNEL_6: - return CH_LAYOUT_5POINT1; - case CHANNEL_7: - return CH_LAYOUT_6POINT1; - case CHANNEL_8: - return CH_LAYOUT_5POINT1POINT2; - case CHANNEL_10: - return CH_LAYOUT_7POINT1POINT2; - case CHANNEL_12: - return CH_LAYOUT_7POINT1POINT4; - case CHANNEL_14: - return CH_LAYOUT_9POINT1POINT4; - case CHANNEL_16: - return CH_LAYOUT_9POINT1POINT6; - default: - return CH_LAYOUT_UNKNOWN; - } -} - static std::shared_ptr GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId) { uint32_t renderId = HDI_INVALID_ID; diff --git a/services/audio_service/test/unittest/BUILD.gn b/services/audio_service/test/unittest/BUILD.gn index 076dd0189c2f72aef519f0f8dbb23d7524ba2c29..6315d84bfdb8f79d37015ebd64411aaf72adb98f 100644 --- a/services/audio_service/test/unittest/BUILD.gn +++ b/services/audio_service/test/unittest/BUILD.gn @@ -768,6 +768,7 @@ ohos_unittest("capturer_in_server_unit_test") { "../../../../frameworks/native/audiopolicy/include", "../../../../frameworks/native/audioinnercall/include", "../../../../frameworks/native/audioinnercall/include", + "../../../../services/audio_engine/plugin/channel_converter/include", "../../../../services/audio_service/client/include", "../../../../services/audio_service/common/include", "../../../../services/audio_service/common/include/dfx", @@ -817,6 +818,7 @@ ohos_unittest("capturer_in_server_unit_test") { "../../../../frameworks/native/audioutils:audio_utils", "../../../../frameworks/native/hdiadapter_new:hdiadapter_new", "../../../../services/audio_engine:audio_engine_manager", + "../../../../services/audio_engine:audio_engine_plugins", "../../../../services/audio_policy:audio_policy_client", "../../../../services/audio_policy:audio_policy_service", "../../../../services/audio_service:audio_client",