From ea54fb3a05a8b271c91d83de7414fae3731fb92d Mon Sep 17 00:00:00 2001 From: c00657214 Date: Sat, 12 Apr 2025 11:23:01 +0800 Subject: [PATCH 01/40] upload proaudio engine folder Signed-off-by: c00657214 --- services/audio_engine/BUILD.gn | 307 +++ .../audio_engine/buffer/hpae_pcm_buffer.cpp | 266 +++ .../audio_engine/buffer/hpae_pcm_buffer.h | 242 +++ .../audio_engine/buffer/hpae_pcm_process.cpp | 74 + .../audio_engine/buffer/hpae_pcm_process.h | 89 + services/audio_engine/dfx/hpae_dfx_tree.cpp | 190 ++ services/audio_engine/dfx/hpae_dfx_tree.h | 64 + .../include/audio_service_hpae_callback.h | 56 + .../audio_service_hpae_dump_callback.h | 31 + .../manager/include/hpae_capture_move_info.h | 32 + .../manager/include/hpae_capturer_manager.h | 114 + .../manager/include/hpae_define.h | 123 ++ .../audio_engine/manager/include/hpae_info.h | 74 + .../include/hpae_inner_capturer_manager.h | 126 ++ .../manager/include/hpae_manager.h | 236 ++ .../manager/include/hpae_msg_channel.h | 146 ++ .../include/hpae_offload_renderer_manager.h | 112 + .../manager/include/hpae_policy_manager.h | 73 + .../manager/include/hpae_renderer_manager.h | 126 ++ .../include/hpae_signal_process_thread.h | 54 + .../manager/include/hpae_stream_manager.h | 55 + .../manager/include/i_hpae_capturer_manager.h | 101 + .../manager/include/i_hpae_manager.h | 129 ++ .../manager/include/i_hpae_renderer_manager.h | 109 + .../manager/src/hpae_capturer_manager.cpp | 863 ++++++++ .../src/hpae_inner_capturer_manager.cpp | 745 +++++++ .../audio_engine/manager/src/hpae_manager.cpp | 1910 +++++++++++++++++ .../src/hpae_offload_renderer_manager.cpp | 607 ++++++ .../manager/src/hpae_policy_manager.cpp | 179 ++ .../manager/src/hpae_renderer_manager.cpp | 951 ++++++++ .../src/hpae_signal_process_thread.cpp | 74 + .../manager/src/i_hpae_manager.cpp | 29 + .../manager/src/i_hpae_renderer_manager.cpp | 76 + .../hpae_audio_format_converter_node.h | 59 + .../node/include/hpae_capture_effect_node.h | 73 + .../node/include/hpae_gain_node.h | 61 + .../node/include/hpae_inner_cap_sink_node.h | 67 + .../node/include/hpae_mixer_node.h | 47 + .../audio_engine/node/include/hpae_node.h | 298 +++ .../node/include/hpae_node_common.h | 37 + .../include/hpae_offload_sinkoutput_node.h | 116 + .../node/include/hpae_output_cluster.h | 63 + .../node/include/hpae_plugin_node.h | 53 + .../node/include/hpae_process_cluster.h | 58 + .../node/include/hpae_render_effect_node.h | 62 + .../node/include/hpae_resample_node.h | 56 + .../node/include/hpae_sink_input_node.h | 78 + .../node/include/hpae_sink_output_node.h | 78 + .../node/include/hpae_source_input_cluster.h | 62 + .../node/include/hpae_source_input_node.h | 88 + .../node/include/hpae_source_output_node.h | 57 + .../include/hpae_source_process_cluster.h | 54 + .../src/hpae_audio_format_converter_node.cpp | 317 +++ .../node/src/hpae_capture_effect_node.cpp | 214 ++ .../audio_engine/node/src/hpae_gain_node.cpp | 233 ++ .../node/src/hpae_inner_cap_sink_node.cpp | 178 ++ .../audio_engine/node/src/hpae_mixer_node.cpp | 94 + .../node/src/hpae_node_common.cpp | 153 ++ .../node/src/hpae_offload_sinkoutput_node.cpp | 527 +++++ .../node/src/hpae_output_cluster.cpp | 241 +++ .../node/src/hpae_plugin_node.cpp | 110 + .../node/src/hpae_process_cluster.cpp | 275 +++ .../node/src/hpae_render_effect_node.cpp | 289 +++ .../node/src/hpae_resample_node.cpp | 174 ++ .../node/src/hpae_sinkInput_node.cpp | 240 +++ .../node/src/hpae_sink_input_node.cpp | 248 +++ .../node/src/hpae_sink_output_node.cpp | 331 +++ .../node/src/hpae_source_input_cluster.cpp | 231 ++ .../node/src/hpae_source_input_node.cpp | 362 ++++ .../node/src/hpae_source_output_node.cpp | 136 ++ .../node/src/hpae_source_process_cluster.cpp | 167 ++ .../bitdepth_converter/bitdepth_converter.c | 329 +++ .../bitdepth_converter/bitdepth_converter.h | 67 + .../include/channel_converter.h | 47 + .../channel_converter/include/down_mixer.h | 95 + .../src/channel_converter.cpp | 138 ++ .../channel_converter/src/down_mixer.cpp | 1087 ++++++++++ .../resample/include/audio_proresampler.h | 53 + .../include/audio_proresampler_process.h | 149 ++ .../plugin/resample/include/resampler.h | 38 + .../proresampler/audio_proresampler.cpp | 174 ++ .../proresampler/audio_proresampler_process.c | 1490 +++++++++++++ services/audio_engine/simd/SimdUtils.cpp | 117 + services/audio_engine/simd/SimdUtils.h | 40 + services/audio_engine/test/unittest/BUILD.gn | 90 + .../hpae_audio_service_callback_unit_test.h | 99 + .../unittest/common/hpae_manager_unit_test.h | 41 + .../test/unittest/common/test_case_common.cpp | 184 ++ .../test/unittest/common/test_case_common.h | 99 + .../test/unittest/dfx/hpae_dfx_tree_test.cpp | 114 + .../hpae_audio_service_callback_unit_test.cpp | 163 ++ .../manager/hpae_capturer_manager_test.cpp | 306 +++ .../manager/hpae_inner_capturer_unit_test.cpp | 341 +++ .../unittest/manager/hpae_manager_test.cpp | 377 ++++ .../manager/hpae_render_manager_test.cpp | 260 +++ .../unittest/node/hpae_gain_node_test.cpp | 135 ++ .../unittest/node/hpae_mixer_node_test.cpp | 125 ++ .../node/hpae_output_cluster_test.cpp | 177 ++ .../unittest/node/hpae_pcm_buffer_test.cpp | 180 ++ .../unittest/node/hpae_pcm_process_test.cpp | 125 ++ .../node/hpae_process_cluster_test.cpp | 168 ++ .../unittest/node/hpae_resample_node_test.cpp | 94 + .../node/hpae_sink_input_node_test.cpp | 154 ++ .../node/hpae_sink_output_node_test.cpp | 123 ++ .../node/hpae_source_input_cluster_test.cpp | 87 + .../node/hpae_source_input_node_test.cpp | 165 ++ .../node/hpae_source_output_node_test.cpp | 148 ++ .../test/unittest/resource/ohos_test.xml | 24 + .../utils/high_resolution_timer.h | 54 + .../utils/hpae_format_convert.cpp | 153 ++ .../audio_engine/utils/hpae_format_convert.h | 28 + .../audio_engine/utils/hpae_no_lock_queue.cpp | 159 ++ .../audio_engine/utils/hpae_no_lock_queue.h | 64 + .../audio_engine/utils/hpae_pcm_dumper.cpp | 57 + services/audio_engine/utils/hpae_pcm_dumper.h | 34 + 115 files changed, 22502 insertions(+) create mode 100644 services/audio_engine/BUILD.gn create mode 100644 services/audio_engine/buffer/hpae_pcm_buffer.cpp create mode 100644 services/audio_engine/buffer/hpae_pcm_buffer.h create mode 100644 services/audio_engine/buffer/hpae_pcm_process.cpp create mode 100644 services/audio_engine/buffer/hpae_pcm_process.h create mode 100644 services/audio_engine/dfx/hpae_dfx_tree.cpp create mode 100644 services/audio_engine/dfx/hpae_dfx_tree.h create mode 100644 services/audio_engine/manager/include/audio_service_hpae_callback.h create mode 100644 services/audio_engine/manager/include/audio_service_hpae_dump_callback.h create mode 100644 services/audio_engine/manager/include/hpae_capture_move_info.h create mode 100644 services/audio_engine/manager/include/hpae_capturer_manager.h create mode 100644 services/audio_engine/manager/include/hpae_define.h create mode 100644 services/audio_engine/manager/include/hpae_info.h create mode 100644 services/audio_engine/manager/include/hpae_inner_capturer_manager.h create mode 100644 services/audio_engine/manager/include/hpae_manager.h create mode 100644 services/audio_engine/manager/include/hpae_msg_channel.h create mode 100644 services/audio_engine/manager/include/hpae_offload_renderer_manager.h create mode 100644 services/audio_engine/manager/include/hpae_policy_manager.h create mode 100644 services/audio_engine/manager/include/hpae_renderer_manager.h create mode 100644 services/audio_engine/manager/include/hpae_signal_process_thread.h create mode 100644 services/audio_engine/manager/include/hpae_stream_manager.h create mode 100644 services/audio_engine/manager/include/i_hpae_capturer_manager.h create mode 100644 services/audio_engine/manager/include/i_hpae_manager.h create mode 100644 services/audio_engine/manager/include/i_hpae_renderer_manager.h create mode 100644 services/audio_engine/manager/src/hpae_capturer_manager.cpp create mode 100644 services/audio_engine/manager/src/hpae_inner_capturer_manager.cpp create mode 100644 services/audio_engine/manager/src/hpae_manager.cpp create mode 100644 services/audio_engine/manager/src/hpae_offload_renderer_manager.cpp create mode 100644 services/audio_engine/manager/src/hpae_policy_manager.cpp create mode 100644 services/audio_engine/manager/src/hpae_renderer_manager.cpp create mode 100644 services/audio_engine/manager/src/hpae_signal_process_thread.cpp create mode 100644 services/audio_engine/manager/src/i_hpae_manager.cpp create mode 100644 services/audio_engine/manager/src/i_hpae_renderer_manager.cpp create mode 100644 services/audio_engine/node/include/hpae_audio_format_converter_node.h create mode 100644 services/audio_engine/node/include/hpae_capture_effect_node.h create mode 100644 services/audio_engine/node/include/hpae_gain_node.h create mode 100644 services/audio_engine/node/include/hpae_inner_cap_sink_node.h create mode 100644 services/audio_engine/node/include/hpae_mixer_node.h create mode 100644 services/audio_engine/node/include/hpae_node.h create mode 100644 services/audio_engine/node/include/hpae_node_common.h create mode 100644 services/audio_engine/node/include/hpae_offload_sinkoutput_node.h create mode 100644 services/audio_engine/node/include/hpae_output_cluster.h create mode 100644 services/audio_engine/node/include/hpae_plugin_node.h create mode 100644 services/audio_engine/node/include/hpae_process_cluster.h create mode 100644 services/audio_engine/node/include/hpae_render_effect_node.h create mode 100644 services/audio_engine/node/include/hpae_resample_node.h create mode 100644 services/audio_engine/node/include/hpae_sink_input_node.h create mode 100644 services/audio_engine/node/include/hpae_sink_output_node.h create mode 100644 services/audio_engine/node/include/hpae_source_input_cluster.h create mode 100644 services/audio_engine/node/include/hpae_source_input_node.h create mode 100644 services/audio_engine/node/include/hpae_source_output_node.h create mode 100644 services/audio_engine/node/include/hpae_source_process_cluster.h create mode 100644 services/audio_engine/node/src/hpae_audio_format_converter_node.cpp create mode 100644 services/audio_engine/node/src/hpae_capture_effect_node.cpp create mode 100644 services/audio_engine/node/src/hpae_gain_node.cpp create mode 100644 services/audio_engine/node/src/hpae_inner_cap_sink_node.cpp create mode 100644 services/audio_engine/node/src/hpae_mixer_node.cpp create mode 100644 services/audio_engine/node/src/hpae_node_common.cpp create mode 100644 services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp create mode 100644 services/audio_engine/node/src/hpae_output_cluster.cpp create mode 100644 services/audio_engine/node/src/hpae_plugin_node.cpp create mode 100644 services/audio_engine/node/src/hpae_process_cluster.cpp create mode 100644 services/audio_engine/node/src/hpae_render_effect_node.cpp create mode 100644 services/audio_engine/node/src/hpae_resample_node.cpp create mode 100644 services/audio_engine/node/src/hpae_sinkInput_node.cpp create mode 100644 services/audio_engine/node/src/hpae_sink_input_node.cpp create mode 100644 services/audio_engine/node/src/hpae_sink_output_node.cpp create mode 100644 services/audio_engine/node/src/hpae_source_input_cluster.cpp create mode 100644 services/audio_engine/node/src/hpae_source_input_node.cpp create mode 100644 services/audio_engine/node/src/hpae_source_output_node.cpp create mode 100644 services/audio_engine/node/src/hpae_source_process_cluster.cpp create mode 100644 services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.c create mode 100644 services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.h create mode 100644 services/audio_engine/plugin/channel_converter/include/channel_converter.h create mode 100644 services/audio_engine/plugin/channel_converter/include/down_mixer.h create mode 100644 services/audio_engine/plugin/channel_converter/src/channel_converter.cpp create mode 100644 services/audio_engine/plugin/channel_converter/src/down_mixer.cpp create mode 100644 services/audio_engine/plugin/resample/include/audio_proresampler.h create mode 100644 services/audio_engine/plugin/resample/include/audio_proresampler_process.h create mode 100644 services/audio_engine/plugin/resample/include/resampler.h create mode 100644 services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp create mode 100644 services/audio_engine/plugin/resample/proresampler/audio_proresampler_process.c create mode 100644 services/audio_engine/simd/SimdUtils.cpp create mode 100644 services/audio_engine/simd/SimdUtils.h create mode 100644 services/audio_engine/test/unittest/BUILD.gn create mode 100644 services/audio_engine/test/unittest/common/hpae_audio_service_callback_unit_test.h create mode 100644 services/audio_engine/test/unittest/common/hpae_manager_unit_test.h create mode 100644 services/audio_engine/test/unittest/common/test_case_common.cpp create mode 100644 services/audio_engine/test/unittest/common/test_case_common.h create mode 100644 services/audio_engine/test/unittest/dfx/hpae_dfx_tree_test.cpp create mode 100644 services/audio_engine/test/unittest/manager/hpae_audio_service_callback_unit_test.cpp create mode 100644 services/audio_engine/test/unittest/manager/hpae_capturer_manager_test.cpp create mode 100644 services/audio_engine/test/unittest/manager/hpae_inner_capturer_unit_test.cpp create mode 100644 services/audio_engine/test/unittest/manager/hpae_manager_test.cpp create mode 100644 services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_gain_node_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_mixer_node_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_output_cluster_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_pcm_buffer_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_pcm_process_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_process_cluster_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_resample_node_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_sink_input_node_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_sink_output_node_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_source_input_cluster_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_source_input_node_test.cpp create mode 100644 services/audio_engine/test/unittest/node/hpae_source_output_node_test.cpp create mode 100644 services/audio_engine/test/unittest/resource/ohos_test.xml create mode 100644 services/audio_engine/utils/high_resolution_timer.h create mode 100644 services/audio_engine/utils/hpae_format_convert.cpp create mode 100644 services/audio_engine/utils/hpae_format_convert.h create mode 100644 services/audio_engine/utils/hpae_no_lock_queue.cpp create mode 100644 services/audio_engine/utils/hpae_no_lock_queue.h create mode 100644 services/audio_engine/utils/hpae_pcm_dumper.cpp create mode 100644 services/audio_engine/utils/hpae_pcm_dumper.h diff --git a/services/audio_engine/BUILD.gn b/services/audio_engine/BUILD.gn new file mode 100644 index 0000000000..5c6bc4256a --- /dev/null +++ b/services/audio_engine/BUILD.gn @@ -0,0 +1,307 @@ +# Copyright (c) 2025 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") + + +ohos_shared_library("audio_engine_utils") { + stack_protector_ret = true + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + install_enable = true + + sources = [ + "utils/hpae_format_convert.cpp", + "utils/hpae_no_lock_queue.cpp", + "utils/hpae_pcm_dumper.cpp", + "dfx/hpae_dfx_tree.cpp", + ] + + include_dirs = [ + "utils", + "dfx", + "buffer", + "manager/include", + "../audio_service/server/include", + "../../interfaces/inner_api/native/audiocommon/include", + "../../frameworks/native/audioutils/include", + ] + + cflags = [ + "-Wall", + "-Werror", + "-D_FORTIFY_SOURCE=2 -O2", + ] + + deps = [ + "../../frameworks/native/audioutils:audio_utils", + ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + subsystem_name = "multimedia" + part_name = "audio_framework" +} + +ohos_shared_library("audio_engine_resample") { + stack_protector_ret = true + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + install_enable = true + + sources = [ + "plugin/resample/proresampler/audio_proresampler.cpp", + "plugin/resample/proresampler/audio_proresampler_process.c", + "plugin/channel_converter/src/channel_converter.cpp", + "plugin/channel_converter/src/down_mixer.cpp", + "plugin/bitdepth_converter/bitdepth_converter.c" + ] + + include_dirs = [ + "plugin/resample/include", + "../../interfaces/inner_api/native/audiocommon/include", + "plugin/channel_converter/include", + "pulgin/bitdepth_converter" + ] + + cflags = [ + "-Wall", + "-Werror", + "-D_FORTIFY_SOURCE=2 -O2", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + subsystem_name = "multimedia" + part_name = "audio_framework" +} + +ohos_shared_library("audio_engine_simd") { + stack_protector_ret = true + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + install_enable = true + + sources = [ + "simd/SimdUtils.cpp", + ] + + include_dirs = [ + "simd", + ] + + cflags = [ + "-Wall", + "-Werror", + "-D_FORTIFY_SOURCE=2 -O2", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + subsystem_name = "multimedia" + part_name = "audio_framework" +} + +ohos_shared_library("audio_engine_buffer") { + stack_protector_ret = true + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + install_enable = true + + sources = [ + "buffer/hpae_pcm_buffer.cpp", + "buffer/hpae_pcm_process.cpp", + ] + + include_dirs = [ + "buffer", + "simd", + "../../interfaces/inner_api/native/audiocommon/include", + ] + + cflags = [ + "-Wall", + "-Werror", + "-D_FORTIFY_SOURCE=2 -O2", + ] + + deps = [ + ":audio_engine_simd", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + subsystem_name = "multimedia" + part_name = "audio_framework" +} + +config("audio_engine_node_config") { + include_dirs = [ + "node/include", + "manager/include", + "buffer", + "simd", + "utils", + "dfx", + "plugin/resample/include", + "plugin/channel_converter/include", + "plugin/bitdepth_converter", + "../audio_service/common/include", + "../audio_service/server/include", + "../audio_policy/util/include", + "../../frameworks/native/audioeffect/include", + "../../interfaces/inner_api/native/audiocommon/include", + "../../frameworks/native/hdiadapter_new/include", + ] + + cflags = [ + "-Wall", + "-Werror", + "-D_FORTIFY_SOURCE=2 -O2", + ] + cflags += [ "-Os" ] + cflags += [ "-DENABLE_HOOK_PCM"] + cflags += [ "-DENABLE_HIDUMP_DFX"] + cflags_cc = cflags +} + +ohos_shared_library("audio_engine_node") { + stack_protector_ret = true + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + install_enable = true + + configs = [ ":audio_engine_node_config" ] + + sources = [ + "node/src/hpae_mixer_node.cpp", + "node/src/hpae_plugin_node.cpp", + "node/src/hpae_sink_input_node.cpp", + "node/src/hpae_sink_output_node.cpp", + "node/src/hpae_source_output_node.cpp", + "node/src/hpae_source_input_node.cpp", + "node/src/hpae_render_effect_node.cpp", + "node/src/hpae_resample_node.cpp", + "node/src/hpae_gain_node.cpp", + "node/src/hpae_node_common.cpp", + "node/src/hpae_process_cluster.cpp", + "node/src/hpae_output_cluster.cpp", + "node/src/hpae_source_input_cluster.cpp", + "node/src/hpae_source_process_cluster.cpp", + "node/src/hpae_capture_effect_node.cpp", + "node/src/hpae_audio_format_converter_node.cpp", + "node/src/hpae_inner_cap_sink_node.cpp", + "node/src/hpae_offload_sinkoutput_node.cpp", + ] + + deps = [ + ":audio_engine_simd", + ":audio_engine_buffer", + ":audio_engine_utils", + ":audio_engine_resample", + "../audio_service:audio_common", + "../audio_policy:audio_foundation", + "../../frameworks/native/audioeffect:audio_effect", + "../../frameworks/native/audioutils:audio_utils", + "../../frameworks/native/hdiadapter_new:hdiadapter_new", + "../../frameworks/native/audioutils:audio_utils", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + subsystem_name = "multimedia" + part_name = "audio_framework" +} + +ohos_shared_library("audio_engine_manager") { + stack_protector_ret = true + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + install_enable = true + + configs = [ ":audio_engine_node_config" ] + + include_dirs = [ + "manager/include", + "../audio_policy/server/include/service/common", + "../../frameworks/native/audioeffect/include", + "../../frameworks/native/audioschedule/include", + ] + + sources = [ + "manager/src/hpae_manager.cpp", + "manager/src/hpae_capturer_manager.cpp", + "manager/src/hpae_policy_manager.cpp", + "manager/src/hpae_renderer_manager.cpp", + "manager/src/hpae_signal_process_thread.cpp", + "manager/src/i_hpae_manager.cpp", + "manager/src/hpae_inner_capturer_manager.cpp", + "manager/src/hpae_offload_renderer_manager.cpp", + "manager/src/i_hpae_renderer_manager.cpp", + ] + + deps = [ + ":audio_engine_utils", + ":audio_engine_node", + "../audio_policy:audio_foundation", + "../../frameworks/native/audioeffect:audio_effect", + "../../frameworks/native/audioschedule:audio_schedule", + "../../frameworks/native/audioutils:audio_utils", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + subsystem_name = "multimedia" + part_name = "audio_framework" +} \ No newline at end of file diff --git a/services/audio_engine/buffer/hpae_pcm_buffer.cpp b/services/audio_engine/buffer/hpae_pcm_buffer.cpp new file mode 100644 index 0000000000..b454a9c695 --- /dev/null +++ b/services/audio_engine/buffer/hpae_pcm_buffer.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2025 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 "HpaePcmBuffer" +#endif + +#include "securec.h" +#include "SimdUtils.h" +#include "hpae_pcm_buffer.h" +#include "audio_engine_log.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaePcmBuffer::HpaePcmBuffer(PcmBufferInfo &pcmBufferInfo) : pcmBufferInfo_(pcmBufferInfo) +{ + InitPcmProcess(); +} + +HpaePcmBuffer &HpaePcmBuffer::operator=(HpaePcmBuffer &other) +{ + if (this != &other) { + pcmBufferInfo_ = other.pcmBufferInfo_; + InitPcmProcess(); + memcpy_s(GetPcmDataBuffer(), bufferByteSize_, other.GetPcmDataBuffer(), bufferByteSize_); + } + return *this; +} + +HpaePcmBuffer::HpaePcmBuffer(HpaePcmBuffer &&other) +{ + pcmBufferInfo_ = other.pcmBufferInfo_; + bufferByteSize_ = other.bufferByteSize_; + bufferFloatSize_ = other.bufferFloatSize_; + pcmDataBuffer_ = std::move(other.pcmDataBuffer_); + pcmProcessVec_ = std::move(other.pcmProcessVec_); + other.pcmBufferInfo_.frames = 0; + other.bufferByteSize_ = 0; + other.bufferFloatSize_ = 0; +} + +void HpaePcmBuffer::InitPcmProcess() +{ + size_t ch = GetChannelCount(); + size_t frameLen = GetFrameLen(); + size_t frames = GetFrames(); + size_t addBytes = MEMORY_ALIGN_BYTE_NUM - (frameLen * sizeof(float) * ch) % MEMORY_ALIGN_BYTE_NUM; + frameByteSize_ = frameLen * sizeof(float) * ch + addBytes; + frameFloatSize_ = frameByteSize_ / sizeof(float); + bufferByteSize_ = frameByteSize_ * frames; + bufferFloatSize_ = frameFloatSize_ * frames; + frameSample_ = frameLen * ch; + pcmDataBuffer_.resize(bufferFloatSize_); + readPos_.store(0); + writePos_.store(0); + curFrames_.store(0); + pcmProcessVec_.clear(); + pcmProcessVec_.reserve(frames); + float *itr = pcmDataBuffer_.data(); + for (size_t i = 0; i < frames; ++i) { + pcmProcessVec_.push_back(HpaePcmProcess(itr, frameSample_)); + itr += frameFloatSize_; + } +} + +HpaePcmBuffer &HpaePcmBuffer::operator+=(HpaePcmBuffer &other) +{ + for (size_t i = 0; i < pcmProcessVec_.size(); ++i) { + pcmProcessVec_[i] += other[i]; + } + return *this; +} + +HpaePcmBuffer &HpaePcmBuffer::operator-=(HpaePcmBuffer &other) +{ + for (size_t i = 0; i < pcmProcessVec_.size(); ++i) { + pcmProcessVec_[i] -= other[i]; + } + return *this; +} + +HpaePcmBuffer &HpaePcmBuffer::operator*=(HpaePcmBuffer &other) +{ + for (size_t i = 0; i < pcmProcessVec_.size(); ++i) { + pcmProcessVec_[i] *= other[i]; + } + return *this; +} + +HpaePcmBuffer &HpaePcmBuffer::operator=(const std::vector> &other) +{ + for (size_t i = 0; i < other.size() && i < pcmProcessVec_.size(); ++i) { + if (IsMultiFrames()) { + if (curFrames_.load() < GetFrames()) { + pcmProcessVec_[i + writePos_.load()] = other[i]; + writePos_.store((writePos_.load() + 1) % GetFrames()); + curFrames_.fetch_add(1); + } else { + AUDIO_WARNING_LOG("HpaePcmBuffer::operator=, frames is full index = %{public}zu", i); + } + } else { + pcmProcessVec_[i] = other[i]; + } + } + return *this; +} + +HpaePcmBuffer &HpaePcmBuffer::operator=(const std::vector &other) +{ + if (IsMultiFrames()) { + if (curFrames_.load() < GetFrames()) { + pcmProcessVec_[writePos_.load()] = other; + writePos_.store((writePos_.load() + 1) % GetFrames()); + curFrames_.fetch_add(1); + } else { + AUDIO_WARNING_LOG("HpaePcmBuffer::operator=, frames is full"); + } + } else { + pcmProcessVec_[0] = other; + } + return *this; +} + +void HpaePcmBuffer::Reset() +{ + for (HpaePcmProcess &pcmProc : pcmProcessVec_) { + pcmProc.Reset(); + } +} + +bool HpaePcmBuffer::GetFrameData(std::vector &frameData) +{ + if (!IsMultiFrames()) { + return false; + } + + if (curFrames_.load() <= 0) { + AUDIO_WARNING_LOG("GetFrameData vector frames is empty"); + return false; + } + int32_t ret = memcpy_s(frameData.data(), + sizeof(float) * frameData.size(), + pcmProcessVec_[readPos_.load()].begin(), + frameSample_ * sizeof(float)); + if (ret != 0) { + return false; + } + readPos_.store((readPos_.load() + 1) % GetFrames()); + curFrames_.fetch_sub(1); + return true; +} +// frameData is not MultiFrames +bool HpaePcmBuffer::GetFrameData(HpaePcmBuffer &frameData) +{ + if (!IsMultiFrames() || frameData.IsMultiFrames()) { + return false; + } + + if (curFrames_.load() <= 0) { + AUDIO_WARNING_LOG("GetFrameData HpaePcmBuffer frames is empty"); + return false; + } + memcpy_s(frameData.GetPcmDataBuffer(), + sizeof(float) * frameData.Size(), + pcmProcessVec_[readPos_.load()].begin(), + frameSample_ * sizeof(float)); + readPos_.store((readPos_.load() + 1) % GetFrames()); + curFrames_.fetch_sub(1); + return true; +} + +bool HpaePcmBuffer::PushFrameData(std::vector &frameData) +{ + if (!IsMultiFrames()) { + return false; + } + + if (curFrames_.load() >= GetFrames()) { + AUDIO_WARNING_LOG("PushFrameData vector frames is full"); + return false; + } + memcpy_s(pcmProcessVec_[writePos_.load()].begin(), frameByteSize_, + frameData.data(), sizeof(float) * frameData.size()); + writePos_.store((writePos_.load() + 1) % GetFrames()); + curFrames_.fetch_add(1); + return true; +} + +bool HpaePcmBuffer::PushFrameData(HpaePcmBuffer &frameData) +{ + if (!IsMultiFrames() || frameData.IsMultiFrames()) { + return false; + } + + if (curFrames_.load() >= GetFrames()) { + AUDIO_WARNING_LOG("PushFrameData HpaePcmBuffer frames is full"); + return false; + } + memcpy_s(pcmProcessVec_[writePos_.load()].begin(), frameByteSize_, + frameData.GetPcmDataBuffer(), frameData.Size()); + writePos_.store((writePos_.load() + 1) % GetFrames()); + curFrames_.fetch_add(1); + return true; +} + +bool HpaePcmBuffer::StoreFrameData(HpaePcmBuffer &frameData) +{ + if (!IsMultiFrames() || frameData.IsMultiFrames()) { + return false; + } + + memcpy_s(pcmProcessVec_[writePos_.load()].begin(), frameByteSize_, + frameData.GetPcmDataBuffer(), frameData.Size()); + writePos_.store((writePos_.load() + 1) % GetFrames()); + readPos_.store((readPos_.load() + 1) % GetFrames()); + return true; +} + +size_t HpaePcmBuffer::RewindBuffer(size_t frames) +{ + if (!IsMultiFrames()) { + return 0; + } + frames = curFrames_.load() + frames > GetFrames() ? GetFrames() - curFrames_.load() : frames; + readPos_.store((readPos_.load() - frames + GetFrames()) % GetFrames()); + curFrames_.fetch_add(frames); + return frames; +} + +bool HpaePcmBuffer::UpdateReadPos(size_t readPos) +{ + readPos_.store(readPos); + return true; +} + +bool HpaePcmBuffer::UpdateWritePos(size_t writePos) +{ + writePos_.store(writePos); + return true; +} + +void HpaePcmBuffer::SetBufferValid(bool valid) +{ + pcmBufferInfo_.isValid = valid; +} + +size_t HpaePcmBuffer::GetCurFrames() const +{ + return curFrames_.load(); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/buffer/hpae_pcm_buffer.h b/services/audio_engine/buffer/hpae_pcm_buffer.h new file mode 100644 index 0000000000..b2bd7ff9f7 --- /dev/null +++ b/services/audio_engine/buffer/hpae_pcm_buffer.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2025 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 HPAE_PCM_BUFFER_H +#define HPAE_PCM_BUFFER_H +#include +#include +#include +#include +#include "hpae_pcm_process.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr size_t MEMORY_ALIGN_BYTE_NUM = 64; + +enum HpaeSourceBufferType { + HPAE_SOURCE_BUFFER_TYPE_DEFAULT, + HPAE_SOURCE_BUFFER_TYPE_MIC, + HPAE_SOURCE_BUFFER_TYPE_EC, + HPAE_SOURCE_BUFFER_TYPE_MICREF, +}; + +// redefine allocator to ensure memory alignment +template +class AlignedAllocator : public std::allocator { +public: + using pointer = T *; + using size_type = size_t; + + pointer allocate(size_type n) + { + void *ptr = std::aligned_alloc(Alignment, n * sizeof(T)); + return static_cast(ptr); + } + + void deallocate(pointer p, size_type n) + { + std::free(p); + } +}; + +struct PcmBufferInfo { + PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1) + : ch(ch1), frameLen(frameLen1), rate(rate1) + {} + PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1, uint64_t channelLayout1) + : ch(ch1), frameLen(frameLen1), rate(rate1), channelLayout(channelLayout1) + {} + PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1, uint64_t channelLayout1, + uint32_t frames1, bool isMultiFrames) + : ch(ch1), frameLen(frameLen1), rate(rate1), channelLayout(channelLayout1), frames(frames1), + isMultiFrames(isMultiFrames) + {} + PcmBufferInfo() = default; + uint32_t ch; + uint32_t frameLen; + uint32_t rate; + uint64_t channelLayout = 0; + uint32_t frames = 1; + bool isMultiFrames = false; + bool isValid = true; +}; + +// todo: multithread access? +class HpaePcmBuffer { +public: + HpaePcmBuffer() = delete; + explicit HpaePcmBuffer(PcmBufferInfo &pcmBufferInfo); + HpaePcmBuffer(HpaePcmBuffer &&other); + HpaePcmBuffer(const HpaePcmBuffer &other) = delete; + ~HpaePcmBuffer() + { + } + HpaePcmBuffer &operator=(HpaePcmBuffer &other); + HpaePcmBuffer &operator=(HpaePcmBuffer &&other) = delete; + + PcmBufferInfo GetPcmBufferInfo() const + { + return pcmBufferInfo_; + } + + uint32_t GetChannelCount() const + { + return pcmBufferInfo_.ch; + } + + uint32_t GetFrameLen() const + { + return pcmBufferInfo_.frameLen; + } + + uint32_t GetSampleRate() const + { + return pcmBufferInfo_.rate; + } + + bool IsMultiFrames() const + { + return pcmBufferInfo_.isMultiFrames; + } + + bool IsValid() const + { + return pcmBufferInfo_.isValid; + } + + uint64_t GetChannelLayout() const + { + return pcmBufferInfo_.channelLayout; + } + + void ReConfig(const PcmBufferInfo &pcmBufferInfo) + { + pcmBufferInfo_ = pcmBufferInfo; + InitPcmProcess(); + } + + bool GetFrameData(std::vector &frameData); + bool GetFrameData(HpaePcmBuffer &frameData); + bool PushFrameData(std::vector &frameData); + bool PushFrameData(HpaePcmBuffer &frameData); + // store history frame for offload + bool StoreFrameData(HpaePcmBuffer &frameData); + // rewind history frame for offload, return frames that rewinded + size_t RewindBuffer(size_t frames); + + HpaePcmProcess &operator[](size_t index) + { + return pcmProcessVec_[index]; + } + + const HpaePcmProcess &operator[](size_t index) const + { + return pcmProcessVec_[index]; + } + + size_t Size() const + { + return bufferByteSize_; + } + + size_t GetFrames() const + { + return pcmBufferInfo_.frames; + } + + size_t GetReadPos() const + { + return readPos_.load(); + } + + size_t GetWritePos() const + { + return writePos_.load(); + } + + bool UpdateReadPos(size_t readPos); + bool UpdateWritePos(size_t writePos); + void SetBufferValid(bool valid); + size_t GetCurFrames() const; + + HpaePcmBuffer &operator=(const std::vector> &other); + HpaePcmBuffer &operator=(const std::vector &other); + + HpaePcmBuffer &operator+=(HpaePcmBuffer &other); + HpaePcmBuffer &operator-=(HpaePcmBuffer &other); + HpaePcmBuffer &operator*=(HpaePcmBuffer &other); + void Reset(); + + std::vector::iterator begin() + { + return pcmProcessVec_.begin(); + } + + std::vector::iterator end() + { + return pcmProcessVec_.end(); + } + + std::vector::const_iterator begin() const + { + return pcmProcessVec_.begin(); + } + + std::vector::const_iterator end() const + { + return pcmProcessVec_.end(); + } + + float *GetPcmDataBuffer() + { + return pcmDataBuffer_.data(); + } + + size_t GetFrameSample() + { + return frameSample_; + } + + HpaeSourceBufferType GetSourceBufferType() + { + return sourceBufferType_; + } + + void SetSourceBufferType(HpaeSourceBufferType type) + { + sourceBufferType_ = type; + } + +private: + void InitPcmProcess(); + + // todo: add err to deal with operator override + std::vector> pcmDataBuffer_; + size_t bufferFloatSize_; + size_t bufferByteSize_; + size_t frameFloatSize_; + size_t frameByteSize_; + size_t frameSample_; + std::atomic readPos_; + std::atomic writePos_; + std::atomic curFrames_; + std::vector pcmProcessVec_; + PcmBufferInfo pcmBufferInfo_; + HpaeSourceBufferType sourceBufferType_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/buffer/hpae_pcm_process.cpp b/services/audio_engine/buffer/hpae_pcm_process.cpp new file mode 100644 index 0000000000..10df391479 --- /dev/null +++ b/services/audio_engine/buffer/hpae_pcm_process.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 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 "HpaePcmProcess" +#endif + +#include "hpae_pcm_process.h" +#include "SimdUtils.h" +#include "audio_engine_log.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaePcmProcess &HpaePcmProcess::operator = (const std::vector& other) +{ + errNo_ = memcpy_s(pcmDataPtr_, sizeof(float) * size_, other.data(), sizeof(float) * other.size()); + CHECK_AND_RETURN_RET_LOG(errNo_ == 0, *this, "memcpy_s failed, errNo: %{public}d", errNo_); + return *this; +} + +HpaePcmProcess &HpaePcmProcess::operator = (const HpaePcmProcess& other) +{ + if (this != &other) { + errNo_ = memcpy_s(pcmDataPtr_, sizeof(float) * size_, other.begin(), sizeof(float) * other.Size()); + CHECK_AND_RETURN_RET_LOG(errNo_ == 0, *this, "memcpy_s failed, errNo: %{public}d", errNo_); + } + return *this; +} + +HpaePcmProcess &HpaePcmProcess::operator+=(const HpaePcmProcess &other) +{ + float *curData = begin(); + const float *otherData = other.begin(); + SimdPointByPointAdd(size_, otherData, curData, curData); + return *this; +} + +HpaePcmProcess &HpaePcmProcess::operator-=(const HpaePcmProcess &other) +{ + float *curData = begin(); + const float *otherData = other.begin(); + SimdPointByPointSub(size_, curData, otherData, curData); + return *this; +} + +HpaePcmProcess &HpaePcmProcess::operator*=(const HpaePcmProcess &other) +{ + float *curData = begin(); + const float *otherData = other.begin(); + SimdPointByPointMul(size_, otherData, curData, curData); + return *this; +} + +void HpaePcmProcess::Reset() +{ + errNo_ = memset_s(begin(), sizeof(float) * size_, 0, sizeof(float) * size_); + CHECK_AND_RETURN_LOG(errNo_ == 0, "memcpy_s failed, errNo: %{public}d", errNo_); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/buffer/hpae_pcm_process.h b/services/audio_engine/buffer/hpae_pcm_process.h new file mode 100644 index 0000000000..6f4cc4ec82 --- /dev/null +++ b/services/audio_engine/buffer/hpae_pcm_process.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025 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 HPAE_PCM_PROCESS_H +#define HPAE_PCM_PROCESS_H +#include +#include "securec.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaePcmProcess { +public: + HpaePcmProcess(float *begin, size_t size) : pcmDataPtr_(begin), size_(size) {} + + float &operator[](size_t index) + { + return *(pcmDataPtr_ + index); + } + + const float &operator[](size_t index) const + { + return *(pcmDataPtr_ + index); + } + + size_t Size() const + { + return size_; + } + + float *begin() + { + return pcmDataPtr_; + } + + float *end() + { + return pcmDataPtr_ + size_; + } + + const float *begin() const + { + return pcmDataPtr_; + } + + const float *end() const + { + return pcmDataPtr_ + size_; + } + + HpaePcmProcess(const HpaePcmProcess &other) = default; + + HpaePcmProcess &operator = (const HpaePcmProcess &other); + + HpaePcmProcess &operator = (const std::vector& other); + + HpaePcmProcess &operator += (const HpaePcmProcess &other); + + HpaePcmProcess &operator -= (const HpaePcmProcess &other); + + HpaePcmProcess &operator *= (const HpaePcmProcess &other); + + void Reset() ; + + int32_t GetErrNo() + { + int32_t tmpErrNo = errNo_; + errNo_ = 0; + return tmpErrNo; + } + +private: + int32_t errNo_; + float* const pcmDataPtr_; + const size_t size_; +}; +}}} +#endif // HPAE_PCM_PROCESS_H \ No newline at end of file diff --git a/services/audio_engine/dfx/hpae_dfx_tree.cpp b/services/audio_engine/dfx/hpae_dfx_tree.cpp new file mode 100644 index 0000000000..0e3a9f63b2 --- /dev/null +++ b/services/audio_engine/dfx/hpae_dfx_tree.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2025 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 "HpaeDfxTree" +#endif +#include "hpae_dfx_tree.h" +#include +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +DfxTreeNode *HpaeDfxTree::FindDfxNode(DfxTreeNode *currentNode, const uint32_t nodeId) +{ + if (!currentNode) { + return nullptr; + } + std::queue q; + q.push(currentNode); + while (!q.empty()) { + DfxTreeNode *node = q.front(); + q.pop(); + if (node->nodeInfo_.nodeId == nodeId) { + return node; + } + for (auto &child : node->children_) { + q.push(child); + } + } + return nullptr; +} + +DfxTreeNode *HpaeDfxTree::FindDfxParent(DfxTreeNode *target) +{ + if (!root_ || target == root_) { + return nullptr; + } + std::queue q; + q.push(root_); + while (!q.empty()) { + DfxTreeNode *node = q.front(); + q.pop(); + for (auto &child : node->children_) { + if (child->nodeInfo_.nodeId == target->nodeInfo_.nodeId) { + return node; + } + q.push(child); + } + } + return nullptr; +} + +bool HpaeDfxTree::Insert(const uint32_t parentNodeId, const HpaeDfxNodeInfo &info) +{ + if (!root_) { + AUDIO_INFO_LOG("Insert Root is null"); + root_ = new DfxTreeNode(info); + return true; + } + DfxTreeNode *parent = FindDfxNode(root_, parentNodeId); + if (!parent) { + AUDIO_INFO_LOG("Insert can not find correct parent"); + return false; + } + parent->children_.push_back(new DfxTreeNode(info)); + return true; +} + +bool HpaeDfxTree::Remove(const uint32_t nodeId) +{ + if (!root_) { + AUDIO_INFO_LOG("Remove Root is null"); + return false; + } + DfxTreeNode *nodeToRemove = FindDfxNode(root_, nodeId); + if (!nodeToRemove) { + return false; + } + + if (nodeToRemove == root_) { + delete root_; + root_ = nullptr; + return true; + } + + DfxTreeNode *parent = FindDfxParent(nodeToRemove); + if (!parent) { + return false; + } + // Remove from parent's children + auto &children = parent->children_; + auto it = find(children.begin(), children.end(), nodeToRemove); + if (it != children.end()) { + children.erase(it); + delete nodeToRemove; + return true; + } + return false; +} + +std::vector> HpaeDfxTree::LevelOrderTraversal() +{ + std::vector> result; + if (!root_) { + return result; + } + std::queue q; + q.push(root_); + while (!q.empty()) { + int32_t levelSize = q.size(); + std::vector curLevelResult; + for (int32_t i = 0; i < levelSize; ++i) { + DfxTreeNode *node = q.front(); + q.pop(); + curLevelResult.push_back(node->nodeInfo_); + for (auto &child : node->children_) { + q.push(child); + } + } + result.push_back(curLevelResult); + } + return result; +} + +void HpaeDfxTree::PrintNodeInfo(std::string &outStr, HpaeDfxNodeInfo &nodeInfo) +{ + outStr = outStr + nodeInfo.nodeName + ": " + "id[" + std::to_string(nodeInfo.sessionId) + "],"; + outStr = outStr + "rate[" + std::to_string(nodeInfo.samplingRate) + "],"; + outStr = outStr + "ch[" + std::to_string(nodeInfo.channels) + "],"; + outStr = outStr + "bw[" + std::to_string(nodeInfo.format) + "],"; + outStr = outStr + "len[" + std::to_string(nodeInfo.frameLen) + "],"; + outStr = outStr + "scene[" + std::to_string(nodeInfo.sceneType) + "] \n"; +} + +void HpaeDfxTree::PrintSubTree(DfxTreeNode *node, const std::string &prefix, bool isLastChild, std::string &outStr) +{ + if (!node) + return; + + outStr = outStr + prefix; + outStr = outStr + (isLastChild ? "|___ " : "|--- "); + PrintNodeInfo(outStr, node->nodeInfo_); + std::string newPrefix = prefix + (isLastChild ? " " : "| "); + for (size_t i = 0; i < node->children_.size(); ++i) { + bool childIsLast = (i == node->children_.size() - 1); + PrintSubTree(node->children_[i], newPrefix, childIsLast, outStr); + } +} + +void HpaeDfxTree::PrintTree(std::string &outStr) +{ + if (!root_) { + return; + } + PrintNodeInfo(outStr, root_->nodeInfo_); + for (size_t i = 0; i < root_->children_.size(); ++i) { + bool isLast = (i == root_->children_.size() - 1); + PrintSubTree(root_->children_[i], "", isLast, outStr); + } +} + +void HpaeDfxTree::UpdateNodeInfo(uint32_t NodeId, const HpaeDfxNodeInfo &nodeInfo) +{ + if (root_ == nullptr) { + AUDIO_WARNING_LOG("Hidumper dfx tree is empty!"); + return; + } + DfxTreeNode *target = FindDfxNode(root_, NodeId); + if (target == nullptr) { + AUDIO_WARNING_LOG("Cannot find Node Id: %{public}d", NodeId); + return; + } + target->nodeInfo_ = nodeInfo; +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/dfx/hpae_dfx_tree.h b/services/audio_engine/dfx/hpae_dfx_tree.h new file mode 100644 index 0000000000..94cf975042 --- /dev/null +++ b/services/audio_engine/dfx/hpae_dfx_tree.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 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 HPAE_DFX_TREE_H +#define HPAE_DFX_TREE_H +#include "hpae_define.h" +#include +#include +#include +#include + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr uint32_t MIN_START_NODE_ID = 100; +class DfxTreeNode { +public: + DfxTreeNode(HpaeDfxNodeInfo val) : nodeInfo_(val) + {} + ~DfxTreeNode() + { + for (auto child : children_) { + delete child; + } + } + HpaeDfxNodeInfo nodeInfo_; + std::vector children_; +}; + +class HpaeDfxTree { +public: + HpaeDfxTree() : root_(nullptr) + {} + ~HpaeDfxTree() + { + delete root_; + } + std::vector> LevelOrderTraversal(); + bool Insert(const uint32_t parentNodeId, const HpaeDfxNodeInfo &info); + bool Remove(const uint32_t nodeId); + void PrintTree(std::string &outStr); + void UpdateNodeInfo(uint32_t NodeId, const HpaeDfxNodeInfo &nodeInfo); +private: + DfxTreeNode *FindDfxNode(DfxTreeNode *currentNode, const uint32_t nodeId); + DfxTreeNode *FindDfxParent(DfxTreeNode *target); + void PrintSubTree(DfxTreeNode *node, const std::string &prefix, bool isLastChild, std::string &outStr); + void PrintNodeInfo(std::string &outStr, HpaeDfxNodeInfo &nodeInfo); + DfxTreeNode *root_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/audio_service_hpae_callback.h b/services/audio_engine/manager/include/audio_service_hpae_callback.h new file mode 100644 index 0000000000..137aeb090b --- /dev/null +++ b/services/audio_engine/manager/include/audio_service_hpae_callback.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 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 AUDIO_SERVICE_HAPE_CALLBACK_H +#define AUDIO_SERVICE_HAPE_CALLBACK_H +#include "audio_effect.h" +namespace OHOS { +namespace AudioStandard { +class AudioServiceHpaeCallback { +public: + virtual void OnOpenAudioPortCb(int32_t portId) = 0; + + virtual void OnCloseAudioPortCb(int32_t result) = 0; + + virtual void OnSetSinkMuteCb(int32_t result) = 0; + + virtual void OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) = 0; + + virtual void OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) = 0; + + virtual void OnGetAllSinksCb(int32_t result, std::vector &sinks) = 0; + + virtual void OnMoveSinkInputByIndexOrNameCb(int32_t result) = 0; + + virtual void OnMoveSourceOutputByIndexOrNameCb(int32_t result) = 0; + + virtual void OnSetSourceOutputMuteCb(int32_t result) = 0; + + virtual void OnGetAudioEffectPropertyCbV3(int32_t result) = 0; + + virtual void OnGetAudioEffectPropertyCb(int32_t result) = 0; + + virtual void OnGetAudioEnhancePropertyCbV3(int32_t result) = 0; + + virtual void OnGetAudioEnhancePropertyCb(int32_t result) = 0; + + virtual void HandleSourceAudioStreamRemoved(uint32_t sessionId) = 0; + + virtual ~AudioServiceHpaeCallback() + {} +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_SERVICE_HAPE_CALLBACK_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/audio_service_hpae_dump_callback.h b/services/audio_engine/manager/include/audio_service_hpae_dump_callback.h new file mode 100644 index 0000000000..d39bcd2fda --- /dev/null +++ b/services/audio_engine/manager/include/audio_service_hpae_dump_callback.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 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 AUDIO_SERVICE_HAPE_DUMP_CALLBACK_H +#define AUDIO_SERVICE_HAPE_DUMP_CALLBACK_H +#include +namespace OHOS { +namespace AudioStandard { +class AudioServiceHpaeDumpCallback { +public: + virtual void OnDumpSinkInfoCb(std::string& dumpStr, int32_t result) = 0; + virtual void OnDumpSourceInfoCb(std::string &dumpStr, int32_t result) = 0; + + virtual ~AudioServiceHpaeDumpCallback() + {} +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_SERVICE_HAPE_CALLBACK_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_capture_move_info.h b/services/audio_engine/manager/include/hpae_capture_move_info.h new file mode 100644 index 0000000000..f42cab99a9 --- /dev/null +++ b/services/audio_engine/manager/include/hpae_capture_move_info.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 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 HPAE_CAPTURE_MOVE_INFO_H +#define HPAE_CAPTURE_MOVE_INFO_H +#include "hpae_define.h" +#include "hpae_source_output_node.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +struct HpaeCaptureMoveInfo { + uint32_t sessionId; + std::shared_ptr sourceOutputNode; + HpaeCapturerSessionInfo sessionInfo; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif // HPAE_CAPTURE_MOVE_INFO_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_capturer_manager.h b/services/audio_engine/manager/include/hpae_capturer_manager.h new file mode 100644 index 0000000000..6ca9a70206 --- /dev/null +++ b/services/audio_engine/manager/include/hpae_capturer_manager.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025 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 HPAE_CAPTURER_MANAGER_H +#define HPAE_CAPTURER_MANAGER_H +#include +#include +#include +#include +#include +#include +#include "audio_effect.h" +#include "hpae_signal_process_thread.h" +#include "hpae_source_input_node.h" +#include "hpae_source_input_cluster.h" +#include "hpae_source_output_node.h" +#include "hpae_source_process_cluster.h" +#include "hpae_no_lock_queue.h" +#include "i_hpae_capturer_manager.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaeCapturerManager : public IHpaeCapturerManager { +public: + HpaeCapturerManager(HpaeSourceInfo &sourceInfo); + virtual ~HpaeCapturerManager(); + int32_t CreateStream(const HpaeStreamInfo& streamInfo) override; + int32_t DestroyStream(uint32_t sessionId) override; + + int32_t Start(uint32_t sessionId) override; + int32_t Pause(uint32_t sessionId) override; + int32_t Flush(uint32_t sessionId) override; + int32_t Drain(uint32_t sessionId) override; + int32_t Stop(uint32_t sessionId) override; + int32_t Release(uint32_t sessionId) override; + int32_t MoveStream(uint32_t sessionId, const std::string& sourceName) override; + int32_t MoveAllStream(const std::string& sourceName, const std::vector& sessionIds, + bool isMoveAll = true) override; + int32_t SetMute(bool isMute) override; + void Process() override; + void HandleMsg() override; + int32_t Init() override; + int32_t DeInit(bool isMoveDefault = false) override; + bool IsInit() override; + bool IsRunning(void) override; + bool IsMsgProcessing() override; + bool DeactivateThread() override; + + int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) override; + HpaeSourceInfo GetSourceInfo() override; + std::vector GetAllSourceOutputsInfo() override; + + void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) override; + void OnNotifyQueue() override; + + int32_t AddNodeToSource(const HpaeCaptureMoveInfo &moveInfo) override; + int32_t AddAllNodesToSource(const std::vector &moveInfos, bool isConnect) override; + std::string GetThreadName() override; + void SetCaptureId(uint32_t captureId); + int32_t ReloadCaptureManager(const HpaeSourceInfo &sourceInfo) override; + void DumpSourceInfo() override; +private: + int32_t CreateOutputSession(const HpaeStreamInfo &streamInfo); + int32_t DeleteOutputSession(uint32_t sessionId); + int32_t ConnectProcessClusterWithEc(HpaeProcessorType &sceneType); + int32_t ConnectProcessClusterWithMicRef(HpaeProcessorType &sceneType); + int32_t ConnectOutputSession(uint32_t sessionId); + int32_t DisConnectOutputSession(uint32_t sessionId); + void DisConnectSceneClusterFromSourceInputCluster(HpaeProcessorType &sceneType); + void SetSessionState(uint32_t sessionId, CapturerState capturerState); + int32_t PrepareCapturerEc(HpaeNodeInfo &ecNodeInfo); + int32_t PrepareCapturerMicRef(HpaeNodeInfo &micRefNodeInfo); + int32_t InitCapturer(); + void AddSingleNodeToSource(const HpaeCaptureMoveInfo &moveInfo, bool isConnect = true); + void MoveAllStreamToNewSource(const std::string &sourceName, + const std::vector& moveIds, bool isMoveAll); + int32_t CaptureEffectCreate(const HpaeProcessorType &sceneType, const AudioEnhanceScene &enhanceScene); + int32_t CaptureEffectRelease(const HpaeProcessorType &sceneType); + int32_t InitCapturerManager(); + +private: + void SendRequest(Request &&request, bool isInit = false); + HpaeNoLockQueue hpaeNoLockQueue_; + std::unique_ptr hpaeSignalProcessThread_ = nullptr; + std::unordered_map sessionNodeMap_; + std::unordered_map streamInfoMap_; + std::unordered_map> sceneClusterMap_; + std::unordered_map> sourceOutputNodeMap_; + std::unordered_map> sourceInputClusterMap_; + + HpaeSourceInputNodeType mainMicType_; + std::atomic isInit_ = false; + std::atomic isMute_ = false; + HpaeSourceInfo sourceInfo_; + uint32_t captureId_ = 0; + uint32_t renderId_ = 0; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_define.h b/services/audio_engine/manager/include/hpae_define.h new file mode 100644 index 0000000000..786895e6df --- /dev/null +++ b/services/audio_engine/manager/include/hpae_define.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2025 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 HPAE_DEFINE_H +#define HPAE_DEFINE_H +#include "hpae_msg_channel.h" +#include "i_stream.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr uint32_t MILLISECOND_PER_SECOND = 1000; + +struct HpaeSessionInfo { + HpaeStreamInfo streamInfo; + uint32_t state = I_STATUS_IDLE; + std::weak_ptr statusCallback; +}; + + +constexpr int32_t SCENE_TYPE_NUM = 9; + +struct HpaeRenderSessionInfo { + uint32_t sinkInputNodeId; + HpaeProcessorType sceneType = HPAE_SCENE_DEFAULT; + uint32_t state = I_STATUS_IDLE; +}; + +struct HpaeSinkInputInfo { + HpaeRenderSessionInfo rendererSessionInfo; + HpaeNodeInfo nodeInfo; +}; + +struct HpaeSinkInfo { + uint32_t sinkId; + std::string deviceNetId; + std::string deviceClass; + std::string adapterName; + std::string filePath; + std::string deviceName; + size_t frameLen; + AudioSamplingRate samplingRate; + AudioSampleFormat format; + AudioChannel channels; + uint32_t suspendTime = 0; // in ms + uint64_t channelLayout = 0ULL; + int32_t deviceType = 0; + float volume = 0.0f; + uint32_t openMicSpeaker = 0; + uint32_t renderInIdleState = 0; + uint32_t sourceType = 0; + uint32_t offloadEnable = 0; + uint32_t fixedLatency = 0; + uint32_t sinkLatency = 0; +}; + +struct HpaeCapturerSessionInfo { + HpaeProcessorType sceneType = HPAE_SCENE_DEFAULT; + uint32_t state = I_STATUS_IDLE; +}; + +struct HpaeSourceOutputInfo { + HpaeCapturerSessionInfo capturerSessionInfo; + HpaeNodeInfo nodeInfo; +}; + +enum HpaeEcType { + HPAE_EC_TYPE_NONE, + HPAE_EC_TYPE_SAME_ADAPTER, + HPAE_EC_TYPE_DIFF_ADAPTER +}; + +enum HpaeMicRefSwitch { + HPAE_REF_OFF = 0, + HPAE_REF_ON +}; + +struct HpaeSourceInfo { + uint32_t sourceId; + std::string deviceNetId; + std::string deviceClass; + std::string adapterName; + std::string sourceName; + SourceType sourceType; + std::string filePath; + std::string deviceName; + size_t frameLen; + AudioSamplingRate samplingRate; + AudioSampleFormat format; + AudioChannel channels; + uint64_t channelLayout = 0ULL; + int32_t deviceType = 0; + float volume = 0.0f; + HpaeEcType ecType; + size_t ecFrameLen; + std::string ecAdapterName; + AudioSamplingRate ecSamplingRate; + AudioSampleFormat ecFormat; + AudioChannel ecChannels; + HpaeMicRefSwitch micRef; + size_t micRefFrameLen; + AudioSamplingRate micRefSamplingRate; + AudioSampleFormat micRefFormat; + AudioChannel micRefChannels; + uint32_t openMicSpeaker; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS + +#endif // HPAE_DEFINE_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_info.h b/services/audio_engine/manager/include/hpae_info.h new file mode 100644 index 0000000000..53606ea837 --- /dev/null +++ b/services/audio_engine/manager/include/hpae_info.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 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 HPAE_INFO_H +#define HPAE_INFO_H +#include "audio_effect.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +enum HpaeStreamClassType { + HPAE_STREAM_CLASS_TYPE_INVALID = -1, + HPAE_STREAM_CLASS_TYPE_PLAY, + HPAE_STREAM_CLASS_TYPE_RECORD, +}; + +enum HpaeNodeType { + HPAE_NODE_TYPE_INVALID = -1, + HPAE_NODE_TYPE_SOURCE_INPUT, + HPAE_NODE_TYPE_SOURCE_OUTPUT, + HPAE_NODE_TYPE_SINK_INPUT, + HPAE_NODE_TYPE_SINK_OUTPUT, + HPAE_NODE_TYPE_PLUGIN, +}; + +struct HpaeEffectInfo { + StreamUsage streamUsage; + AudioVolumeType volumeType; + AudioEffectScene effectScene; + AudioEffectMode effectMode; + AudioEnhanceScene enhanceScene; + AudioEnhanceMode enhanceMode; +}; + +enum FadeType { + DEFAULT_FADE = 0, // default one frame fade + SHORT_FADE, // short 5ms fade + NONE_FADE // do not fade +}; +struct HpaeStreamInfo { + uint32_t sessionId; + size_t frameLen; + HpaeNodeType nodeType; + AudioStreamType streamType; + FadeType fadeType = NONE_FADE; + AudioPipeType pipeType; + AudioSamplingRate samplingRate; + AudioSampleFormat format; + AudioChannel channels; + uint64_t channelLayout = 0ULL; + HpaeStreamClassType streamClassType; + SourceType sourceType; + int32_t uid = -1; + int32_t pid = 0; + HpaeEffectInfo effectInfo; + std::string deviceName; +}; + +#define GET_SIZE_FROM_FORMAT(format) ((format) != SAMPLE_F32LE ? ((format) + 1) : (4)) +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_inner_capturer_manager.h b/services/audio_engine/manager/include/hpae_inner_capturer_manager.h new file mode 100644 index 0000000000..5148fc6729 --- /dev/null +++ b/services/audio_engine/manager/include/hpae_inner_capturer_manager.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2025 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 HPAE_INNER_CAPTURER_MANAGER_H +#define HPAE_INNER_CAPTURER_MANAGER_H +#include +#include +#include +#include +#include +#include +#include "i_renderer_stream.h" +#include "hpae_signal_process_thread.h" +#include "hpae_sink_input_node.h" +#include "hpae_resample_node.h" +#include "hpae_inner_cap_sink_node.h" +#include "hpae_source_output_node.h" +#include "hpae_source_process_cluster.h" +#include "hpae_msg_channel.h" +#include "hpae_no_lock_queue.h" +#include "i_hpae_renderer_manager.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaeInnerCapturerManager : public IHpaeRendererManager { +public: + HpaeInnerCapturerManager(HpaeSinkInfo &sinkInfo); + ~HpaeInnerCapturerManager(); + int32_t CreateStream(const HpaeStreamInfo &streamInfo) override; + int32_t DestroyStream(uint32_t sessionId) override; + + int32_t Start(uint32_t sessionId) override; + int32_t Pause(uint32_t sessionId) override; + int32_t Flush(uint32_t sessionId) override; + int32_t Drain(uint32_t sessionId) override; + int32_t Stop(uint32_t sessionId) override; + int32_t Release(uint32_t sessionId) override; + int32_t MoveStream(uint32_t sessionId, const std::string &sinkName) override; + int32_t MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, + bool isMoveAll = true) override; + int32_t SuspendStreamManager(bool isSuspend) override; + int32_t SetMute(bool isMute) override; + void Process() override; + void HandleMsg() override; + int32_t Init() override; + int32_t DeInit(bool isMoveDefault = false) override; + bool IsInit() override; + bool IsRunning(void) override; + bool IsMsgProcessing() override; + bool DeactivateThread() override; + int32_t SetClientVolume(uint32_t sessionId, float volume) override; + int32_t SetRate(uint32_t sessionId, int32_t rate) override; + int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) override; + int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) override; + int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) override; + int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) override; + int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + + size_t GetWritableSize(uint32_t sessionId) override; + int32_t UpdateSpatializationState( + uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) override; + int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) override; + std::vector GetAllSinkInputsInfo() override; + int32_t GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) override; + HpaeSinkInfo GetSinkInfo() override; + + void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) override; + void OnFadeDone(uint32_t sessionId, IOperation operation) override; + + int32_t AddNodeToSink(const std::shared_ptr &node) override; + int32_t AddAllNodesToSink( + const std::vector> &sinkInputs, bool isConnect) override; + + int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) override; + std::vector GetAllSourceOutputsInfo() override; + std::string GetThreadName() override; + +private: + void TransStreamInfoToNodeInfoInner(const HpaeStreamInfo &streamInfo, HpaeNodeInfo &nodeInfo); + int32_t CreateRendererInputSessionInner(const HpaeStreamInfo &streamInfo); + int32_t CreateCapturerInputSessionInner(const HpaeStreamInfo &streamInfo); + int32_t DeleteRendererInputSessionInner(uint32_t sessionId); + int32_t DeleteCapturerInputSessionInner(uint32_t sessionId); + int32_t ConnectRendererInputSessionInner(uint32_t sessionId); + int32_t ConnectCapturerOutputSessionInner(uint32_t sessionId); + int32_t DisConnectRendererInputSessionInner(uint32_t sessionId); + int32_t DisConnectCapturerInputSessionInner(uint32_t sessionId); + void SetSessionStateInner(uint32_t sessionId, RendererState renderState); + void SetSessionStateInner(uint32_t sessionId, CapturerState capturerState); + void SendRequestInner(Request &&request, bool isInit = false); + uint32_t GetSinkInputNodeIdInner(); + void AddSingleNodeToSinkInner(const std::shared_ptr &node, bool isConnect = true); + void MoveAllStreamToNewSinkInner(const std::string &sinkName, const std::vector &moveIds, bool isMoveAll); + uint32_t sinkInputNodeCounter_ = 0; + std::atomic isInit_ = false; + std::atomic isMute_ = false; + HpaeSinkInfo sinkInfo_; + HpaeNoLockQueue hpaeNoLockQueue_; + std::shared_ptr hpaeInnerCapSinkNode_ = nullptr; + std::unique_ptr hpaeSignalProcessThread_ = nullptr; + std::unordered_map> sinkInputNodeMap_; + std::unordered_map> sourceOutputNodeMap_; + std::unordered_map> capturerResampleNodeMap_; + std::unordered_map> capturerSceneClusterMap_; + std::unordered_map> rendererSceneClusterMap_; + std::unordered_map capturerSessionNodeMap_; + std::unordered_map rendererSessionNodeMap_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_manager.h b/services/audio_engine/manager/include/hpae_manager.h new file mode 100644 index 0000000000..5dce47f5e7 --- /dev/null +++ b/services/audio_engine/manager/include/hpae_manager.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2025 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 HPAE_MANAGER_H +#define HPAE_MANAGER_H +#include +#include +#include "audio_module_info.h" +#include "hpae_capturer_manager.h" +#include "hpae_renderer_manager.h" +#include "hpae_inner_capturer_manager.h" +#include "hpae_msg_channel.h" +#include "i_hpae_manager.h" +#include "i_hpae_renderer_manager.h" +#include "hpae_policy_manager.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaeManager; + +class HpaeManagerThread { +public: + HpaeManagerThread() : running_(false) + {} + ~HpaeManagerThread(); + void ActivateThread(HpaeManager *hpaeManager); + void DeactivateThread(); + void Run(); + void Notify(); + bool IsRunning() const + { + return running_.load(); + } + bool IsMsgProcessing() const + { + return recvSignal_.load(); + } + +private: + std::atomic running_; + std::atomic recvSignal_; + HpaeManager *m_hpaeManager; + std::condition_variable condition_; + std::mutex mutex_; + std::thread thread_; +}; + +class HpaeManager : public IHpaeManager, public ISendMsgCallback, public std::enable_shared_from_this { +public: + static constexpr std::string_view SPLIT_STREAM_SINK = "libmodule-split-stream-sink.z.so"; + static constexpr std::string_view HDI_SINK = "libmodule-hdi-sink.z.so"; + static constexpr std::string_view HDI_SOURCE = "libmodule-hdi-source.z.so"; + static constexpr std::string_view INNER_CAPTURER_SINK = "libmodule-inner-capturer-sink.z.so"; + HpaeManager(); + ~HpaeManager(); + // sync interface + int32_t Init() override; + int32_t DeInit() override; + int32_t RegisterSerivceCallback(const std::weak_ptr &callback) override; + int32_t RegisterHpaeDumpCallback( AudioServiceHpaeDumpCallback *callback) override; + void DumpSinkInfo(std::string deviceName) override; + void DumpSourceInfo(std::string deviceName) override; + uint32_t OpenAudioPort(const AudioModuleInfo &audioModuleInfo) override; + int32_t CloseAudioPort(int32_t audioHandleIndex) override; + int32_t GetAllSinkInputs() override; + int32_t GetAllSourceOutputs() override; + int32_t MoveSourceOutputByIndexOrName( + uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) override; + int32_t MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) override; + void HandleMsg() override; + bool IsInit() override; + bool IsRunning() override; + bool IsMsgProcessing() override; + // async interface + int32_t SetDefaultSink(std::string name) override; + int32_t SetDefaultSource(std::string name) override; + int32_t SuspendAudioDevice(std::string &audioPortName, bool isSuspend) override; + bool SetSinkMute(const std::string &sinkName, bool isMute, bool isSync = false) override; + int32_t SetSourceOutputMute(int32_t uid, bool setMute) override; + int32_t GetAllSinks() override; + + int32_t GetMsgCount(); + + void Invoke(HpaeMsgCode cmdID, const std::any &args) override; + // play and record stream interface + int32_t CreateStream(const HpaeStreamInfo &streamInfo) override; + int32_t DestroyStream(HpaeStreamClassType streamClassType, uint32_t sessionId) override; + int32_t Start(HpaeStreamClassType streamClassType, uint32_t sessionId) override; + int32_t Pause(HpaeStreamClassType streamClassType, uint32_t sessionId) override; + int32_t Flush(HpaeStreamClassType streamClassType, uint32_t sessionId) override; + int32_t Drain(HpaeStreamClassType streamClassType, uint32_t sessionId) override; + int32_t Stop(HpaeStreamClassType streamClassType, uint32_t sessionId) override; + int32_t Release(HpaeStreamClassType streamClassType, uint32_t sessionId) override; + int32_t RegisterStatusCallback(HpaeStreamClassType streamClassType, uint32_t sessionId, + const std::weak_ptr &callback) override; + // record stream interface + void RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeStreamInfo &streamInfo) override; + // play stream interface + int32_t SetClientVolume(uint32_t sessionId, float volume) override; + int32_t SetRate(uint32_t sessionId, int32_t rate) override; + int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) override; + int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) override; + int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) override; + int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) override; + int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + int32_t SetOffloadPolicy(uint32_t sessionId, int32_t state) override; + size_t GetWritableSize(uint32_t sessionId) override; + int32_t UpdateSpatializationState( + uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) override; + int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) override; + // only interface for unit test + int32_t GetSessionInfo(HpaeStreamClassType streamClassType, uint32_t sessionId, HpaeSessionInfo &sessionInfo); + + // interfaces for render effect + void InitAudioEffectChainManager(const std::vector &effectChains, + const EffectChainManagerParam &effectChainManagerParam, + const std::vector> &effectLibraryList) override; + void SetOutputDeviceSink(int32_t device, const std::string &sinkName) override; + int32_t UpdateSpatializationState(AudioSpatializationState spatializationState) override; + int32_t UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) override; + int32_t SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType) override; + int32_t EffectRotationUpdate(const uint32_t rotationState) override; + int32_t SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume) override; + int32_t SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray) override; + int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) override; + int32_t SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray) override; + int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) override; + void InitHdiState() override; + void UpdateEffectBtOffloadSupported(const bool &isSupported) override; + void UpdateParamExtra(const std::string &mainkey, const std::string &subkey, const std::string &value) override; + // interfaces for capture effect + void InitAudioEnhanceChainManager(const std::vector &enhanceChains, + const EffectChainManagerParam &managerParam, + const std::vector> &enhanceLibraryList) override; + int32_t SetInputDevice( + const uint32_t &captureId, const DeviceType &inputDevice, const std::string &deviceName = "") override; + int32_t SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice) override; + int32_t SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol) override; + int32_t SetMicrophoneMuteInfo(const bool &isMute) override; + int32_t SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol) override; + int32_t SetAudioEnhanceProperty( + const AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; + int32_t GetAudioEnhanceProperty( + AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; + int32_t SetAudioEnhanceProperty( + const AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; + int32_t GetAudioEnhanceProperty( + AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; + void UpdateExtraSceneType( + const std::string &mainkey, const std::string &subkey, const std::string &extraSceneType) override; + +private: + void TransModuleInfoToHpaeSinkInfo(const AudioModuleInfo &audioModuleInfo, HpaeSinkInfo &sinkInfo); + void TransModuleInfoToHpaeSourceInfo(const AudioModuleInfo &audioModuleInfo, HpaeSourceInfo &sourceInfo); + AudioSampleFormat TransFormatFromStringToEnum(std::string format); + int32_t CloseOutAudioPort(std::string &sinkName); + void PrintAudioModuleInfo(const AudioModuleInfo &audioModuleInfo); + int32_t CloseInAudioPort(std::string &sourceName); + void AdjustMchSinkInfo(const AudioModuleInfo &audioModuleInfo, HpaeSinkInfo &sinkInfo); + template + void RegisterHandler(HpaeMsgCode cmdID, void (HpaeManager::*func)(Args...)); + void HandleUpdateStatus( + HpaeStreamClassType streamClassType, uint32_t sessionId, uint32_t status, IOperation operation); + void HandleInitDeviceResult(std::string deviceName, int32_t result); + void HandleDeInitDeviceResult(std::string deviceName, int32_t result); + void HandleMoveSinkInput(const std::shared_ptr sinkInputNode, std::string sinkName); + void HandleMoveAllSinkInputs(const std::vector> sinkInputs, std::string sinkNam); + void HandleMoveSourceOutput(const HpaeCaptureMoveInfo moveInfo, std::string sourceName); + void HandleMoveAllSourceOutputs(const std::vector moveInfos, std::string sourceName); + void HandleDumpSinkInfo(std::string deviceName, std::string dumpStr); + void HandleDumpSourceInfo(std::string deviceName, std::string dumpStr); + + void SendRequest(Request &&request); + int32_t OpenAudioPortInner(const AudioModuleInfo &audioModuleInfo); + uint32_t OpenOutputAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex); + uint32_t OpenInputAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex); + uint32_t OpenVirtualAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex); + void HandleRendererManager(const std::string& sinkName, const HpaeStreamInfo &streamInfo); + void CreateStreamForCapInner(const HpaeStreamInfo &streamInfo); + + std::shared_ptr GetRendererManagerById(uint32_t sessionId); + std::shared_ptr GetCapturerManagerById(uint32_t sessionId); + std::shared_ptr GetRendererManagerByNmae(const std::string &sinkName); + std::shared_ptr GetCapturerManagerByName(const std::string &sourceName); + void AddStreamToCollection(const HpaeStreamInfo &streamInfo); + + void MoveToPreferSink(const std::string& name); + +private: + std::unique_ptr hpaeManagerThread_ = nullptr; + std::unique_ptr hpaePolicyManager_ = nullptr; + std::unordered_map> capturerManagerMap_; + std::unordered_map> rendererManagerMap_; + std::unordered_map capturerIdSourceNameMap_; + std::unordered_map rendererIdSinkNameMap_; + std::unordered_map idPreferSinkNameMap_; + std::unordered_map rendererIdStreamInfoMap_; + std::unordered_map capturerIdStreamInfoMap_; + std::unordered_map sinkInputs_; + std::unordered_map sourceOutputs_; + std::unordered_map sinkNameSinkIdMap_; // todo + std::unordered_map sinkIdSinkNameMap_; + std::string defaultSink_ = "Speaker"; + std::unordered_map sourceNameSourceIdMap_; + std::unordered_map sourceIdSourceNameMap_; + std::string defaultSource_ = "Built_in_mic"; + std::atomic sinkSourceIndex_ = 0; + std::atomic isInit_ = false; + + HpaeNoLockQueue hpaeNoLockQueue_; + + std::atomic receiveMsgCount_ = 0; + std::weak_ptr serviceCallback_; + AudioServiceHpaeDumpCallback *dumpCallback_ = nullptr; + std::unordered_map deviceDumpSinkInfoMap_; + std::unordered_map> handlers_; +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif // HPAE_HDI_MANAGER_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_msg_channel.h b/services/audio_engine/manager/include/hpae_msg_channel.h new file mode 100644 index 0000000000..1b93cbe988 --- /dev/null +++ b/services/audio_engine/manager/include/hpae_msg_channel.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2025 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 HPAE_MSG_CHANNEL_H +#define HPAE_MSG_CHANNEL_H +#include +#include "i_stream.h" +#include "hpae_info.h" +#include "audio_engine_log.h" +#include "hpae_pcm_buffer.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +enum HpaeMsgCode { + UPDATE_STATUS, + INIT_DEVICE_RESULT, + DEINIT_DEVICE_RESULT, + MOVE_SINK_INPUT, + MOVE_ALL_SINK_INPUT, + MOVE_SOURCE_OUTPUT, + MOVE_ALL_SOURCE_OUTPUT, + DUMP_SINK_INFO, + DUMP_SOURCE_INFO, +}; + +enum NodeOperation { UNDERFLOW, FADED, DRAINED }; + +class ISendMsgCallback { +public: + virtual void Invoke(HpaeMsgCode cmdID, const std::any &args) = 0; +}; + +class CallbackSender { +protected: + std::weak_ptr weakCallback_; + +public: + void RegisterSendMsgCallback(std::weak_ptr cb) + { + weakCallback_ = cb; + } + + template + void TriggerCallback(HpaeMsgCode cmdID, Args &&...args) + { + if (auto callback = weakCallback_.lock()) { + // pack the arguments into a tuple + auto packed = std::make_tuple(std::forward(args)...); + callback->Invoke(cmdID, packed); + } else { + AUDIO_ERR_LOG("Hpae TriggerCallback callback is null"); + } + } +}; + +enum HpaeProcessorType { + HPAE_SCENE_DEFAULT = 0, + HPAE_SCENE_MUSIC = 1, + HPAE_SCENE_GAME = 2, + HPAE_SCENE_MOVIE = 3, + HPAE_SCENE_SPEECH = 4, + HPAE_SCENE_RING = 5, + HPAE_SCENE_VOIP_DOWN = 6, + HPAE_SCENE_OTHERS = 7, + HPAE_SCENE_EFFECT_NONE = 8, + HPAE_SCENE_EFFECT_OUT = 9, + + // up processor scene + HPAE_SCENE_VOIP_UP = 20, + HPAE_SCENE_RECORD = 21, + HPAE_SCENE_PRE_ENHANCE = 22, + HPAE_SCENE_ASR = 23, + HPAE_SCENE_VOICE_MESSAGE = 24, +}; + +// mark sourceInputNode(cluster) +enum HpaeSourceInputNodeType { + HPAE_SOURCE_DEFAULT, + HPAE_SOURCE_MIC, + HPAE_SOURCE_MIC_EC, + HPAE_SOURCE_EC, + HPAE_SOURCE_MICREF, +}; + +struct HpaeDfxNodeInfo { + uint32_t nodeId; + uint32_t sessionId; + uint32_t frameLen; + size_t historyFrameCount; + AudioSamplingRate samplingRate; + AudioSampleFormat format = AudioSampleFormat::SAMPLE_F32LE; + AudioChannel channels; + AudioChannelLayout channelLayout = AudioChannelLayout::CH_LAYOUT_UNKNOWN; + FadeType fadeType = NONE_FADE; + AudioStreamType streamType; + HpaeProcessorType sceneType; + std::string deviceClass; + std::string deviceNetId; + std::string nodeName; +}; + +class INodeCallback { +public: + virtual void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation){}; + virtual void OnFadeDone(uint32_t sessionId, IOperation operation){}; + virtual void OnRequestLatency(uint32_t sessionId, uint64_t &latency){}; + virtual void OnRewindAndFlush(uint64_t rewindTime){}; + virtual void OnNotifyQueue(){}; + // add callback + virtual uint32_t OnGetNodeId() + { + return 0; + }; + virtual void OnNotifyDfxNodeInfo(bool isConnect, uint32_t preNodeId, HpaeDfxNodeInfo &nodeInfo){}; + virtual void OnNotifyDfxNodeInfoChanged(uint32_t NodeId, const HpaeDfxNodeInfo &nodeInfo){}; +}; + +struct HpaeNodeInfo : HpaeDfxNodeInfo { + HpaeEffectInfo effectInfo; + std::weak_ptr statusCallback; + HpaeSourceBufferType sourceBufferType = HpaeSourceBufferType::HPAE_SOURCE_BUFFER_TYPE_DEFAULT; + HpaeSourceInputNodeType sourceInputNodeType = HpaeSourceInputNodeType::HPAE_SOURCE_DEFAULT; +}; + +class INodeFormatInfoCallback { +public: + virtual int32_t GetEffectNodeInputChannelInfo(uint32_t &channels, uint64_t &channelLayout) = 0; +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_offload_renderer_manager.h b/services/audio_engine/manager/include/hpae_offload_renderer_manager.h new file mode 100644 index 0000000000..a714257a4b --- /dev/null +++ b/services/audio_engine/manager/include/hpae_offload_renderer_manager.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2025 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 HPAE_OFFLOAD_RENDER_MANAGER_H +#define HPAE_OFFLOAD_RENDER_MANAGER_H +#include +#include +#include +#include +#include +#include +#include "hpae_signal_process_thread.h" +#include "hpae_sink_input_node.h" +#include "hpae_process_cluster.h" +#include "hpae_offload_sinkoutput_node.h" +#include "hpae_msg_channel.h" +#include "hpae_no_lock_queue.h" +#include "i_hpae_renderer_manager.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaeOffloadRendererManager : public IHpaeRendererManager { +public: + HpaeOffloadRendererManager(HpaeSinkInfo& sinkInfo); + virtual ~HpaeOffloadRendererManager(); + int32_t CreateStream(const HpaeStreamInfo &streamInfo) override; + int32_t DestroyStream(uint32_t sessionId) override; + + int32_t Start(uint32_t sessionId) override; + int32_t Pause(uint32_t sessionId) override; + int32_t Flush(uint32_t sessionId) override; + int32_t Drain(uint32_t sessionId) override; + int32_t Stop(uint32_t sessionId) override; + int32_t Release(uint32_t sessionId) override; + int32_t MoveStream(uint32_t sessionId, const std::string& sinkName) override; + int32_t MoveAllStream(const std::string& sinkName, const std::vector& sessionIds, + bool isMoveAll = true) override; + int32_t SuspendStreamManager(bool isSuspend) override; + int32_t SetMute(bool isMute) override; + void Process() override; + void HandleMsg() override; + int32_t Init() override; + int32_t DeInit(bool isMoveDefault = false) override; + bool IsInit() override; + bool IsRunning(void) override; + bool IsMsgProcessing() override; + bool DeactivateThread() override; + int32_t SetClientVolume(uint32_t sessionId, float volume) override; + int32_t SetRate(uint32_t sessionId, int32_t rate) override; + int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) override; + int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) override; + int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) override; + int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) override; + int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + + int32_t SetOffloadPolicy(uint32_t sessionId, int32_t state) override; + size_t GetWritableSize(uint32_t sessionId) override; + int32_t UpdateSpatializationState(uint32_t sessionId, bool spatializationEnabled, + bool headTrackingEnabled) override; + int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) override; + std::vector GetAllSinkInputsInfo() override; + int32_t GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) override; + HpaeSinkInfo GetSinkInfo() override; + + int32_t AddNodeToSink(const std::shared_ptr &node) override; + int32_t AddAllNodesToSink( + const std::vector> &sinkInputs, bool isConnect) override; + + void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) override; + void OnRequestLatency(uint32_t sessionId, uint64_t &latency) override; + void OnRewindAndFlush(uint64_t rewindTime) override; + void OnNotifyQueue() override; + std::string GetThreadName() override; + void DumpSinkInfo() override; +private: + void SendRequest(Request &&request, bool isInit = false); + int32_t StartRenderSink(); + int32_t CreateInputSession(const HpaeStreamInfo &streamInfo); + int32_t ConnectInputSession(); + int32_t DisConnectInputSession(); + void AddSingleNodeToSink(const std::shared_ptr &node, bool isConnect = true); + void MoveAllStreamToNewSink(const std::string &sinkName, const std::vector &moveIds, bool isMoveAll); + + HpaeRenderSessionInfo sessionInfo_; + std::shared_ptr sinkInputNode_ = nullptr; + std::shared_ptr formatConverterNode_ = nullptr; + std::unique_ptr sinkOutputNode_ = nullptr; + HpaeNoLockQueue hpaeNoLockQueue_; + std::unique_ptr hpaeSignalProcessThread_ = nullptr; + std::atomic isInit_ = false; + HpaeSinkInfo sinkInfo_; + bool isMute_ = false; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif // HPAE_OFFLOAD_RENDER_MANAGER_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_policy_manager.h b/services/audio_engine/manager/include/hpae_policy_manager.h new file mode 100644 index 0000000000..cb8b3b685c --- /dev/null +++ b/services/audio_engine/manager/include/hpae_policy_manager.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025 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 HPAE_POLICY_MANAGER_H +#define HPAE_POLICY_MANAGER_H + +#include "audio_effect.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + + +class HpaePolicyManager { +public: + HpaePolicyManager(); + ~HpaePolicyManager(); + // interfaces for render effect + void InitAudioEffectChainManager(const std::vector &effectChains, + const EffectChainManagerParam &effectChainManagerParam, + const std::vector> &effectLibraryList); + void SetOutputDeviceSink(int32_t device, const std::string &sinkName); + int32_t UpdateSpatializationState(AudioSpatializationState spatializationState); + int32_t UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType); + int32_t SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType); + int32_t EffectRotationUpdate(const uint32_t rotationState); + int32_t SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume); + int32_t SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray); + int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray); + int32_t SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray); + int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray); + void InitHdiState(); + void UpdateEffectBtOffloadSupported(const bool &isSupported); + void UpdateParamExtra(const std::string &mainkey, const std::string &subkey, const std::string &value); + + // interfaces for capture effect + void InitAudioEnhanceChainManager(const std::vector &enhanceChains, + const EffectChainManagerParam &managerParam, + const std::vector> &enhanceLibraryList); + int32_t SetInputDevice(const uint32_t &captureId, const DeviceType &inputDevice, + const std::string &deviceName = ""); + int32_t SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice); + int32_t SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol); + int32_t SetMicrophoneMuteInfo(const bool &isMute); + int32_t SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol); + int32_t SetAudioEnhanceProperty(const AudioEffectPropertyArrayV3 &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE); + int32_t GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE); + int32_t SetAudioEnhanceProperty(const AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE); + int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE); + void UpdateExtraSceneType(const std::string &mainkey, const std::string &subkey, + const std::string &extraSceneType); +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif // HPAE_POLICY_MANAGER_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_renderer_manager.h b/services/audio_engine/manager/include/hpae_renderer_manager.h new file mode 100644 index 0000000000..cc1bfe4c48 --- /dev/null +++ b/services/audio_engine/manager/include/hpae_renderer_manager.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2025 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 HPAE_RENDER_MANAGER_H +#define HPAE_RENDER_MANAGER_H +#include +#include +#include +#include +#include +#include +#include "hpae_signal_process_thread.h" +#include "hpae_sink_input_node.h" +#include "hpae_process_cluster.h" +#include "hpae_output_cluster.h" +#include "hpae_msg_channel.h" +#include "hpae_no_lock_queue.h" +#include "i_hpae_renderer_manager.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaeRendererManager : public IHpaeRendererManager { +public: + HpaeRendererManager(HpaeSinkInfo &sinkInfo); + virtual ~HpaeRendererManager(); + int32_t CreateStream(const HpaeStreamInfo &streamInfo) override; + int32_t DestroyStream(uint32_t sessionId) override; + + int32_t Start(uint32_t sessionId) override; + int32_t Pause(uint32_t sessionId) override; + int32_t Flush(uint32_t sessionId) override; + int32_t Drain(uint32_t sessionId) override; + int32_t Stop(uint32_t sessionId) override; + int32_t Release(uint32_t sessionId) override; + int32_t MoveStream(uint32_t sessionId, const std::string &sinkName) override; + int32_t MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, + bool isMoveAll = true) override; + int32_t SuspendStreamManager(bool isSuspend) override; + int32_t SetMute(bool isMute) override; + void Process() override; + void HandleMsg() override; + int32_t Init() override; + int32_t DeInit(bool isMoveDefault = false) override; + bool IsInit() override; + bool IsRunning(void) override; + bool IsMsgProcessing() override; + bool DeactivateThread() override; + int32_t SetClientVolume(uint32_t sessionId, float volume) override; + int32_t SetRate(uint32_t sessionId, int32_t rate) override; + int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) override; + int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) override; + int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) override; + int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) override; + int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + + size_t GetWritableSize(uint32_t sessionId) override; + int32_t UpdateSpatializationState( + uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) override; + int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) override; + std::vector GetAllSinkInputsInfo() override; + int32_t GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) override; + HpaeSinkInfo GetSinkInfo() override; + + int32_t AddNodeToSink(const std::shared_ptr &node) override; + int32_t AddAllNodesToSink( + const std::vector> &sinkInputs, bool isConnect) override; + + int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; + void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) override; + void OnFadeDone(uint32_t sessionId, IOperation operation) override; + void OnRequestLatency(uint32_t sessionId, uint64_t &latency) override; + void OnNotifyQueue() override; + std::string GetThreadName() override; + void DumpSinkInfo() override; +private: + void SendRequest(Request &&request, bool isInit = false); + int32_t StartRenderSink(); + bool IsMchDevice(); + int32_t CreateInputSession(const HpaeStreamInfo &streamInfo); + int32_t DeleteInputSession(uint32_t sessionId); + int32_t ConnectInputSession(uint32_t sessionId); + int32_t DisConnectInputSession(uint32_t sessionId); + int32_t ConnectMchInputSession(uint32_t sessionId); + int32_t DisConnectMchInputSession(uint32_t sessionId); + int32_t DeleteMchInputSession(uint32_t sessionId); + void SetSessionState(uint32_t sessionId, RendererState renderState); + void AddSingleNodeToSink(const std::shared_ptr &node, bool isConnect = true); + void MoveAllStreamToNewSink(const std::string &sinkName, const std::vector& moveIds, bool isMoveAll); + void UpdateProcessClusterConnection(uint32_t sessionId, int32_t effectMode); + void ConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType); + void DisConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType); + void DeleteProcessCluster(const HpaeNodeInfo &nodeInfo, HpaeProcessorType sceneType, uint32_t sessionId); + std::shared_ptr CreateProcessCluster(HpaeNodeInfo &nodeInfo); + bool SetSessionFade(uint32_t sessionId, IOperation operation); + +private: + std::unordered_map sessionNodeMap_; + std::unordered_map> sceneClusterMap_; + std::unordered_map> sinkInputNodeMap_; + std::unordered_map> mchIdGainNodeMap_; + std::unique_ptr outputCluster_ = nullptr; + HpaeNoLockQueue hpaeNoLockQueue_; + std::unique_ptr hpaeSignalProcessThread_ = nullptr; + std::atomic isInit_ = false; + std::atomic isMute_ = false; + HpaeSinkInfo sinkInfo_; + std::unordered_map sceneTypeToProcessClusterCountMap_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_signal_process_thread.h b/services/audio_engine/manager/include/hpae_signal_process_thread.h new file mode 100644 index 0000000000..719f420603 --- /dev/null +++ b/services/audio_engine/manager/include/hpae_signal_process_thread.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 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 HPAE_SIGNAL_PROCESS_THREAD_H +#define HPAE_SIGNAL_PROCESS_THREAD_H +#include +#include +#include +#include +#include "hpae_stream_manager.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaeSignalProcessThread { +public: + HpaeSignalProcessThread() : running_(false), recvSignal_(false) + {} + ~HpaeSignalProcessThread(); + void ActivateThread(const std::weak_ptr& streamManager); + void DeactivateThread(); + void Notify(); + void Run(); + bool IsRunning() const + { + return running_.load(); + } + bool IsMsgProcessing() const + { + return recvSignal_.load(); + } +private: + + std::atomic running_; + std::atomic recvSignal_; + std::weak_ptr streamManager_; + std::thread thread_; + std::condition_variable condition_; + std::mutex mutex_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_stream_manager.h b/services/audio_engine/manager/include/hpae_stream_manager.h new file mode 100644 index 0000000000..df67bd734b --- /dev/null +++ b/services/audio_engine/manager/include/hpae_stream_manager.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 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 HPAE_STREAM_MANAGER_H +#define HPAE_STREAM_MANAGER_H +#include +#include "audio_stream_info.h" +#include "hpae_define.h" +#include "i_stream.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaeStreamManager : public CallbackSender, + public INodeCallback, + public std::enable_shared_from_this { +public: + virtual ~HpaeStreamManager() + {} + virtual int32_t CreateStream(const HpaeStreamInfo &streamInfo) = 0; + virtual int32_t DestroyStream(uint32_t sessionId) = 0; + virtual int32_t Start(uint32_t sessionId) = 0; + virtual int32_t Pause(uint32_t sessionId) = 0; + virtual int32_t Flush(uint32_t sessionId) = 0; + virtual int32_t Drain(uint32_t sessionId) = 0; + virtual int32_t Stop(uint32_t sessionId) = 0; + virtual int32_t Release(uint32_t sessionId) = 0; + virtual int32_t MoveStream(uint32_t sessionId, const std::string &sinkName) = 0; + virtual int32_t MoveAllStream(const std::string &name, const std::vector& sessionIds, + bool isMoveAll = true) = 0; + virtual int32_t SetMute(bool isMute) = 0; + virtual void Process() = 0; + virtual void HandleMsg() = 0; + virtual int32_t Init() = 0; + virtual int32_t DeInit(bool isMoveDefault = false) = 0; + virtual bool IsInit() = 0; + virtual bool IsRunning() = 0; + virtual bool IsMsgProcessing() = 0; + virtual bool DeactivateThread() = 0; + virtual std::string GetThreadName() = 0; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/i_hpae_capturer_manager.h b/services/audio_engine/manager/include/i_hpae_capturer_manager.h new file mode 100644 index 0000000000..d9b07373ab --- /dev/null +++ b/services/audio_engine/manager/include/i_hpae_capturer_manager.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2025 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 HPAE_I_CAPTURER_MANAGER_H +#define HPAE_I_CAPTURER_MANAGER_H +#include "audio_info.h" +#include "i_capturer_stream.h" +#include "hpae_stream_manager.h" +#include "hpae_capture_move_info.h" +#include "audio_engine_log.h" +#include "hpae_dfx_tree.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class IHpaeCapturerManager : public HpaeStreamManager { +public: + virtual ~IHpaeCapturerManager() {} + virtual int32_t CreateStream(const HpaeStreamInfo& streamInfo) = 0; + virtual int32_t DestroyStream(uint32_t sessionId) = 0; + + virtual int32_t Start(uint32_t sessionId) = 0; + virtual int32_t Pause(uint32_t sessionId) = 0; + virtual int32_t Flush(uint32_t sessionId) = 0; + virtual int32_t Drain(uint32_t sessionId) = 0; + virtual int32_t Stop(uint32_t sessionId) = 0; + virtual int32_t Release(uint32_t sessionId) = 0; + virtual void Process() = 0; + virtual void HandleMsg() = 0; + virtual int32_t Init() = 0; + virtual int32_t DeInit(bool isMoveDefault = false) = 0; + virtual bool IsInit() = 0; + virtual bool IsRunning(void) = 0; + virtual bool IsMsgProcessing() = 0; + virtual bool DeactivateThread() = 0; + + virtual int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; + virtual int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) = 0; + virtual HpaeSourceInfo GetSourceInfo() = 0; + virtual std::vector GetAllSourceOutputsInfo() = 0; + virtual int32_t AddNodeToSource(const HpaeCaptureMoveInfo &moveInfo) = 0; + virtual int32_t AddAllNodesToSource(const std::vector &moveInfos, bool isConnect) = 0; + virtual std::string GetThreadName() = 0; + virtual int32_t ReloadCaptureManager(const HpaeSourceInfo &sourceInfo) = 0; + virtual void DumpSourceInfo() {}; + virtual void UploadDumpSourceInfo(std::string &deviceName) + { +#ifdef ENABLE_HIDUMP_DFX + std::string dumpStr; + dfxTree_.PrintTree(dumpStr); + TriggerCallback(DUMP_SOURCE_INFO, deviceName, dumpStr); +#endif + }; + virtual void OnNotifyDfxNodeInfo(bool isConnect, uint32_t preNodeId, HpaeDfxNodeInfo &nodeInfo) + { +#ifdef ENABLE_HIDUMP_DFX + AUDIO_INFO_LOG("%{public}s preNodeId %{public}u nodeName:%{public}s, NodeId: %{public}u", + isConnect ? "connect" : "disconnect", + preNodeId, + nodeInfo.nodeName.c_str(), + nodeInfo.nodeId); + if (isConnect) { + dfxTree_.Insert(preNodeId, nodeInfo); + } else { + dfxTree_.Remove(nodeInfo.nodeId); + } +#endif + }; + + virtual uint32_t OnGetNodeId() + { + if (nodeIdCounter_.load() == std::numeric_limits::max()) { + nodeIdCounter_.store(MIN_START_NODE_ID); + } else { + nodeIdCounter_.fetch_add(1); + } + return nodeIdCounter_.load(); + }; +private: + std::atomic nodeIdCounter_ = 0; +#ifdef ENABLE_HIDUMP_DFX + HpaeDfxTree dfxTree_; +#endif +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/i_hpae_manager.h b/services/audio_engine/manager/include/i_hpae_manager.h new file mode 100644 index 0000000000..26d9475d4b --- /dev/null +++ b/services/audio_engine/manager/include/i_hpae_manager.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2025 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 IHPAE_MANAGER_H +#define IHPAE_MANAGER_H +#include "audio_module_info.h" +#include "hpae_info.h" +#include "i_capturer_stream.h" +#include "i_renderer_stream.h" +#include "audio_service_hpae_callback.h" +#include "audio_service_hpae_dump_callback.h" +#include "audio_effect.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class IHpaeManager { +public: + virtual ~IHpaeManager() = default; + + static std::shared_ptr GetHpaeManager(); + + virtual int32_t Init() = 0; + virtual int32_t DeInit() = 0; + virtual int32_t RegisterSerivceCallback(const std::weak_ptr &callback) = 0; + virtual int32_t RegisterHpaeDumpCallback( AudioServiceHpaeDumpCallback *callback) = 0; + virtual void DumpSinkInfo(std::string deviceName) = 0; + virtual void DumpSourceInfo(std::string deviceName) = 0; + virtual uint32_t OpenAudioPort(const AudioModuleInfo &audioModuleInfo) = 0; + virtual int32_t CloseAudioPort(int32_t audioHandleIndex) = 0; + + virtual int32_t SetDefaultSink(std::string name) = 0; + virtual int32_t SetDefaultSource(std::string name) = 0; + virtual int32_t GetAllSinkInputs() = 0; + virtual int32_t GetAllSourceOutputs() = 0; + virtual int32_t MoveSourceOutputByIndexOrName( + uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) = 0; + virtual int32_t MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) = 0; + virtual void HandleMsg() = 0; + virtual bool IsInit() = 0; + virtual bool IsRunning() = 0; + virtual bool IsMsgProcessing() = 0; + virtual int32_t SuspendAudioDevice(std::string &audioPortName, bool isSuspend) = 0; + virtual bool SetSinkMute(const std::string &sinkName, bool isMute, bool isSync = false) = 0; + virtual int32_t SetSourceOutputMute(int32_t uid, bool setMute) = 0; + virtual int32_t GetAllSinks() = 0; + + virtual int32_t CreateStream(const HpaeStreamInfo &streamInfo) = 0; + virtual int32_t DestroyStream(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; + virtual int32_t Start(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; + virtual int32_t Pause(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; + virtual int32_t Flush(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; + virtual int32_t Drain(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; + virtual int32_t Stop(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; + virtual int32_t Release(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; + virtual int32_t RegisterStatusCallback( + HpaeStreamClassType streamClassType, uint32_t sessionId, const std::weak_ptr &callback) = 0; + + virtual void RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; + virtual int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeStreamInfo &streamInfo) = 0; + + virtual int32_t SetClientVolume(uint32_t sessionId, float volume) = 0; + virtual int32_t SetRate(uint32_t sessionId, int32_t rate) = 0; + virtual int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) = 0; + virtual int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) = 0; + virtual int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) = 0; + virtual int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) = 0; + virtual int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; + + virtual int32_t SetOffloadPolicy(uint32_t sessionId, int32_t state) = 0; + virtual size_t GetWritableSize(uint32_t sessionId) = 0; + virtual int32_t UpdateSpatializationState( + uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) = 0; + virtual int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) = 0; + + // interfaces for render effect + virtual void InitAudioEffectChainManager(const std::vector &effectChains, + const EffectChainManagerParam &effectChainManagerParam, + const std::vector> &effectLibraryList) = 0; + virtual void SetOutputDeviceSink(int32_t device, const std::string &sinkName) = 0; + virtual int32_t UpdateSpatializationState(AudioSpatializationState spatializationState) = 0; + virtual int32_t UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) = 0; + virtual int32_t SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType) = 0; + virtual int32_t EffectRotationUpdate(const uint32_t rotationState) = 0; + virtual int32_t SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume) = 0; + virtual int32_t SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray) = 0; + virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) = 0; + virtual int32_t SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray) = 0; + virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) = 0; + virtual void InitHdiState() = 0; + virtual void UpdateEffectBtOffloadSupported(const bool &isSupported) = 0; + virtual void UpdateParamExtra(const std::string &mainkey, const std::string &subkey, const std::string &value) = 0; + // interfaces for capture effect + virtual void InitAudioEnhanceChainManager(const std::vector &enhanceChains, + const EffectChainManagerParam &managerParam, + const std::vector> &enhanceLibraryList) = 0; + virtual int32_t SetInputDevice( + const uint32_t &captureId, const DeviceType &inputDevice, const std::string &deviceName = "") = 0; + virtual int32_t SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice) = 0; + virtual int32_t SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol) = 0; + virtual int32_t SetMicrophoneMuteInfo(const bool &isMute) = 0; + virtual int32_t SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol) = 0; + virtual int32_t SetAudioEnhanceProperty( + const AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; + virtual int32_t GetAudioEnhanceProperty( + AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; + virtual int32_t SetAudioEnhanceProperty( + const AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; + virtual int32_t GetAudioEnhanceProperty( + AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; + virtual void UpdateExtraSceneType( + const std::string &mainkey, const std::string &subkey, const std::string &extraSceneType) = 0; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif // IHPAE_MANAGER_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/i_hpae_renderer_manager.h b/services/audio_engine/manager/include/i_hpae_renderer_manager.h new file mode 100644 index 0000000000..df1f169fd5 --- /dev/null +++ b/services/audio_engine/manager/include/i_hpae_renderer_manager.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2025 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 HPAE_I_RENDER_MANAGER_H +#define HPAE_I_RENDER_MANAGER_H +#include "audio_info.h" +#include "audio_errors.h" +#include "i_renderer_stream.h" +#include "i_capturer_stream.h" +#include "hpae_sink_input_node.h" +#include "hpae_stream_manager.h" +#include "audio_engine_log.h" +#include "hpae_dfx_tree.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class IHpaeRendererManager : public HpaeStreamManager { +public: + static std::shared_ptr CreateRendererManager(HpaeSinkInfo &sinkInfo); + + virtual ~IHpaeRendererManager() + {} + virtual int32_t CreateStream(const HpaeStreamInfo &streamInfo) = 0; + virtual int32_t DestroyStream(uint32_t sessionId) = 0; + virtual int32_t Start(uint32_t sessionId) = 0; + virtual int32_t Pause(uint32_t sessionId) = 0; + virtual int32_t Flush(uint32_t sessionId) = 0; + virtual int32_t Drain(uint32_t sessionId) = 0; + virtual int32_t Stop(uint32_t sessionId) = 0; + virtual int32_t Release(uint32_t sessionId) = 0; + virtual int32_t SuspendStreamManager(bool isSuspend) = 0; + virtual void Process() = 0; + virtual void HandleMsg() = 0; + virtual int32_t Init() = 0; + virtual int32_t DeInit(bool isMoveDefault = false) = 0; + virtual bool IsInit() = 0; + virtual bool IsRunning(void) = 0; + virtual bool IsMsgProcessing() = 0; + virtual bool DeactivateThread() = 0; + virtual int32_t SetClientVolume(uint32_t sessionId, float volume) = 0; + virtual int32_t SetRate(uint32_t sessionId, int32_t rate) = 0; + virtual int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) = 0; + virtual int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) = 0; + virtual int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) = 0; + virtual int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) = 0; + virtual int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; + + virtual int32_t SetOffloadPolicy(uint32_t sessionId, int32_t state) + { + return ERR_NOT_SUPPORTED; + }; + virtual size_t GetWritableSize(uint32_t sessionId) = 0; + virtual int32_t UpdateSpatializationState( + uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) = 0; + virtual int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) = 0; + virtual std::vector GetAllSinkInputsInfo() = 0; + virtual int32_t GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) = 0; + virtual HpaeSinkInfo GetSinkInfo() = 0; + virtual int32_t AddNodeToSink(const std::shared_ptr &node) = 0; + virtual int32_t AddAllNodesToSink( + const std::vector> &sinkInputs, bool isConnect) = 0; + virtual int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; + virtual int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) + { + return 0; + }; + virtual std::vector GetAllSourceOutputsInfo() + { + return {}; + }; + virtual std::string GetThreadName() = 0; + + virtual void DumpSinkInfo() {}; + + virtual void UploadDumpSinkInfo(std::string& deviceName); + + virtual void OnNotifyDfxNodeInfo(bool isConnect, uint32_t preNodeId, HpaeDfxNodeInfo &nodeInfo); + + virtual uint32_t OnGetNodeId(); + + virtual void OnNotifyDfxNodeInfoChanged(uint32_t nodeId, const HpaeDfxNodeInfo &nodeInfo) + { +#ifdef ENABLE_HIDUMP_DFX + dfxTree_.UpdateNodeInfo(nodeId, nodeInfo); +#endif + } + +private: + std::atomic nodeIdCounter_ = 0; +#ifdef ENABLE_HIDUMP_DFX + HpaeDfxTree dfxTree_; +#endif +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_capturer_manager.cpp b/services/audio_engine/manager/src/hpae_capturer_manager.cpp new file mode 100644 index 0000000000..4322ccd654 --- /dev/null +++ b/services/audio_engine/manager/src/hpae_capturer_manager.cpp @@ -0,0 +1,863 @@ +/* + * Copyright (c) 2025 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 "HpaeCapturerManager" +#endif + +#include "hpae_capturer_manager.h" +#include "audio_info.h" +#include "audio_engine_log.h" +#include "audio_errors.h" +#include "hpae_node_common.h" +#include "audio_utils.h" +#include "audio_effect_map.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +const std::string DEFAULT_DEVICE_CLASS = "primary"; +const std::string DEFAULT_DEVICE_NETWORKID = "LocalDevice"; + +HpaeCapturerManager::HpaeCapturerManager(HpaeSourceInfo &sourceInfo) + : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sourceInfo_(sourceInfo) +{ + AUDIO_INFO_LOG("Source info: mic[%{public}d_%{public}d_%{public}d] "\ + "ec[%{public}d_%{public}d_%{public}d] "\ + "micref[%{public}d_%{public}d_%{public}d]", + sourceInfo.samplingRate, sourceInfo.channels, sourceInfo.format, + sourceInfo.ecSamplingRate, sourceInfo.ecChannels, sourceInfo.ecFormat, + sourceInfo.micRefSamplingRate, sourceInfo.micRefChannels, sourceInfo.micRefFormat); +} + +HpaeCapturerManager::~HpaeCapturerManager() +{ + if (isInit_.load()) { + DeInit(); + } +} + +void HpaeCapturerManager::SetCaptureId(uint32_t captureId) +{ + captureId_ = captureId; +} + +int32_t HpaeCapturerManager::CaptureEffectCreate(const HpaeProcessorType &processorType, + const AudioEnhanceScene &sceneType) +{ + const std::unordered_map &audioEnhanceSupportedSceneTypes = + GetEnhanceSupportedSceneType(); + auto item = audioEnhanceSupportedSceneTypes.find(sceneType); + CHECK_AND_RETURN_RET_LOG(item != audioEnhanceSupportedSceneTypes.end(), ERROR, + "sceneType %{public}d not supported", sceneType); + uint64_t sceneCode = static_cast(sceneType); + uint64_t sceneKeyCode = 0; + sceneKeyCode = (sceneCode << SCENE_TYPE_OFFSET) + (captureId_ << CAPTURER_ID_OFFSET) + renderId_; + AUDIO_INFO_LOG("sceneCode:%{public}lu sceneKeyCode:%{public}lu", sceneCode, sceneKeyCode); + CaptureEffectAttr attr = {}; + attr.micChannels = static_cast(sourceInfo_.channels); + attr.ecChannels = static_cast(sourceInfo_.ecChannels); + attr.micRefChannels = static_cast(sourceInfo_.micRefChannels); + + int32_t ret = sceneClusterMap_[processorType]->CaptureEffectCreate(sceneKeyCode, attr); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "sceneType[%{public}u] create failed", sceneType); + return SUCCESS; +} + +int32_t HpaeCapturerManager::CreateOutputSession(const HpaeStreamInfo &streamInfo) +{ + AUDIO_INFO_LOG("Create output node:%{public}d", streamInfo.sessionId); + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = OnGetNodeId(); + nodeInfo.nodeName = "HpaeSourceOutputNode"; + nodeInfo.channels = streamInfo.channels; + nodeInfo.format = streamInfo.format; + nodeInfo.frameLen = streamInfo.frameLen; + nodeInfo.streamType = streamInfo.streamType; + nodeInfo.sessionId = streamInfo.sessionId; + nodeInfo.samplingRate = (AudioSamplingRate)streamInfo.samplingRate; + HpaeProcessorType sceneType = TransSourceTypeToSceneType(streamInfo.sourceType); + nodeInfo.sceneType = sceneType; + nodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC; + nodeInfo.statusCallback = weak_from_this(); + + // todo: sourceType->processorType->sceneType => sourceType->sceneType + AudioEnhanceScene enhanceScene = TransProcessType2EnhanceScene(sceneType); + nodeInfo.effectInfo.enhanceScene = enhanceScene; + sourceOutputNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); + sessionNodeMap_[streamInfo.sessionId].sceneType = sceneType; + + if (sceneType != HPAE_SCENE_EFFECT_NONE && sceneClusterMap_.find(sceneType) == sceneClusterMap_.end()) { + // todo: algorithm instance count control + sceneClusterMap_[sceneType] = std::make_shared(nodeInfo); + if (CaptureEffectCreate(sceneType, enhanceScene) != SUCCESS) { + sceneClusterMap_.erase(sceneType); + } + } + + return SUCCESS; +} + +int32_t HpaeCapturerManager::CaptureEffectRelease(const HpaeProcessorType &sceneType) +{ + uint64_t sceneCode = static_cast(TransProcessType2EnhanceScene(sceneType)); + uint64_t sceneKeyCode = 0; + sceneKeyCode = (sceneCode << SCENE_TYPE_OFFSET) + (captureId_ << CAPTURER_ID_OFFSET) + renderId_; + int32_t ret = sceneClusterMap_[sceneType]->CaptureEffectRelease(sceneKeyCode); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "sceneType[%{public}u] release failed", sceneType); + return SUCCESS; +} + +void HpaeCapturerManager::DisConnectSceneClusterFromSourceInputCluster(HpaeProcessorType &sceneType) +{ + if (sceneClusterMap_[sceneType]->GetOutputPortNum() != 0) { + return; + } + // need to disconnect sceneCluster and sourceInputCluster + HpaeNodeInfo ecNodeInfo; + if (CheckSceneTypeNeedEc(sceneType) && + sceneClusterMap_[sceneType]->GetCapturerEffectConfig(ecNodeInfo, HPAE_SOURCE_BUFFER_TYPE_EC)) { + if (sourceInfo_.ecType == HPAE_EC_TYPE_SAME_ADAPTER) { + sceneClusterMap_[sceneType]->DisConnectWithInfo( + sourceInputClusterMap_[mainMicType_], ecNodeInfo); // ec from mic + } else if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { + sceneClusterMap_[sceneType]->DisConnectWithInfo( + sourceInputClusterMap_[HPAE_SOURCE_EC], ecNodeInfo); // ec + } + } + + HpaeNodeInfo micRefNodeInfo; + if (CheckSceneTypeNeedMicRef(sceneType) && + sceneClusterMap_[sceneType]->GetCapturerEffectConfig(micRefNodeInfo, HPAE_SOURCE_BUFFER_TYPE_MICREF) && + sourceInfo_.micRef == HPAE_REF_ON) { + sceneClusterMap_[sceneType]->DisConnectWithInfo( + sourceInputClusterMap_[HPAE_SOURCE_MICREF], micRefNodeInfo); // micref + } + + HpaeNodeInfo micNodeInfo; + if (sceneClusterMap_[sceneType]->GetCapturerEffectConfig(micNodeInfo, HPAE_SOURCE_BUFFER_TYPE_MIC)) { + sceneClusterMap_[sceneType]->DisConnectWithInfo( + sourceInputClusterMap_[mainMicType_], micNodeInfo); // mic + } + return; +} + +int32_t HpaeCapturerManager::DeleteOutputSession(uint32_t sessionId) +{ + AUDIO_INFO_LOG("delete output node:%{public}d, source name:%{public}s", sessionId, sourceInfo_.deviceClass.c_str()); + if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { + return SUCCESS; + } + + if (!sourceOutputNodeMap_[sessionId]) { + sourceOutputNodeMap_.erase(sessionId); + sessionNodeMap_.erase(sessionId); + return SUCCESS; + } + + HpaeProcessorType sceneType = sessionNodeMap_[sessionId].sceneType; + if (sceneType != HPAE_SCENE_EFFECT_NONE && sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + sourceOutputNodeMap_[sessionId]->DisConnectWithInfo( + sceneClusterMap_[sceneType], sourceOutputNodeMap_[sessionId]->GetNodeInfo()); + DisConnectSceneClusterFromSourceInputCluster(sceneType); + if (sceneClusterMap_[sceneType]->GetOutputPortNum() == 0) { + CaptureEffectRelease(sceneType); + sceneClusterMap_.erase(sceneType); + } + } else { + sourceOutputNodeMap_[sessionId]->DisConnect(sourceInputClusterMap_[mainMicType_]); + } + sourceOutputNodeMap_.erase(sessionId); + sessionNodeMap_.erase(sessionId); + return SUCCESS; +} + +void HpaeCapturerManager::SetSessionState(uint32_t sessionId, CapturerState capturerState) +{ + sessionNodeMap_[sessionId].state = capturerState; +} + +int32_t HpaeCapturerManager::CreateStream(const HpaeStreamInfo &streamInfo) +{ + if (!IsInit()) { + return ERR_INVALID_OPERATION; + } + auto request = [this, streamInfo]() { + AUDIO_INFO_LOG("CreateStream sessionId %{public}u deviceName %{public}s", + streamInfo.sessionId, + sourceInfo_.deviceName.c_str()); + CreateOutputSession(streamInfo); + SetSessionState(streamInfo.sessionId, CAPTURER_NEW); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeCapturerManager::DestroyStream(uint32_t sessionId) +{ + if (!IsInit()) { + return ERR_INVALID_OPERATION; + } + auto request = [this, sessionId]() { + DeleteOutputSession(sessionId); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeCapturerManager::ConnectProcessClusterWithEc(HpaeProcessorType &sceneType) +{ + HpaeNodeInfo ecNodeInfo; + if (CheckSceneTypeNeedEc(sceneType) && + sceneClusterMap_[sceneType]->GetCapturerEffectConfig(ecNodeInfo, HPAE_SOURCE_BUFFER_TYPE_EC)) { + ecNodeInfo.statusCallback = weak_from_this(); + if(sourceInfo_.ecType == HPAE_EC_TYPE_SAME_ADAPTER) { + sceneClusterMap_[sceneType]->ConnectWithInfo(sourceInputClusterMap_[mainMicType_], ecNodeInfo); // ec from mic + } else if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { + sceneClusterMap_[sceneType]->ConnectWithInfo(sourceInputClusterMap_[HPAE_SOURCE_EC], ecNodeInfo); // ec + } + } + return SUCCESS; +} + +int32_t HpaeCapturerManager::ConnectProcessClusterWithMicRef(HpaeProcessorType &sceneType) +{ + HpaeNodeInfo micRefNodeInfo; + if (CheckSceneTypeNeedMicRef(sceneType) && + sceneClusterMap_[sceneType]->GetCapturerEffectConfig(micRefNodeInfo, HPAE_SOURCE_BUFFER_TYPE_MICREF)&& + sourceInfo_.micRef == HPAE_REF_ON) { + micRefNodeInfo.statusCallback = weak_from_this(); + sceneClusterMap_[sceneType]->ConnectWithInfo( + sourceInputClusterMap_[HPAE_SOURCE_MICREF], micRefNodeInfo); // micref + } + return SUCCESS; +} + +int32_t HpaeCapturerManager::ConnectOutputSession(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), ERR_INVALID_PARAM, + "ConnectOutputSession error, sessionId %{public}u can not find in sourceOutputNodeMap.\n", sessionId); + + HpaeProcessorType sceneType = sessionNodeMap_[sessionId].sceneType; + if (sceneType != HPAE_SCENE_EFFECT_NONE && sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + // 1. Determine if the ResampleNode needs to be created + // 2. If ResampleNode needs to be created, it should be connected to the UpEffectNode after creation + // 3. Connect the SourceOutputNode to the ResampleNode + sourceOutputNodeMap_[sessionId]->ConnectWithInfo(sceneClusterMap_[sceneType], + sourceOutputNodeMap_[sessionId]->GetNodeInfo()); + HpaeNodeInfo micNodeInfo; + micNodeInfo.statusCallback = weak_from_this(); + if (sceneClusterMap_[sceneType]->GetCapturerEffectConfig(micNodeInfo, HPAE_SOURCE_BUFFER_TYPE_MIC)) { + sceneClusterMap_[sceneType]->ConnectWithInfo(sourceInputClusterMap_[mainMicType_], micNodeInfo); // mic + } + ConnectProcessClusterWithEc(sceneType); + ConnectProcessClusterWithMicRef(sceneType); + } else { + sourceOutputNodeMap_[sessionId]->ConnectWithInfo(sourceInputClusterMap_[mainMicType_], + sourceOutputNodeMap_[sessionId]->GetNodeInfo()); + } + return SUCCESS; +} + +int32_t HpaeCapturerManager::Start(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeCapturerManager::Start"); + CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), + ERR_INVALID_PARAM, "sessionId %{public}u can not find in sourceOutputNodeMap.", sessionId); + auto request = [this, sessionId]() { + AUDIO_INFO_LOG("Start sessionId %{public}u", sessionId); + ConnectOutputSession(sessionId); + SetSessionState(sessionId, CAPTURER_RUNNING); + if (sourceInputClusterMap_[mainMicType_]->GetSourceState() != CAPTURER_RUNNING) { + int32_t ret = sourceInputClusterMap_[mainMicType_]->CapturerSourceStart(); + CHECK_AND_RETURN_LOG(ret == SUCCESS, "Capturer source start error, ret = %{public}d.\n", ret); + if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { + ret = sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceStart(); + CHECK_AND_RETURN_LOG(ret == SUCCESS, "Capturer ec source start error, ret = %{public}d.\n", ret); + } + if (sourceInfo_.micRef == HPAE_REF_ON) { + ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceStart(); + CHECK_AND_RETURN_LOG(ret == SUCCESS, "Capturer micref source start error, ret = %{public}d.\n", ret); + } + } + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + sessionNodeMap_[sessionId].state, OPERATION_STARTED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeCapturerManager::DisConnectOutputSession(uint32_t sessionId) +{ + if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { + return SUCCESS; + } + HpaeProcessorType sceneType = sessionNodeMap_[sessionId].sceneType; + if (sceneType != HPAE_SCENE_EFFECT_NONE && sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + // 1. Disconnect SourceOutputNode and ResampleNode + // 2. Disconnect the ResampleNode and UpEffectNode + // 3. If the ResampleNode has no output, it needs to be deleted + sourceOutputNodeMap_[sessionId]->DisConnectWithInfo( + sceneClusterMap_[sceneType], sourceOutputNodeMap_[sessionId]->GetNodeInfo()); + DisConnectSceneClusterFromSourceInputCluster(sceneType); + } else { + sourceOutputNodeMap_[sessionId]->DisConnectWithInfo(sourceInputClusterMap_[mainMicType_], + sourceOutputNodeMap_[sessionId]->GetNodeInfo()); + } + + if (sourceInputClusterMap_[mainMicType_]->GetOutputPortNum() == 0) { + sourceInputClusterMap_[mainMicType_]->CapturerSourceStop(); + if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { + sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceStop(); + } + if (sourceInfo_.micRef == HPAE_REF_ON) { + sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceStop(); + } + } + return SUCCESS; +} + +int32_t HpaeCapturerManager::Pause(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeCapturerManager::Pause"); + auto request = [this, sessionId]() { + AUDIO_INFO_LOG("Pause sessionId %{public}u", sessionId); + DisConnectOutputSession(sessionId); + SetSessionState(sessionId, CAPTURER_PAUSED); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + sessionNodeMap_[sessionId].state, OPERATION_PAUSED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeCapturerManager::Flush(uint32_t sessionId) +{ + if (sessionNodeMap_.find(sessionId) == sessionNodeMap_.end()) { + return ERR_INVALID_OPERATION; + } + // to do + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + sessionNodeMap_[sessionId].state, OPERATION_FLUSHED); + return SUCCESS; +} + +int32_t HpaeCapturerManager::Drain(uint32_t sessionId) +{ + if (sessionNodeMap_.find(sessionId) == sessionNodeMap_.end()) { + return ERR_INVALID_OPERATION; + } + // to do + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + sessionNodeMap_[sessionId].state, OPERATION_DRAINED); + return SUCCESS; +} + +int32_t HpaeCapturerManager::Stop(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeCapturerManager::Stop"); + auto request = [this, sessionId]() { + DisConnectOutputSession(sessionId); + SetSessionState(sessionId, CAPTURER_STOPPED); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + sessionNodeMap_[sessionId].state, OPERATION_STOPPED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeCapturerManager::Release(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeCapturerManager::Release"); + return DestroyStream(sessionId); +} + +int32_t HpaeCapturerManager::SetMute(bool isMute) +{ + // to do check pulseaudio + auto request = [this, isMute]() { + if (isMute_ != isMute) { + isMute_ = isMute; // todo: fadein and fadeout and mute feature + } + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeCapturerManager::Process() +{ + Trace trace("HpaeCapturerManager::Process"); + if (!sourceOutputNodeMap_.empty() && IsRunning()) { + for (const auto &sourceOutputNodePair : sourceOutputNodeMap_) { + sourceOutputNodePair.second->DoProcess(); + } + } +} + +void HpaeCapturerManager::HandleMsg() +{ + hpaeNoLockQueue_.HandleRequests(); +} + +int32_t HpaeCapturerManager::PrepareCapturerEc(HpaeNodeInfo &ecNodeInfo) +{ + if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { + ecNodeInfo.frameLen = sourceInfo_.ecFrameLen; + ecNodeInfo.channels = sourceInfo_.ecChannels; + ecNodeInfo.format = sourceInfo_.ecFormat; + ecNodeInfo.samplingRate = sourceInfo_.ecSamplingRate; + ecNodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_EC; + ecNodeInfo.sourceInputNodeType = HPAE_SOURCE_EC; + ecNodeInfo.statusCallback = weak_from_this(); + sourceInputClusterMap_[HPAE_SOURCE_EC] = std::make_shared(ecNodeInfo); + int32_t ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->GetCapturerSourceInstance( + DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_NETWORKID, SOURCE_TYPE_INVALID, HDI_ID_INFO_EC); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, + "get ec capturer soruce instance error, ret = %{public}d.\n", ret); + } + return SUCCESS; +} + +int32_t HpaeCapturerManager::PrepareCapturerMicRef(HpaeNodeInfo &micRefNodeInfo) +{ + if (sourceInfo_.micRef == HPAE_REF_ON) { + micRefNodeInfo.frameLen = sourceInfo_.micRefFrameLen; + micRefNodeInfo.channels = sourceInfo_.micRefChannels; + micRefNodeInfo.format = sourceInfo_.micRefFormat; + micRefNodeInfo.samplingRate = sourceInfo_.micRefSamplingRate; + micRefNodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MICREF; + micRefNodeInfo.sourceInputNodeType = HPAE_SOURCE_MICREF; + micRefNodeInfo.statusCallback = weak_from_this(); + sourceInputClusterMap_[HPAE_SOURCE_MICREF] = std::make_shared(micRefNodeInfo); + int32_t ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->GetCapturerSourceInstance( + DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_NETWORKID, SOURCE_TYPE_INVALID, HDI_ID_INFO_MIC_REF); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, + "get micRef capturer soruce instance error, ret = %{public}d.\n", ret); + } + return SUCCESS; +} + +int32_t HpaeCapturerManager::InitCapturer() +{ + IAudioSourceAttr attr; + attr.adapterName = sourceInfo_.adapterName.c_str(); + attr.sampleRate = sourceInfo_.samplingRate; + attr.channel = sourceInfo_.channels; + attr.format = sourceInfo_.format; + attr.channelLayout = sourceInfo_.channelLayout; + attr.deviceType = sourceInfo_.deviceType; + attr.volume = sourceInfo_.volume; + attr.deviceNetworkId = sourceInfo_.deviceNetId.c_str(); + attr.filePath = sourceInfo_.filePath.c_str(); + attr.isBigEndian = false; + attr.sourceType = static_cast(sourceInfo_.sourceType); + attr.openMicSpeaker = sourceInfo_.openMicSpeaker; + attr.hasEcConfig = mainMicType_ == HPAE_SOURCE_MIC_EC; + if (attr.hasEcConfig) { + attr.formatEc = sourceInfo_.ecFormat; + attr.sampleRateEc = sourceInfo_.ecSamplingRate; + attr.channelEc = sourceInfo_.ecChannels; + } + int32_t ret = sourceInputClusterMap_[mainMicType_]->CapturerSourceInit(attr); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, + "init mic source input node err, , ret = %{public}d.\n", ret); + if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER && + sourceInputClusterMap_.find(HPAE_SOURCE_EC) != sourceInputClusterMap_.end()) { + IAudioSourceAttr attrEc; + attrEc.sourceType = SOURCE_TYPE_EC; + attrEc.adapterName = sourceInfo_.ecAdapterName.c_str(); + attrEc.deviceType = DEVICE_TYPE_MIC; + attrEc.sampleRate = sourceInfo_.ecSamplingRate; + attrEc.channel = sourceInfo_.ecChannels; + attrEc.format = sourceInfo_.ecFormat; + attrEc.isBigEndian = false; + attrEc.openMicSpeaker = sourceInfo_.openMicSpeaker; + ret = sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceInit(attrEc); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, "init ec source input node err"); + } + if (sourceInfo_.micRef == HPAE_REF_ON && + sourceInputClusterMap_.find(HPAE_SOURCE_MICREF) != sourceInputClusterMap_.end()) { + IAudioSourceAttr attrMicRef; + attrMicRef.sourceType = SOURCE_TYPE_MIC_REF; + attrMicRef.adapterName = "primary"; + attrMicRef.deviceType = DEVICE_TYPE_MIC; + attrMicRef.sampleRate = sourceInfo_.micRefSamplingRate; + attrMicRef.channel = sourceInfo_.micRefChannels; + attrMicRef.format = sourceInfo_.micRefFormat; + attrMicRef.isBigEndian = false; + attrMicRef.openMicSpeaker = sourceInfo_.openMicSpeaker; + ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceInit(attrMicRef); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, "init micRef source input node err"); + } + return SUCCESS; +} + +int32_t HpaeCapturerManager::ReloadCaptureManager(const HpaeSourceInfo &sourceInfo) +{ + if (IsInit()) { + DeInit(); + } + hpaeSignalProcessThread_ = std::make_unique(); + auto request = [this, sourceInfo] { + // disconnect + std::vector moveInfos; + for (const auto &it : sourceOutputNodeMap_) { + HpaeCaptureMoveInfo moveInfo; + moveInfo.sessionId = it.first; + moveInfo.sourceOutputNode = it.second; + if (sessionNodeMap_.find(it.first) != sessionNodeMap_.end()) { + moveInfo.sessionInfo = sessionNodeMap_[it.first]; + moveInfos.emplace_back(moveInfo); + } + } + for (const auto &it : moveInfos) { + DeleteOutputSession(it.sessionId); + } + sourceInfo_ = sourceInfo; + int32_t ret = InitCapturerManager(); + if (ret != SUCCESS) { + AUDIO_INFO_LOG("re-Init HpaeCapturerManager failed"); + return; + } + AUDIO_INFO_LOG("re-Init HpaeCapturerManager success"); + // connect + for (const auto &moveInfo : moveInfos) { + AddSingleNodeToSource(moveInfo, true); + } + TriggerCallback(INIT_DEVICE_RESULT, sourceInfo_.deviceName, ret); + }; + SendRequest(request, true); + hpaeSignalProcessThread_->ActivateThread(shared_from_this()); + return SUCCESS; +} + +int32_t HpaeCapturerManager::InitCapturerManager() +{ + HpaeNodeInfo nodeInfo; + HpaeNodeInfo ecNodeInfo; + HpaeNodeInfo micRefNodeInfo; + nodeInfo.channels = sourceInfo_.channels; + nodeInfo.format = sourceInfo_.format; + nodeInfo.frameLen = sourceInfo_.frameLen; + nodeInfo.samplingRate = sourceInfo_.samplingRate; + nodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC; + nodeInfo.statusCallback = weak_from_this(); + mainMicType_ = sourceInfo_.ecType == HPAE_EC_TYPE_SAME_ADAPTER ? HPAE_SOURCE_MIC_EC : HPAE_SOURCE_MIC; + + if (mainMicType_ == HPAE_SOURCE_MIC_EC) { + ecNodeInfo.channels = sourceInfo_.ecChannels; + ecNodeInfo.format = sourceInfo_.ecFormat; + ecNodeInfo.samplingRate = sourceInfo_.ecSamplingRate; + ecNodeInfo.frameLen = sourceInfo_.ecFrameLen; + ecNodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_EC; + ecNodeInfo.statusCallback = weak_from_this(); + nodeInfo.sourceInputNodeType = HPAE_SOURCE_MIC_EC; + std::vector nodeInfos = {nodeInfo, ecNodeInfo}; + sourceInputClusterMap_[mainMicType_] = std::make_shared(nodeInfos); + } else { + nodeInfo.sourceInputNodeType = HPAE_SOURCE_MIC; + sourceInputClusterMap_[mainMicType_] = std::make_shared(nodeInfo); + } + + sourceInputClusterMap_[mainMicType_]->SetSourceInputNodeType(mainMicType_); // to do rewrite, optimise + int32_t ret = sourceInputClusterMap_[mainMicType_]->GetCapturerSourceInstance( + sourceInfo_.deviceClass, sourceInfo_.deviceNetId, sourceInfo_.sourceType, sourceInfo_.sourceName); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "get mic capturer soruce instance error, ret = %{public}d.\n", ret); + CHECK_AND_RETURN_RET_LOG(PrepareCapturerEc(ecNodeInfo) == SUCCESS, ret, "PrepareCapturerEc error"); + CHECK_AND_RETURN_RET_LOG(PrepareCapturerMicRef(micRefNodeInfo) == SUCCESS, ret, "PrepareCapturerMicRef error"); + CHECK_AND_RETURN_RET_LOG(InitCapturer() == SUCCESS, ret, "init main capturer error"); + isInit_.store(true); + return SUCCESS; +} + + +int32_t HpaeCapturerManager::Init() +{ + hpaeSignalProcessThread_ = std::make_unique(); + auto request = [this] { + int32_t ret = InitCapturerManager(); + if (ret == SUCCESS) { + AUDIO_INFO_LOG("Init HpaeCapturerManager success"); + TriggerCallback(INIT_DEVICE_RESULT, sourceInfo_.deviceName, ret); + } + }; + SendRequest(request, true); + hpaeSignalProcessThread_->ActivateThread(shared_from_this()); + return SUCCESS; +} + +int32_t HpaeCapturerManager::DeInit(bool isMoveDefault) +{ + AUDIO_INFO_LOG("DeInit device:%{public}s", sourceInfo_.deviceName.c_str()); + if (hpaeSignalProcessThread_ != nullptr) { + hpaeSignalProcessThread_->DeactivateThread(); + hpaeSignalProcessThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); + int32_t ret = sourceInputClusterMap_[mainMicType_]->CapturerSourceDeInit(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, + "CapturerSourceDeInit error, ret = %{public}d.\n", ret); + if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { + ret = sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceDeInit(); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_INVALID_OPERATION, + "deinit ec source input node err.ret = %d.\n", ret); + } + if (sourceInfo_.micRef == HPAE_REF_ON) { + ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceDeInit(); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_INVALID_OPERATION, + "deinit micref source input node err.ret = %d.\n", ret); + } + isInit_.store(false); + + if (isMoveDefault) { + std::string name = ""; + std::vector ids; + AUDIO_INFO_LOG("move all source to default sink"); + MoveAllStreamToNewSource(name, ids, true); + } + return SUCCESS; +} + +bool HpaeCapturerManager::DeactivateThread() +{ + if (hpaeSignalProcessThread_ != nullptr) { + hpaeSignalProcessThread_->DeactivateThread(); + hpaeSignalProcessThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); + return true; +} + +int32_t HpaeCapturerManager::RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) +{ + auto request = [this, sessionId, callback]() { + sourceOutputNodeMap_[sessionId]->RegisterReadCallback(callback); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeCapturerManager::GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) +{ + if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { + return ERR_INVALID_OPERATION; + } + sourceOutputInfo.nodeInfo = sourceOutputNodeMap_[sessionId]->GetNodeInfo(); + sourceOutputInfo.capturerSessionInfo = sessionNodeMap_[sessionId]; + return SUCCESS; +} + +HpaeSourceInfo HpaeCapturerManager::GetSourceInfo() +{ + return sourceInfo_; +} + +std::vector HpaeCapturerManager::GetAllSourceOutputsInfo() +{ + return {}; +} + +bool HpaeCapturerManager::IsInit() +{ + return isInit_.load(); +} + +bool HpaeCapturerManager::IsMsgProcessing() +{ + return !hpaeNoLockQueue_.IsFinishProcess(); +} + +bool HpaeCapturerManager::IsRunning(void) +{ + if (sourceInputClusterMap_.find(mainMicType_) != sourceInputClusterMap_.end() && + hpaeSignalProcessThread_ != nullptr) { + return sourceInputClusterMap_[mainMicType_]->GetSourceState() == CAPTURER_RUNNING && + hpaeSignalProcessThread_->IsRunning(); + } else { + return false; + } +} + +void HpaeCapturerManager::SendRequest(Request &&request, bool isInit) +{ + if (!isInit && !IsInit()) { + AUDIO_INFO_LOG("HpaeCapturerManager not init"); + return; + } + hpaeNoLockQueue_.PushRequest(std::move(request)); + CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ capturer is nullptr"); + hpaeSignalProcessThread_->Notify(); +} + +void HpaeCapturerManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) +{ + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + sessionNodeMap_[sessionId].state, operation); +} + +int32_t HpaeCapturerManager::AddAllNodesToSource(const std::vector &moveInfos, bool isConnect) +{ + auto request = [this, moveInfos, isConnect]() { + for (const auto &moveInfo : moveInfos) { + AddSingleNodeToSource(moveInfo, isConnect); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeCapturerManager::AddNodeToSource(const HpaeCaptureMoveInfo &moveInfo) +{ + auto request = [this, moveInfo]() { AddSingleNodeToSource(moveInfo); }; + SendRequest(request); + return SUCCESS; +} + +void HpaeCapturerManager::AddSingleNodeToSource(const HpaeCaptureMoveInfo &moveInfo, bool isConnect) +{ + uint32_t sessionId = moveInfo.sessionId; + AUDIO_INFO_LOG("Add node to source:%{public}d", sessionId); + sourceOutputNodeMap_[sessionId] = moveInfo.sourceOutputNode; + sessionNodeMap_[sessionId] = moveInfo.sessionInfo; + HpaeProcessorType sceneType = sessionNodeMap_[sessionId].sceneType; + AudioEnhanceScene enhanceScene = TransProcessType2EnhanceScene(sceneType); + if (sceneType != HPAE_SCENE_EFFECT_NONE) { + // todo: algorithm instance count control + HpaeNodeInfo nodeInfo = moveInfo.sourceOutputNode->GetNodeInfo(); + if (sceneClusterMap_.find(sceneType) == sceneClusterMap_.end()) { + sceneClusterMap_[sceneType] = std::make_shared(nodeInfo); + } + } + if (CaptureEffectCreate(sceneType, enhanceScene) != SUCCESS) { + sceneClusterMap_.erase(sceneType); + } + if (!isConnect) { + AUDIO_INFO_LOG("not need connect session:%{public}d", sessionId); + } + AUDIO_INFO_LOG("connect node :%{public}d to sink:%{public}s", sessionId, sourceInfo_.deviceClass.c_str()); + ConnectOutputSession(sessionId); + if (moveInfo.sessionInfo.state == CAPTURER_RUNNING) { + if (sourceInputClusterMap_[mainMicType_]->GetSourceState() != CAPTURER_RUNNING) { + int32_t ret = sourceInputClusterMap_[mainMicType_]->CapturerSourceStart(); + CHECK_AND_RETURN_LOG(ret == SUCCESS, "capturer source start error, ret = %{public}d.\n", ret); + if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { + ret = sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceStart(); + CHECK_AND_RETURN_LOG(ret == SUCCESS, "ec capturer source start error, ret = %{public}d.\n", ret); + } + if (sourceInfo_.micRef == HPAE_REF_ON) { + ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceStart(); + CHECK_AND_RETURN_LOG(ret == SUCCESS, "micref capturer source start error, ret = %{public}d.\n", ret); + } + } + hpaeSignalProcessThread_->Notify(); + } +} + +int32_t HpaeCapturerManager::MoveAllStream(const std::string &sourceName, const std::vector& sessionIds, + bool isMoveAll) +{ + if (!IsInit()) { + AUDIO_INFO_LOG("source is not init ,use sync mode move to: %{public}s", sourceName.c_str()); + MoveAllStreamToNewSource(sourceName, sessionIds, isMoveAll); + } else { + AUDIO_INFO_LOG("source is init ,use async mode move to: %{public}s", sourceName.c_str()); + auto request = [this, sourceName, sessionIds, isMoveAll]() { + MoveAllStreamToNewSource(sourceName, sessionIds, isMoveAll); + }; + SendRequest(request); + } + return SUCCESS; +} + +void HpaeCapturerManager::MoveAllStreamToNewSource(const std::string &sourceName, + const std::vector& moveIds, bool isMoveAll = true) +{ + std::string name = sourceName; + std::vector moveInfos; + for (const auto &it : sourceOutputNodeMap_) { + if (isMoveAll || std::find(moveIds.begin(), moveIds.end(), it.first) != moveIds.end()) { + HpaeCaptureMoveInfo moveInfo; + moveInfo.sessionId = it.first; + moveInfo.sourceOutputNode = it.second; + if (sessionNodeMap_.find(it.first) != sessionNodeMap_.end()) { + moveInfo.sessionInfo = sessionNodeMap_[it.first]; + moveInfos.emplace_back(moveInfo); + } + } + } + + for (const auto &it : moveInfos) { + DeleteOutputSession(it.sessionId); + } + + AUDIO_INFO_LOG("move source count: %{public}zu,source name:%{public}s", moveInfos.size(), sourceName.c_str()); + TriggerCallback(MOVE_ALL_SOURCE_OUTPUT, moveInfos, name); +} + +int32_t HpaeCapturerManager::MoveStream(uint32_t sessionId, const std::string& sourceName) +{ + AUDIO_INFO_LOG("soft stop session:%{public}d,source name:%{public}s", sessionId, sourceName.c_str()); + auto request = [this, sessionId, sourceName]() { + AUDIO_ERR_LOG("trigger call back1, source name:%{public}s", sourceName.c_str()); + if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { + AUDIO_ERR_LOG("could not find session:%{public}d,source name:%{public}s", sessionId, sourceName.c_str()); + return; + } + AUDIO_ERR_LOG("trigger call back2, source name:%{public}s", sourceName.c_str()); + std::shared_ptr sourceNode = sourceOutputNodeMap_[sessionId]; + if (sessionNodeMap_.find(sessionId)==sessionNodeMap_.end()) { + AUDIO_ERR_LOG("can not find session node:%{public}d,source name:%{public}s", sessionId, sourceName.c_str()); + return; + } + HpaeCapturerSessionInfo sessionInfo = sessionNodeMap_[sessionId]; + if (sessionInfo.state == CAPTURER_RUNNING) { + // todo: do fade out + } + HpaeCaptureMoveInfo moveInfo; + moveInfo.sessionId = sessionId; + moveInfo.sourceOutputNode = sourceNode; + moveInfo.sessionInfo = sessionInfo; + DeleteOutputSession(sessionId); + if (!sourceName.empty()) { + std::string name = sourceName; + AUDIO_ERR_LOG("trigger call back, source name:%{public}s", sourceName.c_str()); + TriggerCallback(MOVE_SOURCE_OUTPUT, moveInfo, name); + } + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeCapturerManager::OnNotifyQueue() +{ + hpaeSignalProcessThread_->Notify(); +} + +std::string HpaeCapturerManager::GetThreadName() +{ + return sourceInfo_.deviceName; +} + +void HpaeCapturerManager::DumpSourceInfo() +{ + SendRequest([this](){ + AUDIO_INFO_LOG("DumpSourceInfo deviceName %{public}s", sourceInfo_.deviceName.c_str()); + UploadDumpSourceInfo(sourceInfo_.deviceName); + }); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_inner_capturer_manager.cpp b/services/audio_engine/manager/src/hpae_inner_capturer_manager.cpp new file mode 100644 index 0000000000..cc8355d154 --- /dev/null +++ b/services/audio_engine/manager/src/hpae_inner_capturer_manager.cpp @@ -0,0 +1,745 @@ +/* + * Copyright (c) 2025 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 "HpaeInnerCapturerManager" +#endif +#include "audio_stream_info.h" +#include "audio_errors.h" +#include "audio_engine_log.h" +#include "hpae_node_common.h" +#include "hpae_inner_capturer_manager.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +// todo sinkInfo +HpaeInnerCapturerManager::HpaeInnerCapturerManager(HpaeSinkInfo &sinkInfo) + : sinkInfo_(sinkInfo), hpaeNoLockQueue_(CURRENT_REQUEST_COUNT) +{} + +HpaeInnerCapturerManager::~HpaeInnerCapturerManager() +{ + AUDIO_INFO_LOG("destructor inner capturer sink."); + if (isInit_.load()) { + DeInit(); + } +} + +int32_t HpaeInnerCapturerManager::AddNodeToSink(const std::shared_ptr &node) +{ + auto request = [this, node]() { + AddSingleNodeToSinkInner(node); + }; + SendRequestInner(request); + return SUCCESS; +} + +void HpaeInnerCapturerManager::AddSingleNodeToSinkInner(const std::shared_ptr &node, bool isConnect) +{ + HpaeNodeInfo nodeInfo = node->GetNodeInfo(); + uint32_t sessionId = nodeInfo.sessionId; + AUDIO_INFO_LOG("add node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); + sinkInputNodeMap_[sessionId] = node; + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + nodeInfo.statusCallback = weak_from_this(); + sinkInputNodeMap_[sessionId]->SetNodeInfo(nodeInfo); + SetSessionStateInner(sessionId, node->GetState()); + rendererSessionNodeMap_[sessionId].sinkInputNodeId = nodeInfo.nodeId; + rendererSessionNodeMap_[sessionId].sceneType = nodeInfo.sceneType; + + if (rendererSceneClusterMap_.find(nodeInfo.sceneType) == rendererSceneClusterMap_.end()) { + rendererSceneClusterMap_[nodeInfo.sceneType] = std::make_shared(nodeInfo, sinkInfo_); + } + + if (!isConnect) { + AUDIO_INFO_LOG("not need connect session:%{public}d", sessionId); + return; + } + if (node->GetState() == RENDERER_RUNNING) { + AUDIO_INFO_LOG("connect node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); + ConnectRendererInputSessionInner(sessionId); // todo: fadein + if (hpaeInnerCapSinkNode_->GetSinkState() != RENDERER_RUNNING) { + hpaeInnerCapSinkNode_->InnerCapturerSinkStart(); + } + } +} + +int32_t HpaeInnerCapturerManager::AddAllNodesToSink( + const std::vector> &sinkInputs, bool isConnect) +{ + auto request = [this, sinkInputs, isConnect]() { + for (const auto &it : sinkInputs) { + AddSingleNodeToSinkInner(it, isConnect); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +void HpaeInnerCapturerManager::MoveAllStreamToNewSinkInner(const std::string &sinkName, + const std::vector& moveIds, bool isMoveAll) +{ + std::string name = sinkName; + std::vector> sinkInputs; + std::vector sessionIds; + for (const auto &it : sinkInputNodeMap_) { + if (isMoveAll || std::find(moveIds.begin(), moveIds.end(), it.first) != moveIds.end()) { + sinkInputs.emplace_back(it.second); + sessionIds.emplace_back(it.first); + } + } + for (const auto &it : sessionIds) { + DisConnectRendererInputSessionInner(it); + } + AUDIO_INFO_LOG("sink input count:%{public}zu", sinkInputs.size()); + TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name); +} + +int32_t HpaeInnerCapturerManager::MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, + bool isMoveAll) +{ + if (!IsInit()) { + AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str()); + MoveAllStreamToNewSinkInner(sinkName, sessionIds, isMoveAll); + } else { + AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str()); + auto request = [this, sinkName, sessionIds, isMoveAll]() { + MoveAllStreamToNewSinkInner(sinkName, sessionIds, isMoveAll); + }; + SendRequestInner(request); + } + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::MoveStream(uint32_t sessionId, const std::string &sinkName) +{ + AUDIO_INFO_LOG("move session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); + auto request = [this, sessionId, sinkName]() { + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + AUDIO_ERR_LOG("could not find session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); + return; + } + std::shared_ptr inputNode = sinkInputNodeMap_[sessionId]; + if (inputNode->GetState() == RENDERER_RUNNING) { + // todo: do fade out + } + DisConnectRendererInputSessionInner(sessionId); + if (!sinkName.empty()) { + std::string name = sinkName; + AUDIO_ERR_LOG("trigger call back, sink name:%{public}s", sinkName.c_str()); + TriggerCallback(MOVE_SINK_INPUT, inputNode, name); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::CreateStream(const HpaeStreamInfo &streamInfo) +{ + if (!IsInit()) { + AUDIO_INFO_LOG("CreateStream not init"); + return ERR_INVALID_OPERATION; + } + auto request = [this, streamInfo]() { + if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { + AUDIO_INFO_LOG("CreateCapRendererStream sessionID: %{public}d", streamInfo.sessionId); + CreateRendererInputSessionInner(streamInfo); + SetSessionStateInner(streamInfo.sessionId, RENDERER_NEW); + sinkInputNodeMap_[streamInfo.sessionId]->SetState(RENDERER_NEW); + } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD) { + AUDIO_INFO_LOG("CreateCapCapturerStream sessionID: %{public}d", streamInfo.sessionId); + CreateCapturerInputSessionInner(streamInfo); + SetSessionStateInner(streamInfo.sessionId, CAPTURER_NEW); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::DestroyStream(uint32_t sessionId) +{ + if (!IsInit()) { + return ERR_INVALID_OPERATION; + } + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || + sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ + "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); + AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("DestroyCapRendererStream sessionID: %{public}d", sessionId); + DeleteRendererInputSessionInner(sessionId); + } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { + AUDIO_INFO_LOG("DestroyCapCapturerStream sessionID: %{public}d", sessionId); + DeleteCapturerInputSessionInner(sessionId); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::Init() +{ + hpaeSignalProcessThread_ = std::make_unique(); + auto request = [this] { + HpaeNodeInfo nodeInfo; + nodeInfo.channels = sinkInfo_.channels; + nodeInfo.format = sinkInfo_.format; + nodeInfo.frameLen = sinkInfo_.frameLen; + nodeInfo.nodeId = 0; + nodeInfo.samplingRate = sinkInfo_.samplingRate; + nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT; + hpaeInnerCapSinkNode_ = std::make_unique(nodeInfo); + AUDIO_INFO_LOG("Init innerCapSinkNode"); + hpaeInnerCapSinkNode_->InnerCapturerSinkInit(); + isInit_.store(true); + TriggerCallback(INIT_DEVICE_RESULT, sinkInfo_.deviceName, SUCCESS); + }; + SendRequestInner(request, true); + hpaeSignalProcessThread_->ActivateThread(shared_from_this()); + return SUCCESS; +} + +bool HpaeInnerCapturerManager::DeactivateThread() +{ + if (hpaeSignalProcessThread_ != nullptr) { + hpaeSignalProcessThread_->DeactivateThread(); + hpaeSignalProcessThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); + return true; +} + +int32_t HpaeInnerCapturerManager::DeInit(bool isMoveDefault) +{ + if (hpaeSignalProcessThread_ != nullptr) { + hpaeSignalProcessThread_->DeactivateThread(); + hpaeSignalProcessThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); + int32_t ret = hpaeInnerCapSinkNode_->InnerCapturerSinkDeInit(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InnerCapManagerDeInit error, ret %{public}d.\n", ret); + hpaeInnerCapSinkNode_->ResetAll(); + isInit_.store(false); + TriggerCallback(DEINIT_DEVICE_RESULT, sinkInfo_.deviceName, ret); + if (isMoveDefault) { + std::string sinkName = ""; + std::vector ids; + AUDIO_INFO_LOG("move all sink to default sink"); + MoveAllStreamToNewSinkInner(sinkName, ids, true); + } + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::Start(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || + sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ + "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("StartCapRendererStream sessionId %{public}u", sessionId); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->SetState(RENDERER_RUNNING); + } + ConnectRendererInputSessionInner(sessionId); + SetSessionStateInner(sessionId, RENDERER_RUNNING); + if (hpaeInnerCapSinkNode_->GetSinkState() != RENDERER_RUNNING) { + hpaeInnerCapSinkNode_->InnerCapturerSinkStart(); + } + } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { + AUDIO_INFO_LOG("StartCapCapturerStream sessionId %{public}u", sessionId); + ConnectCapturerOutputSessionInner(sessionId); + SetSessionStateInner(sessionId, CAPTURER_RUNNING); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + capturerSessionNodeMap_[sessionId].state, OPERATION_STARTED); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::Pause(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || + sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ + "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("PauseCapRendererStream sessionId %{public}u", sessionId); + DisConnectRendererInputSessionInner(sessionId); + SetSessionStateInner(sessionId, RENDERER_PAUSED); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->SetState(RENDERER_PAUSED); + } + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, + rendererSessionNodeMap_[sessionId].state, OPERATION_PAUSED); + } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { + AUDIO_INFO_LOG("PauseCapCapturerStream sessionId %{public}u", sessionId); + DisConnectCapturerInputSessionInner(sessionId); + SetSessionStateInner(sessionId, CAPTURER_PAUSED); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + capturerSessionNodeMap_[sessionId].state, OPERATION_PAUSED); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::Flush(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || + sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ + "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("FlushCapRendererStream sessionId %{public}u", sessionId); + CHECK_AND_RETURN_LOG(rendererSessionNodeMap_.find(sessionId) != rendererSessionNodeMap_.end(), + "Flush not find sessionId %{public}u", sessionId); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, + rendererSessionNodeMap_[sessionId].state, OPERATION_FLUSHED); + } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { + AUDIO_INFO_LOG("FlushCapCapturerStream sessionId %{public}u", sessionId); + CHECK_AND_RETURN_LOG(capturerSessionNodeMap_.find(sessionId) != capturerSessionNodeMap_.end(), + "Flush not find sessionId %{public}u", sessionId); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + capturerSessionNodeMap_[sessionId].state, OPERATION_FLUSHED); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::Drain(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || + sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ + "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("DrainCapRendererStream sessionId %{public}u", sessionId); + CHECK_AND_RETURN_LOG(rendererSessionNodeMap_.find(sessionId) != rendererSessionNodeMap_.end(), + "Drain not find sessionId %{public}u", sessionId); + sinkInputNodeMap_[sessionId]->Drain(); + if (rendererSessionNodeMap_[sessionId].state != RENDERER_RUNNING) { + AUDIO_INFO_LOG("TriggerCallback Drain sessionId %{public}u", sessionId); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, + rendererSessionNodeMap_[sessionId].state, OPERATION_DRAINED); + } + } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { + AUDIO_INFO_LOG("DrainCapCapturerStream sessionId %{public}u", sessionId); + CHECK_AND_RETURN_LOG(capturerSessionNodeMap_.find(sessionId) != capturerSessionNodeMap_.end(), + "Drain not find sessionId %{public}u", sessionId); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + capturerSessionNodeMap_[sessionId].state, OPERATION_DRAINED); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::Stop(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || + sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ + "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("StopCapRendererStream sessionId %{public}u", sessionId); + DisConnectRendererInputSessionInner(sessionId); + SetSessionStateInner(sessionId, RENDERER_STOPPED); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->SetState(RENDERER_STOPPED); + } + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, + rendererSessionNodeMap_[sessionId].state, OPERATION_STOPPED); + } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { + AUDIO_INFO_LOG("StopCapCapturerStream sessionId %{public}u", sessionId); + DisConnectCapturerInputSessionInner(sessionId); + SetSessionStateInner(sessionId, CAPTURER_STOPPED); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, + capturerSessionNodeMap_[sessionId].state, OPERATION_STOPPED); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::Release(uint32_t sessionId) +{ + return DestroyStream(sessionId); +} + +int32_t HpaeInnerCapturerManager::SuspendStreamManager(bool isSuspend) +{ + auto request = [this, isSuspend]() { + if (isSuspend) { + // todo fadout + hpaeInnerCapSinkNode_->InnerCapturerSinkStop(); + } else { + // todo fadout + hpaeInnerCapSinkNode_->InnerCapturerSinkStart(); + } + }; + SendRequestInner(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::SetMute(bool isMute) +{ + auto request = [this, isMute]() { + if (isMute_ != isMute) { + isMute_ = isMute; // todo: fadein and fadeout and mute feature + } + }; + SendRequestInner(request); + return SUCCESS; +} + +void HpaeInnerCapturerManager::Process() +{ + if (hpaeInnerCapSinkNode_ != nullptr && !sourceOutputNodeMap_.empty() && IsRunning()) { + for (const auto& sourceOutputNodePair : sourceOutputNodeMap_) { + if (capturerSessionNodeMap_[sourceOutputNodePair.first].state == CAPTURER_RUNNING) { + sourceOutputNodePair.second->DoProcess(); + } + } + } +} + +void HpaeInnerCapturerManager::HandleMsg() +{ + hpaeNoLockQueue_.HandleRequests(); +} + +bool HpaeInnerCapturerManager::IsInit() +{ + return isInit_.load(); +} + +bool HpaeInnerCapturerManager::IsRunning(void) +{ + if (hpaeInnerCapSinkNode_ != nullptr && hpaeSignalProcessThread_ != nullptr) { + return hpaeSignalProcessThread_->IsRunning(); + } else { + return false; + } +} + +bool HpaeInnerCapturerManager::IsMsgProcessing() +{ + return !hpaeNoLockQueue_.IsFinishProcess(); +} + +int32_t HpaeInnerCapturerManager::SetClientVolume(uint32_t sessionId, float volume) +{ + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::SetRate(uint32_t sessionId, int32_t rate) +{ + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) +{ + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) +{ + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType) +{ + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType) +{ + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::RegisterWriteCallback(uint32_t sessionId, + const std::weak_ptr &callback) +{ + auto request = [this, sessionId, callback]() { + AUDIO_INFO_LOG("RegisterWriteCallback sessionId %{public}u", sessionId); + CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || + sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ + "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->RegisterWriteCallback(callback); + } + }; + hpaeNoLockQueue_.PushRequest(request); + return SUCCESS; +} + +int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) +{ + return SUCCESS; +} + +size_t HpaeInnerCapturerManager::GetWritableSize(uint32_t sessionId) +{ + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::UpdateSpatializationState( + uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) +{ + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) +{ + return SUCCESS; +} + +std::vector HpaeInnerCapturerManager::GetAllSinkInputsInfo() +{ + std::vector sinkInputs; + return sinkInputs; +} + +int32_t HpaeInnerCapturerManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) +{ + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + return ERR_INVALID_OPERATION; + } + sinkInputInfo.nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); + sinkInputInfo.rendererSessionInfo = rendererSessionNodeMap_[sessionId]; + return SUCCESS; +} + +HpaeSinkInfo HpaeInnerCapturerManager::GetSinkInfo() +{ + return sinkInfo_; +} + +void HpaeInnerCapturerManager::OnFadeDone(uint32_t sessionId, IOperation operation) +{ + auto request = [this, sessionId, operation]() { + DisConnectRendererInputSessionInner(sessionId); + RendererState state = operation == OPERATION_STOPPED ? RENDERER_STOPPED : RENDERER_PAUSED; + SetSessionStateInner(sessionId, state); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->SetState(state); + } + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, + rendererSessionNodeMap_[sessionId].state, operation); + }; + SendRequestInner(request); +} + +void HpaeInnerCapturerManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) +{ + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, + rendererSessionNodeMap_[sessionId].state, operation); +} + +int32_t HpaeInnerCapturerManager::RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) +{ + auto request = [this, sessionId, callback]() { + AUDIO_INFO_LOG("RegisterReadCallback sessionId %{public}u", sessionId); + sourceOutputNodeMap_[sessionId]->RegisterReadCallback(callback); + }; + hpaeNoLockQueue_.PushRequest(request); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) +{ + if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { + return ERR_INVALID_OPERATION; + } + sourceOutputInfo.nodeInfo = sourceOutputNodeMap_[sessionId]->GetNodeInfo(); + sourceOutputInfo.capturerSessionInfo = capturerSessionNodeMap_[sessionId]; + return SUCCESS; +} + +std::vector HpaeInnerCapturerManager::GetAllSourceOutputsInfo() +{ + // to do + std::vector sourceOutputs; + return sourceOutputs; +} + +int32_t HpaeInnerCapturerManager::CreateRendererInputSessionInner(const HpaeStreamInfo &streamInfo) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.channels = streamInfo.channels; + nodeInfo.format = streamInfo.format; + nodeInfo.frameLen = streamInfo.frameLen; + nodeInfo.nodeId = GetSinkInputNodeIdInner(); + nodeInfo.streamType = streamInfo.streamType; + nodeInfo.sessionId = streamInfo.sessionId; + nodeInfo.samplingRate = (AudioSamplingRate)streamInfo.samplingRate; + nodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE; + nodeInfo.statusCallback = weak_from_this(); + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + AUDIO_INFO_LOG("nodeInfo.channels %{public}d, nodeInfo.format %{public}hhu, nodeInfo.frameLen %{public}d", + nodeInfo.channels, nodeInfo.format, nodeInfo.frameLen); + sinkInputNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); + + if (rendererSceneClusterMap_.find(nodeInfo.sceneType) == rendererSceneClusterMap_.end()) { + rendererSceneClusterMap_[nodeInfo.sceneType] = std::make_shared(nodeInfo, sinkInfo_); + } + // todo change nodeInfo + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::CreateCapturerInputSessionInner(const HpaeStreamInfo &streamInfo) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.channels = streamInfo.channels; + nodeInfo.format = streamInfo.format; + nodeInfo.frameLen = streamInfo.frameLen; + nodeInfo.streamType = streamInfo.streamType; + nodeInfo.sessionId = streamInfo.sessionId; + nodeInfo.samplingRate = (AudioSamplingRate)streamInfo.samplingRate; + nodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE; + AUDIO_INFO_LOG("nodeInfo.channels %{public}d, nodeInfo.format %{public}hhu, nodeInfo.frameLen %{public}d", + nodeInfo.channels, nodeInfo.format, nodeInfo.frameLen); + sourceOutputNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); + HpaeNodeInfo outputNodeInfo = hpaeInnerCapSinkNode_->GetNodeInfo(); + // todo change nodeInfo + capturerResampleNodeMap_[streamInfo.sessionId] = std::make_shared(outputNodeInfo, nodeInfo); + capturerSessionNodeMap_[streamInfo.sessionId].sceneType = nodeInfo.sceneType; + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::DeleteRendererInputSessionInner(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end(), SUCCESS, + "sessionId %{public}u can not find in sinkInputNodeMap_.", sessionId); + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + if (rendererSceneClusterMap_.find(sceneType) != rendererSceneClusterMap_.end()) { + rendererSceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]); + if (rendererSceneClusterMap_[sceneType]->GetPreOutNum() == 0) { + hpaeInnerCapSinkNode_->DisConnect(rendererSceneClusterMap_[sceneType]); + rendererSceneClusterMap_.erase(sceneType); + } + } + sinkInputNodeMap_.erase(sessionId); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::DeleteCapturerInputSessionInner(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), SUCCESS, + "sessionId %{public}u can not find in sourceOutputNodeMap_.", sessionId); + CHECK_AND_RETURN_RET_LOG(capturerResampleNodeMap_.find(sessionId) != capturerResampleNodeMap_.end(), SUCCESS, + "sessionId %{public}u can not find in capturerResampleNodeMap_.", sessionId); + // no need process cluster + sourceOutputNodeMap_[sessionId]->DisConnect(capturerResampleNodeMap_[sessionId]); + capturerResampleNodeMap_[sessionId]->DisConnect(hpaeInnerCapSinkNode_); + // if need disconnect all? + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::ConnectRendererInputSessionInner(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end(), ERR_INVALID_PARAM, + "sessionId %{public}u can not find in sinkInputNodeMap_.", sessionId); + CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_[sessionId]->GetState() == RENDERER_RUNNING, SUCCESS, + "sink input node is running"); + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + CHECK_AND_RETURN_RET_LOG(rendererSceneClusterMap_.find(sceneType) != rendererSceneClusterMap_.end(), SUCCESS, + "miss corresponding process cluster for scene type %{public}d", sceneType); + rendererSceneClusterMap_[sceneType]->Connect(sinkInputNodeMap_[sessionId]); + // todo check if connect process cluster + hpaeInnerCapSinkNode_->Connect(rendererSceneClusterMap_[sceneType]); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::ConnectCapturerOutputSessionInner(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), ERR_INVALID_PARAM, + "sessionId %{public}u can not find in sourceOutputCLusterMap.", sessionId); + CHECK_AND_RETURN_RET_LOG(capturerResampleNodeMap_.find(sessionId) != capturerResampleNodeMap_.end(), + ERR_INVALID_PARAM, + "sessionId %{public}u can not find in capturerResampleNodeMap_.", sessionId); + // todo connect gain node + sourceOutputNodeMap_[sessionId]->Connect(capturerResampleNodeMap_[sessionId]); + capturerResampleNodeMap_[sessionId]->Connect(hpaeInnerCapSinkNode_); + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::DisConnectRendererInputSessionInner(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end(), SUCCESS, + "sessionId %{public}u can not find in sinkInputNodeMap_.", sessionId); + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + if (rendererSceneClusterMap_.find(sceneType) != rendererSceneClusterMap_.end()) { + rendererSceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]); + if (rendererSceneClusterMap_[sceneType]->GetPreOutNum() == 0) { + hpaeInnerCapSinkNode_->DisConnect(rendererSceneClusterMap_[sceneType]); + } + } + return SUCCESS; +} + +int32_t HpaeInnerCapturerManager::DisConnectCapturerInputSessionInner(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), SUCCESS, + "sessionId %{public}u can not find in sourceOutputNodeMap_.", sessionId); + CHECK_AND_RETURN_RET_LOG(capturerResampleNodeMap_.find(sessionId) != capturerResampleNodeMap_.end(), SUCCESS, + "sessionId %{public}u can not find in capturerResampleNodeMap_.", sessionId); + sourceOutputNodeMap_[sessionId]->DisConnect(capturerResampleNodeMap_[sessionId]); + capturerResampleNodeMap_[sessionId]->DisConnect(hpaeInnerCapSinkNode_); + // todo if need disconnect render + return SUCCESS; +} + +void HpaeInnerCapturerManager::SetSessionStateInner(uint32_t sessionId, RendererState renderState) +{ + rendererSessionNodeMap_[sessionId].state = renderState; +} + +void HpaeInnerCapturerManager::SetSessionStateInner(uint32_t sessionId, CapturerState capturerState) +{ + capturerSessionNodeMap_[sessionId].state = capturerState; +} + +void HpaeInnerCapturerManager::SendRequestInner(Request &&request, bool isInit) +{ + if (!isInit && !IsInit()) { + AUDIO_INFO_LOG("HpaeInnerCapturerManager not init"); + return; + } + hpaeNoLockQueue_.PushRequest(std::move(request)); + CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ inner capturer sink is nullptr"); + hpaeSignalProcessThread_->Notify(); +} + +uint32_t HpaeInnerCapturerManager::GetSinkInputNodeIdInner() +{ + return sinkInputNodeCounter_++; +} + +std::string HpaeInnerCapturerManager::GetThreadName() +{ + return sinkInfo_.deviceName; +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_manager.cpp b/services/audio_engine/manager/src/hpae_manager.cpp new file mode 100644 index 0000000000..ea55765d79 --- /dev/null +++ b/services/audio_engine/manager/src/hpae_manager.cpp @@ -0,0 +1,1910 @@ +/* + * Copyright (c) 2025 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 "HpaeManager" +#endif +#include "hpae_manager.h" +#include +#include +#include +#include "audio_errors.h" +#include "audio_schedule.h" +#include "audio_engine_log.h" +#include "audio_utils.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +namespace { +constexpr uint32_t DEFAULT_SUSPEND_TIME_IN_MS = 3000; // 3s to stop hdi +static inline const std::unordered_set INNER_SOURCE_TYPE_SET = { + SOURCE_TYPE_PLAYBACK_CAPTURE, SOURCE_TYPE_REMOTE_CAST}; +} // namespace +static constexpr uint32_t DEFAULT_MULTICHANNEL_NUM = 6; +static constexpr uint32_t DEFAULT_MULTICHANNEL_CHANNELLAYOUT = 1551; +static constexpr float MAX_SINK_VOLUME_LEVEL = 1.0; +static constexpr uint32_t DEFAULT_MULTICHANNEL_FRAME_LEN_MS = 20; +static constexpr uint32_t MS_PER_SECOND = 1000; +static std::map formatFromParserStrToEnum = { + {"s16le", SAMPLE_S16LE}, + {"s24le", SAMPLE_S24LE}, + {"s32le", SAMPLE_S32LE}, + {"f32le", SAMPLE_F32LE}, +}; + +// base + offset * 8 +static uint32_t GetRenderId(const std::string &deviceClass) +{ + uint32_t renderId = 0; + if (deviceClass == "usb") { + renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_USB); + } else if (deviceClass == "dp") { + renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DP); + } else if (deviceClass == "voip") { + renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP); + } else if (deviceClass == "direct") { + renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DIRECT); + } else { + renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_PRIMARY); + } + return renderId; +} + +static uint32_t GetCaptureId(const std::string &deviceClass) +{ + uint32_t captureId = 0; + if (deviceClass == "usb") { + captureId = GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_USB); + } else if (deviceClass == "a2dp") { + captureId = GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_BLUETOOTH); + } else { + captureId = GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_PRIMARY); + } + return captureId; +} + +HpaeManagerThread::~HpaeManagerThread() +{ + DeactivateThread(); +} + +void HpaeManagerThread::ActivateThread(HpaeManager *hpaeManager) +{ + m_hpaeManager = hpaeManager; + auto threadFunc = std::bind(&HpaeManagerThread::Run, this); + thread_ = std::thread(threadFunc); + pthread_setname_np(thread_.native_handle(), "HpaeManager"); +} + +void HpaeManagerThread::Run() +{ + running_.store(true); + ScheduleThreadInServer(getpid(), gettid()); + while (running_.load() && m_hpaeManager != nullptr) { + { + std::unique_lock lock(mutex_); + condition_.wait(lock, [this] { return recvSignal_.load() || m_hpaeManager->IsMsgProcessing(); }); + } + m_hpaeManager->HandleMsg(); + recvSignal_.store(false); + } + UnscheduleThreadInServer(getpid(), gettid()); +} + +void HpaeManagerThread::Notify() +{ + recvSignal_.store(true); + condition_.notify_all(); +} + +void HpaeManagerThread::DeactivateThread() +{ + Notify(); + running_.store(false); + if (thread_.joinable()) { + thread_.join(); + } +} + +HpaeManager::HpaeManager() : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT) // todo Message queue exceeds the upper limit +{ + RegisterHandler(UPDATE_STATUS, &HpaeManager::HandleUpdateStatus); + RegisterHandler(INIT_DEVICE_RESULT, &HpaeManager::HandleInitDeviceResult); + RegisterHandler(DEINIT_DEVICE_RESULT, &HpaeManager::HandleDeInitDeviceResult); + RegisterHandler(MOVE_SINK_INPUT, &HpaeManager::HandleMoveSinkInput); + RegisterHandler(MOVE_ALL_SINK_INPUT, &HpaeManager::HandleMoveAllSinkInputs); + RegisterHandler(MOVE_SOURCE_OUTPUT, &HpaeManager::HandleMoveSourceOutput); + RegisterHandler(MOVE_ALL_SOURCE_OUTPUT, &HpaeManager::HandleMoveAllSourceOutputs); + RegisterHandler(DUMP_SINK_INFO, &HpaeManager::HandleDumpSinkInfo); + RegisterHandler(DUMP_SOURCE_INFO, &HpaeManager::HandleDumpSourceInfo); +} + +HpaeManager::~HpaeManager() +{ + if (IsInit()) { + DeInit(); + } +} + +int32_t HpaeManager::Init() +{ + sinkSourceIndex_ = 0; + hpaeManagerThread_ = std::make_unique(); + hpaeManagerThread_->ActivateThread(this); + hpaePolicyManager_ = std::make_unique(); + isInit_.store(true); + return 0; +} + +int32_t HpaeManager::SuspendAudioDevice(std::string &audioPortName, bool isSuspend) +{ + AUDIO_INFO_LOG("suspend audio device: %{public}s, isSuspend: %{public}d", audioPortName.c_str(), isSuspend); + auto request = [this, audioPortName, isSuspend]() { + if (rendererManagerMap_.find(audioPortName) != rendererManagerMap_.end()) { + rendererManagerMap_[audioPortName]->SuspendStreamManager(isSuspend); + } else if (capturerManagerMap_.find(audioPortName) != capturerManagerMap_.end()) { + AUDIO_WARNING_LOG("capture not support suspend"); + return; + } else { + AUDIO_WARNING_LOG("can not find sink: %{public}s", audioPortName.c_str()); + return; + } + }; + SendRequest(request); + return SUCCESS; +} + +bool HpaeManager::SetSinkMute(const std::string &sinkName, bool isMute, bool isSync) +{ + auto request = [this, sinkName, isMute, isSync]() { + // todo for device change + AUDIO_INFO_LOG("HpaeManager::SetSinkMute sinkName: %{public}s isMute: %{public}d, isSync: %{public}d", + sinkName.c_str(), + isMute, + isSync); + if (rendererManagerMap_.find(sinkName) != rendererManagerMap_.end()) { + rendererManagerMap_[sinkName]->SetMute(isMute); + } else { + AUDIO_WARNING_LOG("can not find sink: %{public}s for mute:%{public}d", sinkName.c_str(), isMute); + } + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnSetSinkMuteCb(SUCCESS); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetSourceOutputMute(int32_t uid, bool setMute) +{ + auto request = [this, uid, setMute]() { + AUDIO_INFO_LOG("HpaeManager::SetSourceOutputMute uid: %{public}d setMute: %{public}d", uid, setMute); + if (capturerIdSourceNameMap_.find(uid) != capturerIdSourceNameMap_.end()) { + capturerManagerMap_[capturerIdSourceNameMap_[uid]]->SetMute(setMute); + } else { + AUDIO_WARNING_LOG("can not find sink: %{public}d for mute:%{public}d", uid, setMute); + } + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnSetSourceOutputMuteCb(SUCCESS); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::GetAllSinks() +{ + auto request = [this]() { + std::vector sinks; + // todo for device change + AUDIO_INFO_LOG("HpaeManager::GetAllSinks end"); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnGetAllSinksCb(SUCCESS, sinks); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::DeInit() +{ + if (hpaeManagerThread_ != nullptr) { + hpaeManagerThread_->DeactivateThread(); + hpaeManagerThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); // todo suspend + isInit_.store(false); + AUDIO_INFO_LOG("HpaeManager::DeInit end"); + return SUCCESS; +} + +int32_t HpaeManager::RegisterSerivceCallback(const std::weak_ptr &callback) +{ + auto request = [this, callback]() { + serviceCallback_ = callback; + AUDIO_INFO_LOG("HpaeManager::RegisterSerivceCallback end"); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::RegisterHpaeDumpCallback(AudioServiceHpaeDumpCallback *callback) +{ + auto request = [this, callback]() { + dumpCallback_ = callback; + AUDIO_INFO_LOG("HpaeManager::RegisterHpaeDumpCallback end"); + }; + SendRequest(request); + return SUCCESS; +} + +AudioSampleFormat HpaeManager::TransFormatFromStringToEnum(std::string format) +{ + return static_cast(formatFromParserStrToEnum[format]); +} + +void HpaeManager::AdjustMchSinkInfo(const AudioModuleInfo &audioModuleInfo, HpaeSinkInfo &sinkInfo) +{ + if (sinkInfo.deviceName != "MCH_Speaker") { + return; + } + sinkInfo.channels = static_cast(DEFAULT_MULTICHANNEL_NUM); + sinkInfo.channelLayout = DEFAULT_MULTICHANNEL_CHANNELLAYOUT; + sinkInfo.frameLen = DEFAULT_MULTICHANNEL_FRAME_LEN_MS * sinkInfo.samplingRate / MS_PER_SECOND; + sinkInfo.volume = MAX_SINK_VOLUME_LEVEL; + AUDIO_INFO_LOG("adjust MCH SINK info ch: %{public}u, channelLayout: %{public}" PRIu64 + " frameLen: %{public}zu volume %{public}f", + sinkInfo.channels, + sinkInfo.channelLayout, + sinkInfo.frameLen, + sinkInfo.volume); +} + +void HpaeManager::TransModuleInfoToHpaeSinkInfo(const AudioModuleInfo &audioModuleInfo, HpaeSinkInfo &sinkInfo) +{ + sinkInfo.deviceNetId = audioModuleInfo.networkId; + sinkInfo.deviceClass = audioModuleInfo.className; + AUDIO_INFO_LOG("HpaeManager::deviceNetId: %{public}s, deviceClass: %{public}s", + sinkInfo.deviceNetId.c_str(), + sinkInfo.deviceClass.c_str()); + sinkInfo.adapterName = audioModuleInfo.adapterName; + sinkInfo.filePath = audioModuleInfo.fileName; + + sinkInfo.samplingRate = static_cast(std::atol(audioModuleInfo.rate.c_str())); + sinkInfo.format = static_cast(TransFormatFromStringToEnum(audioModuleInfo.format)); + sinkInfo.channels = static_cast(std::atol(audioModuleInfo.channels.c_str())); + int32_t bufferSize = static_cast(std::atol(audioModuleInfo.bufferSize.c_str())); + sinkInfo.frameLen = bufferSize / (sinkInfo.channels * GET_SIZE_FROM_FORMAT(sinkInfo.format)); + sinkInfo.channelLayout = 0ULL; + sinkInfo.deviceType = static_cast(std::atol(audioModuleInfo.deviceType.c_str())); + sinkInfo.volume = static_cast(std::atol(audioModuleInfo.deviceType.c_str())); + sinkInfo.openMicSpeaker = static_cast(std::atol(audioModuleInfo.OpenMicSpeaker.c_str())); + sinkInfo.renderInIdleState = static_cast(std::atol(audioModuleInfo.renderInIdleState.c_str())); + sinkInfo.offloadEnable = static_cast(std::atol(audioModuleInfo.offloadEnable.c_str())); + sinkInfo.sinkLatency = static_cast(std::atol(audioModuleInfo.sinkLatency.c_str())); + sinkInfo.fixedLatency = static_cast(std::atol(audioModuleInfo.fixedLatency.c_str())); + sinkInfo.deviceName = audioModuleInfo.name; + AdjustMchSinkInfo(audioModuleInfo, sinkInfo); +} + +void HpaeManager::TransModuleInfoToHpaeSourceInfo(const AudioModuleInfo &audioModuleInfo, HpaeSourceInfo &sourceInfo) +{ + sourceInfo.deviceNetId = audioModuleInfo.networkId; + sourceInfo.deviceClass = audioModuleInfo.className; + sourceInfo.adapterName = audioModuleInfo.adapterName; + sourceInfo.sourceName = audioModuleInfo.name; // built_in_mic + sourceInfo.deviceName = audioModuleInfo.name; + sourceInfo.sourceType = static_cast(std::atol(audioModuleInfo.sourceType.c_str())); + sourceInfo.filePath = audioModuleInfo.fileName; + int32_t bufferSize = static_cast(std::atol(audioModuleInfo.bufferSize.c_str())); + sourceInfo.channels = static_cast(std::atol(audioModuleInfo.channels.c_str())); + sourceInfo.format = TransFormatFromStringToEnum(audioModuleInfo.format); + sourceInfo.frameLen = bufferSize / (sourceInfo.channels * GET_SIZE_FROM_FORMAT(sourceInfo.format)); + sourceInfo.samplingRate = static_cast(std::atol(audioModuleInfo.rate.c_str())); + sourceInfo.channelLayout = 0ULL; + sourceInfo.deviceType = static_cast(std::atol(audioModuleInfo.deviceType.c_str())); + sourceInfo.volume = static_cast(std::atol(audioModuleInfo.deviceType.c_str())); // 1.0f; + + sourceInfo.ecType = static_cast(std::atol(audioModuleInfo.ecType.c_str())); + sourceInfo.ecAdapterName = audioModuleInfo.ecAdapter; + sourceInfo.ecSamplingRate = static_cast(std::atol(audioModuleInfo.ecSamplingRate.c_str())); + sourceInfo.ecFormat = TransFormatFromStringToEnum(audioModuleInfo.ecFormat); + sourceInfo.ecChannels = static_cast(std::atol(audioModuleInfo.ecChannels.c_str())); + sourceInfo.ecFrameLen = DEFAULT_MULTICHANNEL_FRAME_LEN_MS * (sourceInfo.ecSamplingRate / MS_PER_SECOND); + + sourceInfo.micRef = static_cast(std::atol(audioModuleInfo.openMicRef.c_str())); + sourceInfo.micRefSamplingRate = static_cast(std::atol(audioModuleInfo.micRefRate.c_str())); + sourceInfo.micRefFormat = TransFormatFromStringToEnum(audioModuleInfo.micRefFormat); + sourceInfo.micRefChannels = static_cast(std::atol(audioModuleInfo.micRefChannels.c_str())); + sourceInfo.openMicSpeaker = static_cast(std::atol(audioModuleInfo.OpenMicSpeaker.c_str())); + sourceInfo.micRefFrameLen = DEFAULT_MULTICHANNEL_FRAME_LEN_MS * (sourceInfo.micRefSamplingRate / MS_PER_SECOND); +} + +void HpaeManager::PrintAudioModuleInfo(const AudioModuleInfo &audioModuleInfo) +{ + AUDIO_INFO_LOG("rate: %{public}s ch: %{public}s buffersize: %{public}s ", + audioModuleInfo.rate.c_str(), + audioModuleInfo.channels.c_str(), + audioModuleInfo.bufferSize.c_str()); + AUDIO_INFO_LOG("format: %{public}s name: %{public}s lib: %{public}s ", + audioModuleInfo.format.c_str(), + audioModuleInfo.name.c_str(), + audioModuleInfo.lib.c_str()); + AUDIO_INFO_LOG("deviceType: %{public}s className: %{public}s adapterName: %{public}s ", + audioModuleInfo.deviceType.c_str(), + audioModuleInfo.className.c_str(), + audioModuleInfo.adapterName.c_str()); + AUDIO_INFO_LOG("OpenMicSpeaker: %{public}s networkId: %{public}s fileName: %{public}s ", + audioModuleInfo.OpenMicSpeaker.c_str(), + audioModuleInfo.networkId.c_str(), + audioModuleInfo.fileName.c_str()); + AUDIO_INFO_LOG("fixedLatency: %{public}s sinkLatency: %{public}s renderInIdleState: %{public}s ", + audioModuleInfo.fixedLatency.c_str(), + audioModuleInfo.sinkLatency.c_str(), + audioModuleInfo.renderInIdleState.c_str()); + AUDIO_INFO_LOG("sceneName: %{public}s sourceType: %{public}s offloadEnable: %{public}s ", + audioModuleInfo.sceneName.c_str(), + audioModuleInfo.sourceType.c_str(), + audioModuleInfo.offloadEnable.c_str()); +} + +uint32_t HpaeManager::OpenOutputAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex) +{ + if (rendererManagerMap_.find(audioModuleInfo.name) != rendererManagerMap_.end()) { + AUDIO_INFO_LOG("sink name: %{public}s already open", audioModuleInfo.name.c_str()); + if (!rendererManagerMap_[audioModuleInfo.name]->IsInit()) { + rendererManagerMap_[audioModuleInfo.name]->Init(); + MoveToPreferSink(audioModuleInfo.name); + } else if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnOpenAudioPortCb(sinkNameSinkIdMap_[audioModuleInfo.name]); + } + return sinkNameSinkIdMap_[audioModuleInfo.name]; + } + sinkSourceIndex_.fetch_add(1); + HpaeSinkInfo sinkInfo; + sinkInfo.sinkId = sinkSourceIndex; + sinkInfo.suspendTime = DEFAULT_SUSPEND_TIME_IN_MS; + TransModuleInfoToHpaeSinkInfo(audioModuleInfo, sinkInfo); + auto rendererManager = IHpaeRendererManager::CreateRendererManager(sinkInfo); + rendererManagerMap_[audioModuleInfo.name] = rendererManager; + sinkNameSinkIdMap_[audioModuleInfo.name] = sinkSourceIndex; + sinkIdSinkNameMap_[sinkSourceIndex] = audioModuleInfo.name; + rendererManager->Init(); + rendererManager->RegisterSendMsgCallback(weak_from_this()); + MoveToPreferSink(audioModuleInfo.name); + AUDIO_INFO_LOG( + "open sink name: %{public}s end sinkIndex is %{public}u", audioModuleInfo.name.c_str(), sinkSourceIndex); + uint32_t renderId = GetRenderId(sinkInfo.deviceClass); + // todo: set renderId to CaptureManger + hpaePolicyManager_->SetOutputDevice(renderId, static_cast(sinkInfo.deviceType)); + return SUCCESS; +} + +uint32_t HpaeManager::OpenInputAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex) +{ + if (capturerManagerMap_.find(audioModuleInfo.name) != capturerManagerMap_.end()) { + HpaeEcType ecType = static_cast(std::atol(audioModuleInfo.ecType.c_str())); + HpaeMicRefSwitch micRef = static_cast(std::atol(audioModuleInfo.openMicRef.c_str())); + HpaeSourceInfo oldInfo = capturerManagerMap_[audioModuleInfo.name]->GetSourceInfo(); + if (oldInfo.ecType != ecType || oldInfo.micRef != micRef) { + AUDIO_INFO_LOG("source name: %{public}s need reload", audioModuleInfo.name.c_str()); + HpaeSourceInfo sourceInfo; + sourceInfo.sourceId = oldInfo.sourceId; + TransModuleInfoToHpaeSourceInfo(audioModuleInfo, sourceInfo); + capturerManagerMap_[audioModuleInfo.name]->ReloadCaptureManager(sourceInfo); + return sourceNameSourceIdMap_[audioModuleInfo.name]; + } + AUDIO_INFO_LOG("source name: %{public}s already open", audioModuleInfo.name.c_str()); + if (!capturerManagerMap_[audioModuleInfo.name]->IsInit()) { + capturerManagerMap_[audioModuleInfo.name]->Init(); + } else if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnOpenAudioPortCb(sourceNameSourceIdMap_[audioModuleInfo.name]); + } + return sourceNameSourceIdMap_[audioModuleInfo.name]; + } + sinkSourceIndex_.fetch_add(1); + HpaeSourceInfo sourceInfo; + sourceInfo.sourceId = sinkSourceIndex; + TransModuleInfoToHpaeSourceInfo(audioModuleInfo, sourceInfo); + auto capturerManager = std::make_shared(sourceInfo); + capturerManagerMap_[audioModuleInfo.name] = capturerManager; + sourceNameSourceIdMap_[audioModuleInfo.name] = sinkSourceIndex; + sourceIdSourceNameMap_[sinkSourceIndex] = audioModuleInfo.name; + capturerManagerMap_[audioModuleInfo.name]->Init(); + capturerManager->RegisterSendMsgCallback(weak_from_this()); + AUDIO_INFO_LOG( + "open source name: %{public}s end sourceIndex is %{public}u", audioModuleInfo.name.c_str(), sinkSourceIndex); + uint32_t captureId = GetCaptureId(sourceInfo.deviceClass); + capturerManager->SetCaptureId(captureId); + hpaePolicyManager_->SetInputDevice(captureId, static_cast(sourceInfo.deviceType)); + return SUCCESS; +} + +uint32_t HpaeManager::OpenVirtualAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex) +{ + if (rendererManagerMap_.find(audioModuleInfo.name) != rendererManagerMap_.end()) { + AUDIO_INFO_LOG("inner capture name: %{public}s already open", audioModuleInfo.name.c_str()); + if (!rendererManagerMap_[audioModuleInfo.name]->IsInit()) { + rendererManagerMap_[audioModuleInfo.name]->Init(); + } else if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnOpenAudioPortCb(sinkNameSinkIdMap_[audioModuleInfo.name]); + } + return sinkNameSinkIdMap_[audioModuleInfo.name]; + } + sinkSourceIndex_.fetch_add(1); + HpaeSinkInfo sinkInfo; + sinkInfo.sinkId = sinkSourceIndex; + TransModuleInfoToHpaeSinkInfo(audioModuleInfo, sinkInfo); + auto rendererManager = IHpaeRendererManager::CreateRendererManager(sinkInfo); + rendererManagerMap_[audioModuleInfo.name] = rendererManager; + sinkNameSinkIdMap_[audioModuleInfo.name] = sinkSourceIndex; + sinkIdSinkNameMap_[sinkSourceIndex] = audioModuleInfo.name; + rendererManagerMap_[audioModuleInfo.name]->Init(); + rendererManager->RegisterSendMsgCallback(weak_from_this()); + AUDIO_INFO_LOG("HpaeManager::OpenAudioPort name: %{public}s end sinkIndex is %{public}u", + audioModuleInfo.name.c_str(), + sinkSourceIndex); + return SUCCESS; +} + +int32_t HpaeManager::OpenAudioPortInner(const AudioModuleInfo &audioModuleInfo) +{ + int32_t sinkSourceIndex = sinkSourceIndex_.load(); + if ((audioModuleInfo.lib != "libmodule-hdi-source.z.so") && + (audioModuleInfo.lib != "libmodule-inner-capturer-sink.z.so")) { + OpenOutputAudioPort(audioModuleInfo, sinkSourceIndex); + } else if (audioModuleInfo.lib == "libmodule-hdi-source.z.so") { + OpenInputAudioPort(audioModuleInfo, sinkSourceIndex); + } else { + OpenVirtualAudioPort(audioModuleInfo, sinkSourceIndex); + } + return sinkSourceIndex; +} + +uint32_t HpaeManager::OpenAudioPort(const AudioModuleInfo &audioModuleInfo) +{ + auto request = [this, audioModuleInfo]() { + PrintAudioModuleInfo(audioModuleInfo); + OpenAudioPortInner(audioModuleInfo); + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeManager::DumpSinkInfo(std::string deviceName) +{ + auto request = [this, deviceName]() { + AUDIO_INFO_LOG("DumpSinkInfo %{public}s", deviceName.c_str()); + if (rendererManagerMap_.find(deviceName) == rendererManagerMap_.end()) { + AUDIO_WARNING_LOG("can not find sinkName: %{public}s in rendererManagerMap_", deviceName.c_str()); + if (dumpCallback_) { + std::string dumpStr; + dumpCallback_->OnDumpSinkInfoCb(dumpStr, ERROR); + } + return; + } + rendererManagerMap_[deviceName]->DumpSinkInfo(); + }; + SendRequest(request); +} + +void HpaeManager::DumpSourceInfo(std::string deviceName) +{ + auto request = [this, deviceName]() { + AUDIO_INFO_LOG("DumpSourceInfo %{public}s", deviceName.c_str()); + if (capturerManagerMap_.find(deviceName) == capturerManagerMap_.end()) { + AUDIO_WARNING_LOG("can not find sourceName: %{public}s in capturerManagerMap_", deviceName.c_str()); + if (dumpCallback_) { + std::string dumpStr; + dumpCallback_->OnDumpSourceInfoCb(dumpStr, ERROR); + } + return; + } + capturerManagerMap_[deviceName]->DumpSourceInfo(); + }; + SendRequest(request); +} + +int32_t HpaeManager::CloseOutAudioPort(std::string &sinkName) +{ + if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { + AUDIO_WARNING_LOG("can not find sinkName: %{public}s in rendererManagerMap_", sinkName.c_str()); + return SUCCESS; + } + rendererManagerMap_[sinkName]->DeInit(sinkName != defaultSink_); + if (sinkName != defaultSink_) { + rendererManagerMap_.erase(sinkName); + sinkIdSinkNameMap_.erase(sinkNameSinkIdMap_[sinkName]); + sinkNameSinkIdMap_.erase(sinkName); + } + return SUCCESS; +} + +int32_t HpaeManager::CloseInAudioPort(std::string &sourceName) +{ + if (capturerManagerMap_.find(sourceName) == capturerManagerMap_.end()) { + AUDIO_WARNING_LOG("can not find sourceName: %{public}s in capturerManagerMap_", sourceName.c_str()); + return SUCCESS; + } + capturerManagerMap_[sourceName]->DeInit(sourceName != defaultSource_); + if (sourceName != defaultSource_) { + capturerManagerMap_.erase(sourceName); + sourceIdSourceNameMap_.erase(sourceNameSourceIdMap_[sourceName]); + sourceNameSourceIdMap_.erase(sourceName); + } + return SUCCESS; +} + +int32_t HpaeManager::CloseAudioPort(int32_t audioHandleIndex) +{ + auto request = [this, audioHandleIndex]() { + int32_t ret = -1; + if (sinkIdSinkNameMap_.find(audioHandleIndex) != sinkIdSinkNameMap_.end()) { + AUDIO_INFO_LOG("close sink index: %{public}d name %{public}s", + audioHandleIndex, + sinkIdSinkNameMap_[audioHandleIndex].c_str()); + ret = CloseOutAudioPort(sinkIdSinkNameMap_[audioHandleIndex]); + } else { + AUDIO_INFO_LOG("close source index: %{public}d name %{public}s", + audioHandleIndex, + sourceIdSourceNameMap_[audioHandleIndex].c_str()); + ret = CloseInAudioPort(sourceIdSourceNameMap_[audioHandleIndex]); + } + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnCloseAudioPortCb(ret); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetDefaultSink(std::string name) +{ + auto request = [this, name]() { + AUDIO_INFO_LOG("SetDefaultSink name: %{public}s", name.c_str()); + if (name == defaultSink_) { + AUDIO_INFO_LOG("sink is same as default sink"); + return; + } + std::shared_ptr rendererManager = GetRendererManagerByNmae(defaultSink_); + if (rendererManager == nullptr) { + AUDIO_INFO_LOG("default sink not exist, set default sink direct"); + defaultSink_ = name; + return; + } + if (rendererManagerMap_.find(name) == rendererManagerMap_.end()) { + AUDIO_WARNING_LOG("sink: %{public}s not exist, do not change default sink", name.c_str()); + return; + } + std::vector sessionIds; + rendererManager->MoveAllStream(name, sessionIds, true); + std::string oldDefaultSink = defaultSink_; + defaultSink_ = name; + if (!rendererManager->IsInit()) { + rendererManagerMap_.erase(defaultSink_); + sinkIdSinkNameMap_.erase(sinkNameSinkIdMap_[defaultSink_]); + sinkNameSinkIdMap_.erase(defaultSink_); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetDefaultSource(std::string name) +{ + AUDIO_INFO_LOG("HpaeManager::SetDefaultSource name: %{public}s", name.c_str()); + auto request = [this, name]() { + if (name == defaultSource_) { + AUDIO_INFO_LOG("source is same as default source"); + return; + } + std::shared_ptr capturerManager = GetCapturerManagerByName(defaultSource_); + if (capturerManager == nullptr) { + AUDIO_INFO_LOG("default source not exist, set default source direct"); + defaultSource_ = name; + return; + } + if (capturerManagerMap_.find(name) == capturerManagerMap_.end()) { + AUDIO_WARNING_LOG("source: %{public}s not exist, do not change default source", name.c_str()); + return; + } + std::vector sessionIds; + capturerManager->MoveAllStream(name, sessionIds, true); + std::string oldDefaultSource_ = defaultSource_; + defaultSource_ = name; + if (!capturerManager->IsInit()) { + capturerManagerMap_.erase(oldDefaultSource_); + sourceIdSourceNameMap_.erase(sourceNameSourceIdMap_[oldDefaultSource_]); + sourceNameSourceIdMap_.erase(oldDefaultSource_); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::GetAllSinkInputs() +{ + AUDIO_INFO_LOG("GetAllSinkInputs"); + auto request = [this]() { + std::vector results; + std::transform(sinkInputs_.begin(), sinkInputs_.end(), std::back_inserter(results), [](const auto &pair) { + return pair.second; + }); + AUDIO_INFO_LOG("sink input number:%{public}zu", results.size()); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnGetAllSinkInputsCb(SUCCESS, results); + } + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeManager::MoveToPreferSink(const std::string &name) +{ + AUDIO_INFO_LOG("enter in"); + std::unordered_map> sinkIdMap; + for (const auto &id : idPreferSinkNameMap_) { + if (id.second == name && rendererIdSinkNameMap_[id.first] != id.second) { + if (sinkIdMap.find(id.second) == sinkIdMap.end()) { + sinkIdMap[id.second] = std::vector{}; + } + sinkIdMap[id.second].push_back(id.first); + } + } + for (const auto &sinkId : sinkIdMap) { + std::string sinkName = sinkId.first; + const std::vector ids = sinkId.second; + auto request = [this, sinkName, name, ids]() { + AUDIO_INFO_LOG("MoveToPreferSink name: %{public}s", name.c_str()); + if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { + AUDIO_ERR_LOG("can not find prefer sink: %{public}s", sinkName.c_str()); + return; + } + rendererManagerMap_[sinkName]->MoveAllStream(name, ids, false); + }; + SendRequest(request); + } +} + +int32_t HpaeManager::GetAllSourceOutputs() +{ + AUDIO_INFO_LOG("GetAllSourceOutputs"); + auto request = [this]() { + std::vector results; + std::transform(sourceOutputs_.begin(), sourceOutputs_.end(), std::back_inserter(results), [](const auto &pair) { + return pair.second; + }); + AUDIO_INFO_LOG("source output number:%{public}zu", results.size()); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnGetAllSourceOutputsCb(SUCCESS, results); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::MoveSourceOutputByIndexOrName( + uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) +{ + auto request = [this, sourceOutputId, sourceName]() { + AUDIO_INFO_LOG("start to move id:%{public}d, source name:%{public}s", sourceOutputId, sourceName.c_str()); + if (sourceName.empty()) { + AUDIO_ERR_LOG("source name is empty."); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSourceOutputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + + std::shared_ptr oldCaptureManager = GetCapturerManagerById(sourceOutputId); + if (oldCaptureManager == nullptr) { + AUDIO_ERR_LOG("can not find source by id:%{public}d.", sourceOutputId); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSourceOutputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + if (capturerManagerMap_.find(sourceName) == capturerManagerMap_.end()) { + AUDIO_ERR_LOG("can not find source by name:%{public}s.", sourceName.c_str()); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSourceOutputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + if (sourceName == capturerIdSourceNameMap_[sourceOutputId]) { + AUDIO_INFO_LOG("source is the same, no need move,source name:%{public}s", sourceName.c_str()); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSourceOutputByIndexOrNameCb(SUCCESS); + } + return; + } + oldCaptureManager->MoveStream(sourceOutputId, sourceName); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) +{ + auto request = [this, sinkInputId, sinkName]() { + AUDIO_INFO_LOG("start to move id:%{public}d, sink name:%{public}s", sinkInputId, sinkName.c_str()); + if (sinkName.empty()) { + AUDIO_ERR_LOG("sink name is empty."); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + std::shared_ptr oldRendererManager = GetRendererManagerById(sinkInputId); + if (oldRendererManager == nullptr) { + AUDIO_ERR_LOG("can not find sink by id:%{public}d", sinkInputId); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + if (sinkName == rendererIdSinkNameMap_[sinkInputId]) { + AUDIO_INFO_LOG("sink is the same, no need move,sink:%{public}s", sinkName.c_str()); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSinkInputByIndexOrNameCb(SUCCESS); + } + return; + } + if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { + AUDIO_ERR_LOG("can not find sink:%{public}s.", sinkName.c_str()); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + if (rendererIdStreamInfoMap_.find(sinkInputId) == rendererIdStreamInfoMap_.end()) { + AUDIO_ERR_LOG("can not find session info:%{public}d", sinkInputId); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + oldRendererManager->MoveStream(sinkInputId, sinkName); + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeManager::HandleMsg() +{ + hpaeNoLockQueue_.HandleRequests(); +} + +bool HpaeManager::IsInit() +{ + return isInit_.load(); +} + +bool HpaeManager::IsRunning() +{ + if (hpaeManagerThread_ == nullptr) { + return false; + } + return hpaeManagerThread_->IsRunning(); +} + +bool HpaeManager::IsMsgProcessing() +{ + return !hpaeNoLockQueue_.IsFinishProcess(); +} + +int32_t HpaeManager::GetMsgCount() +{ + return receiveMsgCount_.load(); +} + +void HpaeManager::Invoke(HpaeMsgCode cmdID, const std::any &args) +{ + auto it = handlers_.find(cmdID); + if (it != handlers_.end()) { + auto request = [it, args]() { it->second(args); }; + SendRequest(request); + return; + }; + AUDIO_ERR_LOG("HpaeManager::Invoke cmdID %{public}d not found", (int32_t)cmdID); +} + +template +void HpaeManager::RegisterHandler(HpaeMsgCode cmdID, void (HpaeManager::*func)(Args...)) +{ + handlers_[cmdID] = [this, cmdID, func](const std::any &packedArgs) { + // unpack args + auto args = std::any_cast>(&packedArgs); + // print log if args parse error + CHECK_AND_RETURN_LOG(args != nullptr, "cmdId %{public}d type mismatched", cmdID); + std::apply( + [this, func]( + auto &&...unpackedArgs) { (this->*func)(std::forward(unpackedArgs)...); }, + *args); + }; +} + +void HpaeManager::HandleMoveSinkInput(const std::shared_ptr sinkInputNode, std::string sinkName) +{ + AUDIO_INFO_LOG("move to new sink:%{public}s", sinkName.c_str()); + std::shared_ptr rendererManager = GetRendererManagerByNmae(sinkName); + if (rendererManager == nullptr) { + AUDIO_ERR_LOG("can not find sink by new name:%{public}s", sinkName.c_str()); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + uint32_t sessionId = sinkInputNode->GetNodeInfo().sessionId; + rendererManager->AddNodeToSink(sinkInputNode); + rendererIdSinkNameMap_[sessionId] = sinkName; + idPreferSinkNameMap_[sessionId] = sinkName; + if (sinkInputs_.find(sessionId) != sinkInputs_.end()) { + sinkInputs_[sessionId].deviceSinkId = sinkNameSinkIdMap_[sinkName]; + sinkInputs_[sessionId].sinkName = sinkName; + } + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSinkInputByIndexOrNameCb(SUCCESS); + } +} + +void HpaeManager::HandleMoveSourceOutput(const HpaeCaptureMoveInfo moveInfo, std::string sourceName) +{ + AUDIO_INFO_LOG("move to new source:%{public}s", sourceName.c_str()); + std::shared_ptr catpureManager = GetCapturerManagerByName(sourceName); + if (catpureManager == nullptr) { + AUDIO_ERR_LOG("can not find source by name:%{public}s", sourceName.c_str()); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSourceOutputByIndexOrNameCb(ERROR_INVALID_PARAM); + } + return; + } + uint32_t sessionId = moveInfo.sessionId; + catpureManager->AddNodeToSource(moveInfo); + capturerIdSourceNameMap_[sessionId] = sourceName; + if (sourceOutputs_.find(sessionId) != sourceOutputs_.end()) { + sourceOutputs_[sessionId].deviceSourceId = sourceNameSourceIdMap_[sourceName]; + } + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnMoveSourceOutputByIndexOrNameCb(SUCCESS); + } +} + +void HpaeManager::HandleMoveAllSinkInputs( + const std::vector> sinkInputs, std::string sinkName) +{ + AUDIO_INFO_LOG("sink name is :%{public}s", sinkName.c_str()); + if (sinkName.empty()) { + AUDIO_INFO_LOG("sink name is empty, move to default sink:%{public}s", defaultSink_.c_str()); + sinkName = defaultSink_; + } + if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { + AUDIO_WARNING_LOG("can not find sink: %{public}s", sinkName.c_str()); + return; + } + AUDIO_INFO_LOG("sink input count:%{public}zu", sinkInputs.size()); + rendererManagerMap_[sinkName]->AddAllNodesToSink(sinkInputs, false); + for (const auto &sinkInput : sinkInputs) { + uint32_t sessionId = sinkInput->GetNodeInfo().sessionId; + rendererIdSinkNameMap_[sessionId] = sinkName; + if (sinkInputs_.find(sessionId) != sinkInputs_.end()) { + sinkInputs_[sessionId].deviceSinkId = sinkNameSinkIdMap_[sinkName]; + sinkInputs_[sessionId].sinkName = sinkName; + } + } +} + +void HpaeManager::HandleMoveAllSourceOutputs(const std::vector moveInfos, std::string sourceName) +{ + AUDIO_INFO_LOG("move all source to :%{public}s", sourceName.c_str()); + if (sourceName.empty()) { + AUDIO_INFO_LOG("source is empty, move to default source:%{public}s", defaultSource_.c_str()); + sourceName = defaultSource_; + } + if (capturerManagerMap_.find(sourceName) == capturerManagerMap_.end()) { + AUDIO_WARNING_LOG("can not find source: %{public}s", sourceName.c_str()); + return; + } + AUDIO_INFO_LOG("sink input count:%{public}zu", moveInfos.size()); + capturerManagerMap_[sourceName]->AddAllNodesToSource(moveInfos, false); + for (const auto &it : moveInfos) { + capturerIdSourceNameMap_[it.sessionId] = sourceName; + if (sourceOutputs_.find(it.sessionId) != sourceOutputs_.end()) { + sourceOutputs_[it.sessionId].deviceSourceId = sourceNameSourceIdMap_[sourceName]; + } + } +} + +void HpaeManager::HandleUpdateStatus( + HpaeStreamClassType streamClassType, uint32_t sessionId, uint32_t status, IOperation operation) +{ + AUDIO_INFO_LOG("HpaeManager::HandleUpdateStatus sessionid:%{public}u " + "status:%{public}d operation:%{public}d", + sessionId, + status, + operation); + if (operation == OPERATION_INVALID) { + // maybe dosomething while move sink inputs + return; + } + auto it = streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY ? rendererIdStreamInfoMap_.find(sessionId) + : capturerIdStreamInfoMap_.find(sessionId); + if (it != rendererIdStreamInfoMap_.end() && it != capturerIdStreamInfoMap_.end()) { + if (auto callback = it->second.statusCallback.lock()) { + callback->OnStatusUpdate(operation); + } + } +} + +void HpaeManager::HandleDumpSinkInfo(std::string deviceName, std::string dumpStr) +{ + AUDIO_INFO_LOG("HpaeManager::HandleDumpSinkInfo deviceName:%{public}s dumpStr:%{public}s", + deviceName.c_str(), + dumpStr.c_str()); + if (dumpCallback_) { + dumpCallback_->OnDumpSinkInfoCb(dumpStr, SUCCESS); + } +} + +void HpaeManager::HandleDumpSourceInfo(std::string deviceName, std::string dumpStr) +{ + AUDIO_INFO_LOG("HpaeManager::HandleDumpSourceInfo deviceName:%{public}s dumpStr:%{public}s", + deviceName.c_str(), + dumpStr.c_str()); + if (dumpCallback_) { + dumpCallback_->OnDumpSourceInfoCb(dumpStr, SUCCESS); + } +} + +void HpaeManager::HandleInitDeviceResult(std::string deviceName, int32_t result) +{ + AUDIO_INFO_LOG("deviceName:%{public}s result:%{public}d ", deviceName.c_str(), result); + auto serviceCallback = serviceCallback_.lock(); + if (serviceCallback && result == SUCCESS) { + if (sinkNameSinkIdMap_.find(deviceName) != sinkNameSinkIdMap_.end()) { + serviceCallback->OnOpenAudioPortCb(sinkNameSinkIdMap_[deviceName]); + } else if (sourceNameSourceIdMap_.find(deviceName) != sourceNameSourceIdMap_.end()) { + serviceCallback->OnOpenAudioPortCb(sourceNameSourceIdMap_[deviceName]); + } else { + AUDIO_ERR_LOG("device:%{public}s is not exist.", deviceName.c_str()); + serviceCallback->OnOpenAudioPortCb(ERROR); + } + } else if (serviceCallback) { + serviceCallback->OnOpenAudioPortCb(ERROR); + AUDIO_INFO_LOG("HandleInitDeviceResult deviceName:%{public}s " + "result:%{public}d error", + deviceName.c_str(), + result); + } else { + AUDIO_INFO_LOG("HandleInitDeviceResult OnOpenAudioPortCb is nullptr"); + } +} + +void HpaeManager::HandleDeInitDeviceResult(std::string deviceName, int32_t result) +{ + AUDIO_INFO_LOG("deviceName:%{public}s result:%{public}d ", deviceName.c_str(), result); + auto serviceCallback = serviceCallback_.lock(); + if (serviceCallback && result == SUCCESS && sinkNameSinkIdMap_.find(deviceName) != sinkNameSinkIdMap_.end()) { + serviceCallback->OnCloseAudioPortCb(sinkNameSinkIdMap_[deviceName]); + } else if (serviceCallback) { + serviceCallback->OnCloseAudioPortCb(ERROR); + AUDIO_INFO_LOG("deviceName:%{public}s " + "result:%{public}d error", + deviceName.c_str(), + result); + } else { + AUDIO_INFO_LOG("HandleDeInitDeviceResult is nullptr"); + } + if (rendererManagerMap_.find(deviceName) != rendererManagerMap_.end()) { + AUDIO_INFO_LOG("OnCloseAudioPortCb is sink"); + rendererManagerMap_[deviceName]->DeactivateThread(); + if (deviceName != defaultSink_) { + rendererManagerMap_.erase(deviceName); + sinkIdSinkNameMap_.erase(sinkNameSinkIdMap_[deviceName]); + sinkNameSinkIdMap_.erase(deviceName); + } + } else if (capturerManagerMap_.find(deviceName) != capturerManagerMap_.end()) { + AUDIO_INFO_LOG("OnCloseAudioPortCb is source"); + capturerManagerMap_[deviceName]->DeactivateThread(); + if (deviceName != defaultSource_) { + capturerManagerMap_.erase(deviceName); + sourceIdSourceNameMap_.erase(sourceNameSourceIdMap_[deviceName]); + sourceNameSourceIdMap_.erase(deviceName); + } + } else { + AUDIO_INFO_LOG("deviceName:%{public}s can not find", deviceName.c_str()); + } +} + +void HpaeManager::SendRequest(Request &&request) +{ + hpaeNoLockQueue_.PushRequest(std::move(request)); + CHECK_AND_RETURN_LOG(hpaeManagerThread_, "hpaeManagerThread_ is nullptr"); + hpaeManagerThread_->Notify(); +} +// play and record stream interface +int32_t HpaeManager::CreateStream(const HpaeStreamInfo &streamInfo) +{ + auto request = [this, streamInfo]() { + AUDIO_INFO_LOG("defaultSink_ is %{public}s defaultSource_ is %{public}s streamClassType %{public}u", + defaultSink_.c_str(), + defaultSource_.c_str(), + streamInfo.streamClassType); + AUDIO_INFO_LOG("streamType is %{public}d sessionId %{public}u sourceType is %{public}d", + streamInfo.streamType, + streamInfo.sessionId, + streamInfo.sourceType); + if (INNER_SOURCE_TYPE_SET.count(streamInfo.sourceType) != 0) { + return CreateStreamForCapInner(streamInfo); + } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { + std::string deviceName = streamInfo.deviceName == "" ? defaultSink_ : streamInfo.deviceName; + AUDIO_INFO_LOG("devicename:%{public}s, sessionId:%{public}u", deviceName.c_str(), streamInfo.sessionId); + CHECK_AND_RETURN_LOG(rendererManagerMap_.find(deviceName) != rendererManagerMap_.end(), + "can not find sink[%{public}s] in rendererManagerMap_", + deviceName.c_str()); + rendererIdSinkNameMap_[streamInfo.sessionId] = defaultSink_; + rendererManagerMap_[defaultSink_]->CreateStream(streamInfo); + rendererIdStreamInfoMap_[streamInfo.sessionId].streamInfo = streamInfo; + rendererIdStreamInfoMap_[streamInfo.sessionId].state = I_STATUS_IDLE; + AddStreamToCollection(streamInfo); + } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD) { + std::string deviceName = streamInfo.deviceName == "" ? defaultSource_ : streamInfo.deviceName; + AUDIO_INFO_LOG("source:%{public}s, sessionId:%{public}u", deviceName.c_str(), streamInfo.sessionId); + CHECK_AND_RETURN_LOG(capturerManagerMap_.find(deviceName) != capturerManagerMap_.end(), + "can not find source[%{public}s] in capturerManagerMap_", + deviceName.c_str()); + capturerIdSourceNameMap_[streamInfo.sessionId] = deviceName; + capturerManagerMap_[deviceName]->CreateStream(streamInfo); + capturerIdStreamInfoMap_[streamInfo.sessionId].streamInfo = streamInfo; + capturerIdStreamInfoMap_[streamInfo.sessionId].state = I_STATUS_IDLE; + AddStreamToCollection(streamInfo); + } else { + AUDIO_WARNING_LOG( + "can not find default sink or source streamClassType %{public}d", streamInfo.streamClassType); + } + }; + SendRequest(request); + AUDIO_WARNING_LOG( + "defaultSink_ is %{public}s streamClassType %{public}u", defaultSink_.c_str(), streamInfo.sessionId); + return SUCCESS; +} + +void HpaeManager::AddStreamToCollection(const HpaeStreamInfo &streamInfo) +{ + auto now = std::chrono::system_clock::now(); + auto ms = std::chrono::duration_cast(now.time_since_epoch()); + if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { + SinkInput sinkInput; + sinkInput.streamId = streamInfo.sessionId; + sinkInput.paStreamId = streamInfo.sessionId; + sinkInput.streamType = streamInfo.streamType; + sinkInput.sinkName = defaultSink_; + sinkInput.deviceSinkId = sinkNameSinkIdMap_[defaultSink_]; + sinkInput.pid = streamInfo.pid; + sinkInput.uid = streamInfo.uid; + sinkInput.startTime = ms.count(); + sinkInputs_[streamInfo.sessionId] = sinkInput; + } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD) { + SourceOutput sourceOutputInfo; + sourceOutputInfo.streamId = streamInfo.sessionId; + sourceOutputInfo.paStreamId = streamInfo.sessionId; + sourceOutputInfo.streamType = streamInfo.streamType; + sourceOutputInfo.deviceSourceId = sourceNameSourceIdMap_[defaultSource_]; + sourceOutputInfo.pid = streamInfo.pid; + sourceOutputInfo.uid = streamInfo.uid; + sourceOutputInfo.startTime = ms.count(); + sourceOutputs_[streamInfo.sessionId] = sourceOutputInfo; + } +} + +int32_t HpaeManager::DestroyStream(HpaeStreamClassType streamClassType, uint32_t sessionId) +{ + auto request = [this, streamClassType, sessionId]() { + AUDIO_INFO_LOG("DestroyStream streamClassType %{public}d, sessionId %{public}u", streamClassType, sessionId); + if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && + rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->DestroyStream(sessionId); + rendererIdSinkNameMap_.erase(sessionId); + rendererIdStreamInfoMap_.erase(sessionId); + sinkInputs_.erase(sessionId); + } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && + capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { + rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->DestroyStream(sessionId); + } else { + capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->DestroyStream(sessionId); + } + capturerIdSourceNameMap_.erase(sessionId); + capturerIdStreamInfoMap_.erase(sessionId); + sourceOutputs_.erase(sessionId); + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->HandleSourceAudioStreamRemoved(sessionId); + } + } else { + AUDIO_WARNING_LOG( + "can not find sessionId streamClassType %{public}d, sessionId %{public}u", streamClassType, sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} +int32_t HpaeManager::Start(HpaeStreamClassType streamClassType, uint32_t sessionId) +{ + auto request = [this, streamClassType, sessionId]() { + AUDIO_INFO_LOG( + "HpaeManager::Start sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); + if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && + rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + AUDIO_INFO_LOG("renderer Start sessionId: %{public}u deviceName:%{public}s", + sessionId, + rendererIdSinkNameMap_[sessionId].c_str()); + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Start(sessionId); + rendererIdStreamInfoMap_[sessionId].state = I_STATUS_STARTING; + rendererIdStreamInfoMap_[sessionId].statusCallback.lock()->OnStatusUpdate(OPERATION_STARTED); + } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && + capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + AUDIO_INFO_LOG("capturer Start sessionId: %{public}u deviceName:%{public}s", + sessionId, + capturerIdSourceNameMap_[sessionId].c_str()); + if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { + rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Start(sessionId); + } else { + capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Start(sessionId); + } + capturerIdStreamInfoMap_[sessionId].state = I_STATUS_STARTING; + } else { + AUDIO_WARNING_LOG("Start can not find sessionId streamClassType %{public}d, sessionId %{public}u", + streamClassType, + sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} +int32_t HpaeManager::Pause(HpaeStreamClassType streamClassType, uint32_t sessionId) +{ + auto request = [this, streamClassType, sessionId]() { + AUDIO_INFO_LOG( + "HpaeManager::Pause sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); + if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && + rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + AUDIO_INFO_LOG("renderer Pause sessionId: %{public}u deviceName:%{public}s", + sessionId, + rendererIdSinkNameMap_[sessionId].c_str()); + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Pause(sessionId); + rendererIdStreamInfoMap_[sessionId].state = I_STATUS_PAUSING; + } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && + capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + AUDIO_INFO_LOG("capturer Pause sessionId: %{public}u deviceName:%{public}s", + sessionId, + capturerIdSourceNameMap_[sessionId].c_str()); + if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { + rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Pause(sessionId); + } else { + capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Pause(sessionId); + } + capturerIdStreamInfoMap_[sessionId].state = I_STATUS_PAUSING; + } else { + AUDIO_WARNING_LOG("Pause can not find sessionId streamClassType %{public}d, sessionId %{public}u", + streamClassType, + sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} +int32_t HpaeManager::Flush(HpaeStreamClassType streamClassType, uint32_t sessionId) +{ + auto request = [this, streamClassType, sessionId]() { + AUDIO_INFO_LOG( + "HpaeManager::Flush sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); + if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && + rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + AUDIO_INFO_LOG("renderer Flush sessionId: %{public}u deviceName:%{public}s", + sessionId, + rendererIdSinkNameMap_[sessionId].c_str()); + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Flush(sessionId); + rendererIdStreamInfoMap_[sessionId].state = I_STATUS_FLUSHING_WHEN_STOPPED; + } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && + capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + AUDIO_INFO_LOG("capturer Flush sessionId: %{public}u deviceName:%{public}s", + sessionId, + capturerIdSourceNameMap_[sessionId].c_str()); + if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { + rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Flush(sessionId); + } else { + capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Flush(sessionId); + } + capturerIdStreamInfoMap_[sessionId].state = I_STATUS_FLUSHING_WHEN_STOPPED; + } else { + AUDIO_WARNING_LOG("Flush can not find sessionId streamClassType %{public}d, sessionId %{public}u", + streamClassType, + sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} +int32_t HpaeManager::Drain(HpaeStreamClassType streamClassType, uint32_t sessionId) +{ + auto request = [this, streamClassType, sessionId]() { + AUDIO_INFO_LOG( + "HpaeManager::Drain sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); + if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && + rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + AUDIO_INFO_LOG("renderer Drain sessionId: %{public}u deviceName:%{public}s", + sessionId, + rendererIdSinkNameMap_[sessionId].c_str()); + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Drain(sessionId); + rendererIdStreamInfoMap_[sessionId].state = I_STATUS_DRAINING; + } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && + capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + AUDIO_INFO_LOG("capturer Drain sessionId: %{public}u deviceName:%{public}s", + sessionId, + capturerIdSourceNameMap_[sessionId].c_str()); + if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { + rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Drain(sessionId); + } else { + capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Drain(sessionId); + } + capturerIdStreamInfoMap_[sessionId].state = I_STATUS_DRAINING; + } else { + AUDIO_WARNING_LOG("Drain can not find sessionId streamClassType %{public}d, sessionId %{public}u", + streamClassType, + sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} +int32_t HpaeManager::Stop(HpaeStreamClassType streamClassType, uint32_t sessionId) +{ + auto request = [this, streamClassType, sessionId]() { + AUDIO_INFO_LOG( + "HpaeManager::Stop sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); + if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && + rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + AUDIO_INFO_LOG("renderer Stop sessionId: %{public}u deviceName:%{public}s", + sessionId, + rendererIdSinkNameMap_[sessionId].c_str()); + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Stop(sessionId); + rendererIdStreamInfoMap_[sessionId].state = I_STATUS_STOPPING; + } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && + capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + AUDIO_INFO_LOG("capturer Stop sessionId: %{public}u deviceName:%{public}s", + sessionId, + capturerIdSourceNameMap_[sessionId].c_str()); + if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { + rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Stop(sessionId); + } else { + capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Stop(sessionId); + } + capturerIdStreamInfoMap_[sessionId].state = I_STATUS_STOPPING; + } else { + AUDIO_WARNING_LOG("Stop can not find sessionId streamClassType %{public}d, sessionId %{public}u", + streamClassType, + sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} +int32_t HpaeManager::Release(HpaeStreamClassType streamClassType, uint32_t sessionId) +{ + DestroyStream(streamClassType, sessionId); + return SUCCESS; +} +int32_t HpaeManager::RegisterStatusCallback( + HpaeStreamClassType streamClassType, uint32_t sessionId, const std::weak_ptr &callback) +{ + auto request = [this, streamClassType, sessionId, callback]() { + AUDIO_INFO_LOG( + "RegisterStatusCallback streamClassType %{public}d, sessionId %{public}u", streamClassType, sessionId); + if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && + rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + AUDIO_INFO_LOG("renderer RegisterStatusCallback sessionId: %{public}u deviceName:%{public}s", + sessionId, + rendererIdSinkNameMap_[sessionId].c_str()); + rendererIdStreamInfoMap_[sessionId].statusCallback = callback; + } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && + capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + AUDIO_INFO_LOG("capturer RegisterStatusCallback sessionId: %{public}u deviceName:%{public}s", + sessionId, + capturerIdSourceNameMap_[sessionId].c_str()); + capturerIdStreamInfoMap_[sessionId].statusCallback = callback; + } else { + AUDIO_WARNING_LOG( + "RegisterStatusCallback can not find sessionId streamClassType %{public}d, sessionId %{public}u", + streamClassType, + sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} + +// record stream interface +void HpaeManager::RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) +{ + auto request = [this, sessionId, callback]() { + AUDIO_INFO_LOG("RegisterReadCallback sessionId %{public}u", sessionId); + if (capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + AUDIO_INFO_LOG("capturer RegisterReadCallback sessionId: %{public}u deviceName:%{public}s", + sessionId, + capturerIdSourceNameMap_[sessionId].c_str()); + if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { + rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->RegisterReadCallback(sessionId, callback); + } else { + capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->RegisterReadCallback(sessionId, callback); + } + } else { + AUDIO_WARNING_LOG("RegisterReadCallback can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return; +} + +int32_t HpaeManager::GetSourceOutputInfo(uint32_t sessionId, HpaeStreamInfo &streamInfo) +{ + // to do + return SUCCESS; +} +// play stream interface +int32_t HpaeManager::SetClientVolume(uint32_t sessionId, float volume) +{ + auto request = [this, sessionId, volume]() { + AUDIO_INFO_LOG("SetClientVolume sessionId %{public}u %{public}f", sessionId, volume); + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetClientVolume(sessionId, volume); + } else { + AUDIO_WARNING_LOG("SetClientVolume can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetRate(uint32_t sessionId, int32_t rate) +{ + auto request = [this, sessionId, rate]() { + AUDIO_INFO_LOG("SetRate sessionId %{public}u %{public}d", sessionId, rate); + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetRate(sessionId, rate); + } else { + AUDIO_WARNING_LOG("SetRate can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) +{ + auto request = [this, sessionId, effectMode]() { + AUDIO_INFO_LOG("SetAudioEffectMode sessionId %{public}u %{public}d", sessionId, effectMode); + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetAudioEffectMode(sessionId, effectMode); + } else { + AUDIO_WARNING_LOG("SetAudioEffectMode can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) +{ + return SUCCESS; +} + +int32_t HpaeManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType) +{ + auto request = [this, sessionId, privacyType]() { + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetPrivacyType(sessionId, privacyType); + } else { + AUDIO_WARNING_LOG("SetPrivacyType can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType) +{ + return SUCCESS; +} +int32_t HpaeManager::RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) +{ + auto request = [this, sessionId, callback]() { + AUDIO_INFO_LOG("RegisterWriteCallback sessionId %{public}u", sessionId); + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + AUDIO_INFO_LOG("renderer RegisterWriteCallback sessionId: %{public}u deviceName:%{public}s", + sessionId, + rendererIdSinkNameMap_[sessionId].c_str()); + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->RegisterWriteCallback(sessionId, callback); + } else { + AUDIO_WARNING_LOG("RegisterWriteCallback can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} +int32_t HpaeManager::SetOffloadPolicy(uint32_t sessionId, int32_t state) +{ + auto request = [this, sessionId, state]() { + AUDIO_INFO_LOG("SetOffloadPolicy sessionId %{public}u %{public}d", sessionId, state); + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetOffloadPolicy(sessionId, state); + } else { + AUDIO_WARNING_LOG("SetOffloadPolicy can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} + +size_t HpaeManager::GetWritableSize(uint32_t sessionId) +{ + return SUCCESS; +} + +int32_t HpaeManager::UpdateSpatializationState(uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) +{ + auto request = [this, sessionId, spatializationEnabled, headTrackingEnabled]() { + AUDIO_INFO_LOG("UpdateSpatializationState sessionId %{public}u spatializationEnabled %{public}d " + "headTrackingEnabled %{public}d", + sessionId, + spatializationEnabled, + headTrackingEnabled); + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->UpdateSpatializationState( + sessionId, spatializationEnabled, headTrackingEnabled); + } else { + AUDIO_WARNING_LOG("UpdateSpatializationState can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) +{ + auto request = [this, sessionId, maxLength]() { + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->UpdateMaxLength(sessionId, maxLength); + } else { + AUDIO_WARNING_LOG("UpdateMaxLength can not find sessionId, sessionId %{public}u", sessionId); + } + }; + SendRequest(request); + return SUCCESS; +} + +// only interface for unit test +int32_t HpaeManager::GetSessionInfo( + HpaeStreamClassType streamClassType, uint32_t sessionId, HpaeSessionInfo &sessionInfo) +{ + if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && + rendererIdStreamInfoMap_.find(sessionId) != rendererIdStreamInfoMap_.end()) { + sessionInfo = rendererIdStreamInfoMap_[sessionId]; + } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && + capturerIdStreamInfoMap_.find(sessionId) != capturerIdStreamInfoMap_.end()) { + sessionInfo = capturerIdStreamInfoMap_[sessionId]; + } else { + return ERROR; + } + return SUCCESS; +} + +std::shared_ptr HpaeManager::GetRendererManagerByNmae(const std::string &sinkName) +{ + if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { + AUDIO_WARNING_LOG("can not find sinkName: %{public}s ", sinkName.c_str()); + return nullptr; + } + return rendererManagerMap_[sinkName]; +} + +std::shared_ptr HpaeManager::GetCapturerManagerByName(const std::string &sourceName) +{ + if (capturerManagerMap_.find(sourceName) == capturerManagerMap_.end()) { + AUDIO_WARNING_LOG("can not find sourceName: %{public}s ", sourceName.c_str()); + return nullptr; + } + return capturerManagerMap_[sourceName]; +} + +std::shared_ptr HpaeManager::GetRendererManagerById(uint32_t sessionId) +{ + if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { + return GetRendererManagerByNmae(rendererIdSinkNameMap_[sessionId]); + } + AUDIO_WARNING_LOG("can not find renderer by sessionId: %{public}u", sessionId); + return nullptr; +} + +std::shared_ptr HpaeManager::GetCapturerManagerById(uint32_t sessionId) +{ + if (capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { + return GetCapturerManagerByName(capturerIdSourceNameMap_[sessionId]); + } + AUDIO_WARNING_LOG("can not find capture by sessionId: %{public}u", sessionId); + return nullptr; +} + +void HpaeManager::InitAudioEffectChainManager(const std::vector &effectChains, + const EffectChainManagerParam &effectChainManagerParam, + const std::vector> &effectLibraryList) +{ + auto request = [this, effectChains, effectChainManagerParam, effectLibraryList]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->InitAudioEffectChainManager(effectChains, effectChainManagerParam, effectLibraryList); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); +} + +void HpaeManager::SetOutputDeviceSink(int32_t device, const std::string &sinkName) +{ + auto request = [this, device, sinkName]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetOutputDeviceSink(device, sinkName); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); +} + +int32_t HpaeManager::UpdateSpatializationState(AudioSpatializationState spatializationState) +{ + auto request = [this, spatializationState]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->UpdateSpatializationState(spatializationState); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) +{ + auto request = [this, spatialDeviceType]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->UpdateSpatialDeviceType(spatialDeviceType); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType) +{ + auto request = [this, spatializationSceneType]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetSpatializationSceneType(spatializationSceneType); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::EffectRotationUpdate(const uint32_t rotationState) +{ + auto request = [this, rotationState]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->EffectRotationUpdate(rotationState); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume) +{ + auto request = [this, systemVolumeType, systemVolume]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetEffectSystemVolume(systemVolumeType, systemVolume); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray) +{ + auto request = [this, propertyArray]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetAudioEffectProperty(propertyArray); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) +{ + auto request = [this, &propertyArray]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->GetAudioEffectProperty(propertyArray); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnGetAudioEffectPropertyCbV3(SUCCESS); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray) +{ + auto request = [this, propertyArray]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetAudioEffectProperty(propertyArray); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) +{ + auto request = [this, &propertyArray]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->GetAudioEffectProperty(propertyArray); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + if (auto serviceCallback = serviceCallback_.lock()) { + serviceCallback->OnGetAudioEffectPropertyCb(SUCCESS); + } + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeManager::InitHdiState() +{ + auto request = [this]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->InitHdiState(); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); +} + +void HpaeManager::UpdateEffectBtOffloadSupported(const bool &isSupported) +{ + auto request = [this, isSupported]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->UpdateEffectBtOffloadSupported(isSupported); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); +} + +void HpaeManager::UpdateParamExtra(const std::string &mainkey, const std::string &subkey, const std::string &value) +{ + auto request = [this, mainkey, subkey, value]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->UpdateParamExtra(mainkey, subkey, value); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); +} + +void HpaeManager::HandleRendererManager(const std::string &sinkName, const HpaeStreamInfo &streamInfo) +{ + auto it = rendererManagerMap_.find(sinkName); + if (it == rendererManagerMap_.end()) { + AUDIO_INFO_LOG("can not find sink[%{public}s] in rendererManagerMap_", sinkName.c_str()); + return; + } + it->second->CreateStream(streamInfo); + if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { + rendererIdSinkNameMap_[streamInfo.sessionId] = sinkName; + rendererIdStreamInfoMap_[streamInfo.sessionId] = {streamInfo, I_STATUS_IDLE}; + } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD) { + capturerIdSourceNameMap_[streamInfo.sessionId] = sinkName; + capturerIdStreamInfoMap_[streamInfo.sessionId] = {streamInfo, I_STATUS_IDLE}; + } +} + +void HpaeManager::CreateStreamForCapInner(const HpaeStreamInfo &streamInfo) +{ + if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_INVALID) { + AUDIO_INFO_LOG("streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_INVALID"); + return; + } + std::string deviceName = streamInfo.deviceName; + HandleRendererManager(deviceName, streamInfo); + HandleRendererManager("RemoteCastInnerCapturer", streamInfo); + AddStreamToCollection(streamInfo); + return; +} + +void HpaeManager::InitAudioEnhanceChainManager(const std::vector &enhanceChains, + const EffectChainManagerParam &managerParam, + const std::vector> &enhanceLibraryList) +{ + auto request = [this, enhanceChains, managerParam, enhanceLibraryList]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->InitAudioEnhanceChainManager(enhanceChains, managerParam, enhanceLibraryList); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); +} + +int32_t HpaeManager::SetInputDevice( + const uint32_t &captureId, const DeviceType &inputDevice, const std::string &deviceName) +{ + auto request = [this, captureId, inputDevice, deviceName]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetInputDevice(captureId, inputDevice, deviceName); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice) +{ + auto request = [this, renderId, outputDevice]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetOutputDevice(renderId, outputDevice); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol) +{ + auto request = [this, volumeType, systemVol]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetVolumeInfo(volumeType, systemVol); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetMicrophoneMuteInfo(const bool &isMute) +{ + auto request = [this, isMute]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetMicrophoneMuteInfo(isMute); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol) +{ + auto request = [this, sessionId, streamVol]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetStreamVolumeInfo(sessionId, streamVol); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetAudioEnhanceProperty(const AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType) +{ + auto request = [this, propertyArray, deviceType]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetAudioEnhanceProperty(propertyArray, deviceType); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType) +{ + auto request = [this, &propertyArray, deviceType]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->GetAudioEnhanceProperty(propertyArray, deviceType); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &propertyArray, DeviceType deviceType) +{ + auto request = [this, propertyArray, deviceType]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->SetAudioEnhanceProperty(propertyArray, deviceType); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeManager::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, DeviceType deviceType) +{ + auto request = [this, &propertyArray, deviceType]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->GetAudioEnhanceProperty(propertyArray, deviceType); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeManager::UpdateExtraSceneType( + const std::string &mainkey, const std::string &subkey, const std::string &extraSceneType) +{ + auto request = [this, mainkey, subkey, extraSceneType]() { + if (hpaePolicyManager_ != nullptr) { + hpaePolicyManager_->UpdateExtraSceneType(mainkey, subkey, extraSceneType); + } else { + AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); + } + }; + SendRequest(request); + return; +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/manager/src/hpae_offload_renderer_manager.cpp b/services/audio_engine/manager/src/hpae_offload_renderer_manager.cpp new file mode 100644 index 0000000000..369616212a --- /dev/null +++ b/services/audio_engine/manager/src/hpae_offload_renderer_manager.cpp @@ -0,0 +1,607 @@ +/* + * Copyright (c) 2025 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 "HpaeOffloadRendererManager" +#endif + +#include "hpae_offload_renderer_manager.h" +#include "audio_stream_info.h" +#include "audio_errors.h" +#include "audio_engine_log.h" +#include "hpae_node_common.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +namespace { +constexpr uint32_t HISTORY_INTERVAL_S = 7; // 7s buffer for rewind +} + +HpaeOffloadRendererManager::HpaeOffloadRendererManager(HpaeSinkInfo &sinkInfo) + : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sinkInfo_(sinkInfo) +{} + +HpaeOffloadRendererManager::~HpaeOffloadRendererManager() +{ + AUDIO_INFO_LOG("destructor offload renderer"); + if (isInit_.load()) { + DeInit(); + } +} + +// private method +int32_t HpaeOffloadRendererManager::CreateInputSession(const HpaeStreamInfo &streamInfo) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.channels = streamInfo.channels; + nodeInfo.format = streamInfo.format; + nodeInfo.frameLen = streamInfo.frameLen; + nodeInfo.streamType = streamInfo.streamType; + nodeInfo.sessionId = streamInfo.sessionId; + nodeInfo.samplingRate = static_cast(streamInfo.samplingRate); + nodeInfo.sceneType = TransStreamTypeToSceneType(streamInfo.streamType); + nodeInfo.historyFrameCount = HISTORY_INTERVAL_S * nodeInfo.samplingRate / nodeInfo.frameLen; + nodeInfo.statusCallback = weak_from_this(); + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + nodeInfo.nodeId = OnGetNodeId(); + nodeInfo.nodeName = "HpaeSinkInputNode"; + sinkInputNode_ = std::make_shared(nodeInfo); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::AddNodeToSink(const std::shared_ptr &node) +{ + auto request = [this, node]() { AddSingleNodeToSink(node); }; + SendRequest(request); + return SUCCESS; +} + +void HpaeOffloadRendererManager::AddSingleNodeToSink(const std::shared_ptr &node, bool isConnect) +{ + HpaeNodeInfo nodeInfo = node->GetNodeInfo(); + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + // 7s history buffer to rewind + nodeInfo.historyFrameCount = HISTORY_INTERVAL_S * nodeInfo.samplingRate / nodeInfo.frameLen; + nodeInfo.statusCallback = weak_from_this(); + node->SetNodeInfo(nodeInfo); + uint32_t sessionId = nodeInfo.sessionId; + AUDIO_INFO_LOG("add node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); + sinkInputNode_ = node; + sessionInfo_.state = node->GetState(); + + if (!isConnect || sinkInputNode_->GetState() != RENDERER_RUNNING) { + AUDIO_INFO_LOG("not need connect session:%{public}d", sessionId); + return; + } + + if (node->GetState() == RENDERER_RUNNING) { + AUDIO_INFO_LOG("connect node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); + ConnectInputSession(); // todo: fadein + if (sinkOutputNode_->GetSinkState() != RENDERER_RUNNING) { + sinkOutputNode_->RenderSinkStart(); + } + } +} + +int32_t HpaeOffloadRendererManager::AddAllNodesToSink( + const std::vector> &sinkInputs, bool isConnect) +{ + auto request = [this, sinkInputs, isConnect]() { + for (const auto &it : sinkInputs) { + AddSingleNodeToSink(it, isConnect); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::CreateStream(const HpaeStreamInfo &streamInfo) +{ + if (!IsInit()) { + return ERR_INVALID_OPERATION; + } + auto request = [this, streamInfo]() { + CreateInputSession(streamInfo); + sessionInfo_.state = RENDERER_NEW; + sinkInputNode_->SetState(RENDERER_NEW); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::DestroyStream(uint32_t sessionId) +{ + if (!IsInit()) { + return ERR_INVALID_OPERATION; + } + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(), + "DestroyStream not find sessionId %{public}u", + sessionId); + AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId); + DisConnectInputSession(); + sinkInputNode_ = nullptr; + formatConverterNode_ = nullptr; + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::ConnectInputSession() +{ + if (sinkInputNode_->GetState() != RENDERER_RUNNING) { + return SUCCESS; + } + + if (CheckHpaeNodeInfoIsSame(sinkInputNode_->GetNodeInfo(), sinkOutputNode_->GetNodeInfo())) { + formatConverterNode_ = nullptr; + sinkOutputNode_->Connect(sinkInputNode_); + OnNotifyDfxNodeInfo(true, sinkOutputNode_->GetNodeId(), sinkInputNode_->GetNodeInfo()); + } else { + HpaeNodeInfo nodeInfo = sinkOutputNode_->GetNodeInfo(); + nodeInfo.nodeName = "HpaeAudioFormatConverterNode"; + nodeInfo.nodeId = OnGetNodeId(); + nodeInfo.sessionId = sinkInputNode_->GetSessionId(); + formatConverterNode_ = std::make_shared( + sinkInputNode_->GetNodeInfo(), nodeInfo); + formatConverterNode_->Connect(sinkInputNode_); + sinkOutputNode_->Connect(formatConverterNode_); + OnNotifyDfxNodeInfo(true, sinkOutputNode_->GetNodeId(), formatConverterNode_->GetNodeInfo()); + OnNotifyDfxNodeInfo(true, formatConverterNode_->GetNodeId(), sinkInputNode_->GetNodeInfo()); + } + // single stream manager + HpaeNodeInfo nodeInfo = sinkOutputNode_->GetNodeInfo(); + nodeInfo.sessionId = sinkInputNode_->GetSessionId(); + nodeInfo.streamType = sinkInputNode_->GetStreamType(); + sinkOutputNode_->SetNodeInfo(nodeInfo); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::Start(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG( + sessionId == sinkInputNode_->GetSessionId(), "Start not find sessionId %{public}u", sessionId); + AUDIO_INFO_LOG("Start sessionId %{public}u", sessionId); + sinkInputNode_->SetState(RENDERER_RUNNING); + ConnectInputSession(); + if (sinkOutputNode_->GetSinkState() != RENDERER_RUNNING) { + sinkOutputNode_->RenderSinkStart(); + } + sessionInfo_.state = RENDERER_RUNNING; + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_STARTED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::DisConnectInputSession() +{ + if (formatConverterNode_ == nullptr) { + sinkOutputNode_->DisConnect(sinkInputNode_); + OnNotifyDfxNodeInfo(false, sinkOutputNode_->GetNodeId(), sinkInputNode_->GetNodeInfo()); + } else { + formatConverterNode_->DisConnect(sinkInputNode_); + sinkOutputNode_->DisConnect(formatConverterNode_); + OnNotifyDfxNodeInfo(false, formatConverterNode_->GetNodeId(), sinkInputNode_->GetNodeInfo()); + OnNotifyDfxNodeInfo(false, sinkOutputNode_->GetNodeId(), formatConverterNode_->GetNodeInfo()); + } + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::Pause(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG( + sessionId == sinkInputNode_->GetSessionId(), "Pause not find sessionId %{public}u", sessionId); + AUDIO_INFO_LOG("Pause sessionId %{public}u", sessionId); + DisConnectInputSession(); + sinkInputNode_->SetState(RENDERER_PAUSED); + sinkOutputNode_->StopStream(); + sessionInfo_.state = RENDERER_PAUSED; + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_PAUSED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::Flush(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG( + sessionId == sinkInputNode_->GetSessionId(), "Pause not find sessionId %{public}u", sessionId); + AUDIO_INFO_LOG("Flush sessionId %{public}u", sessionId); + // flush history buffer + sinkInputNode_->Flush(); + // flush sinkoutput cache + sinkOutputNode_->FlushStream(); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_FLUSHED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::Drain(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG( + sessionId == sinkInputNode_->GetSessionId(), "Drain not find sessionId %{public}u", sessionId); + AUDIO_INFO_LOG("Drain sessionId %{public}u", sessionId); + sinkInputNode_->Drain(); + if (sessionInfo_.state != RENDERER_RUNNING) { + TriggerCallback( + UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_DRAINED); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::Stop(uint32_t sessionId) +{ + auto request = [this, sessionId]() { + CHECK_AND_RETURN_LOG( + sessionId == sinkInputNode_->GetSessionId(), "Stop not find sessionId %{public}u", sessionId); + AUDIO_INFO_LOG("Stop sessionId %{public}u", sessionId); + DisConnectInputSession(); + sinkInputNode_->SetState(RENDERER_STOPPED); + sessionInfo_.state = RENDERER_STOPPED; + sinkOutputNode_->StopStream(); + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_STOPPED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::Release(uint32_t sessionId) +{ + return DestroyStream(sessionId); +} + +void HpaeOffloadRendererManager::MoveAllStreamToNewSink(const std::string &sinkName, + const std::vector& moveIds, bool isMoveAll) +{ + std::string name = sinkName; + std::vector> sinkInputs; + std::vector sessionIds; + if (sinkInputNode_) { + uint32_t sessionId = sinkInputNode_->GetSessionId(); + if (isMoveAll || std::find(moveIds.begin(), moveIds.end(), sessionId) != moveIds.end()) { + sinkInputs.emplace_back(sinkInputNode_); + sessionIds.emplace_back(sinkInputNode_->GetSessionId()); + DisConnectInputSession(); + } + } + TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name); +} + +int32_t HpaeOffloadRendererManager::MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, + bool isMoveAll) +{ + if (!IsInit()) { + AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str()); + MoveAllStreamToNewSink(sinkName, sessionIds, isMoveAll); + } else { + AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str()); + auto request = [this, sinkName, sessionIds, isMoveAll]() { + MoveAllStreamToNewSink(sinkName, sessionIds, isMoveAll); + }; + SendRequest(request); + } + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::MoveStream(uint32_t sessionId, const std::string &sinkName) +{ + AUDIO_INFO_LOG("move session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); + auto request = [this, sessionId, sinkName]() { + CHECK_AND_RETURN_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(), + "could not find session:%{public}d,sink name:%{public}s", + sessionId, + sinkName.c_str()); + + std::shared_ptr inputNode = sinkInputNode_; + if (inputNode->GetState() == RENDERER_RUNNING) { + // todo: do fade out + } + DisConnectInputSession(); + sinkOutputNode_->StopStream(); + sinkInputNode_ = nullptr; + formatConverterNode_ = nullptr; + if (!sinkName.empty()) { + std::string name = sinkName; + AUDIO_ERR_LOG("trigger call back, sink name:%{public}s", sinkName.c_str()); + TriggerCallback(MOVE_SINK_INPUT, inputNode, name); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::SuspendStreamManager(bool isSuspend) +{ + auto request = [this, isSuspend]() { + if (isSuspend) { + // todo fadout + sinkOutputNode_->RenderSinkStop(); + } else { + // todo fadin + sinkOutputNode_->RenderSinkStart(); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::SetMute(bool isMute) +{ + auto request = [this, isMute]() { + isMute_ = isMute; // todo: set to sinkoutputnode + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeOffloadRendererManager::HandleMsg() +{ + hpaeNoLockQueue_.HandleRequests(); +} + +int32_t HpaeOffloadRendererManager::Init() +{ + hpaeSignalProcessThread_ = std::make_unique(); + auto request = [this] { + AUDIO_INFO_LOG("HpaeOffloadRendererManager::init"); + HpaeNodeInfo nodeInfo; + nodeInfo.channels = sinkInfo_.channels; + nodeInfo.format = sinkInfo_.format; + nodeInfo.frameLen = sinkInfo_.frameLen; + nodeInfo.nodeId = 0; + nodeInfo.samplingRate = sinkInfo_.samplingRate; + nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.statusCallback = weak_from_this(); + nodeInfo.nodeName = "HpaeOffloadSinkOutputNode"; + nodeInfo.nodeId = OnGetNodeId(); + sinkOutputNode_ = std::make_unique(nodeInfo); + OnNotifyDfxNodeInfo(true, 0, nodeInfo); + sinkOutputNode_->SetTimeoutStopThd(sinkInfo_.suspendTime); + // if failed, RenderSinkInit will failed either, so no need to deal ret + AUDIO_INFO_LOG("HpaeOffloadRendererManager::GetRenderSinkInstance"); + sinkOutputNode_->GetRenderSinkInstance(sinkInfo_.deviceClass, sinkInfo_.deviceNetId); + IAudioSinkAttr attr; + attr.adapterName = sinkInfo_.adapterName.c_str(); + attr.sampleRate = sinkInfo_.samplingRate; + attr.channel = sinkInfo_.channels; + attr.format = sinkInfo_.format; + attr.channelLayout = sinkInfo_.channelLayout; + attr.deviceType = sinkInfo_.deviceType; + attr.volume = sinkInfo_.volume; + attr.openMicSpeaker = sinkInfo_.openMicSpeaker; + attr.deviceNetworkId = sinkInfo_.deviceNetId.c_str(); + attr.filePath = sinkInfo_.filePath.c_str(); + int32_t ret = sinkOutputNode_->RenderSinkInit(attr); + isInit_.store(true); + TriggerCallback(INIT_DEVICE_RESULT, sinkInfo_.deviceName, ret); + AUDIO_INFO_LOG("HpaeOffloadRendererManager::inited"); + }; + SendRequest(request, true); + hpaeSignalProcessThread_->ActivateThread(shared_from_this()); + return SUCCESS; +} + +bool HpaeOffloadRendererManager::DeactivateThread() +{ + if (hpaeSignalProcessThread_ != nullptr) { + hpaeSignalProcessThread_->DeactivateThread(); + hpaeSignalProcessThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); + return true; +} + +int32_t HpaeOffloadRendererManager::DeInit(bool isMoveDefault) +{ + if (hpaeSignalProcessThread_ != nullptr) { + hpaeSignalProcessThread_->DeactivateThread(); + hpaeSignalProcessThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); + int32_t ret = sinkOutputNode_->RenderSinkDeInit(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "RenderSinkDeInit error, ret %{public}d.", ret); + sinkOutputNode_->ResetAll(); + isInit_.store(false); + if (isMoveDefault) { + std::string sinkName = ""; + std::vector ids; + AUDIO_INFO_LOG("move all sink to default sink"); + MoveAllStreamToNewSink(sinkName, ids, true); + } + return SUCCESS; +} + +bool HpaeOffloadRendererManager::IsInit() +{ + return isInit_.load(); +} + +bool HpaeOffloadRendererManager::IsRunning(void) +{ + if (sinkOutputNode_ != nullptr && hpaeSignalProcessThread_ != nullptr) { + return sinkOutputNode_->GetSinkState() == RENDERER_RUNNING && hpaeSignalProcessThread_->IsRunning(); + } + return false; +} + +bool HpaeOffloadRendererManager::IsMsgProcessing() +{ + return !hpaeNoLockQueue_.IsFinishProcess(); +} + +int32_t HpaeOffloadRendererManager::SetClientVolume(uint32_t sessionId, float volume) +{ + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::SetRate(uint32_t sessionId, int32_t rate) +{ + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) +{ + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) +{ + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType) +{ + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType) +{ + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::RegisterWriteCallback( + uint32_t sessionId, const std::weak_ptr &callback) +{ + auto request = [this, sessionId, callback]() { + CHECK_AND_RETURN_LOG(sessionId == sinkInputNode_->GetSessionId(), + "RegisterWriteCallback not find sessionId %{public}u", + sessionId); + sinkInputNode_->RegisterWriteCallback(callback); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::RegisterReadCallback( + uint32_t sessionId, const std::weak_ptr &callback) +{ + return ERR_NOT_SUPPORTED; +} + +void HpaeOffloadRendererManager::Process() +{ + if (sinkOutputNode_ != nullptr && IsRunning()) { + sinkOutputNode_->DoProcess(); + } +} + +int32_t HpaeOffloadRendererManager::SetOffloadPolicy(uint32_t sessionId, int32_t state) +{ + auto request = [this, sessionId, state]() { + CHECK_AND_RETURN_LOG(sessionId == sinkInputNode_->GetSessionId(), + "RegisterWriteCallback not find sessionId %{public}u", + sessionId); + if (sinkOutputNode_) { + sinkOutputNode_->SetPolicyState(state); + } + }; + SendRequest(request); + return SUCCESS; +} + +size_t HpaeOffloadRendererManager::GetWritableSize(uint32_t sessionId) +{ + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::UpdateSpatializationState( + uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) +{ + return SUCCESS; +} + +int32_t HpaeOffloadRendererManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) +{ + return SUCCESS; +} + +std::vector HpaeOffloadRendererManager::GetAllSinkInputsInfo() +{ + std::vector sinkInputs; + return sinkInputs; +} + +int32_t HpaeOffloadRendererManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) +{ + CHECK_AND_RETURN_RET_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(), + ERR_INVALID_OPERATION, + "RegisterWriteCallback not find sessionId %{public}u", + sessionId); + sinkInputInfo.nodeInfo = sinkInputNode_->GetNodeInfo(); + sinkInputInfo.rendererSessionInfo = sessionInfo_; + return SUCCESS; +} + +HpaeSinkInfo HpaeOffloadRendererManager::GetSinkInfo() +{ + return sinkInfo_; +} + +void HpaeOffloadRendererManager::SendRequest(Request &&request, bool isInit) +{ + CHECK_AND_RETURN_LOG(isInit || IsInit(), "HpaeOffloadRendererManager not init"); + hpaeNoLockQueue_.PushRequest(std::move(request)); + CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ offloadrenderer is nullptr"); + hpaeSignalProcessThread_->Notify(); +} + +void HpaeOffloadRendererManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) +{ + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, operation); +} + +void HpaeOffloadRendererManager::OnRequestLatency(uint32_t sessionId, uint64_t &latency) +{ + latency = sinkOutputNode_->GetLatency(); +} + +void HpaeOffloadRendererManager::OnRewindAndFlush(uint64_t rewindTime) +{ + sinkInputNode_->RewindHistoryBuffer(rewindTime); +} + +void HpaeOffloadRendererManager::OnNotifyQueue() +{ + hpaeSignalProcessThread_->Notify(); +} + +std::string HpaeOffloadRendererManager::GetThreadName() +{ + return sinkInfo_.deviceName; +} + +void HpaeOffloadRendererManager::DumpSinkInfo() +{ + auto request = [this]() { + AUDIO_INFO_LOG("DumpSinkInfo deviceName %{public}s", sinkInfo_.deviceName.c_str()); + UploadDumpSinkInfo(sinkInfo_.deviceName); + }; + SendRequest(request); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_policy_manager.cpp b/services/audio_engine/manager/src/hpae_policy_manager.cpp new file mode 100644 index 0000000000..63900974fa --- /dev/null +++ b/services/audio_engine/manager/src/hpae_policy_manager.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2025 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 "HpaePolicyManager" +#endif +#include "hpae_policy_manager.h" +#include +#include "audio_errors.h" +#include "audio_engine_log.h" +#include "audio_effect_chain_manager.h" +#include "audio_enhance_chain_manager.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +HpaePolicyManager::HpaePolicyManager() +{ + AUDIO_DEBUG_LOG("Hpae policy manager created"); +} + +HpaePolicyManager::~HpaePolicyManager() +{ + AUDIO_WARNING_LOG("Hpae policy manager destroyed"); +} + +void HpaePolicyManager::InitAudioEffectChainManager(const std::vector &effectChains, + const EffectChainManagerParam &effectChainManagerParam, + const std::vector> &effectLibraryList) +{ + AudioEffectChainManager::GetInstance()->InitAudioEffectChainManager(effectChains, + effectChainManagerParam, effectLibraryList); +} + +void HpaePolicyManager::SetOutputDeviceSink(int32_t device, const std::string &sinkName) +{ + AudioEffectChainManager::GetInstance()->SetOutputDeviceSink(device, sinkName); +} + +int32_t HpaePolicyManager::UpdateSpatializationState(AudioSpatializationState spatializationState) +{ + return AudioEffectChainManager::GetInstance()->UpdateSpatializationState(spatializationState); +} + +int32_t HpaePolicyManager::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) +{ + return AudioEffectChainManager::GetInstance()->UpdateSpatialDeviceType(spatialDeviceType); +} + +int32_t HpaePolicyManager::SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType) +{ + return AudioEffectChainManager::GetInstance()->SetSpatializationSceneType(spatializationSceneType); +} + +int32_t HpaePolicyManager::EffectRotationUpdate(const uint32_t rotationState) +{ + return AudioEffectChainManager::GetInstance()->EffectRotationUpdate(rotationState); +} + +int32_t HpaePolicyManager::SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume) +{ + return AudioEffectChainManager::GetInstance()->SetEffectSystemVolume(systemVolumeType, systemVolume); +} + +int32_t HpaePolicyManager::SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray) +{ + return AudioEffectChainManager::GetInstance()->SetAudioEffectProperty(propertyArray); +} + +int32_t HpaePolicyManager::GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) +{ + return AudioEffectChainManager::GetInstance()->GetAudioEffectProperty(propertyArray); +} + +int32_t HpaePolicyManager::SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray) +{ + return AudioEffectChainManager::GetInstance()->SetAudioEffectProperty(propertyArray); +} + +int32_t HpaePolicyManager::GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) +{ + return AudioEffectChainManager::GetInstance()->GetAudioEffectProperty(propertyArray); +} + +void HpaePolicyManager::InitHdiState() +{ + AudioEffectChainManager::GetInstance()->InitHdiState(); +} + +void HpaePolicyManager::UpdateEffectBtOffloadSupported(const bool &isSupported) +{ + AudioEffectChainManager::GetInstance()->UpdateEffectBtOffloadSupported(isSupported); +} + +void HpaePolicyManager::UpdateParamExtra(const std::string &mainkey, const std::string &subkey, + const std::string &value) +{ + AudioEffectChainManager::GetInstance()->UpdateParamExtra(mainkey, subkey, value); +} + +void HpaePolicyManager::InitAudioEnhanceChainManager(const std::vector &enhanceChains, + const EffectChainManagerParam &managerParam, + const std::vector> &enhanceLibraryList) +{ + AudioEnhanceChainManager::GetInstance()->InitAudioEnhanceChainManager(enhanceChains, managerParam, + enhanceLibraryList); +} + +int32_t HpaePolicyManager::SetInputDevice(const uint32_t &captureId, const DeviceType &inputDevice, + const std::string &deviceName) +{ + return AudioEnhanceChainManager::GetInstance()->SetInputDevice(captureId, inputDevice, deviceName); +} + +int32_t HpaePolicyManager::SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice) +{ + return AudioEnhanceChainManager::GetInstance()->SetOutputDevice(renderId, outputDevice); +} + +int32_t HpaePolicyManager::SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol) +{ + return AudioEnhanceChainManager::GetInstance()->SetVolumeInfo(volumeType, systemVol); +} + +int32_t HpaePolicyManager::SetMicrophoneMuteInfo(const bool &isMute) +{ + return AudioEnhanceChainManager::GetInstance()->SetMicrophoneMuteInfo(isMute); +} + +int32_t HpaePolicyManager::SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol) +{ + return AudioEnhanceChainManager::GetInstance()->SetStreamVolumeInfo(sessionId, streamVol); +} + +int32_t HpaePolicyManager::SetAudioEnhanceProperty(const AudioEffectPropertyArrayV3 &propertyArray, + DeviceType deviceType) +{ + return AudioEnhanceChainManager::GetInstance()->SetAudioEnhanceProperty(propertyArray, deviceType); +} + +int32_t HpaePolicyManager::GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, + DeviceType deviceType) +{ + return AudioEnhanceChainManager::GetInstance()->GetAudioEnhanceProperty(propertyArray, deviceType); +} + +int32_t HpaePolicyManager::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType) +{ + return AudioEnhanceChainManager::GetInstance()->SetAudioEnhanceProperty(propertyArray, deviceType); +} + +// todo: change to callback mode +int32_t HpaePolicyManager::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType) +{ + return AudioEnhanceChainManager::GetInstance()->GetAudioEnhanceProperty(propertyArray, deviceType); +} + +void HpaePolicyManager::UpdateExtraSceneType(const std::string &mainkey, const std::string &subkey, + const std::string &extraSceneType) +{ + return AudioEnhanceChainManager::GetInstance()->UpdateExtraSceneType(mainkey, subkey, extraSceneType); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/manager/src/hpae_renderer_manager.cpp b/services/audio_engine/manager/src/hpae_renderer_manager.cpp new file mode 100644 index 0000000000..13a5c00be4 --- /dev/null +++ b/services/audio_engine/manager/src/hpae_renderer_manager.cpp @@ -0,0 +1,951 @@ +/* + * Copyright (c) 2025 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 "HpaeRendererManager" +#endif +#include "hpae_renderer_manager.h" +#include "audio_stream_info.h" +#include "audio_errors.h" +#include "audio_engine_log.h" +#include "hpae_node_common.h" +#include "audio_effect_chain_manager.h" +#include "audio_utils.h" + +#define DEFAULT_EFFECT_RATE 48000 +#define DEFAULT_EFFECT_FRAME_LEN 960 + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +HpaeRendererManager::HpaeRendererManager(HpaeSinkInfo &sinkInfo) + : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sinkInfo_(sinkInfo) +{} + +HpaeRendererManager::~HpaeRendererManager() +{ + AUDIO_INFO_LOG("destructor renderer"); + if (isInit_.load()) { + DeInit(); + } +} + +bool HpaeRendererManager::IsMchDevice() +{ + return sinkInfo_.deviceName == "MCH_Speaker"; +} + +int32_t HpaeRendererManager::CreateInputSession(const HpaeStreamInfo &streamInfo) +{ + Trace trace("[" + std::to_string(streamInfo.sessionId) + "]HpaeRendererManager::CreateInputSession"); + HpaeNodeInfo nodeInfo; + nodeInfo.channels = streamInfo.channels; + nodeInfo.format = streamInfo.format; + nodeInfo.frameLen = streamInfo.frameLen; + nodeInfo.channelLayout = (AudioChannelLayout)streamInfo.channelLayout; + nodeInfo.streamType = streamInfo.streamType; + nodeInfo.sessionId = streamInfo.sessionId; + nodeInfo.samplingRate = static_cast(streamInfo.samplingRate); + nodeInfo.sceneType = TransStreamTypeToSceneType(streamInfo.streamType); + nodeInfo.effectInfo = streamInfo.effectInfo; + nodeInfo.fadeType = streamInfo.fadeType; + nodeInfo.statusCallback = weak_from_this(); + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + nodeInfo.nodeName = "HpaeSinkInputNode"; + nodeInfo.nodeId = OnGetNodeId(); + sinkInputNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); + + AUDIO_INFO_LOG("streamType %{public}u, sessionId = %{public}u, current sceneType is %{public}d", + nodeInfo.streamType, + nodeInfo.sessionId, + nodeInfo.sceneType); + if (IsMchDevice()) { + AUDIO_INFO_LOG("MCH device, only need create gain node"); + nodeInfo.nodeName = "HpaeGainNode"; + nodeInfo.nodeId = OnGetNodeId(); + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + mchIdGainNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); + return SUCCESS; + } + std::shared_ptr hpaeProcessCluster = CreateProcessCluster(nodeInfo); + if (hpaeProcessCluster != nullptr) { + sceneClusterMap_[nodeInfo.sceneType] = hpaeProcessCluster; + } + int32_t ret = sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo); + if (ret != SUCCESS) { + AUDIO_WARNING_LOG("update audio effect when creating failed, ret = %{public}d", ret); + } + return SUCCESS; +} + +int32_t HpaeRendererManager::AddNodeToSink(const std::shared_ptr &node) +{ + auto request = [this, node]() { AddSingleNodeToSink(node); }; + SendRequest(request); + return SUCCESS; +} + +void HpaeRendererManager::AddSingleNodeToSink(const std::shared_ptr &node, bool isConnect) +{ + Trace trace("HpaeRendererManager::AddSingleNodeToSink"); + HpaeNodeInfo nodeInfo = node->GetNodeInfo(); + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + // no need history buffer in not offload sink + nodeInfo.historyFrameCount = 0; + nodeInfo.statusCallback = weak_from_this(); + node->SetNodeInfo(nodeInfo); + uint32_t sessionId = nodeInfo.sessionId; + AUDIO_INFO_LOG("add node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); + sinkInputNodeMap_[sessionId] = node; + SetSessionState(sessionId, node->GetState()); + sessionNodeMap_[sessionId].sinkInputNodeId = nodeInfo.nodeId; + sessionNodeMap_[sessionId].sceneType = nodeInfo.sceneType; + + AUDIO_INFO_LOG("streamType %{public}u, sessionId = %{public}u, current sceneType is %{public}d", + nodeInfo.streamType, + nodeInfo.sessionId, + nodeInfo.sceneType); + HpaeNodeInfo processNodeInfo = nodeInfo; + processNodeInfo.samplingRate = (AudioSamplingRate)DEFAULT_EFFECT_RATE; + processNodeInfo.frameLen = (uint32_t)DEFAULT_EFFECT_FRAME_LEN; + processNodeInfo.channels = STEREO; + processNodeInfo.channelLayout = CH_LAYOUT_STEREO; + std::shared_ptr hpaeProcessCluster = CreateProcessCluster(processNodeInfo); + if (hpaeProcessCluster != nullptr) { + sceneClusterMap_[nodeInfo.sceneType] = hpaeProcessCluster; + } + int32_t ret = sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo); + if (ret != SUCCESS) { + AUDIO_WARNING_LOG("update audio effect when creating failed, ret = %{public}d", ret); + } + + if (!isConnect) { + AUDIO_INFO_LOG("not need connect session:%{public}d", sessionId); + return; + } + if (node->GetState() == RENDERER_RUNNING) { + AUDIO_INFO_LOG("connect node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); + ConnectInputSession(sessionId); // todo: fadein + if (outputCluster_->GetState() != RENDERER_RUNNING) { + outputCluster_->Start(); + } + } +} + +std::shared_ptr HpaeRendererManager::CreateProcessCluster(HpaeNodeInfo &nodeInfo) +{ + Trace trace("HpaeRendererManager::CreateProcessCluster"); + std::shared_ptr hpaeProcessCluster = nullptr; + std::string sceneType = TransProcessorTypeToSceneType(nodeInfo.sceneType); + int32_t processClusterDecision = AudioEffectChainManager::GetInstance()->CheckProcessClusterInstances(sceneType); + switch (processClusterDecision) { + case NO_NEED_TO_CREATE_PROCESSCLUSTER: + AUDIO_INFO_LOG("no need to create processCluster"); + if (sceneClusterMap_.find(nodeInfo.sceneType) == sceneClusterMap_.end()) { + AUDIO_INFO_LOG("processCluster is null, create a new processCluster"); + hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); + } + break; + case CREATE_NEW_PROCESSCLUSTER: + AUDIO_INFO_LOG("create new processCluster"); + hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); + break; + case CREATE_DEFAULT_PROCESSCLUSTER: + AUDIO_INFO_LOG("begin control, create default processCluster"); + hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); + sceneClusterMap_[HPAE_SCENE_DEFAULT] = hpaeProcessCluster; + sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++; + break; + case USE_DEFAULT_PROCESSCLUSTER: + AUDIO_INFO_LOG("use default processCluster"); + if (sceneClusterMap_.find(HPAE_SCENE_DEFAULT) == sceneClusterMap_.end()) { + AUDIO_INFO_LOG("default processCluster is null, create default processCluster"); + hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); + sceneClusterMap_[HPAE_SCENE_DEFAULT] = hpaeProcessCluster; + sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++; + } else { + hpaeProcessCluster = sceneClusterMap_[HPAE_SCENE_DEFAULT]; + sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++; + } + break; + case USE_NONE_PROCESSCLUSTER: + AUDIO_INFO_LOG("use none processCluster"); + hpaeProcessCluster = sceneClusterMap_[HPAE_SCENE_EFFECT_NONE]; + sceneTypeToProcessClusterCountMap_[HPAE_SCENE_EFFECT_NONE]++; + break; + case CREATE_EXTRA_PROCESSCLUSTER: + AUDIO_INFO_LOG("out of control"); + if (sceneClusterMap_.find(nodeInfo.sceneType) == sceneClusterMap_.end()) { + AUDIO_INFO_LOG("out of control, create a new processCluster"); + hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); + } + break; + default: + break; + } + sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]++; + return hpaeProcessCluster; +} + +int32_t HpaeRendererManager::AddAllNodesToSink( + const std::vector> &sinkInputs, bool isConnect) +{ + auto request = [this, sinkInputs, isConnect]() { + for (const auto &it : sinkInputs) { + AddSingleNodeToSink(it, isConnect); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::CreateStream(const HpaeStreamInfo &streamInfo) +{ + Trace trace("HpaeRendererManager::CreateStream id[" + + std::to_string(streamInfo.sessionId) + "]"); + if (!IsInit()) { + return ERR_INVALID_OPERATION; + } + auto request = [this, streamInfo]() { + AUDIO_INFO_LOG("CreateStream sessionId %{public}u deviceName %{public}s", + streamInfo.sessionId, + sinkInfo_.deviceName.c_str()); + CreateInputSession(streamInfo); + SetSessionState(streamInfo.sessionId, RENDERER_NEW); + sinkInputNodeMap_[streamInfo.sessionId]->SetState(RENDERER_NEW); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::DestroyStream(uint32_t sessionId) +{ + Trace trace("HpaeRendererManager::DestroyStream id[" + + std::to_string(sessionId) + "]"); + if (!IsInit()) { + return ERR_INVALID_OPERATION; + } + auto request = [this, sessionId]() { + AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId); + DeleteInputSession(sessionId); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::DeleteMchInputSession(uint32_t sessionId) +{ + DisConnectMchInputSession(sessionId); + sinkInputNodeMap_.erase(sessionId); + if (mchIdGainNodeMap_.find(sessionId) != mchIdGainNodeMap_.end()) { + mchIdGainNodeMap_.erase(sessionId); + } else { + AUDIO_ERR_LOG("could not find gain node id:%{public}d", sessionId); + return ERROR; + } + return SUCCESS; +} + +int32_t HpaeRendererManager::DeleteInputSession(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::DeleteInputSession"); + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("could not find session:%{public}d", sessionId); + return SUCCESS; + } + if (IsMchDevice()) { + return DeleteMchInputSession(sessionId); + } else { + HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); + int32_t effectMode = nodeInfo.effectInfo.effectMode; + HpaeProcessorType sceneType = (effectMode == EFFECT_NONE) ? HPAE_SCENE_EFFECT_NONE : nodeInfo.sceneType; + if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + DeleteProcessCluster(nodeInfo, sceneType, sessionId); + } + sinkInputNodeMap_.erase(sessionId); + } + return SUCCESS; +} + +void HpaeRendererManager::DeleteProcessCluster( + const HpaeNodeInfo &nodeInfo, HpaeProcessorType sceneType, uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + + "]HpaeRendererManager::DeleteProcessCluster sceneType:" + std::to_string(sessionId)); + sceneClusterMap_[nodeInfo.sceneType]->AudioRendererRelease(sinkInputNodeMap_[sessionId]->GetNodeInfo()); + sceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]); + sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]--; + if (sceneClusterMap_[nodeInfo.sceneType] == sceneClusterMap_[HPAE_SCENE_DEFAULT]) { + sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]--; + } + if (sceneClusterMap_[nodeInfo.sceneType] == sceneClusterMap_[HPAE_SCENE_EFFECT_NONE] && + nodeInfo.sceneType != HPAE_SCENE_EFFECT_NONE) { + sceneTypeToProcessClusterCountMap_[HPAE_SCENE_EFFECT_NONE]--; + } + + if (sceneClusterMap_[sceneType]->GetPreOutNum() == 0) { + outputCluster_->DisConnect(sceneClusterMap_[sceneType]); + } + + if (sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType] == 0) { + sceneClusterMap_.erase(nodeInfo.sceneType); + sceneTypeToProcessClusterCountMap_.erase(nodeInfo.sceneType); + } + if (sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT] == 0) { + sceneClusterMap_.erase(HPAE_SCENE_DEFAULT); + sceneTypeToProcessClusterCountMap_.erase(HPAE_SCENE_DEFAULT); + } +} + +int32_t HpaeRendererManager::ConnectMchInputSession(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectMchInputSession"); + AUDIO_INFO_LOG("Mch Device connect input session:%{public}d", sessionId); + if (mchIdGainNodeMap_.find(sessionId) == mchIdGainNodeMap_.end()) { + AUDIO_INFO_LOG("Mch Device connect can not find gain node, create it session:%{public}d", sessionId); + auto nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); + nodeInfo.nodeName = "HpaeGainNode"; + nodeInfo.nodeId = OnGetNodeId(); + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + mchIdGainNodeMap_[sessionId] = std::make_shared(nodeInfo); + } + mchIdGainNodeMap_[sessionId]->Connect(sinkInputNodeMap_[sessionId]); + outputCluster_->Connect(mchIdGainNodeMap_[sessionId]); + OnNotifyDfxNodeInfo(true, mchIdGainNodeMap_[sessionId]->GetNodeId(), sinkInputNodeMap_[sessionId]->GetNodeInfo()); + return SUCCESS; +} + +int32_t HpaeRendererManager::ConnectInputSession(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectInputSession"); + AUDIO_INFO_LOG("connect input session:%{public}d", sessionId); + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("could not input node by sessionid:%{public}d", sessionId); + return ERR_INVALID_PARAM; + } + if (sinkInputNodeMap_[sessionId]->GetState() != RENDERER_RUNNING) { + return SUCCESS; + } + if (IsMchDevice()) { + return ConnectMchInputSession(sessionId); + } + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); + int32_t effectMode = nodeInfo.effectInfo.effectMode; + if (effectMode == EFFECT_NONE) { + sceneType = HPAE_SCENE_EFFECT_NONE; + } + if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + ConnectProcessCluster(sessionId, sceneType); + } + return SUCCESS; +} + +void HpaeRendererManager::ConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectProcessCluster sceneType:" + + std::to_string(sceneType)); + int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStart(sinkInputNodeMap_[sessionId]->GetNodeInfo()); + if (ret != SUCCESS) { + AUDIO_WARNING_LOG("update audio effect when starting failed, ret = %{public}d", ret); + } + if (!outputCluster_->IsProcessClusterConnected(sceneType)) { + outputCluster_->Connect(sceneClusterMap_[sceneType]); + } + sceneClusterMap_[sceneType]->Connect(sinkInputNodeMap_[sessionId]); +} + +void HpaeRendererManager::MoveAllStreamToNewSink(const std::string &sinkName, + const std::vector& moveIds, bool isMoveAll) +{ + Trace trace("HpaeRendererManager::MoveAllStreamToNewSink[" + sinkName + "]"); + std::string name = sinkName; + std::vector> sinkInputs; + std::vector sessionIds; + for (const auto &it : sinkInputNodeMap_) { + if (isMoveAll || std::find(moveIds.begin(), moveIds.end(), it.first) != moveIds.end()) { + sinkInputs.emplace_back(it.second); + sessionIds.emplace_back(it.first); + } + } + for (const auto &it : sessionIds) { + DisConnectInputSession(it); + } + AUDIO_INFO_LOG("sink input count:%{public}zu", sinkInputs.size()); + TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name); +} + +int32_t HpaeRendererManager::MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, + bool isMoveAll) +{ + if (!IsInit()) { + AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str()); + MoveAllStreamToNewSink(sinkName, sessionIds, isMoveAll); + } else { + AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str()); + auto request = [this, sinkName, sessionIds, isMoveAll]() { + MoveAllStreamToNewSink(sinkName, sessionIds, isMoveAll); + }; + SendRequest(request); + } + return SUCCESS; +} + +int32_t HpaeRendererManager::MoveStream(uint32_t sessionId, const std::string &sinkName) +{ + AUDIO_INFO_LOG("move session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); + auto request = [this, sessionId, sinkName]() { + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + AUDIO_ERR_LOG("could not find session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); + return; + } + AUDIO_INFO_LOG("move enter session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); + std::shared_ptr inputNode = sinkInputNodeMap_[sessionId]; + if (inputNode->GetState() == RENDERER_RUNNING) { + // todo: do fade out + } + DeleteInputSession(sessionId); + if (!sinkName.empty()) { + std::string name = sinkName; + AUDIO_ERR_LOG("trigger call back, sink name:%{public}s", sinkName.c_str()); + TriggerCallback(MOVE_SINK_INPUT, inputNode, name); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::Start(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Start"); + auto request = [this, sessionId]() { + AUDIO_INFO_LOG("Start sessionId %{public}u, deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str()); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->SetState(RENDERER_RUNNING); + } + ConnectInputSession(sessionId); + SetSessionState(sessionId, RENDERER_RUNNING); + if (outputCluster_->GetState() != RENDERER_RUNNING) { + outputCluster_->Start(); + } + SetSessionFade(sessionId, OPERATION_STARTED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::DisConnectMchInputSession(uint32_t sessionId) +{ + AUDIO_INFO_LOG("Mch Device Disconnect input session:%{public}d", sessionId); + if (mchIdGainNodeMap_.find(sessionId) == mchIdGainNodeMap_.end()) { + AUDIO_INFO_LOG("Mch Device DisConnect can not find gain node session:%{public}u", sessionId); + return ERROR; + } + mchIdGainNodeMap_[sessionId]->DisConnect(sinkInputNodeMap_[sessionId]); + outputCluster_->DisConnect(mchIdGainNodeMap_[sessionId]); + return SUCCESS; +} + +int32_t HpaeRendererManager::DisConnectInputSession(uint32_t sessionId) +{ + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("DisConnectInputSession sessionId %{public}u", sessionId); + return SUCCESS; + } + if (IsMchDevice()) { + return DisConnectMchInputSession(sessionId); + } + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); + int32_t effectMode = nodeInfo.effectInfo.effectMode; + if (effectMode == EFFECT_NONE) { + sceneType = HPAE_SCENE_EFFECT_NONE; + } + if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + DisConnectProcessCluster(sessionId, sceneType); + } + return SUCCESS; +} + +void HpaeRendererManager::DisConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType) +{ + sceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]); + int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStop(sinkInputNodeMap_[sessionId]->GetNodeInfo()); + if (ret != SUCCESS) { + AUDIO_WARNING_LOG("update audio effect when stopping failed, ret = %{public}d", ret); + } + if (sceneClusterMap_[sceneType]->GetPreOutNum() == 0) { + outputCluster_->DisConnect(sceneClusterMap_[sceneType]); + } +} + +void HpaeRendererManager::SetSessionState(uint32_t sessionId, RendererState renderState) +{ + sessionNodeMap_[sessionId].state = renderState; +} + +int32_t HpaeRendererManager::Pause(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Pause"); + auto request = [this, sessionId]() { + AUDIO_INFO_LOG("Pause sessionId %{public}u deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str()); + if (!SetSessionFade(sessionId, OPERATION_PAUSED)) { + DisConnectInputSession(sessionId); + } + SetSessionState(sessionId, RENDERER_PAUSED); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->SetState(RENDERER_PAUSED); + } + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + std::shared_ptr sessionGainNode = nullptr; + if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + sessionGainNode = sceneClusterMap_[sceneType]->GetGainNodeById(sessionId); + } + if (sessionGainNode == nullptr) { + TriggerCallback(UPDATE_STATUS, + HPAE_STREAM_CLASS_TYPE_PLAY, + sessionId, + sessionNodeMap_[sessionId].state, + OPERATION_PAUSED); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::Flush(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Flush"); + auto request = [this, sessionId]() { + AUDIO_INFO_LOG("Flush sessionId %{public}u deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str()); + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("Flush not find sessionId %{public}u", sessionId); + return; + } + // flush history buffer + sinkInputNodeMap_[sessionId]->Flush(); + TriggerCallback( + UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionNodeMap_[sessionId].state, OPERATION_FLUSHED); + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::Drain(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Drain"); + auto request = [this, sessionId]() { + AUDIO_INFO_LOG("Drain sessionId %{public}u deviceName %{public}s ", sessionId, sinkInfo_.deviceName.c_str()); + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + AUDIO_INFO_LOG("Drain not find sessionId %{public}u", sessionId); + return; + } + sinkInputNodeMap_[sessionId]->Drain(); + if (sessionNodeMap_[sessionId].state != RENDERER_RUNNING) { + AUDIO_INFO_LOG("TriggerCallback Drain sessionId %{public}u", sessionId); + TriggerCallback(UPDATE_STATUS, + HPAE_STREAM_CLASS_TYPE_PLAY, + sessionId, + sessionNodeMap_[sessionId].state, + OPERATION_DRAINED); + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::Stop(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Stop"); + auto request = [this, sessionId]() { + AUDIO_INFO_LOG("Stop sessionId %{public}u deviceName %{public}s ", sessionId, sinkInfo_.deviceName.c_str()); + if (!SetSessionFade(sessionId, OPERATION_STOPPED)) { + DisConnectInputSession(sessionId); + } + SetSessionState(sessionId, RENDERER_STOPPED); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->SetState(RENDERER_STOPPED); + } + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + std::shared_ptr sessionGainNode = nullptr; + if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + sessionGainNode = sceneClusterMap_[sceneType]->GetGainNodeById(sessionId); + } + if (sessionGainNode == nullptr) { + TriggerCallback(UPDATE_STATUS, + HPAE_STREAM_CLASS_TYPE_PLAY, + sessionId, + sessionNodeMap_[sessionId].state, + OPERATION_STOPPED); // if no gainnode, trigger + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::Release(uint32_t sessionId) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Release"); + return DestroyStream(sessionId); +} + +int32_t HpaeRendererManager::SuspendStreamManager(bool isSuspend) +{ + Trace trace("HpaeRendererManager::SuspendStreamManager: " + std::to_string(isSuspend)); + auto request = [this, isSuspend]() { + if (isSuspend) { + if (outputCluster_ != nullptr) { + // todo fade out + outputCluster_->Stop(); + } + } else { + if (outputCluster_ != nullptr) { + // todo fade in + outputCluster_->Start(); + } + } + }; + SendRequest(request); + return SUCCESS; +} + +int32_t HpaeRendererManager::SetMute(bool isMute) +{ + // to do check pulseaudio + auto request = [this, isMute]() { + if (isMute_ != isMute) { + isMute_ = isMute; // todo: fadein and fadeout and mute feature + } + }; + SendRequest(request); + return SUCCESS; +} + +void HpaeRendererManager::HandleMsg() +{ + hpaeNoLockQueue_.HandleRequests(); +} + +int32_t HpaeRendererManager::Init() +{ + Trace trace("HpaeRendererManager::Init"); + hpaeSignalProcessThread_ = std::make_unique(); + auto request = [this] { + AUDIO_INFO_LOG("HpaeRendererManager::init devicename:%{public}s", sinkInfo_.deviceName.c_str()); + HpaeNodeInfo nodeInfo; + nodeInfo.channels = sinkInfo_.channels; + nodeInfo.format = sinkInfo_.format; + nodeInfo.frameLen = sinkInfo_.frameLen; + nodeInfo.nodeId = 0; + nodeInfo.samplingRate = sinkInfo_.samplingRate; + nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT; + nodeInfo.deviceNetId = sinkInfo_.deviceNetId; + nodeInfo.deviceClass = sinkInfo_.deviceClass; + nodeInfo.statusCallback = weak_from_this(); + outputCluster_ = std::make_unique(nodeInfo); + outputCluster_->SetTimeoutStopThd(sinkInfo_.suspendTime); + int32_t ret = outputCluster_->GetInstance(sinkInfo_.deviceClass, sinkInfo_.deviceNetId); + IAudioSinkAttr attr; + attr.adapterName = sinkInfo_.adapterName.c_str(); + attr.sampleRate = sinkInfo_.samplingRate; + attr.channel = sinkInfo_.channels; + attr.format = sinkInfo_.format; + attr.channelLayout = sinkInfo_.channelLayout; + attr.deviceType = sinkInfo_.deviceType; + attr.volume = sinkInfo_.volume; + attr.openMicSpeaker = sinkInfo_.openMicSpeaker; + attr.deviceNetworkId = sinkInfo_.deviceNetId.c_str(); + attr.filePath = sinkInfo_.filePath.c_str(); + if (!sceneClusterMap_.count(HPAE_SCENE_EFFECT_NONE)) { + HpaeNodeInfo defaultNodeInfo; + defaultNodeInfo.frameLen = (uint32_t)DEFAULT_EFFECT_FRAME_LEN; + defaultNodeInfo.samplingRate = (AudioSamplingRate)DEFAULT_EFFECT_RATE; + defaultNodeInfo.format = AudioSampleFormat::INVALID_WIDTH; + defaultNodeInfo.channels = STEREO; + defaultNodeInfo.channelLayout = AudioChannelLayout::CH_LAYOUT_STEREO; + defaultNodeInfo.streamType = STREAM_DEFAULT; + defaultNodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE; + defaultNodeInfo.deviceNetId = sinkInfo_.deviceNetId; + defaultNodeInfo.deviceClass = sinkInfo_.deviceClass; + defaultNodeInfo.statusCallback = weak_from_this(); + sceneClusterMap_[HPAE_SCENE_EFFECT_NONE] = std::make_shared(defaultNodeInfo, sinkInfo_); + sceneTypeToProcessClusterCountMap_[HPAE_SCENE_EFFECT_NONE] = 1; + } + + ret = outputCluster_->Init(attr); + isInit_.store(ret == SUCCESS); + TriggerCallback(INIT_DEVICE_RESULT, sinkInfo_.deviceName, ret); + }; + SendRequest(request, true); + hpaeSignalProcessThread_->ActivateThread(shared_from_this()); + return SUCCESS; +} + +bool HpaeRendererManager::DeactivateThread() +{ + if (hpaeSignalProcessThread_ != nullptr) { + hpaeSignalProcessThread_->DeactivateThread(); + hpaeSignalProcessThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); + return true; +} + +int32_t HpaeRendererManager::DeInit(bool isMoveDefault) +{ + Trace trace("HpaeRendererManager::DeInit"); + if (hpaeSignalProcessThread_ != nullptr) { + hpaeSignalProcessThread_->DeactivateThread(); + hpaeSignalProcessThread_ = nullptr; + } + hpaeNoLockQueue_.HandleRequests(); + int32_t ret = outputCluster_->DeInit(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "RenderSinkDeInit error, ret %{public}d.", ret); + outputCluster_->ResetAll(); + isInit_.store(false); + if (isMoveDefault) { + std::string sinkName = ""; + std::vector ids; + AUDIO_INFO_LOG("move all sink to default sink"); + MoveAllStreamToNewSink(sinkName, ids, true); + } + return SUCCESS; +} + +int32_t HpaeRendererManager::StartRenderSink() +{ + return SUCCESS; +} + +int32_t HpaeRendererManager::SetClientVolume(uint32_t sessionId, float volume) +{ + return SUCCESS; +} + +int32_t HpaeRendererManager::SetRate(uint32_t sessionId, int32_t rate) +{ + return SUCCESS; +} + +int32_t HpaeRendererManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) +{ + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + return ERR_INVALID_OPERATION; + } + if (effectMode < EFFECT_NONE || effectMode > EFFECT_DEFAULT) { + return ERR_INVALID_OPERATION; + } + + HpaeNodeInfo &nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); + if (nodeInfo.effectInfo.effectMode != static_cast(effectMode)) { + nodeInfo.effectInfo.effectMode = static_cast(effectMode); + UpdateProcessClusterConnection(sessionId, effectMode); + } + return SUCCESS; +} + +int32_t HpaeRendererManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) +{ + return SUCCESS; +} + +int32_t HpaeRendererManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType) +{ + return SUCCESS; +} + +int32_t HpaeRendererManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType) +{ + return SUCCESS; +} + +int32_t HpaeRendererManager::RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) +{ + auto request = [this, sessionId, callback]() { + AUDIO_INFO_LOG("RegisterWriteCallback sessionId %{public}u", sessionId); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->RegisterWriteCallback(callback); + } + }; + hpaeNoLockQueue_.PushRequest(request); + return SUCCESS; +} + +void HpaeRendererManager::Process() +{ + Trace trace("HpaeRendererManager::Process"); + if (outputCluster_ != nullptr && IsRunning()) { + outputCluster_->DoProcess(); + } +} + +size_t HpaeRendererManager::GetWritableSize(uint32_t sessionId) +{ + return SUCCESS; +} + +int32_t HpaeRendererManager::UpdateSpatializationState( + uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) +{ + return SUCCESS; +} + +int32_t HpaeRendererManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) +{ + return SUCCESS; +} + +std::vector HpaeRendererManager::GetAllSinkInputsInfo() +{ + return {}; +} + +int32_t HpaeRendererManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) +{ + if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { + return ERR_INVALID_OPERATION; + } + sinkInputInfo.nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); + sinkInputInfo.rendererSessionInfo = sessionNodeMap_[sessionId]; + return SUCCESS; +} + +HpaeSinkInfo HpaeRendererManager::GetSinkInfo() +{ + return sinkInfo_; +} + +bool HpaeRendererManager::IsInit() +{ + return isInit_.load(); +} + +bool HpaeRendererManager::IsMsgProcessing() +{ + return !hpaeNoLockQueue_.IsFinishProcess(); +} + +bool HpaeRendererManager::IsRunning(void) +{ + if (outputCluster_ != nullptr && hpaeSignalProcessThread_ != nullptr) { + return outputCluster_->GetState() == RENDERER_RUNNING && hpaeSignalProcessThread_->IsRunning(); + } else { + return false; + } +} + +void HpaeRendererManager::SendRequest(Request &&request, bool isInit) +{ + AUDIO_DEBUG_LOG("HpaeRendererManager::isInit is %{public}s", isInit ? "true" : "false"); + CHECK_AND_RETURN_LOG(isInit || IsInit(), "HpaeRendererManager not init"); + hpaeNoLockQueue_.PushRequest(std::move(request)); + CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ renderer is nullptr"); + hpaeSignalProcessThread_->Notify(); +} + +void HpaeRendererManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) +{ + TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionNodeMap_[sessionId].state, operation); +} + +void HpaeRendererManager::OnFadeDone(uint32_t sessionId, IOperation operation) +{ + Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::OnFadeDone: " + std::to_string(operation)); + AUDIO_INFO_LOG("Fade done, call back at RendererManager"); + auto request = [this, sessionId, operation]() { + DisConnectInputSession(sessionId); + RendererState state = operation == OPERATION_STOPPED ? RENDERER_STOPPED : RENDERER_PAUSED; + SetSessionState(sessionId, state); + if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { + sinkInputNodeMap_[sessionId]->SetState(state); + } + TriggerCallback( + UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionNodeMap_[sessionId].state, operation); + }; + SendRequest(request); +} + +int32_t HpaeRendererManager::RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) +{ + return SUCCESS; +} + +void HpaeRendererManager::OnRequestLatency(uint32_t sessionId, uint64_t &latency) +{ + // todo: add processLatency + return; +} + +void HpaeRendererManager::OnNotifyQueue() +{ + hpaeSignalProcessThread_->Notify(); +} + +void HpaeRendererManager::UpdateProcessClusterConnection(uint32_t sessionId, int32_t effectMode) +{ + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + if (sceneClusterMap_.find(sceneType) == sceneClusterMap_.end()) { + AUDIO_WARNING_LOG("miss corresponding process cluster for scene type %{public}d", sceneType); + return; + } + if (effectMode == EFFECT_NONE) { + DisConnectProcessCluster(sessionId, sceneType); + ConnectProcessCluster(sessionId, HPAE_SCENE_EFFECT_NONE); + } else { + DisConnectProcessCluster(sessionId, HPAE_SCENE_EFFECT_NONE); + ConnectProcessCluster(sessionId, sceneType); + } +} + +std::string HpaeRendererManager::GetThreadName() +{ + return sinkInfo_.deviceName; +} + +bool HpaeRendererManager::SetSessionFade(uint32_t sessionId, IOperation operation) +{ + CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end(), false, + "can not get input node of session %{public}u", sessionId); + HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); + std::shared_ptr sessionGainNode = nullptr; + if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { + sessionGainNode = sceneClusterMap_[sceneType]->GetGainNodeById(sessionId); + AUDIO_INFO_LOG("get gain node of session %{public}d.", sessionId); + } + if (sessionGainNode != nullptr) { + sessionGainNode->SetFadeState(operation); + return true; + } + AUDIO_WARNING_LOG("session %{public}d do not have gain node!", sessionId); + return false; +} + +void HpaeRendererManager::DumpSinkInfo() +{ + auto request = [this]() { + AUDIO_INFO_LOG("DumpSinkInfo deviceName %{public}s", sinkInfo_.deviceName.c_str()); + UploadDumpSinkInfo(sinkInfo_.deviceName); + }; + SendRequest(request); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_signal_process_thread.cpp b/services/audio_engine/manager/src/hpae_signal_process_thread.cpp new file mode 100644 index 0000000000..2736b8a095 --- /dev/null +++ b/services/audio_engine/manager/src/hpae_signal_process_thread.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 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 "hpae_signal_process_thread.h" +#include "audio_schedule.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaeSignalProcessThread::~HpaeSignalProcessThread() +{ + DeactivateThread(); +} + +void HpaeSignalProcessThread::ActivateThread(const std::weak_ptr &streamManager) +{ + streamManager_ = streamManager; + running_.store(true); + auto threadFunc = std::bind(&HpaeSignalProcessThread::Run, this); + thread_ = std::thread(threadFunc); + if (streamManager_.lock() != nullptr) { + pthread_setname_np(thread_.native_handle(), streamManager_.lock()->GetThreadName().c_str()); + } +} + +void HpaeSignalProcessThread::DeactivateThread() +{ + running_.store(false); + Notify(); + if (thread_.joinable()) { + thread_.join(); + } +} + +void HpaeSignalProcessThread::Notify() +{ + recvSignal_.store(true); + condition_.notify_all(); +} + +void HpaeSignalProcessThread::Run() +{ + ScheduleThreadInServer(getpid(), gettid()); + while (running_.load() && streamManager_.lock() != nullptr) { + { + std::unique_lock lock(mutex_); + condition_.wait(lock, [this] { + return !running_.load() || streamManager_.lock()->IsRunning() || recvSignal_.load() || + streamManager_.lock()->IsMsgProcessing(); + }); + } + if (streamManager_.lock()) { + streamManager_.lock()->HandleMsg(); + streamManager_.lock()->Process(); + } + recvSignal_.store(false); + } + UnscheduleThreadInServer(getpid(), gettid()); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/manager/src/i_hpae_manager.cpp b/services/audio_engine/manager/src/i_hpae_manager.cpp new file mode 100644 index 0000000000..853901df1c --- /dev/null +++ b/services/audio_engine/manager/src/i_hpae_manager.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 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 "hpae_manager.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +std::shared_ptr IHpaeManager::GetHpaeManager() +{ + static auto hpaeManager = std::make_shared(); + return hpaeManager; +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp b/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp new file mode 100644 index 0000000000..226fd2815c --- /dev/null +++ b/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 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 "IHpaeRendererManager" +#endif +#include "i_hpae_renderer_manager.h" +#include "hpae_renderer_manager.h" +#include "hpae_offload_renderer_manager.h" +#include "hpae_inner_capturer_manager.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +static const std::string DEVICE_CLASS_OFFLOAD = "offload"; +static const std::string DEVICE_NAME_INNER_CAP = "InnerCapturerSink"; +static const std::string DEVICE_NAME_CAST_INNER_CAP = "RemoteCastInnerCapturer"; +std::shared_ptr IHpaeRendererManager::CreateRendererManager(HpaeSinkInfo &sinkInfo) +{ + if (sinkInfo.deviceClass == DEVICE_CLASS_OFFLOAD) { + return std::make_shared(sinkInfo); + } else if ((sinkInfo.deviceName.compare(0, DEVICE_NAME_INNER_CAP.length(), DEVICE_NAME_INNER_CAP) == 0) + || sinkInfo.deviceName == DEVICE_NAME_CAST_INNER_CAP) { + return std::make_shared(sinkInfo); + } + return std::make_shared(sinkInfo); +} + +void IHpaeRendererManager::UploadDumpSinkInfo(std::string& deviceName) +{ +#ifdef ENABLE_HIDUMP_DFX + std::string dumpStr; + dfxTree_.PrintTree(dumpStr); + TriggerCallback(DUMP_SINK_INFO, deviceName, dumpStr); +#endif +}; + +void IHpaeRendererManager::OnNotifyDfxNodeInfo(bool isConnect, uint32_t preNodeId, HpaeDfxNodeInfo &nodeInfo) +{ +#ifdef ENABLE_HIDUMP_DFX + AUDIO_INFO_LOG("%{public}s preNodeId %{public}u nodeName:%{public}s, NodeId: %{public}u", + isConnect ? "connect" : "disconnect", + preNodeId, + nodeInfo.nodeName.c_str(), + nodeInfo.nodeId); + if (isConnect) { + dfxTree_.Insert(preNodeId, nodeInfo); + } else { + dfxTree_.Remove(nodeInfo.nodeId); + } +#endif +}; + +uint32_t IHpaeRendererManager::OnGetNodeId() +{ + if (nodeIdCounter_.load() == std::numeric_limits::max()) { + nodeIdCounter_.store(MIN_START_NODE_ID); + } else { + nodeIdCounter_.fetch_add(1); + } + return nodeIdCounter_.load(); +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/node/include/hpae_audio_format_converter_node.h b/services/audio_engine/node/include/hpae_audio_format_converter_node.h new file mode 100644 index 0000000000..d7a0160193 --- /dev/null +++ b/services/audio_engine/node/include/hpae_audio_format_converter_node.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 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 HPAE_AUDIOFORMAT_CONVERTER_H +#define HPAE_AUDIOFORMAT_CONVERTER_H +#include "audio_stream_info.h" +#include "hpae_plugin_node.h" +#include "channel_converter.h" +#include "audio_proresampler.h" +#ifdef ENABLE_HOOK_PCM + #include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaeAudioFormatConverterNode : public HpaePluginNode { +public: + HpaeAudioFormatConverterNode(HpaeNodeInfo preNodeInfo, HpaeNodeInfo nodeInfo); + void RegisterCallback(INodeFormatInfoCallback *callback); + void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; + void DisConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) override; +protected: + HpaePcmBuffer* SignalProcess(const std::vector& inputs) override; +private: + bool CheckUpdateInInfo(HpaePcmBuffer *input); + bool CheckUpdateOutInfo(); + int32_t ConverterProcess(float *srcData, float *dstData, float *tmpData, HpaePcmBuffer *input); + void CheckAndUpdateInfo(HpaePcmBuffer *input); + void UpdateTmpOutPcmBufferInfo(const PcmBufferInfo &outPcmBufferInfo); + PcmBufferInfo pcmBufferInfo_; + HpaePcmBuffer converterOuput_; + HpaeNodeInfo preNodeInfo_; + std::unique_ptr resampler_ = nullptr; + ChannelConverter channelConverter_; + HpaePcmBuffer tmpOutBuf_; // cache between resample and converter + // if there is render effect, the effect node decides the output format of converter node + INodeFormatInfoCallback *nodeFormatInfoCallback_ = nullptr; +#ifdef ENABLE_HOOK_PCM + std::unique_ptr inputPcmDumper_ = nullptr; + std::unique_ptr outputPcmDumper_ = nullptr; +#endif +}; + +} // HPAE +} // AudioStandard +} // OHOS +#endif diff --git a/services/audio_engine/node/include/hpae_capture_effect_node.h b/services/audio_engine/node/include/hpae_capture_effect_node.h new file mode 100644 index 0000000000..21bfba8cad --- /dev/null +++ b/services/audio_engine/node/include/hpae_capture_effect_node.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025 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 HPAE_CAPTURE_EFFECT_NODE_H +#define HPAE_CAPTURE_EFFECT_NODE_H +#include +#include "hpae_plugin_node.h" +#include "hpae_node.h" +#include "audio_effect.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +constexpr uint32_t SCENE_TYPE_OFFSET = 32; +constexpr uint32_t CAPTURER_ID_OFFSET = 16; +constexpr uint32_t BITLENGTH = 8; +constexpr uint32_t FRAME_LEN = 20; + +struct CaptureEffectAttr { + uint32_t micChannels; + uint32_t ecChannels; + uint32_t micRefChannels; +}; + +class HpaeCaptureEffectNode : public HpaePluginNode { +public: + HpaeCaptureEffectNode(HpaeNodeInfo &nodeInfo); + HpaeCaptureEffectNode(std::vector &nodeInfos); + virtual bool Reset() override; + void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; + void DisConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) override; + bool GetCapturerEffectConfig(HpaeNodeInfo& nodeInfo, HpaeSourceBufferType type = HPAE_SOURCE_BUFFER_TYPE_MIC); + int32_t CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr); + int32_t CaptureEffectRelease(uint64_t sceneKeyCode); +protected: + HpaePcmBuffer *SignalProcess(const std::vector &inputs) override; +private: + void SetCapturerEffectConfig(AudioBufferConfig micConfig, AudioBufferConfig ecConfig, + AudioBufferConfig micrefConfig); + + uint64_t sceneKeyCode_ = 0; + std::string sceneType_ = ""; + uint32_t micBufferLength_ = 0; + uint32_t ecBufferLength_ = 0; + uint32_t micrefBufferLength_ = 0; + std::vector cacheDataIn_; + std::vector cacheDataOut_; + std::unordered_map capturerEffectConfigMap_; +#ifdef ENABLE_HOOK_PCM + std::unique_ptr outputPcmDumper_; +#endif +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif // HPAE_CAPTURE_EFFECT_NODE_H \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_gain_node.h b/services/audio_engine/node/include/hpae_gain_node.h new file mode 100644 index 0000000000..40e395884e --- /dev/null +++ b/services/audio_engine/node/include/hpae_gain_node.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 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 HPAE_GAIN_NODE_H +#define HPAE_GAIN_NODE_H +#include "hpae_plugin_node.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#include "i_stream.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +enum class FadeOutState { + NO_FADEOUT, + DO_FADEOUT, + DONE_FADEOUT +}; +class HpaeGainNode : public HpaePluginNode { +public: + HpaeGainNode(HpaeNodeInfo &nodeInfo); + bool SetClientVolume(float gain); + float GetClientVolume(); + void SetFadeState(IOperation operation); +protected: + HpaePcmBuffer *SignalProcess(const std::vector &inputs) override; +private: + float preGain_ = 1.0f; + float curGain_ = 1.0f; + bool isGainChanged_ = false; + bool needGainState_ = true; + bool fadeInState_ = false; + FadeOutState fadeOutState_ = FadeOutState::NO_FADEOUT; + IOperation operation_; + void DoGain(HpaePcmBuffer *input, uint32_t frameLen, uint32_t channelCount); + void DoFading(HpaePcmBuffer *input); + void SlienceData(HpaePcmBuffer *pcmBuffer); + bool IsSilentData(HpaePcmBuffer *pcmBuffer); +#ifdef ENABLE_HOOK_PCM + std::unique_ptr inputPcmDumper_; + std::unique_ptr outputPcmDumper_; +#endif +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_inner_cap_sink_node.h b/services/audio_engine/node/include/hpae_inner_cap_sink_node.h new file mode 100644 index 0000000000..f59d56207b --- /dev/null +++ b/services/audio_engine/node/include/hpae_inner_cap_sink_node.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 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 HPAE_INNER_CAP_SINK_NODE_H +#define HPAE_INNER_CAP_SINK_NODE_H +#include +#include "hpae_node.h" +#include "hpae_pcm_buffer.h" +#include "source/i_audio_capture_source.h" +#include "hpae_renderer_manager.h" +#include "hpae_source_input_node.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaeInnerCapSinkNode : public OutputNode, public InputNode { +public: + HpaeInnerCapSinkNode(HpaeNodeInfo& nodeInfo); + virtual ~HpaeInnerCapSinkNode() {}; + virtual void DoProcess() override; + virtual bool Reset() override; + virtual bool ResetAll() override; + + std::shared_ptr GetSharedInstance() override; + OutputPort* GetOutputPort() override; + void Connect(const std::shared_ptr>& preNode) override; + void DisConnect(const std::shared_ptr>& preNode) override; + size_t GetPreOutNum(); + size_t GetOutputPortNum(); + + int32_t InnerCapturerSinkInit(); + int32_t InnerCapturerSinkDeInit(); + int32_t InnerCapturerSinkFlush(); + int32_t InnerCapturerSinkPause(); + int32_t InnerCapturerSinkReset(); + int32_t InnerCapturerSinkResume(); + int32_t InnerCapturerSinkStart(); + int32_t InnerCapturerSinkStop(); + RendererState GetSinkState(); +private: + OutputPort outputStream_; + InputPort inputStream_; + PcmBufferInfo pcmBufferInfo_; + HpaePcmBuffer silenceData_; + + HighResolutionTimer intervalTimer_; + RendererState state_ = RENDERER_NEW; +#ifdef ENABLE_HOOK_PCM + std::unique_ptr outputPcmDumper_ = nullptr; +#endif +}; + +}}} + +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_mixer_node.h b/services/audio_engine/node/include/hpae_mixer_node.h new file mode 100644 index 0000000000..87c470e885 --- /dev/null +++ b/services/audio_engine/node/include/hpae_mixer_node.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 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 HPAE_MIXER_NODE_H +#define HPAE_MIXER_NODE_H +#include +#include +#include "hpae_node.h" +#include "hpae_plugin_node.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaeMixerNode : public HpaePluginNode { +public: + HpaeMixerNode(HpaeNodeInfo &nodeInfo); + virtual bool Reset() override; +protected: + HpaePcmBuffer *SignalProcess(const std::vector &inputs) override; +private: + std::unordered_map streamVolumeMap_; + PcmBufferInfo pcmBufferInfo_; + HpaePcmBuffer mixedOutput_; +#ifdef ENABLE_HOOK_PCM + std::unique_ptr outputPcmDumper_ = nullptr;; +#endif +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_node.h b/services/audio_engine/node/include/hpae_node.h new file mode 100644 index 0000000000..6d4ae57cd8 --- /dev/null +++ b/services/audio_engine/node/include/hpae_node.h @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2025 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 HPAE_NODE_H +#define HPAE_NODE_H +#include +#include +#include +#include +#include +#include "hpae_pcm_buffer.h" +#include "hpae_define.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaeNode : public std::enable_shared_from_this { +public: + HpaeNode(){}; + virtual ~HpaeNode(){}; + HpaeNode(HpaeNodeInfo& nodeInfo) : nodeInfo_(nodeInfo) + {} + virtual void DoProcess() = 0; + // for process node + virtual bool Reset() = 0; + virtual bool ResetAll() = 0; + + virtual HpaeNodeInfo& GetNodeInfo() + { + return nodeInfo_; + } + + virtual void SetNodeInfo(HpaeNodeInfo& nodeInfo) + { + nodeInfo_ = nodeInfo; + } + + virtual AudioSamplingRate GetSampleRate() + { + return nodeInfo_.samplingRate; + } + + virtual AudioSampleFormat GetBitWidth() + { + return nodeInfo_.format; + } + + virtual AudioChannel GetChannelCount() + { + return nodeInfo_.channels; + } + + virtual AudioChannelLayout GetChannelLayout() + { + return nodeInfo_.channelLayout; + } + + virtual size_t GetFrameLen() + { + return nodeInfo_.frameLen; + } + + virtual uint32_t GetNodeId() + { + return nodeInfo_.nodeId; + } + + virtual uint32_t GetSessionId() + { + return nodeInfo_.sessionId; + } + + virtual AudioStreamType GetStreamType() + { + return nodeInfo_.streamType; + } + + virtual HpaeProcessorType GetSceneType() + { + return nodeInfo_.sceneType; + } + + virtual std::string GetDeviceClass() + { + return nodeInfo_.deviceClass; + } + + virtual std::string GetDeviceNetId() + { + return nodeInfo_.deviceNetId; + } + + virtual std::string GetNodeName() + { + return nodeInfo_.nodeName; + } + + virtual std::weak_ptr GetNodeStatusCallback() + { + return nodeInfo_.statusCallback; + } +private: + HpaeNodeInfo nodeInfo_; +}; + +template +class InputPort; + +template +class OutputPort { +public: + explicit OutputPort(HpaeNode *node) : hpaeNode_(node) + {} + void WriteDataToOutput(T data); + OutputPort(const OutputPort &that) = delete; + T PullOutputData(); + void AddInput(InputPort *input); + bool RemoveInput(InputPort *input); + size_t GetInputNum() const; +private: + std::set*> inputPortSet_; + std::vector outputData_; + HpaeNode *hpaeNode_; +}; + +template +class OutputNode : virtual public HpaeNode { +public: + virtual ~OutputNode() + {} + virtual std::shared_ptr GetSharedInstance() = 0; + virtual std::shared_ptr GetSharedInstance(HpaeNodeInfo &nodeInfo) { return nullptr; } + virtual OutputPort* GetOutputPort() = 0; + virtual OutputPort* GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) { return nullptr; } + virtual HpaeSourceBufferType GetOutputPortBufferType(HpaeNodeInfo &nodeInfo) + { return HPAE_SOURCE_BUFFER_TYPE_DEFAULT; } +}; + +template +class InputNode : virtual public HpaeNode { +public: + virtual ~InputNode() + {} + virtual void Connect(const std::shared_ptr> &preNode) = 0; + virtual void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) {} + virtual void DisConnect(const std::shared_ptr> &preNode) = 0; + virtual void DisConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) {} +}; + +template +class InputPort { +public: + InputPort() + {} + ~InputPort(); + std::vector& ReadPreOutputData(); + + void Connect(const std::shared_ptr& node, OutputPort* output); + + void DisConnect(OutputPort* output); + + size_t GetPreOutputNum() const; + + const std::unordered_map *, std::shared_ptr>& GetPreOuputMap(); + + InputPort(const InputPort &that) = delete; + + void AddPreOutput(const std::shared_ptr &node, OutputPort* output); + void RemovePreOutput(OutputPort* output); +private: + std::unordered_map*, std::shared_ptr> outputPorts_; + std::vector inputData_; +}; + +template +InputPort::~InputPort() +{ + for (auto &o : outputPorts_) { + o.first->RemoveInput(this); + } +} + +template +std::vector& InputPort::ReadPreOutputData() +{ + inputData_.clear(); + for (auto &o : outputPorts_) { + T pcmData = o.first->PullOutputData(); + if (pcmData != nullptr) { + inputData_.emplace_back(std::move(pcmData)); + } + } + return inputData_; +} + +template +void InputPort::Connect(const std::shared_ptr &node, OutputPort* output) +{ + output->AddInput(this); + AddPreOutput(node, output); +} + +template +void InputPort::DisConnect(OutputPort* output) +{ + output->RemoveInput(this); + RemovePreOutput(output); +} + +template +size_t InputPort::GetPreOutputNum() const +{ + return outputPorts_.size(); +} + +template +const std::unordered_map *, std::shared_ptr>& InputPort::GetPreOuputMap() +{ + return outputPorts_; +} + +template +void InputPort::AddPreOutput(const std::shared_ptr &node, OutputPort *output) +{ + outputPorts_[output] = node; +} + +template +void InputPort::RemovePreOutput(OutputPort *output) +{ + outputPorts_.erase(output); +} + +template +T OutputPort::PullOutputData() +{ + if (outputData_.empty()) { + hpaeNode_->DoProcess(); + } + if (!outputData_.empty()) { + T retValue = std::move(outputData_.back()); + outputData_.pop_back(); + return retValue; + } else { + return nullptr; + } +} + +template +void OutputPort::WriteDataToOutput(T data) +{ + outputData_.clear(); + outputData_.emplace_back(std::move(data)); + + for (size_t i = 1; i < inputPortSet_.size(); i++) { + outputData_.push_back(outputData_[0]); + } +} + +template +void OutputPort::AddInput(InputPort *input) +{ + inputPortSet_.insert(input); +} +template +size_t OutputPort::GetInputNum() const +{ + return inputPortSet_.size(); +} +template +bool OutputPort::RemoveInput(InputPort *input) +{ + auto it = inputPortSet_.find(input); + if (it == inputPortSet_.end()) { + return false; + } + + inputPortSet_.erase(it); + return true; +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_node_common.h b/services/audio_engine/node/include/hpae_node_common.h new file mode 100644 index 0000000000..903b0794e2 --- /dev/null +++ b/services/audio_engine/node/include/hpae_node_common.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 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 HPAE_NODE_COMMON_H +#define HPAE_NODE_COMMON_H +#include "hpae_define.h" +#include "audio_effect.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +bool CheckHpaeNodeInfoIsSame(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &curNodeInfo); +HpaeProcessorType TransStreamTypeToSceneType(AudioStreamType streamType); +HpaeProcessorType TransSourceTypeToSceneType(SourceType sourceType); +bool CheckSceneTypeNeedEc(HpaeProcessorType processorType); +bool CheckSceneTypeNeedMicRef(HpaeProcessorType processorType); +std::string TransHpaeResampleNodeInfoToStringKey(HpaeNodeInfo& nodeInfo); +AudioEnhanceScene TransProcessType2EnhanceScene(const HpaeProcessorType &processorType); +std::string TransProcessorTypeToSceneType(HpaeProcessorType processorType); +uint64_t ConvertDatalenToUs(size_t bufferSize, const HpaeNodeInfo &nodeInfo); +size_t ConvertUsToFrameCount(uint64_t usTime, const HpaeNodeInfo &nodeInfo); +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_offload_sinkoutput_node.h b/services/audio_engine/node/include/hpae_offload_sinkoutput_node.h new file mode 100644 index 0000000000..de7678c413 --- /dev/null +++ b/services/audio_engine/node/include/hpae_offload_sinkoutput_node.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2025 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 HPAE_OFFLOAD_SINK_OUTPUT_NODE_H +#define HPAE_OFFLOAD_SINK_OUTPUT_NODE_H +#include +#include "hpae_node.h" +#include "hpae_pcm_buffer.h" +#include "audio_info.h" +#include "sink/i_audio_render_sink.h" +#include "common/hdi_adapter_info.h" +#include "manager/hdi_adapter_manager.h" +#ifdef ENABLE_HOOK_PCM +#include "high_resolution_timer.h" +#include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +typedef void(*AppCallbackFunc)(void* pHndl); +class HpaeOffloadSinkOutputNode : public InputNode { +public: + HpaeOffloadSinkOutputNode(HpaeNodeInfo& nodeInfo); + virtual void DoProcess() override; + virtual bool Reset() override; + virtual bool ResetAll() override; + void Connect(const std::shared_ptr>& preNode) override; + void DisConnect(const std::shared_ptr>& preNode) override; + int32_t GetRenderSinkInstance(const std::string &deviceClass, const std::string &deviceNetworkId); + int32_t RenderSinkInit(IAudioSinkAttr& attr); + int32_t RenderSinkDeInit(); + int32_t RenderSinkFlush(); + int32_t RenderSinkStart(); + int32_t RenderSinkStop(); + size_t GetPreOutNum(); + RendererState GetSinkState(void); + const char* GetRenderFrameData(void); + // need flush hdi cache and rewind + void StopStream(); + // flush need clear sinkoutputjnode cache + void FlushStream(); + // set offload policy state + void SetPolicyState(int32_t policyState); + // get offload latency for sinkinputnode, maybe extend to all node + uint64_t GetLatency(); + // set timeout to suspend render and stop hdi + int32_t SetTimeoutStopThd(uint32_t timeoutThdMs); +private: + // lock/unlock running lock + void RunningLock(bool isLock); + // Set hdi buffer size, change after render frame success + void SetBufferSizeWhileRenderFrame(); + int32_t ProcessRenderFrame(); + // get presentation position from hdi, only trigger in offloadcallback + int32_t UpdatePresentationPosition(); + // return hdi cache len in us, cal by hdiPos_ + uint64_t CalcOffloadCacheLenInHdi(); + // set hdi volume when first write + void OffloadSetHdiVolume(); + // reset hdipos and firstWriteHdi + void OffloadReset(); + // register callback to hdi + void RegOffloadCallback(); + // offload callback reg to hdi + void OffloadCallback(const RenderCallbackType type); + // check when stop hdi, if need suspend + bool CheckIfSuspend(); + + InputPort inputStream_; + std::vector renderFrameData_; + std::vector interleveData_; + std::shared_ptr audioRendererSink_ = nullptr; + uint32_t renderId_ = HDI_INVALID_ID; + IAudioSinkAttr sinkOutAttr_; + RendererState state_ = RENDERER_NEW; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer intervalTimer_; + std::unique_ptr outputPcmDumper_ = nullptr; +#endif + + AudioOffloadType hdiPolicyState_ = OFFLOAD_ACTIVE_FOREGROUND; + struct OffloadPolicyTask { + bool flag = false; // indicate if task exsit + AudioOffloadType state; + TimePoint time; + } setPolicyStateTask_; + + bool firstWriteHdi_ = true; + uint64_t writePos_ = 0; + int32_t setHdiBufferSizeNum_ = 0; + + std::atomic isHdiFull_ = false; + + uint32_t frameLenMs_ = 0; + uint32_t timeoutThdFrames_ = 0; + // first stand for pos(in us), second stand for time + std::pair hdiPos_; +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_output_cluster.h b/services/audio_engine/node/include/hpae_output_cluster.h new file mode 100644 index 0000000000..eff788612d --- /dev/null +++ b/services/audio_engine/node/include/hpae_output_cluster.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025 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 HPAE_OUTPUT_CLUSTER_H +#define HPAE_OUTPUT_CLUSTER_H +#include "hpae_mixer_node.h" +#include "hpae_sink_output_node.h" +#include "hpae_audio_format_converter_node.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr uint32_t TIME_OUT_STOP_THD_DEFAULT_FRAME = 150; +constexpr uint32_t FRAME_LEN_MS_DEFAULT_MS = 20; +class HpaeOutputCluster : public InputNode { +public: + HpaeOutputCluster(HpaeNodeInfo &nodeInfo); + virtual ~HpaeOutputCluster(); + virtual void DoProcess() override; + virtual bool Reset() override; + virtual bool ResetAll() override; + void Connect(const std::shared_ptr> &preNode) override; + void DisConnect(const std::shared_ptr> &preNode) override; + int32_t GetConverterNodeCount(); + int32_t GetPreOutNum(); + int32_t GetInstance(std::string deviceClass, std::string deviceNetId); + int32_t Init(IAudioSinkAttr &attr); + int32_t DeInit(); + int32_t Flush(void); + int32_t Pause(void); + int32_t ResetRender(void); + int32_t Resume(void); + int32_t Start(void); + int32_t Stop(void); + int32_t SetTimeoutStopThd(uint32_t timeoutThdMs); + const char *GetFrameData(void); + RendererState GetState(void); + bool IsProcessClusterConnected(HpaeProcessorType sceneType); +private: + std::shared_ptr mixerNode_ = nullptr; + std::shared_ptr hpaeSinkOutputNode_ = nullptr; + std::unordered_map> sceneConverterMap_; + uint32_t timeoutThdFrames_ = TIME_OUT_STOP_THD_DEFAULT_FRAME; + uint32_t timeoutStopCount_ = 0; + uint32_t frameLenMs_ = FRAME_LEN_MS_DEFAULT_MS; + std::set connectedProcessCluster_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_plugin_node.h b/services/audio_engine/node/include/hpae_plugin_node.h new file mode 100644 index 0000000000..26f727fd1e --- /dev/null +++ b/services/audio_engine/node/include/hpae_plugin_node.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 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 HPAE_PLUGIN_NODE_H +#define HPAE_PLUGIN_NODE_H +#include +#include "hpae_node.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaePluginNode : public OutputNode, public InputNode { +public: + HpaePluginNode(HpaeNodeInfo& nodeInfo); + virtual ~HpaePluginNode() {}; + virtual void DoProcess() override; + virtual bool Reset() override; + virtual bool ResetAll() override; + + std::shared_ptr GetSharedInstance() override; + OutputPort* GetOutputPort() override; + void Connect(const std::shared_ptr>& preNode) override; + void DisConnect(const std::shared_ptr>& preNode) override; + virtual size_t GetPreOutNum(); + virtual size_t GetOutputPortNum(); + virtual int32_t EnableProcess(bool enable); + virtual bool IsEnableProcess(); + HpaePluginNode(const HpaePluginNode& others) = delete; +private: + OutputPort outputStream_; + bool enableProcess_; + PcmBufferInfo pcmBufferInfo_; +protected: + virtual HpaePcmBuffer* SignalProcess(const std::vector& inputs) = 0; + InputPort inputStream_; + HpaePcmBuffer silenceData_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_process_cluster.h b/services/audio_engine/node/include/hpae_process_cluster.h new file mode 100644 index 0000000000..aad56b6165 --- /dev/null +++ b/services/audio_engine/node/include/hpae_process_cluster.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 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 HPAE_PROCESS_CLUSTER_H +#define HPAE_PROCESS_CLUSTER_H +#include "hpae_mixer_node.h" +#include "hpae_audio_format_converter_node.h" +#include "hpae_gain_node.h" +#include "hpae_render_effect_node.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaeProcessCluster : public OutputNode, public InputNode, + public INodeFormatInfoCallback { +public: + HpaeProcessCluster(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &sinkInfo); + virtual ~HpaeProcessCluster(); + virtual void DoProcess() override; + virtual bool Reset() override; + virtual bool ResetAll() override; + std::shared_ptr GetSharedInstance() override; + OutputPort *GetOutputPort() override; + void Connect(const std::shared_ptr> &preNode) override; + void DisConnect(const std::shared_ptr> &preNode) override; + int32_t GetGainNodeCount(); + int32_t GetConverterNodeCount(); + int32_t GetPreOutNum(); + int32_t AudioRendererCreate(HpaeNodeInfo &nodeInfo); + int32_t AudioRendererStart(HpaeNodeInfo &nodeInfo); + int32_t AudioRendererStop(HpaeNodeInfo &nodeInfo); + int32_t AudioRendererRelease(HpaeNodeInfo &nodeInfo); + int32_t GetEffectNodeInputChannelInfo(uint32_t &channels, uint64_t &channelLayout) override; + std::shared_ptr GetGainNodeById(uint32_t id) const; + std::shared_ptr GetConverterNodeById(uint32_t id) const; +private: + std::shared_ptr mixerNode_; + std::shared_ptr renderEffectNode_ = nullptr; + std::unordered_map> idConverterMap_; + std::unordered_map> idGainMap_; + HpaeSinkInfo sinkInfo_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif // HPAE_PROCESS_CLUSTER_H \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_render_effect_node.h b/services/audio_engine/node/include/hpae_render_effect_node.h new file mode 100644 index 0000000000..6c88b490aa --- /dev/null +++ b/services/audio_engine/node/include/hpae_render_effect_node.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 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 HPAE_RENDER_EFFECT_NODE_H +#define HPAE_RENDER_EFFECT_NODE_H + +#include "hpae_plugin_node.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +enum ModifyAudioEffectChainInfoReason { + ADD_AUDIO_EFFECT_CHAIN_INFO = 0, + REMOVE_AUDIO_EFFECT_CHAIN_INFO = 1, +}; + +class HpaeRenderEffectNode : public HpaePluginNode { +public: + HpaeRenderEffectNode(HpaeNodeInfo &nodeInfo); + int32_t AudioRendererCreate(HpaeNodeInfo &nodeInfo); + int32_t AudioRendererStart(HpaeNodeInfo &nodeInfo); + int32_t AudioRendererStop(HpaeNodeInfo &nodeInfo); + int32_t AudioRendererRelease(HpaeNodeInfo &nodeInfo); + int32_t GetExpectedInputChannelInfo(uint32_t &channels, uint64_t &channelLayout); +protected: + HpaePcmBuffer* SignalProcess(const std::vector &inputs) override; +private: + void ReconfigOutputBuffer(); + int32_t CreateAudioEffectChain(HpaeNodeInfo &nodeInfo); + int32_t ReleaseAudioEffectChain(HpaeNodeInfo &nodeInfo); + void ModifyAudioEffectChainInfo(HpaeNodeInfo &nodeInfo, ModifyAudioEffectChainInfoReason reason); + void UpdateAudioEffectChainInfo(HpaeNodeInfo &nodeInfo); + PcmBufferInfo pcmBufferInfo_; + HpaePcmBuffer effectOutput_; + HpaeNodeInfo nodeInfo_; + std::string sceneType_ = "EFFECT_NONE"; +#ifdef ENABLE_HOOK_PCM + std::unique_ptr inputPcmDumper_; + std::unique_ptr outputPcmDumper_; +#endif +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS + +#endif // HPAE_RENDER_EFFECT_NODE_H \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_resample_node.h b/services/audio_engine/node/include/hpae_resample_node.h new file mode 100644 index 0000000000..8c6b45cb99 --- /dev/null +++ b/services/audio_engine/node/include/hpae_resample_node.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 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 HPAE_RESAMPLE_NODE_H +#define HPAE_RESAMPLE_NODE_H +#include "audio_proresampler.h" +#include "hpae_plugin_node.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +enum class ResamplerType { + PRORESAMPLER +}; + +class HpaeResampleNode : public HpaePluginNode { +public: + HpaeResampleNode(HpaeNodeInfo& nodeInfo, HpaeNodeInfo& preNodeInfo, ResamplerType type); + HpaeResampleNode(HpaeNodeInfo& nodeInfo, HpaeNodeInfo& preNodeInfo); + ~HpaeResampleNode() = default; + virtual bool Reset() override; + void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; + void DisConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) override; +protected: + HpaePcmBuffer* SignalProcess(const std::vector& inputs) override; +private: + void ResampleProcess(float *srcData, uint32_t inputFrameLen, float *dstData, uint32_t outputFrameLen); + PcmBufferInfo pcmBufferInfo_; + HpaePcmBuffer resampleOuput_; + HpaeNodeInfo preNodeInfo_; + std::vector tempOuput_; +#ifdef ENABLE_HOOK_PCM + std::unique_ptr inputPcmDumper_ = nullptr; + std::unique_ptr outputPcmDumper_ = nullptr; +#endif + std::unique_ptr resampler_ = nullptr; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_sink_input_node.h b/services/audio_engine/node/include/hpae_sink_input_node.h new file mode 100644 index 0000000000..4ff055eb3e --- /dev/null +++ b/services/audio_engine/node/include/hpae_sink_input_node.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 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 HPAE_SINK_INPUT_NODE_H +#define HPAE_SINK_INPUT_NODE_H +#include +#include +#include "hpae_msg_channel.h" +#include "hpae_node.h" +#include "hpae_pcm_buffer.h" +#include "audio_info.h" +#include "i_renderer_stream.h" +#include "linear_pos_time_model.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +typedef void (*AppCallbackFunc)(void *pHndl); + +class HpaeSinkInputNode : public OutputNode { +public: + HpaeSinkInputNode(HpaeNodeInfo &nodeInfo); + ~HpaeSinkInputNode(); + virtual void DoProcess() override; + virtual bool Reset() override; // no implement, virtual class + virtual bool ResetAll() override; // no implement, virtual class + std::shared_ptr GetSharedInstance() override; + OutputPort *GetOutputPort() override; + bool RegisterWriteCallback(const std::weak_ptr &callback); + void Flush(); + bool Drain(); + int32_t SetState(RendererState renderState); + RendererState GetState(); + uint64_t GetFramesWritten(); + + int32_t GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp); + int32_t RewindHistoryBuffer(uint64_t rewindTime); + +private: + void CheckAndDestoryHistoryBuffer(); + bool GetAudioTime(uint64_t &framePos, int64_t &sec, int64_t &nanoSec); + std::weak_ptr writeCallback_; + AudioCallBackStreamInfo streamInfo_; + PcmBufferInfo pcmBufferInfo_; + HpaePcmBuffer inputAudioBuffer_; + OutputPort outputStream_; + std::vector interleveData_; + std::atomic framesWritten_; + uint64_t totalFrames_; + std::unique_ptr handleTimeModel_; + bool isDrain_ = false; + RendererState state_ = RENDERER_NEW; + + std::unique_ptr historyBuffer_; +#ifdef ENABLE_HOOK_PCM + std::unique_ptr inputPcmDumper_ = nullptr; +#endif +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_sink_output_node.h b/services/audio_engine/node/include/hpae_sink_output_node.h new file mode 100644 index 0000000000..205cbc8a35 --- /dev/null +++ b/services/audio_engine/node/include/hpae_sink_output_node.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 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 HPAE_SINK_OUTPUT_NODE_H +#define HPAE_SINK_OUTPUT_NODE_H +#include +#include "hpae_node.h" +#include "hpae_pcm_buffer.h" +#include "audio_info.h" +#include "sink/i_audio_render_sink.h" +#include "common/hdi_adapter_info.h" +#include "manager/hdi_adapter_manager.h" +#include "high_resolution_timer.h" +#ifdef ENABLE_HOOK_PCM +#include "high_resolution_timer.h" +#include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +typedef void (*AppCallbackFunc)(void *pHndl); + +class HpaeSinkOutputNode : public InputNode { +public: + HpaeSinkOutputNode(HpaeNodeInfo &nodeInfo); + virtual void DoProcess() override; + virtual bool Reset() override; + virtual bool ResetAll() override; + void Connect(const std::shared_ptr> &preNode) override; + void DisConnect(const std::shared_ptr> &preNode) override; + int32_t GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId); + int32_t RenderSinkInit(IAudioSinkAttr &attr); + int32_t RenderSinkDeInit(); + int32_t RenderSinkFlush(void); + int32_t RenderSinkPause(void); + int32_t RenderSinkReset(void); + int32_t RenderSinkResume(void); + int32_t RenderSinkStart(void); + int32_t RenderSinkStop(void); + size_t GetPreOutNum(); + // for ut test + const char *GetRenderFrameData(void); + RendererState GetSinkState(void); + +private: + void HandleRemoteTiming(); + InputPort inputStream_; + std::vector renderFrameData_; + std::vector interleveData_; + std::shared_ptr audioRendererSink_ = nullptr; + uint32_t renderId_ = HDI_INVALID_ID; + IAudioSinkAttr sinkOutAttr_; + RendererState state_ = RENDERER_NEW; + HighResolutionTimer remoteTimer_; + TimePoint remoteTimePoint_; + std::chrono::milliseconds remoteSleepTime_ = std::chrono::milliseconds(0); +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer intervalTimer_; + std::unique_ptr outputPcmDumper_ = nullptr; +#endif +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_source_input_cluster.h b/services/audio_engine/node/include/hpae_source_input_cluster.h new file mode 100644 index 0000000000..fa83fe530f --- /dev/null +++ b/services/audio_engine/node/include/hpae_source_input_cluster.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 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 HPAE_SOURCE_INPUT_CLUSTER_H +#define HPAE_SOURCE_INPUT_CLUSTER_H + +#include "hpae_source_input_node.h" +#include "hpae_audio_format_converter_node.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaeSourceInputCluster : public OutputNode{ +public: + HpaeSourceInputCluster(HpaeNodeInfo &nodeInfo); + HpaeSourceInputCluster(std::vector &nodeInfos); + virtual ~HpaeSourceInputCluster(); + virtual void DoProcess() final; + virtual bool Reset() final; + virtual bool ResetAll() final; + std::shared_ptr GetSharedInstance() final; + std::shared_ptr GetSharedInstance(HpaeNodeInfo &nodeInfo) final; + OutputPort *GetOutputPort() final; + OutputPort *GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) final; + int32_t GetCapturerSourceInstance(const std::string &deviceClass, const std::string &deviceNetId, + const SourceType &sourceType, const std::string &sourceName); + int32_t CapturerSourceInit(IAudioSourceAttr &attr); + int32_t CapturerSourceDeInit(); + int32_t CapturerSourceFlush(void); + int32_t CapturerSourcePause(void); + int32_t CapturerSourceReset(void); + int32_t CapturerSourceResume(void); + int32_t CapturerSourceStart(void); + int32_t CapturerSourceStop(void); + CapturerState GetSourceState(void); + size_t GetOutputPortNum(); + size_t GetOutputPortNum(HpaeNodeInfo &nodeInfo); + HpaeSourceInputNodeType GetSourceInputNodeType(); + void SetSourceInputNodeType(HpaeSourceInputNodeType type); + + // for test + uint32_t GetConverterNodeCount(); + uint32_t GetSourceInputNodeUseCount(); +private: + std::shared_ptr sourceInputNode_; + std::unordered_map> fmtConverterNodeMap_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_source_input_node.h b/services/audio_engine/node/include/hpae_source_input_node.h new file mode 100644 index 0000000000..047f207149 --- /dev/null +++ b/services/audio_engine/node/include/hpae_source_input_node.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2025 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 HPAE_SOURCE_INTPUT_NODE_H +#define HPAE_SOURCE_INTPUT_NODE_H +#include +#include "hpae_node.h" +#include "hpae_pcm_buffer.h" +#include "source/i_audio_capture_source.h" +#include "common/hdi_adapter_type.h" +#include "common/hdi_adapter_info.h" +#include "manager/hdi_adapter_manager.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaeSourceInputNode : public OutputNode { +public: + HpaeSourceInputNode(HpaeNodeInfo &nodeInfo); + HpaeSourceInputNode(std::vector &nodeInfos); + virtual void DoProcess() override; + virtual bool Reset() override; + virtual bool ResetAll() override; + std::shared_ptr GetSharedInstance() final; + + OutputPort *GetOutputPort() final; + OutputPort *GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) final; + HpaeSourceBufferType GetOutputPortBufferType(HpaeNodeInfo &nodeInfo) final; + int32_t GetCapturerSourceInstance(const std::string &deviceClass, const std::string &deviceNetId, + const SourceType &sourceType, const std::string &sourceName); + int32_t CapturerSourceInit(IAudioSourceAttr &attr); + int32_t CapturerSourceDeInit(); + int32_t CapturerSourceFlush(void); + int32_t CapturerSourcePause(void); + int32_t CapturerSourceReset(void); + int32_t CapturerSourceResume(void); + int32_t CapturerSourceStart(void); + int32_t CapturerSourceStop(void); + CapturerState GetSourceState(void); + int32_t WriteCapturerData(char *data, int32_t dataSize); + size_t GetOutputPortNum(); + size_t GetOutputPortNum(HpaeNodeInfo &nodeInfo); + HpaeSourceInputNodeType GetSourceInputNodeType(); + void SetSourceInputNodeType(HpaeSourceInputNodeType type); +private: + int32_t GetCapturerSourceAdapter( + const std::string &deviceClass, const SourceType &sourceType, const std::string &info); + +private: + std::shared_ptr audioCapturerSource_ = nullptr; + uint32_t captureId_ = HDI_INVALID_ID; + IAudioSourceAttr audioSourceAttr_; + std::string defaultSinkName_; + std::string defaultSourceName_; + CapturerState state_ = CAPTURER_NEW; + HpaeSourceInputNodeType sourceInputNodeType_; + + std::unordered_map> outputStreamMap_; // output port + std::unordered_map nodeInfoMap_; // nodeInfo, portInfo + std::unordered_map pcmBufferInfoMap_; // bufferInfo + std::unordered_map inputAudioBufferMap_; // output buffer + std::unordered_map frameByteSizeMap_; + std::unordered_map> capturerFrameDataMap_; // input buffer + std::unordered_map fdescMap_; // CaptureframeWithEc argument struct + +#ifdef ENABLE_HOOK_PCM + std::unordered_map> inputPcmDumperMap_; +#endif +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_source_output_node.h b/services/audio_engine/node/include/hpae_source_output_node.h new file mode 100644 index 0000000000..67cac88245 --- /dev/null +++ b/services/audio_engine/node/include/hpae_source_output_node.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 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 HPAE_SOURCE_OUTPUT_NODE_H +#define HPAE_SOURCE_OUTPUT_NODE_H +#include +#include "hpae_node.h" +#include "hpae_pcm_buffer.h" +#include "audio_info.h" +#include "i_capturer_stream.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class HpaeSourceOutputNode : public InputNode { +public: + HpaeSourceOutputNode(HpaeNodeInfo &nodeInfo); + virtual void DoProcess() final; + virtual bool Reset() final; + bool ResetAll() final; + void Connect(const std::shared_ptr> &preNode) override; + void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; + void DisConnect(const std::shared_ptr> &preNode) override; + void DisConnectWithInfo( + const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; + bool RegisterReadCallback(const std::weak_ptr &callback); + +private: + InputPort inputStream_; + std::weak_ptr readCallback_; + std::vector sourceOuputData_; + std::vector interleveData_; +#ifdef ENABLE_HOOK_PCM + std::unique_ptr outputPcmDumper_ = nullptr; +#endif +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_source_process_cluster.h b/services/audio_engine/node/include/hpae_source_process_cluster.h new file mode 100644 index 0000000000..d478e397db --- /dev/null +++ b/services/audio_engine/node/include/hpae_source_process_cluster.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 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 HPAE_SOURCE_PROCESS_CLUSTER_H +#define HPAE_SOURCE_PROCESS_CLUSTER_H +#include "hpae_capture_effect_node.h" +#include "hpae_audio_format_converter_node.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaeSourceProcessCluster : public OutputNode, public InputNode { +public: + HpaeSourceProcessCluster(HpaeNodeInfo &nodeInfo); + virtual ~HpaeSourceProcessCluster(); + virtual void DoProcess() override; + virtual bool Reset() override; + virtual bool ResetAll() override; + std::shared_ptr GetSharedInstance() override; + std::shared_ptr GetSharedInstance(HpaeNodeInfo &nodeInfo) override; + OutputPort *GetOutputPort() override; + OutputPort *GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) override; + + // HpaeNodeInfo& GetOutputNodeInfo() override; + void Connect(const std::shared_ptr>& preNode) override; + void DisConnect(const std::shared_ptr>& preNode) override; + void ConnectWithInfo(const std::shared_ptr>& preNode, HpaeNodeInfo &nodeInfo) override; + void DisConnectWithInfo(const std::shared_ptr>& preNode, + HpaeNodeInfo &nodeInfo) override; + bool GetCapturerEffectConfig(HpaeNodeInfo& nodeInfo, HpaeSourceBufferType type = HPAE_SOURCE_BUFFER_TYPE_MIC); + + size_t GetOutputPortNum(); + int32_t CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr); + int32_t CaptureEffectRelease(uint64_t sceneKeyCode); +private: + std::shared_ptr captureEffectNode_; + std::unordered_map> fmtConverterNodeMap_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp b/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp new file mode 100644 index 0000000000..254457b871 --- /dev/null +++ b/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2025 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 "HpaeAudioFormatConverterNode" +#endif +#include "hpae_audio_format_converter_node.h" +#include "audio_engine_log.h" +#include "audio_utils.h" + +static constexpr uint32_t DEFAULT_EFFECT_RATE = 48000; + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr int REASAMPLE_QUAILTY = 5; +HpaeAudioFormatConverterNode::HpaeAudioFormatConverterNode(HpaeNodeInfo preNodeInfo, HpaeNodeInfo nodeInfo) + : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), + pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout), + converterOuput_(pcmBufferInfo_), preNodeInfo_(preNodeInfo), tmpOutBuf_(pcmBufferInfo_) +{ + UpdateTmpOutPcmBufferInfo(pcmBufferInfo_); + // use ProResamppler as default + resampler_ = std::make_unique(preNodeInfo_.samplingRate, nodeInfo.samplingRate, + std::min(preNodeInfo_.channels, nodeInfo.channels), REASAMPLE_QUAILTY); + + AudioChannelInfo inChannelInfo = { + .channelLayout = preNodeInfo.channelLayout, + .numChannels = preNodeInfo.channels, + }; + AudioChannelInfo outChannelInfo = { + .channelLayout = nodeInfo.channelLayout, + .numChannels = nodeInfo.channels, + }; + + // for now, work at float32le by default + channelConverter_.SetParam(inChannelInfo, outChannelInfo, SAMPLE_F32LE, true); + AUDIO_INFO_LOG("node id %{public}d, sessionid %{public}d, " + "input: bitformat %{public}d, sample rate %{public}d, channels %{public}d, channelLayout %{public}lu" + ", output: bitformat %{public}d, sample rate %{public}d, channels %{public}d, channelLayout %{public}lu", + GetNodeId(), GetSessionId(), preNodeInfo.format, preNodeInfo.samplingRate, inChannelInfo.numChannels, + inChannelInfo.channelLayout, nodeInfo.format, nodeInfo.samplingRate, outChannelInfo.numChannels, + outChannelInfo.channelLayout); +#ifdef ENABLE_HOOK_PCM + inputPcmDumper_ = std::make_unique("HpaeConverterNodeInput_id_" + std::to_string(GetSessionId()) + + "_ch_" + std::to_string(preNodeInfo_.channels) + "_rate_" + + std::to_string(preNodeInfo_.samplingRate) + "_" + GetTime() + ".pcm"); + outputPcmDumper_ = std::make_unique("HpaeConverterNodeOutput_id_" + std::to_string(GetSessionId()) + + "_ch_" + std::to_string(GetChannelCount()) + "_rate_" + + std::to_string(GetSampleRate()) + "_" + GetTime() + ".pcm"); +#endif +} + +void HpaeAudioFormatConverterNode::RegisterCallback(INodeFormatInfoCallback *callback) +{ + nodeFormatInfoCallback_ = callback; +} + +HpaePcmBuffer *HpaeAudioFormatConverterNode::SignalProcess(const std::vector &inputs) +{ + auto rate = "rate[" + std::to_string(GetSampleRate()) + "]_"; + auto ch = "ch[" + std::to_string(GetChannelCount()) + "]_"; + auto len = "len[" + std::to_string(GetFrameLen()) + "]"; + Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeAudioFormatConverterNode::SignalProcess " + + rate + ch + len); + if (inputs.empty()) { + AUDIO_WARNING_LOG("HpaeConverterNode inputs size is empty, SessionId:%{public}d", GetSessionId()); + return nullptr; + } + if (inputs.size() != 1) { + AUDIO_WARNING_LOG("error inputs size is not eqaul to 1, SessionId:%{public}d", GetSessionId()); + } + float *srcData = (*(inputs[0])).GetPcmDataBuffer(); +#ifdef ENABLE_HOOK_PCM + if (inputPcmDumper_ != nullptr) { + inputPcmDumper_->Dump((int8_t *)(srcData), + inputs[0]->GetFrameLen() * inputs[0]->GetChannelCount() * sizeof(float)); + } +#endif + converterOuput_.Reset(); + tmpOutBuf_.Reset(); + + CheckAndUpdateInfo(inputs[0]); + + float *dstData = converterOuput_.GetPcmDataBuffer(); + float *tmpData = tmpOutBuf_.GetPcmDataBuffer(); + + if (resampler_ == nullptr) { + return &silenceData_; + } + int32_t ret = ConverterProcess(srcData, dstData, tmpData, inputs[0]); + if (ret != EOK) { + AUDIO_ERR_LOG("NodeId %{public}d, sessionId %{public}d, Format Converter fail to process!", + GetNodeId(), GetSessionId()); + return &silenceData_; + } + +#ifdef ENABLE_HOOK_PCM + if (outputPcmDumper_ != nullptr) { + outputPcmDumper_->Dump((int8_t *)dstData, + converterOuput_.GetFrameLen() * sizeof(float) * channelConverter_.GetOutChannelInfo().numChannels); + } +#endif + AUDIO_DEBUG_LOG("NodeId %{public}d, buffer valid %{public}d", GetSessionId(), converterOuput_.IsValid()); + return &converterOuput_; +} + +int32_t HpaeAudioFormatConverterNode::ConverterProcess(float *srcData, float *dstData, float *tmpData, + HpaePcmBuffer *input) +{ + AudioChannelInfo inChannelInfo = channelConverter_.GetInChannelInfo(); + AudioChannelInfo outChannelInfo = channelConverter_.GetOutChannelInfo(); + uint32_t inRate = resampler_->GetInRate(); + uint32_t outRate = resampler_->GetOutRate(); + + uint32_t inputFrameLen = preNodeInfo_.frameLen; + uint32_t outputFrameLen = converterOuput_.GetFrameLen(); + uint32_t inputFrameBytes = inputFrameLen * inChannelInfo.numChannels * sizeof(float); + uint32_t outputFrameBytes = outputFrameLen * outChannelInfo.numChannels * sizeof(float); + int32_t ret = EOK; + + if ((inChannelInfo.numChannels == outChannelInfo.numChannels) && (inRate == outRate)) { + ret = memcpy_s(dstData, outputFrameBytes, srcData, inputFrameBytes); + } else if (inChannelInfo.numChannels == outChannelInfo.numChannels) { + ret = resampler_->Process(srcData, &inputFrameLen, dstData, &outputFrameLen); + } else if (inRate == outRate) { + ret = channelConverter_.Process(inputFrameLen, srcData, (*input).Size(), dstData, converterOuput_.Size()); + } else if (inChannelInfo.numChannels > outChannelInfo.numChannels) { // convert, then resample + ret = channelConverter_.Process(inputFrameLen, srcData, (*input).Size(), tmpData, tmpOutBuf_.Size()); + ret += resampler_->Process(tmpData, &inputFrameLen, dstData, &outputFrameLen); + } else { // output channels larger than input channels, resample, then convert + ret = resampler_->Process(srcData, &inputFrameLen, tmpData, &outputFrameLen); + ret += channelConverter_.Process(outputFrameLen, tmpData, tmpOutBuf_.Size(), dstData, converterOuput_.Size()); + } + return ret; +} + +// return true if output info is updated +bool HpaeAudioFormatConverterNode::CheckUpdateOutInfo() +{ + // update channelLayout and numChannels + if (nodeFormatInfoCallback_ == nullptr) { + return false; + } + + uint32_t numChannels = 0; + uint64_t channelLayout = CH_LAYOUT_UNKNOWN; + // effectnode input is 48k by default now + uint32_t sampleRate = DEFAULT_EFFECT_RATE; + + // if there exists an effect node, converter node output is effect node input + // update channels and channelLayout + + nodeFormatInfoCallback_->GetEffectNodeInputChannelInfo(numChannels, channelLayout); + + if (numChannels == 0 || channelLayout == CH_LAYOUT_UNKNOWN) { + // set to node info, which is device output info + AUDIO_INFO_LOG("Fail to check format into from effect node"); + numChannels = GetChannelCount(); + channelLayout = (uint64_t)GetChannelLayout(); + sampleRate = GetSampleRate(); + } + + AudioChannelInfo curOutChannelInfo = channelConverter_.GetOutChannelInfo(); + if ((curOutChannelInfo.numChannels == numChannels) && (curOutChannelInfo.channelLayout == channelLayout) && + (sampleRate == resampler_->GetOutRate())) { + return false; + } + // update channel info + if (curOutChannelInfo.numChannels != numChannels || curOutChannelInfo.channelLayout != channelLayout) { + AudioChannelInfo newOutChannelInfo = { + .channelLayout = (AudioChannelLayout)channelLayout, + .numChannels = numChannels, + }; + AUDIO_INFO_LOG("NodeId %{public}d, update out channels and channelLayout: channels %{public}d -> %{public}d", + GetNodeId(), curOutChannelInfo.numChannels, numChannels); + CHECK_AND_RETURN_RET_LOG(channelConverter_.SetOutChannelInfo(newOutChannelInfo) == DMIX_ERR_SUCCESS, false, + "NodeId: %{public}d, Fail to set output channel info from effectNode!", GetNodeId()); + + uint32_t resampleChannels = std::min(channelConverter_.GetInChannelInfo().numChannels, numChannels); + if (resampleChannels != resampler_->GetChannels()) { + AUDIO_INFO_LOG("NodeId: %{public}d, Update resampler work channel from effectNode!", GetNodeId()); + resampler_->UpdateChannels(resampleChannels); + } + } + // update sample rate + if (resampler_->GetOutRate() != sampleRate) { + AUDIO_INFO_LOG("NodeId: %{public}d, update output sample rate: %{public}d -> %{public}d", + GetNodeId(), resampler_->GetOutRate(), sampleRate); + resampler_->UpdateRates(preNodeInfo_.samplingRate, sampleRate); + } + + HpaeNodeInfo nodeInfo = GetNodeInfo(); + nodeInfo.channels = (AudioChannel)numChannels; + nodeInfo.channelLayout = (AudioChannelLayout)channelLayout; + nodeInfo.samplingRate = (AudioSamplingRate)resampler_->GetOutRate(); + SetNodeInfo(nodeInfo); + return true; +} + +// update channel info from processCluster. For now sample rate will not change +bool HpaeAudioFormatConverterNode::CheckUpdateInInfo(HpaePcmBuffer *input) +{ + uint32_t numChannels = input->GetChannelCount(); + uint64_t channelLayout = input->GetChannelLayout(); + uint32_t sampleRate = input->GetSampleRate(); + AudioChannelInfo curInChannelInfo = channelConverter_.GetInChannelInfo(); + bool isInfoUpdated = false; + // update channels and channelLayout + if ((curInChannelInfo.numChannels != numChannels) || (curInChannelInfo.channelLayout != channelLayout)) { + AUDIO_INFO_LOG("NodeId %{public}d: Update innput channel info from pcmBufferInfo, " + "channels: %{public}d -> %{public}d, channellayout: %{public}lu -> %{public}lu.", + GetNodeId(), curInChannelInfo.numChannels, numChannels, curInChannelInfo.channelLayout, channelLayout); + + AudioChannelInfo newInChannelInfo = { + .channelLayout = (AudioChannelLayout)channelLayout, + .numChannels = numChannels, + }; + channelConverter_.SetInChannelInfo(newInChannelInfo); + preNodeInfo_.channelLayout = (AudioChannelLayout)channelLayout; + preNodeInfo_.channels = (AudioChannel)numChannels; + + uint32_t resampleChannels = std::min(numChannels, channelConverter_.GetOutChannelInfo().numChannels); + if (resampleChannels != resampler_->GetChannels()) { + AUDIO_INFO_LOG("NodeId %{public}d: Update resampler work channel from effectNode!", GetNodeId()); + resampler_->UpdateChannels(resampleChannels); + } + isInfoUpdated = true; + } + // update sample rate + if (sampleRate != resampler_->GetInRate()) { + AUDIO_INFO_LOG("NodeId %{public}d: Update resampler input sample rate: %{public}d -> %{public}d", + GetNodeId(), resampler_->GetInRate(), sampleRate); + preNodeInfo_.frameLen = input->GetFrameLen(); + preNodeInfo_.samplingRate = (AudioSamplingRate)sampleRate; + resampler_->UpdateRates(sampleRate, resampler_->GetOutRate()); + isInfoUpdated = true; + } + return isInfoUpdated; +} + +void HpaeAudioFormatConverterNode::UpdateTmpOutPcmBufferInfo(const PcmBufferInfo &outPcmBufferInfo) +{ + if (outPcmBufferInfo.ch == preNodeInfo_.channels || outPcmBufferInfo.rate == preNodeInfo_.samplingRate) { + // do not need tmpOutput Buffer + return; + } + PcmBufferInfo tmpOutPcmBufferInfo = outPcmBufferInfo; + if (outPcmBufferInfo.ch < preNodeInfo_.channels) { // downmix, then resample + tmpOutPcmBufferInfo.rate = preNodeInfo_.samplingRate; + tmpOutPcmBufferInfo.frameLen = preNodeInfo_.frameLen; + } else { // resample, then upmix + tmpOutPcmBufferInfo.ch = preNodeInfo_.channels; + } + AUDIO_INFO_LOG("NodeId: %{public}d, updated tmp buffer rate %{public}d, frameLen %{public}d, channels %{public}d", + GetNodeId(), tmpOutPcmBufferInfo.rate, tmpOutPcmBufferInfo.frameLen, tmpOutPcmBufferInfo.ch); + tmpOutBuf_.ReConfig(tmpOutPcmBufferInfo); +} + + +void HpaeAudioFormatConverterNode::CheckAndUpdateInfo(HpaePcmBuffer *input) +{ + bool isInfoUpdated = CheckUpdateInInfo(input); + bool isOutInfoUpdated = CheckUpdateOutInfo(); + if ((!isInfoUpdated) && (!isOutInfoUpdated)) { + return; + } + + AudioChannelInfo outChannelInfo = channelConverter_.GetOutChannelInfo(); + PcmBufferInfo outPcmBufferInfo = pcmBufferInfo_; // isMultiFrames_ and frame_ are inheritated from sinkInputNode + outPcmBufferInfo.ch = outChannelInfo.numChannels; + outPcmBufferInfo.rate = resampler_->GetOutRate(); + outPcmBufferInfo.frameLen = preNodeInfo_.frameLen * resampler_->GetOutRate() / resampler_->GetInRate(); + outPcmBufferInfo.channelLayout = outChannelInfo.channelLayout; + + AUDIO_INFO_LOG("NodeId %{public}d: output or input format info is changed, update tmp PCM buffer info!", + GetNodeId()); + UpdateTmpOutPcmBufferInfo(outPcmBufferInfo); + + if (isOutInfoUpdated) { + AUDIO_INFO_LOG("NodeId %{public}d: output format info is changed, update output PCM buffer info!", GetNodeId()); + converterOuput_.ReConfig(outPcmBufferInfo); + silenceData_.ReConfig(outPcmBufferInfo); +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfoChanged(GetNodeId(), GetNodeInfo()); + } +#endif + } +} + +void HpaeAudioFormatConverterNode::ConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) +{ + inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort(nodeInfo)); + converterOuput_.SetSourceBufferType(nodeInfo.sourceBufferType); +} +void HpaeAudioFormatConverterNode::DisConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) +{ + inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true)); +} + +} // Hpae +} // AudioStandard +} // OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_capture_effect_node.cpp b/services/audio_engine/node/src/hpae_capture_effect_node.cpp new file mode 100644 index 0000000000..e0e28a7635 --- /dev/null +++ b/services/audio_engine/node/src/hpae_capture_effect_node.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2025 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 "HpaeCaptureEffectNode" +#endif + +#include "hpae_capture_effect_node.h" +#include +#include "hpae_pcm_buffer.h" +#include "audio_engine_log.h" +#include "audio_errors.h" +#include "hpae_format_convert.h" +#include "audio_enhance_chain_manager.h" +#include "audio_effect_map.h" +#include "audio_utils.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaeCaptureEffectNode::HpaeCaptureEffectNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo) +{ + const std::unordered_map &audioEnhanceSupportedSceneTypes = + GetEnhanceSupportedSceneType(); + auto item = audioEnhanceSupportedSceneTypes.find(nodeInfo.effectInfo.enhanceScene); + if (item != audioEnhanceSupportedSceneTypes.end()) { + sceneType_ = item->second; + AUDIO_INFO_LOG("HpaeCaptureEffectNode created scenetype: [%{public}s]", sceneType_.c_str()); + } else { + AUDIO_ERR_LOG("scenetype: %{public}u not supported", nodeInfo.effectInfo.enhanceScene); + } +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_ = std::make_unique( + "HpaeCaptureEffectNode_id_" + std::to_string(GetNodeId()) + "_" + sceneType_ + "_Out.pcm"); +#endif +} + +HpaeCaptureEffectNode::HpaeCaptureEffectNode(std::vector &nodeInfos) + : HpaeNode(*nodeInfos.begin()), HpaePluginNode(*nodeInfos.begin()) +{ + for (auto &nodeInfo : nodeInfos) { + capturerEffectConfigMap_.emplace(nodeInfo.sourceBufferType, nodeInfo); + } +} + +bool HpaeCaptureEffectNode::Reset() +{ + return HpaePluginNode::Reset(); +} + +HpaePcmBuffer *HpaeCaptureEffectNode::SignalProcess(const std::vector &inputs) +{ + Trace trace("[" + sceneType_ + "]HpaeRenderEffectNode::SignalProcess inputs num[" + + std::to_string(inputs.size()) + "]"); + if (inputs.empty()) { + AUDIO_WARNING_LOG("HpaeCaptureEffectNode inputs size is empty, SessionId:%{public}d", GetSessionId()); + return nullptr; + } + + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + uint32_t processLength = 0; + uint32_t outputIndex = 0; + for (uint32_t i = 0; i < inputs.size(); i++) { + if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_MIC) { + ConvertFromFloat(SAMPLE_S16LE, micBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE), + inputs[i]->GetPcmDataBuffer(), static_cast(cacheDataIn_.data())); + audioEnhanceChainManager->CopyToEnhanceBuffer(static_cast(cacheDataIn_.data()), micBufferLength_); + processLength = micBufferLength_; + outputIndex = i; + AUDIO_DEBUG_LOG("CopyToEnhanceBuffer size:%{public}u", processLength); + } else if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_EC) { + ConvertFromFloat(SAMPLE_S16LE, ecBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE), + inputs[i]->GetPcmDataBuffer(), static_cast(cacheDataIn_.data())); + audioEnhanceChainManager->CopyEcToEnhanceBuffer(static_cast(cacheDataIn_.data()), ecBufferLength_); + AUDIO_DEBUG_LOG("CopyEcToEnhanceBuffer size:%{public}u", ecBufferLength_); + } else if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_MICREF) { + ConvertFromFloat(SAMPLE_S16LE, micrefBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE), + inputs[i]->GetPcmDataBuffer(), static_cast(cacheDataIn_.data())); + audioEnhanceChainManager->CopyMicRefToEnhanceBuffer(static_cast(cacheDataIn_.data()), + micrefBufferLength_); + AUDIO_DEBUG_LOG("CopyMicRefToEnhanceBuffer size:%{public}u", micrefBufferLength_); + } + cacheDataIn_.clear(); + } + int32_t ret = audioEnhanceChainManager->ApplyAudioEnhanceChain(sceneKeyCode_, processLength); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, inputs[outputIndex], "effect apply failed, ret:%{public}d", ret); + audioEnhanceChainManager->CopyFromEnhanceBuffer(static_cast(cacheDataOut_.data()), processLength); + ConvertToFloat(SAMPLE_S16LE, micBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE), + static_cast(cacheDataOut_.data()), inputs[outputIndex]->GetPcmDataBuffer()); +#ifdef ENABLE_HOOK_PCM + if (outputPcmDumper_) { + outputPcmDumper_->Dump((int8_t *)inputs[outputIndex]->GetPcmDataBuffer(), + micBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE) * sizeof(float)); + } +#endif + return inputs[outputIndex]; +} + +void HpaeCaptureEffectNode::ConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) +{ + std::shared_ptr realPreNode = preNode->GetSharedInstance(nodeInfo); + inputStream_.Connect(realPreNode, preNode->GetOutputPort(nodeInfo)); +#ifdef ENABLE_HIDUMP_DFX + if (auto callback = realPreNode->GetNodeInfo().statusCallback.lock()) { + callback->OnNotifyDfxNodeInfo( + true, realPreNode->GetNodeId(), GetNodeInfo()); + } +#endif +} + +void HpaeCaptureEffectNode::DisConnectWithInfo(const std::shared_ptr>& preNode, + HpaeNodeInfo &nodeInfo) +{ + inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true)); +} + +bool HpaeCaptureEffectNode::GetCapturerEffectConfig(HpaeNodeInfo& nodeInfo, HpaeSourceBufferType type) +{ + CHECK_AND_RETURN_RET_LOG(capturerEffectConfigMap_.find(type) != capturerEffectConfigMap_.end(), + false, "not need resample node, type:%{public}u", type); + nodeInfo = capturerEffectConfigMap_[type]; + return true; +} + +void HpaeCaptureEffectNode::SetCapturerEffectConfig(AudioBufferConfig micConfig, AudioBufferConfig ecConfig, + AudioBufferConfig micrefConfig) +{ + HpaeNodeInfo micInfo = {}; + HpaeNodeInfo ecInfo = {}; + HpaeNodeInfo micrefInfo = {}; + micInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC; + micInfo.frameLen = FRAME_LEN * (micConfig.samplingRate / MILLISECOND_PER_SECOND); + micInfo.samplingRate = static_cast(micConfig.samplingRate); + micInfo.channels = static_cast(micConfig.channels); + micInfo.format = static_cast(micConfig.format / BITLENGTH - 1); + ecInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_EC; + ecInfo.frameLen = FRAME_LEN * (ecConfig.samplingRate / MILLISECOND_PER_SECOND); + ecInfo.samplingRate = static_cast(ecConfig.samplingRate); + ecInfo.channels = static_cast(ecConfig.channels); + ecInfo.format = static_cast(ecConfig.format / BITLENGTH - 1); + micrefInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MICREF; + micrefInfo.frameLen = FRAME_LEN * (micrefConfig.samplingRate / MILLISECOND_PER_SECOND); + micrefInfo.samplingRate = static_cast(micrefConfig.samplingRate); + micrefInfo.channels = static_cast(micrefConfig.channels); + micrefInfo.format = static_cast(micrefConfig.format / BITLENGTH - 1); + capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_MIC, micInfo); + capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_EC, ecInfo); + capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_MICREF, micrefInfo); +} + +int32_t HpaeCaptureEffectNode::CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr) +{ + sceneKeyCode_ = sceneKeyCode; + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager, ERR_ILLEGAL_STATE, "audioEnhanceChainManager is nullptr"); + AudioEnhanceDeviceAttr enhanceAttr = {}; + enhanceAttr.micChannels = attr.micChannels; + enhanceAttr.ecChannels = attr.ecChannels; + enhanceAttr.micRefChannels = attr.micRefChannels; + int32_t ret = audioEnhanceChainManager->CreateAudioEnhanceChainDynamic(sceneKeyCode, enhanceAttr); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("CreateAudioEnhanceChainDynamic failed, ret:%{public}d", ret); + } + audioEnhanceChainManager->InitEnhanceBuffer(); + + AudioBufferConfig micConfig = {}; + AudioBufferConfig ecConfig = {}; + AudioBufferConfig micrefConfig = {}; + ret = audioEnhanceChainManager->AudioEnhanceChainGetAlgoConfig(sceneKeyCode, micConfig, ecConfig, micrefConfig); + if (ret != 0 || micConfig.samplingRate == 0) { + AUDIO_ERR_LOG("get algo config failed, ret:%{public}d", ret); + return ERROR; + } + SetCapturerEffectConfig(micConfig, ecConfig, micrefConfig); + micBufferLength_ = FRAME_LEN * micConfig.channels * (micConfig.samplingRate / MILLISECOND_PER_SECOND) * + (micConfig.format / BITLENGTH); + ecBufferLength_ = FRAME_LEN * ecConfig.channels * (ecConfig.samplingRate / MILLISECOND_PER_SECOND) * + (ecConfig.format / BITLENGTH); + micrefBufferLength_ = FRAME_LEN * micrefConfig.channels * (micrefConfig.samplingRate / MILLISECOND_PER_SECOND) * + (micrefConfig.format / BITLENGTH); + uint32_t maxLength = (micBufferLength_ > ecBufferLength_) ? + (micBufferLength_ > micrefBufferLength_ ? micBufferLength_ : micrefBufferLength_) : + (ecBufferLength_ > micrefBufferLength_ ? ecBufferLength_ : micrefBufferLength_); + AUDIO_INFO_LOG("micLength: %{public}u, ecLength: %{public}u, micrefLength: %{public}u, maxLength:%{public}u", + micBufferLength_, ecBufferLength_, micrefBufferLength_, maxLength); + cacheDataIn_.resize(maxLength); + cacheDataOut_.resize(maxLength); + return ret; +} + +int32_t HpaeCaptureEffectNode::CaptureEffectRelease(uint64_t sceneKeyCode) +{ + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager, ERROR_ILLEGAL_STATE, "audioEnhanceChainManager is nullptr"); + return audioEnhanceChainManager->ReleaseAudioEnhanceChainDynamic(sceneKeyCode); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/node/src/hpae_gain_node.cpp b/services/audio_engine/node/src/hpae_gain_node.cpp new file mode 100644 index 0000000000..7c36858d4e --- /dev/null +++ b/services/audio_engine/node/src/hpae_gain_node.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2025 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 "HpaeGainNode" +#endif + +#include "hpae_gain_node.h" +#include "hpae_pcm_buffer.h" +#include "audio_volume_c.h" +#include "audio_engine_log.h" +#include "audio_utils.h" +#include "securec.h" +#include "volume_tools_c.h" +#include "audio_stream_info.h" +#include "hpae_info.h" + +#include +#include + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +static constexpr float FADE_LOW = 0.0f; +static constexpr float FADE_HIGH = 1.0f; +static constexpr float SHORT_FADE_PERIOD = 0.005f; // 5ms fade for 10ms < playback duration <= 40ms +static constexpr float EPSILON = 1e-6f; + +HpaeGainNode::HpaeGainNode(HpaeNodeInfo &nodeInfo) : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo) +{ + float curSystemGain = GetCurVolumeByStreamType(GetSessionId(), (int32_t)GetStreamType(), GetDeviceClass().c_str()); + SetPreVolume(GetSessionId(), curSystemGain); + AUDIO_INFO_LOG("HpaeGainNode curSystemGain:%{public}f streamType :%{public}d", curSystemGain, GetStreamType()); + AUDIO_INFO_LOG( + "HpaeGainNode SessionId:%{public}u deviceClass :%{public}s", GetSessionId(), GetDeviceClass().c_str()); +#ifdef ENABLE_HOOK_PCM + inputPcmDumper_ = std::make_unique("HpaeGainNodeInput_id_" + std::to_string(GetSessionId()) + + "_ch_" + std::to_string(GetChannelCount()) + "_rate_" + + std::to_string(GetSampleRate()) + "_" + GetTime() + ".pcm"); + outputPcmDumper_ = std::make_unique("HpaeGainNodeOut_id_" + std::to_string(GetSessionId()) + "_ch_" + + std::to_string(GetChannelCount()) + "_rate_" + + std::to_string(GetSampleRate()) + "_" + GetTime() + ".pcm"); +#endif +} + +HpaePcmBuffer *HpaeGainNode::SignalProcess(const std::vector &inputs) +{ + if (inputs.empty()) { + AUDIO_WARNING_LOG("HpaeGainNode inputs size is empty, SessionId:%{public}d", GetSessionId()); + return nullptr; + } + auto rate = "rate[" + std::to_string(inputs[0]->GetSampleRate()) + "]_"; + auto ch = "ch[" + std::to_string(inputs[0]->GetChannelCount()) + "]_"; + auto len = "len[" + std::to_string(inputs[0]->GetFrameLen()) + "]"; + Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeGainNode::SignalProcess " + rate + ch + len); + if (fadeOutState_ == FadeOutState::DONE_FADEOUT) { + AUDIO_INFO_LOG("HpaeGainNode: fadeout done, set session %{public}d slience", GetSessionId()); + SlienceData(inputs[0]); + } + float *inputData = (float *)inputs[0]->GetPcmDataBuffer(); + uint32_t frameLen = inputs[0]->GetFrameLen(); + uint32_t channelCount = inputs[0]->GetChannelCount(); + +#ifdef ENABLE_HOOK_PCM + if (inputPcmDumper_ != nullptr) { + inputPcmDumper_->Dump((int8_t *)(inputData), (frameLen * sizeof(float) * channelCount)); + } +#endif + + if (needGainState_) { + DoGain(inputs[0], frameLen, channelCount); + } + DoFading(inputs[0]); + +#ifdef ENABLE_HOOK_PCM + if (outputPcmDumper_ != nullptr) { + outputPcmDumper_->Dump((int8_t *)(inputData), (frameLen * sizeof(float) * channelCount)); + } +#endif + return inputs[0]; +} + +bool HpaeGainNode::SetClientVolume(float gain) +{ + preGain_ = curGain_; + curGain_ = gain; + isGainChanged_ = true; + return true; +} + +float HpaeGainNode::GetClientVolume() +{ + return curGain_; +} + +void HpaeGainNode::SetFadeState(IOperation operation) +{ + operation_ = operation; + // fade in + if (operation_ == OPERATION_STARTED) { + if (fadeInState_ == false) { // todo: add operation for softstart + fadeInState_ = true; + AUDIO_INFO_LOG("need to fade in"); + } else { + AUDIO_WARNING_LOG("fadeInState already set"); + } + fadeOutState_ = FadeOutState::NO_FADEOUT; // reset fadeOutState_ + } + + // fade out + if (operation_ == OPERATION_PAUSED || operation_ == OPERATION_STOPPED) { + if (fadeOutState_ == FadeOutState::NO_FADEOUT) { + fadeOutState_ = FadeOutState::DO_FADEOUT; + AUDIO_INFO_LOG("need to fade out"); + } else { + AUDIO_WARNING_LOG("current fadeout state %{public}d, cannot prepare fadeout", fadeOutState_); + } + } + AUDIO_DEBUG_LOG("fadeInState_[%{public}d], fadeOutState_[%{public}d]", fadeInState_, fadeOutState_); +} + + +void HpaeGainNode::DoFading(HpaePcmBuffer *input) +{ + if (!input->IsValid() && fadeOutState_ == FadeOutState::DO_FADEOUT) { + AUDIO_WARNING_LOG("after drain, get invalid data, no need to do fade out"); + fadeOutState_ = FadeOutState::DONE_FADEOUT; + auto statusCallback = GetNodeStatusCallback().lock(); + CHECK_AND_RETURN_LOG(statusCallback != nullptr, "statusCallback is null, cannot callback"); + statusCallback->OnFadeDone(GetSessionId(), operation_); + } + AudioRawFormat rawFormat; + rawFormat.format = SAMPLE_F32LE; // for now PCM in gain node is float32 + rawFormat.channels = GetChannelCount(); + uint32_t byteLength = 0; + uint8_t *data = (uint8_t *)input->GetPcmDataBuffer(); + switch (GetNodeInfo().fadeType) { + case FadeType::NONE_FADE: { + break; + } + case FadeType::SHORT_FADE: { + byteLength = (float)GetSampleRate() * SHORT_FADE_PERIOD * rawFormat.channels * sizeof(float); + AUDIO_DEBUG_LOG("GainNode: short fade length in Bytes: %{public}u", byteLength); + break; + } + case FadeType::DEFAULT_FADE: { + byteLength = input->Size(); + AUDIO_DEBUG_LOG("GainNode: default fade length in Bytes: %{public}u", byteLength); + break; + } + default: + break; + } + AUDIO_DEBUG_LOG("Final fade in/out length of GainNode in Bytes: %{public}u.", byteLength); + if (fadeInState_) { + CHECK_AND_RETURN_LOG(input->IsValid(), "GainNode: invalid data no need to do fade in"); + CHECK_AND_RETURN_LOG(!IsSilentData(input), "GainNode: silent data no need to do fade in"); + AUDIO_INFO_LOG("GainNode: fade in started!"); + ProcessVol(data, byteLength, rawFormat, FADE_LOW, FADE_HIGH); + fadeInState_ = false; + } + if (fadeOutState_ == FadeOutState::DO_FADEOUT) { + AUDIO_INFO_LOG("GainNode: fade out started!"); + ProcessVol(data, byteLength, rawFormat, FADE_HIGH, FADE_LOW); + fadeOutState_ = FadeOutState::DONE_FADEOUT; + return; + } + if (fadeOutState_ == FadeOutState::DONE_FADEOUT) { + AUDIO_INFO_LOG("fade out done, session %{public}d callback to update status", GetSessionId()); + auto statusCallback = GetNodeStatusCallback().lock(); + CHECK_AND_RETURN_LOG(statusCallback != nullptr, "statusCallback is null, cannot callback"); + statusCallback->OnFadeDone(GetSessionId(), operation_); // if operation is stop or pause, callback + } +} + +void HpaeGainNode::SlienceData(HpaePcmBuffer *pcmBuffer) +{ + void *data = pcmBuffer->GetPcmDataBuffer(); + if (GetNodeInfo().format == INVALID_WIDTH) { + AUDIO_WARNING_LOG("HpaePcmBuffer.SetDataSlience: invalid format"); + } else if (GetNodeInfo().format == SAMPLE_U8) { + // set silence data for all the frames + memset_s(data, pcmBuffer->Size(), 0x80, pcmBuffer->Size()); + } else { + memset_s(data, pcmBuffer->Size(), 0, pcmBuffer->Size()); + } +} + +void HpaeGainNode::DoGain(HpaePcmBuffer *input, uint32_t frameLen, uint32_t channelCount) +{ + float *inputData = (float *)input->GetPcmDataBuffer(); + float curSystemGain = GetCurVolumeByStreamType(GetSessionId(), (int32_t)GetStreamType(), GetDeviceClass().c_str()); + float preSystemGain = GetPreVolume(GetSessionId()); + float systemStepGain = (curSystemGain - preSystemGain) / frameLen; + AUDIO_DEBUG_LOG( + "curSystemGain:%{public}f, preSystemGain:%{public}f, systemStepGain:%{public}f deviceClass :%{public}s", + curSystemGain, + preSystemGain, + systemStepGain, + GetDeviceClass().c_str()); + SetPreVolume(GetSessionId(), curSystemGain); + for (uint32_t i = 0; i < frameLen; i++) { + for (uint32_t j = 0; j < channelCount; j++) { + inputData[channelCount * i + j] = inputData[channelCount * i + j] * (preSystemGain + systemStepGain * i); + } + } +} + +bool HpaeGainNode::IsSilentData(HpaePcmBuffer *pcmBuffer) +{ + float *data = pcmBuffer->GetPcmDataBuffer(); + size_t length = pcmBuffer->Size() / sizeof(float); + AUDIO_DEBUG_LOG("HpaeGainNode::Data length:%{public}zu", length); + return std::all_of(data, data + length, [](float value) { + return fabs(value) < EPSILON; + }); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_inner_cap_sink_node.cpp b/services/audio_engine/node/src/hpae_inner_cap_sink_node.cpp new file mode 100644 index 0000000000..74e1b66c53 --- /dev/null +++ b/services/audio_engine/node/src/hpae_inner_cap_sink_node.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2025 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 "HpaeInnerCapSinkNode" +#endif + +#include "hpae_inner_cap_sink_node.h" +#include "hpae_format_convert.h" +#include "audio_errors.h" +#include "audio_policy_log.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif +#include +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +const int32_t DEFAULT_NANO_SECONDS = 20000000; +const int32_t NANO_SECONDS = 1000000; + +HpaeInnerCapSinkNode::HpaeInnerCapSinkNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), outputStream_(this), + pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), silenceData_(pcmBufferInfo_) +{ + silenceData_.Reset(); +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_ = std::make_unique("HpaeInnerCapSinkNode_bit_" + + std::to_string(GetBitWidth()) + "_ch_" + std::to_string(GetChannelCount()) + + "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); +#endif +} + +void HpaeInnerCapSinkNode::DoProcess() +{ + std::vector &outputVec = inputStream_.ReadPreOutputData(); + if (outputVec.empty()) { + outputStream_.WriteDataToOutput(&silenceData_); + } else { + HpaePcmBuffer *outputData = outputVec.front(); +#ifdef ENABLE_HOOK_PCM + if (outputPcmDumper_) { + outputPcmDumper_->Dump((int8_t *)outputData->GetPcmDataBuffer(), GetChannelCount() * + GetFrameLen() * GET_SIZE_FROM_FORMAT(GetBitWidth())); + } +#endif + // no need convert + outputStream_.WriteDataToOutput(outputVec[0]); + } + // sleep + intervalTimer_.Stop(); + auto elapsed = intervalTimer_.Elapsed(); + std::this_thread::sleep_for(std::chrono::nanoseconds(DEFAULT_NANO_SECONDS - elapsed)); + AUDIO_DEBUG_LOG("sleeptime : %{public}f", DEFAULT_NANO_SECONDS - ((static_cast(elapsed))/NANO_SECONDS)); + intervalTimer_.Start(); +} + +bool HpaeInnerCapSinkNode::Reset() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + inputStream_.DisConnect(output); + } + return true; +} + +bool HpaeInnerCapSinkNode::ResetAll() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + std::shared_ptr hpaeNode = preOutput.second; + if (hpaeNode->ResetAll()) { + inputStream_.DisConnect(output); + } + } + return true; +} + +// todo +std::shared_ptr HpaeInnerCapSinkNode::GetSharedInstance() +{ + return shared_from_this(); +} + +// todo +OutputPort *HpaeInnerCapSinkNode::GetOutputPort() +{ + return &outputStream_; +} + +void HpaeInnerCapSinkNode::Connect(const std::shared_ptr>& preNode) +{ + AUDIO_INFO_LOG("Connect"); + inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); +} + +void HpaeInnerCapSinkNode::DisConnect(const std::shared_ptr>& preNode) +{ + AUDIO_INFO_LOG("DisConnect"); + inputStream_.DisConnect(preNode->GetOutputPort()); +} + +int32_t HpaeInnerCapSinkNode::InnerCapturerSinkInit() +{ + AUDIO_INFO_LOG("Init"); + state_ = RENDERER_NEW; + return SUCCESS; +} + +int32_t HpaeInnerCapSinkNode::InnerCapturerSinkDeInit() +{ + AUDIO_INFO_LOG("DeInit"); + state_ = RENDERER_INVALID; + return SUCCESS; +} + +int32_t HpaeInnerCapSinkNode::InnerCapturerSinkFlush() +{ + AUDIO_INFO_LOG("Flush"); + return SUCCESS; +} + +int32_t HpaeInnerCapSinkNode::InnerCapturerSinkPause() +{ + AUDIO_INFO_LOG("Pause"); + state_ = RENDERER_PAUSED; + return SUCCESS; +} + +int32_t HpaeInnerCapSinkNode::InnerCapturerSinkReset() +{ + AUDIO_INFO_LOG("Reset"); + return SUCCESS; +} + +int32_t HpaeInnerCapSinkNode::InnerCapturerSinkResume() +{ + AUDIO_INFO_LOG("Resume"); + state_ = RENDERER_RUNNING; + return SUCCESS; +} + +int32_t HpaeInnerCapSinkNode::InnerCapturerSinkStart() +{ + AUDIO_INFO_LOG("Start"); + state_ = RENDERER_RUNNING; + return SUCCESS; +} + +int32_t HpaeInnerCapSinkNode::InnerCapturerSinkStop() +{ + AUDIO_INFO_LOG("Stop"); + state_ = RENDERER_STOPPED; + return SUCCESS; +} + +RendererState HpaeInnerCapSinkNode::GetSinkState(void) +{ + return state_; +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_mixer_node.cpp b/services/audio_engine/node/src/hpae_mixer_node.cpp new file mode 100644 index 0000000000..47bdd549b1 --- /dev/null +++ b/services/audio_engine/node/src/hpae_mixer_node.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2025 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 "HpaeMixerNode" +#endif +#include +#include "hpae_mixer_node.h" +#include "hpae_pcm_buffer.h" +#include "audio_utils.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaeMixerNode::HpaeMixerNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), + pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout), + mixedOutput_(pcmBufferInfo_) +{ +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_ = std::make_unique("HpaeMixerNodeOut_ch_" + + std::to_string(nodeInfo.channels) + "_scenType_" + + std::to_string(GetSceneType()) + "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); + AUDIO_INFO_LOG("HpaeMixerNode scene type is %{public}d", GetSceneType()); +#endif +} + +bool HpaeMixerNode::Reset() +{ + return HpaePluginNode::Reset(); +} + +HpaePcmBuffer *HpaeMixerNode::SignalProcess(const std::vector &inputs) +{ + Trace trace("HpaeMixerNode::SignalProcess"); + CHECK_AND_RETURN_RET_LOG(!inputs.empty(), nullptr, "inputs is empty"); + + mixedOutput_.Reset(); + + bool isPCMBufferInfoUpdated = false; + if (pcmBufferInfo_.ch != inputs[0]->GetChannelCount()) { + AUDIO_INFO_LOG("Update channel count: %{public}d -> %{public}d", + pcmBufferInfo_.ch, inputs[0]->GetChannelCount()); + pcmBufferInfo_.ch = inputs[0]->GetChannelCount(); + isPCMBufferInfoUpdated = true; + } + if (pcmBufferInfo_.frameLen != inputs[0]->GetFrameLen()) { + AUDIO_INFO_LOG("Update frame len %{public}d -> %{public}d", + pcmBufferInfo_.frameLen, inputs[0]->GetFrameLen()); + pcmBufferInfo_.frameLen = inputs[0]->GetFrameLen(); + isPCMBufferInfoUpdated = true; + } + if (pcmBufferInfo_.rate != inputs[0]->GetSampleRate()) { + AUDIO_INFO_LOG("Update sample rate %{public}d -> %{public}d", + pcmBufferInfo_.rate, inputs[0]->GetSampleRate()); + pcmBufferInfo_.rate = inputs[0]->GetSampleRate(); + isPCMBufferInfoUpdated = true; + } + if (pcmBufferInfo_.channelLayout != inputs[0]->GetChannelLayout()) { + AUDIO_INFO_LOG("Update channel layout %{public}lu -> %{public}lu", + pcmBufferInfo_.channelLayout, inputs[0]->GetChannelLayout()); + pcmBufferInfo_.channelLayout = inputs[0]->GetChannelLayout(); + isPCMBufferInfoUpdated = true; + } + // if other bitwidth is supported, add check here + + if (isPCMBufferInfoUpdated) { + mixedOutput_.ReConfig(pcmBufferInfo_); + } + + for (auto input : inputs) { + mixedOutput_ += *input; + } +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_->CheckAndReopenHandlde(); + outputPcmDumper_->Dump((int8_t *)(mixedOutput_.GetPcmDataBuffer()), + mixedOutput_.GetChannelCount() * sizeof(float) * mixedOutput_.GetFrameLen()); +#endif + return &mixedOutput_; +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_node_common.cpp b/services/audio_engine/node/src/hpae_node_common.cpp new file mode 100644 index 0000000000..d584a0aef3 --- /dev/null +++ b/services/audio_engine/node/src/hpae_node_common.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2025 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 "hpae_node_common.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +static constexpr uint64_t TIME_US_PER_S = 1000000; +static std::map g_streamTypeToSceneTypeMap = { + {STREAM_MUSIC, HPAE_SCENE_MUSIC}, + {STREAM_GAME, HPAE_SCENE_GAME}, + {STREAM_MOVIE, HPAE_SCENE_MOVIE}, + {STREAM_GAME, HPAE_SCENE_GAME}, + {STREAM_SPEECH, HPAE_SCENE_SPEECH}, + {STREAM_VOICE_RING, HPAE_SCENE_RING}, + {STREAM_VOICE_COMMUNICATION, HPAE_SCENE_VOIP_DOWN}, + {STREAM_MEDIA, HPAE_SCENE_OTHERS} +}; + +static std::unordered_map g_sourceTypeToSceneTypeMap = { + {SOURCE_TYPE_MIC, HPAE_SCENE_RECORD}, + {SOURCE_TYPE_CAMCORDER, HPAE_SCENE_RECORD}, + {SOURCE_TYPE_VOICE_CALL, HPAE_SCENE_VOIP_UP}, + {SOURCE_TYPE_VOICE_COMMUNICATION, HPAE_SCENE_VOIP_UP}, + {SOURCE_TYPE_VOICE_TRANSCRIPTION, HPAE_SCENE_PRE_ENHANCE}, + {SOURCE_TYPE_VOICE_MESSAGE, HPAE_SCENE_VOICE_MESSAGE} +}; + + +static std::unordered_set g_processorTypeNeedEcSet = { + HPAE_SCENE_VOIP_UP, + HPAE_SCENE_PRE_ENHANCE, +}; + +static std::unordered_set g_processorTypeNeedMicRefSet = { + HPAE_SCENE_VOIP_UP, + HPAE_SCENE_RECORD, +}; + +static std::unordered_map g_processorTypeToSceneTypeMap = { + {HPAE_SCENE_RECORD, SCENE_RECORD}, + {HPAE_SCENE_VOIP_UP, SCENE_VOIP_UP}, + {HPAE_SCENE_PRE_ENHANCE, SCENE_PRE_ENHANCE}, + {HPAE_SCENE_VOICE_MESSAGE, SCENE_VOICE_MESSAGE} +}; + +HpaeProcessorType TransStreamTypeToSceneType(AudioStreamType streamType) +{ + if (g_streamTypeToSceneTypeMap.find(streamType) == g_streamTypeToSceneTypeMap.end()) { + return HPAE_SCENE_EFFECT_NONE; + } else { + return g_streamTypeToSceneTypeMap[streamType]; + } +} + +HpaeProcessorType TransSourceTypeToSceneType(SourceType sourceType) +{ + if (g_sourceTypeToSceneTypeMap.find(sourceType) == g_sourceTypeToSceneTypeMap.end()) { + return HPAE_SCENE_EFFECT_NONE; + } else { + return g_sourceTypeToSceneTypeMap[sourceType]; + } +} + +bool CheckSceneTypeNeedEc(HpaeProcessorType processorType) +{ + return g_processorTypeNeedEcSet.find(processorType) != g_processorTypeNeedEcSet.end(); +} + +bool CheckSceneTypeNeedMicRef(HpaeProcessorType processorType) +{ + return g_processorTypeNeedMicRefSet.find(processorType) != g_processorTypeNeedMicRefSet.end(); +} + +static std::unordered_map g_processorTypeToEffectSceneTypeMap = { + {HPAE_SCENE_OTHERS, "SCENE_OTHERS"}, + {HPAE_SCENE_MUSIC, "SCENE_MUSIC"}, + {HPAE_SCENE_GAME, "SCENE_GAME"}, + {HPAE_SCENE_MOVIE, "SCENE_MOVIE"}, + {HPAE_SCENE_SPEECH, "SCENE_SPEECH"}, + {HPAE_SCENE_RING, "SCENE_RING"}, + {HPAE_SCENE_VOIP_DOWN, "SCENE_VOIP_DOWN"}}; + +std::string TransProcessorTypeToSceneType(HpaeProcessorType processorType) +{ + if (g_processorTypeToEffectSceneTypeMap.find(processorType) == g_processorTypeToEffectSceneTypeMap.end()) { + return "SCENE_EXTRA"; + } else { + return g_processorTypeToEffectSceneTypeMap[processorType]; + } +} + +bool CheckHpaeNodeInfoIsSame(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &curNodeInfo) +{ + return preNodeInfo.channels == curNodeInfo.channels && //&& preNodeInfo.format == curNodeInfo.format todo + preNodeInfo.samplingRate == curNodeInfo.samplingRate && + preNodeInfo.channelLayout == curNodeInfo.channelLayout; +} + +std::string TransHpaeResampleNodeInfoToStringKey(HpaeNodeInfo& nodeInfo) +{ + std::string nodeKey = std::to_string(nodeInfo.sourceBufferType) + "_" + + std::to_string(nodeInfo.samplingRate) + "_" + + std::to_string(nodeInfo.channels) + "_" + + std::to_string(nodeInfo.format); + return nodeKey; +} + +AudioEnhanceScene TransProcessType2EnhanceScene(const HpaeProcessorType &processorType) +{ + if (g_processorTypeToSceneTypeMap.find(processorType) == g_processorTypeToSceneTypeMap.end()) { + return SCENE_NONE; + } else { + return g_processorTypeToSceneTypeMap[processorType]; + } +} + +size_t ConvertUsToFrameCount(uint64_t usTime, const HpaeNodeInfo &nodeInfo) +{ + return usTime * nodeInfo.samplingRate / TIME_US_PER_S / + (nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); +} + +uint64_t ConvertDatalenToUs(size_t bufferSize, const HpaeNodeInfo &nodeInfo) +{ + if (nodeInfo.channels == 0 || GET_SIZE_FROM_FORMAT(nodeInfo.format) == 0 || nodeInfo.samplingRate == 0) { + AUDIO_ERR_LOG("invalid nodeInfo"); + return 0; + } + + double samples = static_cast(bufferSize) / + (nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); + double seconds = samples / static_cast(nodeInfo.samplingRate); + double microseconds = seconds * TIME_US_PER_S; + + return static_cast(microseconds); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp new file mode 100644 index 0000000000..d6f8a869eb --- /dev/null +++ b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2025 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 "HpaeOffloadSinkOutputNode" +#endif + +#include "hpae_offload_sinkoutput_node.h" +#include "audio_errors.h" +#include +#include "hpae_format_convert.h" +#include "hpae_node_common.h" +#include "audio_engine_log.h" +#include "audio_volume.h" +#include "audio_common_utils.h" +#include "inttypes.h" +#ifdef ENABLE_HOOK_PCM +#include "hpae_pcm_dumper.h" +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +namespace { + constexpr uint32_t CACHE_FRAME_COUNT = 2; + constexpr uint32_t TIME_US_PER_MS = 1000; + constexpr uint32_t TIME_MS_PER_SEC = 1000; + constexpr uint32_t ERR_RETRY_COUNT = 20; + constexpr uint32_t FRAME_TIME_IN_MS = 20; + constexpr int32_t OFFLOAD_FULL = -1; + constexpr int32_t OFFLOAD_WRITE_FAILED = -2; + constexpr uint32_t OFFLOAD_HDI_CACHE_BACKGROUND_IN_MS = 7000; + constexpr uint32_t OFFLOAD_HDI_CACHE_FRONTGROUND_IN_MS = 200; + // hdi fallback, modify when hdi change + constexpr uint32_t OFFLOAD_FAD_INTERVAL_IN_US = 180; + constexpr uint32_t OFFLOAD_SET_BUFFER_SIZE_NUM = 5; + constexpr uint32_t POLICY_STATE_DELAY_IN_SEC = 3; + + const std::string DEVICE_CLASS_OFFLOAD = "offload"; +} +HpaeOffloadSinkOutputNode::HpaeOffloadSinkOutputNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), + renderFrameData_(nodeInfo.frameLen * nodeInfo.channels * + GET_SIZE_FROM_FORMAT(nodeInfo.format) * CACHE_FRAME_COUNT), + interleveData_(nodeInfo.frameLen * nodeInfo.channels) +{ +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_ = std::make_unique( + "HpaeOffloadSinkOutputNode_Out_bit_" + std::to_string(GetBitWidth()) + "_ch_" + + std::to_string(GetChannelCount()) + "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); +#endif + frameLenMs_ = nodeInfo.frameLen * TIME_MS_PER_SEC / nodeInfo.samplingRate; +} + +bool HpaeOffloadSinkOutputNode::CheckIfSuspend() +{ + static uint32_t suspendCount = 0; + if (!GetPreOutNum()) { + suspendCount++; + usleep(TIME_US_PER_MS * FRAME_TIME_IN_MS); + if (suspendCount > timeoutThdFrames_) { + RenderSinkStop(); + } + return true; + } else { + suspendCount = 0; + return false; + } +} + +void HpaeOffloadSinkOutputNode::DoProcess() +{ + CHECK_AND_RETURN_LOG(audioRendererSink_, "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + if (CheckIfSuspend()) { + return; + } + // if there are no enough frames in cache, read more data from pre-output + size_t frameSize = GET_SIZE_FROM_FORMAT(GetBitWidth()) * GetFrameLen() * GetChannelCount(); + while (renderFrameData_.size() < CACHE_FRAME_COUNT * frameSize) { + std::vector &outputVec = inputStream_.ReadPreOutputData(); + if (outputVec.front()->IsValid()) { + renderFrameData_.resize(renderFrameData_.size() + frameSize); + ConvertFromFloat(GetBitWidth(), GetChannelCount() * GetFrameLen(), + outputVec.front()->GetPcmDataBuffer(), renderFrameData_.data() + renderFrameData_.size() - frameSize); + } else { + break; + } + } + int32_t ret = ProcessRenderFrame(); + // if renderframe faild, sleep and return directly + // if renderframe full, unlock the powerlock + static uint32_t retryCount = 1; + if (ret != SUCCESS) { + if (ret == OFFLOAD_FULL) { + RunningLock(false); + isHdiFull_.store(true); + return; + } + usleep(std::min(retryCount, FRAME_TIME_IN_MS) * TIME_US_PER_MS); + if (retryCount < ERR_RETRY_COUNT) { + retryCount++; + } + return; + } + retryCount = 1; + return; +} + +bool HpaeOffloadSinkOutputNode::Reset() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + inputStream_.DisConnect(output); + } + return true; +} + +bool HpaeOffloadSinkOutputNode::ResetAll() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + std::shared_ptr hpaeNode = preOutput.second; + if (hpaeNode->ResetAll()) { + inputStream_.DisConnect(output); + } + } + return true; +} + +void HpaeOffloadSinkOutputNode::Connect(const std::shared_ptr> &preNode) +{ + inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); +} + +void HpaeOffloadSinkOutputNode::DisConnect(const std::shared_ptr> &preNode) +{ + inputStream_.DisConnect(preNode->GetOutputPort()); +} + +int32_t HpaeOffloadSinkOutputNode::GetRenderSinkInstance(const std::string &deviceClass, + const std::string &deviceNetworkId) +{ + renderId_ = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass( + deviceClass, HDI_ID_INFO_DEFAULT, true); + audioRendererSink_ = HdiAdapterManager::GetInstance().GetRenderSink(renderId_, true); + if (audioRendererSink_ == nullptr) { + AUDIO_ERR_LOG("get offload sink fail, deviceClass: %{public}s, renderId_: %{public}u", + deviceClass.c_str(), renderId_); + HdiAdapterManager::GetInstance().ReleaseId(renderId_); + return ERROR; + } + return SUCCESS; +} + +void HpaeOffloadSinkOutputNode::OffloadReset() +{ + writePos_ = 0; + hdiPos_ = std::make_pair(0, std::chrono::high_resolution_clock::now()); + firstWriteHdi_ = true; + isHdiFull_.store(false); + renderFrameData_.clear(); + setPolicyStateTask_.flag = false; // unset the task when reset + RunningLock(true); +} + +int32_t HpaeOffloadSinkOutputNode::RenderSinkInit(IAudioSinkAttr &attr) +{ + CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, + "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + + sinkOutAttr_ = attr; + state_ = RENDERER_PREPARED; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + int32_t ret = audioRendererSink_->Init(attr); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, + "audioRendererSink_ init failed, errCode is %{public}d", ret); +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkInit Elapsed: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, interval); +#endif + return ret; +} + +int32_t HpaeOffloadSinkOutputNode::RenderSinkDeInit(void) +{ + CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, + "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + state_ = RENDERER_INVALID; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + audioRendererSink_->DeInit(); + audioRendererSink_ = nullptr; + HdiAdapterManager::GetInstance().ReleaseId(renderId_); +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkDeInit Elapsed: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, interval); +#endif + return SUCCESS; +} + +int32_t HpaeOffloadSinkOutputNode::RenderSinkFlush(void) +{ + CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, + "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + int32_t ret; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + ret = audioRendererSink_->Flush(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, + "audioRendererSink_ flush failed, errCode is %{public}d", ret); +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkFlush Elapsed: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, interval); +#endif + return ret; +} + +int32_t HpaeOffloadSinkOutputNode::RenderSinkStart(void) +{ + CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, + "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + + int32_t ret; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + ret = audioRendererSink_->Start(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, + "audioRendererSink_ start failed, errCode is %{public}d", ret); + RegOffloadCallback(); + // start need lock + RunningLock(true); + OffloadSetHdiVolume(); +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkStart Elapsed: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, interval); +#endif + state_ = RENDERER_RUNNING; + return SUCCESS; +} + +int32_t HpaeOffloadSinkOutputNode::RenderSinkStop(void) +{ + CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, + "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + int32_t ret; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + ret = audioRendererSink_->Stop(); + OffloadReset(); + RunningLock(false); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, + "audioRendererSink_ stop failed, errCode is %{public}d", ret); +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkStop Elapsed: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, interval); +#endif + state_ = RENDERER_STOPPED; + return SUCCESS; +} + +void HpaeOffloadSinkOutputNode::FlushStream() +{ + renderFrameData_.clear(); +} + +size_t HpaeOffloadSinkOutputNode::GetPreOutNum() +{ + return inputStream_.GetPreOutputNum(); +} + +RendererState HpaeOffloadSinkOutputNode::GetSinkState(void) +{ + return isHdiFull_.load() ? RENDERER_PAUSED : state_; +} + +const char *HpaeOffloadSinkOutputNode::GetRenderFrameData(void) +{ + return renderFrameData_.data(); +} + +void HpaeOffloadSinkOutputNode::StopStream() +{ + // flush hdi when disconnect + RunningLock(true); + auto ret = RenderSinkFlush(); + CHECK_AND_RETURN_LOG(ret == SUCCESS, "RenderSinkFlush failed"); + uint64_t cacheLenInHdi = CalcOffloadCacheLenInHdi(); + cacheLenInHdi = cacheLenInHdi > OFFLOAD_FAD_INTERVAL_IN_US ? + cacheLenInHdi - OFFLOAD_FAD_INTERVAL_IN_US : 0; + uint64_t rewindTime = cacheLenInHdi + ConvertDatalenToUs(renderFrameData_.size(), GetNodeInfo()); + AUDIO_DEBUG_LOG("OffloadRewindAndFlush rewind time in us %{public}" PRIu64, rewindTime); + auto callback = GetNodeInfo().statusCallback.lock(); + callback->OnRewindAndFlush(rewindTime); + OffloadReset(); +} + +void HpaeOffloadSinkOutputNode::SetPolicyState(int32_t state) +{ + if (setPolicyStateTask_.flag) { + if (state == hdiPolicyState_) { + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: unset policy state task"); + setPolicyStateTask_.flag = false; + } + return; + } + if (hdiPolicyState_ != state && state == OFFLOAD_INACTIVE_BACKGROUND) { + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: set policy state task"); + setPolicyStateTask_.flag = true; + setPolicyStateTask_.time = std::chrono::high_resolution_clock::now(); + setPolicyStateTask_.state = OFFLOAD_INACTIVE_BACKGROUND; + return; + } + hdiPolicyState_ = static_cast(state); + int32_t bufferSize = hdiPolicyState_ == OFFLOAD_INACTIVE_BACKGROUND ? + OFFLOAD_HDI_CACHE_BACKGROUND_IN_MS : OFFLOAD_HDI_CACHE_FRONTGROUND_IN_MS; + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: set hdi buffer size to %{public}d", bufferSize); + audioRendererSink_->SetBufferSize(bufferSize); +} + +uint64_t HpaeOffloadSinkOutputNode::GetLatency() +{ + return CalcOffloadCacheLenInHdi() + ConvertDatalenToUs(renderFrameData_.size(), GetNodeInfo()); +} + +int32_t HpaeOffloadSinkOutputNode::SetTimeoutStopThd(uint32_t timeoutThdMs) +{ + if (frameLenMs_ != 0) { + timeoutThdFrames_ = timeoutThdMs / frameLenMs_; + } + AUDIO_INFO_LOG( + "SetTimeoutStopThd: timeoutThdFrames_:%{public}u, timeoutThdMs :%{public}u", timeoutThdFrames_, timeoutThdMs); + return SUCCESS; +} + +void HpaeOffloadSinkOutputNode::RunningLock(bool islock) +{ + if (islock) { + audioRendererSink_->LockOffloadRunningLock(); + } else if (!islock && hdiPolicyState_ == OFFLOAD_INACTIVE_BACKGROUND) { + // only unlock when background + audioRendererSink_->UnLockOffloadRunningLock(); + } +} + +void HpaeOffloadSinkOutputNode::SetBufferSizeWhileRenderFrame() +{ + // 3s delay works, when change to BACKGROUND + if (setPolicyStateTask_.flag) { + auto now = std::chrono::high_resolution_clock::now(); + if (std::chrono::duration_cast(now - setPolicyStateTask_.time).count() >= + POLICY_STATE_DELAY_IN_SEC) { + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: excute set policy state task"); + setPolicyStateTask_.flag = false; + hdiPolicyState_ = setPolicyStateTask_.state; + audioRendererSink_->SetBufferSize(hdiPolicyState_ == OFFLOAD_INACTIVE_BACKGROUND ? + OFFLOAD_HDI_CACHE_BACKGROUND_IN_MS : OFFLOAD_HDI_CACHE_FRONTGROUND_IN_MS); + } + return; // no need to set buffer size twice at one process + } + // first start need to set buffer size 5 times + if (setHdiBufferSizeNum_ > 0) { + setHdiBufferSizeNum_--; + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: set policy state cause first render"); + audioRendererSink_->SetBufferSize(hdiPolicyState_ == OFFLOAD_INACTIVE_BACKGROUND ? + OFFLOAD_HDI_CACHE_BACKGROUND_IN_MS : OFFLOAD_HDI_CACHE_FRONTGROUND_IN_MS); + } +} + +int32_t HpaeOffloadSinkOutputNode::ProcessRenderFrame() +{ + if (renderFrameData_.empty()) { + return OFFLOAD_WRITE_FAILED; + } + uint64_t writeLen = 0; + char *renderFrameData = (char *)renderFrameData_.data(); +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); + intervalTimer_.Stop(); + uint64_t interval = intervalTimer_.Elapsed(); + AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, interval); +#endif + auto now = std::chrono::high_resolution_clock::now(); + auto ret = audioRendererSink_->RenderFrame(*renderFrameData, renderFrameData_.size(), writeLen); + if (ret == SUCCESS && writeLen == 0 && !firstWriteHdi_) { + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: offload renderFrame full"); + return OFFLOAD_FULL; + } + if (!(ret == SUCCESS && writeLen == renderFrameData_.size())) { + AUDIO_ERR_LOG("HpaeOffloadSinkOutputNode: offload renderFrame failed, errCode is %{public}d", ret); + return OFFLOAD_WRITE_FAILED; + } + // calc written data length + writePos_ += ConvertDatalenToUs(renderFrameData_.size(), GetNodeInfo()); + // now is the time to first write hdi + if (firstWriteHdi_) { + firstWriteHdi_ = false; + hdiPos_ = std::make_pair(0, now); + setHdiBufferSizeNum_ = OFFLOAD_SET_BUFFER_SIZE_NUM; + // if the hdi is flushing, it will block the volume setting. + // so the render frame judge it. + OffloadSetHdiVolume(); + AUDIO_INFO_LOG("offload write pos: %{public}" PRIu64 " hdi pos: %{public}" PRIu64 " ", + writePos_, hdiPos_.first); + } + // hdi fallback, dont modify + SetBufferSizeWhileRenderFrame(); +#ifdef ENABLE_HOOK_PCM + AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, interval); + if (outputPcmDumper_) { + outputPcmDumper_->Dump((int8_t *)renderFrameData, renderFrameData_.size()); + } + timer.Stop(); + uint64_t elapsed = timer.Elapsed(); + AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode :name %{public}s, RenderFrame elapsed time: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, elapsed); + intervalTimer_.Start(); +#endif + renderFrameData_.clear(); + return SUCCESS; +} + +int32_t HpaeOffloadSinkOutputNode::UpdatePresentationPosition() +{ + CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, + "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + uint64_t frames; + int64_t timeSec; + int64_t timeNanoSec; + int ret = audioRendererSink_->GetPresentationPosition(frames, timeSec, timeNanoSec); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetPresentationPosition failed, errCode is %{public}d", ret); + auto total_ns = std::chrono::seconds(timeSec) + std::chrono::nanoseconds(timeNanoSec); + hdiPos_ = std::make_pair(frames, TimePoint(total_ns)); + return 0; +} + +uint64_t HpaeOffloadSinkOutputNode::CalcOffloadCacheLenInHdi() +{ + auto now = std::chrono::high_resolution_clock::now(); + uint64_t time = now > hdiPos_.second ? + std::chrono::duration_cast(now - hdiPos_.second).count() : 0; + uint64_t hdiPos = hdiPos_.first + time; + uint64_t cacheLenInHdi = writePos_ > hdiPos ? (writePos_ - hdiPos) : 0; + AUDIO_DEBUG_LOG("offload latency: %{public}" PRIu64 " write pos: %{public}" PRIu64 + " hdi pos: %{public}" PRIu64 " time: %{public}" PRIu64, + cacheLenInHdi, writePos_, hdiPos, time); + return cacheLenInHdi; +} + +void HpaeOffloadSinkOutputNode::OffloadSetHdiVolume() +{ + AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(GetStreamType()); + float volumeEnd = AudioVolume::GetInstance()->GetVolume(GetSessionId(), volumeType, DEVICE_CLASS_OFFLOAD); + float volumeBeg = AudioVolume::GetInstance()->GetHistoryVolume(GetSessionId()); + if (volumeBeg != volumeEnd) { + AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode::sessionID:%{public}u, volumeBeg:%{public}f, volumeEnd:%{public}f", + GetSessionId(), volumeBeg, volumeEnd); + AudioVolume::GetInstance()->SetHistoryVolume(GetSessionId(), volumeEnd); + AudioVolume::GetInstance()->Monitor(GetSessionId(), true); + } + CHECK_AND_RETURN_LOG(audioRendererSink_, "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + audioRendererSink_->SetVolume(volumeEnd, volumeEnd); +} + +void HpaeOffloadSinkOutputNode::OffloadCallback(const RenderCallbackType type) +{ + switch (type) { + case CB_NONBLOCK_WRITE_COMPLETED: { + if (isHdiFull_.load()) { + RunningLock(true); + UpdatePresentationPosition(); + auto callback = GetNodeInfo().statusCallback.lock(); + isHdiFull_.store(false); + if (callback) { + callback->OnNotifyQueue(); + } + } + break; + } + default: + break; + } +} + +void HpaeOffloadSinkOutputNode::RegOffloadCallback() +{ + CHECK_AND_RETURN_LOG(audioRendererSink_, "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + audioRendererSink_->RegistOffloadHdiCallback([this](const RenderCallbackType type) { OffloadCallback(type); }); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/node/src/hpae_output_cluster.cpp b/services/audio_engine/node/src/hpae_output_cluster.cpp new file mode 100644 index 0000000000..f32fd61d3f --- /dev/null +++ b/services/audio_engine/node/src/hpae_output_cluster.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2025 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 "HpaeOutputCluster" +#endif + +#include "hpae_output_cluster.h" +#include "hpae_node_common.h" +#include "audio_engine_log.h" +#include "audio_errors.h" +#include "audio_utils.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +HpaeOutputCluster::HpaeOutputCluster(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), mixerNode_(std::make_shared(nodeInfo)), + hpaeSinkOutputNode_(std::make_shared(nodeInfo)) +{ +#ifdef ENABLE_HIDUMP_DFX + if (nodeInfo.statusCallback.lock()) { + nodeInfo.nodeName = "hpaeSinkOutputNode"; + nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); + hpaeSinkOutputNode_->SetNodeInfo(nodeInfo); + nodeInfo.statusCallback.lock()->OnNotifyDfxNodeInfo(true, 0, nodeInfo); + nodeInfo.nodeName = "HpaeMixerNode"; + nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); + mixerNode_->SetNodeInfo(nodeInfo); + nodeInfo.statusCallback.lock()->OnNotifyDfxNodeInfo(true, hpaeSinkOutputNode_->GetNodeId(), nodeInfo); + } +#endif + hpaeSinkOutputNode_->Connect(mixerNode_); + frameLenMs_ = nodeInfo.frameLen * MILLISECOND_PER_SECOND / nodeInfo.samplingRate; + AUDIO_INFO_LOG( + "HpaeOutputCluster frameLenMs_:%{public}u ms, timeoutThdFrames_:%{public}u", frameLenMs_, timeoutThdFrames_); +} + +HpaeOutputCluster::~HpaeOutputCluster() +{ + Reset(); +} + +void HpaeOutputCluster::DoProcess() +{ + Trace trace("HpaeOutputCluster::DoProcess"); + hpaeSinkOutputNode_->DoProcess(); + if (mixerNode_->GetPreOutNum() == 0) { + timeoutStopCount_++; + } else { + timeoutStopCount_ = 0; + } + if (timeoutStopCount_ > timeoutThdFrames_) { + int32_t ret = hpaeSinkOutputNode_->RenderSinkStop(); + timeoutStopCount_ = 0; + AUDIO_INFO_LOG("HpaeOutputCluster timeout RenderSinkStop ret :%{public}d", ret); + } +} + +bool HpaeOutputCluster::Reset() +{ + mixerNode_->Reset(); + for (auto converterNode : sceneConverterMap_) { + converterNode.second->Reset(); + } + hpaeSinkOutputNode_->DisConnect(mixerNode_); +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = hpaeSinkOutputNode_->GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfo(false, hpaeSinkOutputNode_->GetNodeId(), hpaeSinkOutputNode_->GetNodeInfo()); + } +#endif + return true; +} + +bool HpaeOutputCluster::ResetAll() +{ + return hpaeSinkOutputNode_->ResetAll(); // Complete the code here +} + +void HpaeOutputCluster::Connect(const std::shared_ptr> &preNode) +{ + HpaeNodeInfo &preNodeInfo = preNode->GetSharedInstance()->GetNodeInfo(); + HpaeNodeInfo &curNodeInfo = GetNodeInfo(); + HpaeProcessorType sceneType = preNodeInfo.sceneType; + AUDIO_INFO_LOG("HpaeOutputCluster input sceneType is %{public}u", preNodeInfo.sceneType); + AUDIO_INFO_LOG("HpaeOutputCluster input rate is %{public}u, ch is %{public}u", preNodeInfo.samplingRate, preNodeInfo.channels); + AUDIO_INFO_LOG(" HpaeOutputCluster output rate is %{public}u, ch is %{public}u", curNodeInfo.samplingRate, curNodeInfo.channels); + AUDIO_INFO_LOG(" HpaeOutputCluster preNode name %{public}s, curNode name is %{public}s", preNodeInfo.nodeName.c_str(), curNodeInfo.nodeName.c_str()); + AUDIO_INFO_LOG("HpaeOutputCluster mixer id %{public}u, SinkOut id %{public}u", mixerNode_->GetNodeId(), hpaeSinkOutputNode_->GetNodeId()); + +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { + curNodeInfo.nodeId = callBack->OnGetNodeId(); + curNodeInfo.nodeName = "HpaeAudioFormatConverterNode"; + } +#endif + + if (sceneConverterMap_.find(sceneType) == sceneConverterMap_.end()) { + sceneConverterMap_[sceneType] = std::make_shared(preNodeInfo, curNodeInfo); + } else { +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfo(false, mixerNode_->GetNodeId(), sceneConverterMap_[sceneType]->GetNodeInfo()); + } +#endif + sceneConverterMap_.erase(sceneType); + sceneConverterMap_[sceneType] = std::make_shared(preNodeInfo, curNodeInfo); + } + sceneConverterMap_[sceneType]->Connect(preNode); +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { + AUDIO_INFO_LOG("HpaeOutputCluster connect curNodeInfo name %{public}s", curNodeInfo.nodeName.c_str()); + AUDIO_INFO_LOG("HpaeOutputCluster connect preNodeInfo name %{public}s", preNodeInfo.nodeName.c_str()); + callBack->OnNotifyDfxNodeInfo(true, mixerNode_->GetNodeId(), curNodeInfo); + callBack->OnNotifyDfxNodeInfo(true, curNodeInfo.nodeId, preNodeInfo); + } +#endif + mixerNode_->Connect(sceneConverterMap_[sceneType]); + connectedProcessCluster_.insert(sceneType); +} + +void HpaeOutputCluster::DisConnect(const std::shared_ptr> &preNode) +{ + HpaeNodeInfo &preNodeInfo = preNode->GetSharedInstance()->GetNodeInfo(); + HpaeProcessorType sceneType = preNodeInfo.sceneType; + AUDIO_INFO_LOG("HpaeOutputCluster input sceneType is %{public}u", preNodeInfo.sceneType); + if (sceneConverterMap_.find(sceneType) != sceneConverterMap_.end()) { + sceneConverterMap_[sceneType]->DisConnect(preNode); + mixerNode_->DisConnect(sceneConverterMap_[sceneType]); +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfo(false, mixerNode_->GetNodeId(), sceneConverterMap_[sceneType]->GetNodeInfo()); + } +#endif + sceneConverterMap_.erase(sceneType); + } else { + mixerNode_->DisConnect(preNode); +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfo(false, mixerNode_->GetNodeId(), preNodeInfo); + } +#endif + } + connectedProcessCluster_.erase(sceneType); +} + +int32_t HpaeOutputCluster::GetConverterNodeCount() +{ + return sceneConverterMap_.size(); +} + +int32_t HpaeOutputCluster::GetInstance(std::string deviceClass, std::string deviceNetId) +{ + return hpaeSinkOutputNode_->GetRenderSinkInstance(deviceClass, deviceNetId); +} + +int32_t HpaeOutputCluster::Init(IAudioSinkAttr &attr) +{ + return hpaeSinkOutputNode_->RenderSinkInit(attr); +} + +int32_t HpaeOutputCluster::DeInit() +{ + return hpaeSinkOutputNode_->RenderSinkDeInit(); +} + +int32_t HpaeOutputCluster::Flush(void) +{ + return hpaeSinkOutputNode_->RenderSinkFlush(); +} + +int32_t HpaeOutputCluster::Pause(void) +{ + return hpaeSinkOutputNode_->RenderSinkPause(); +} + +int32_t HpaeOutputCluster::ResetRender(void) +{ + return hpaeSinkOutputNode_->RenderSinkReset(); +} + +int32_t HpaeOutputCluster::Resume(void) +{ + return hpaeSinkOutputNode_->RenderSinkResume(); +} + +int32_t HpaeOutputCluster::Start(void) +{ + return hpaeSinkOutputNode_->RenderSinkStart(); +} + +int32_t HpaeOutputCluster::Stop(void) +{ + return hpaeSinkOutputNode_->RenderSinkStop(); +} + +const char *HpaeOutputCluster::GetFrameData(void) +{ + return hpaeSinkOutputNode_->GetRenderFrameData(); +} + +RendererState HpaeOutputCluster::GetState(void) +{ + return hpaeSinkOutputNode_->GetSinkState(); +} + +int32_t HpaeOutputCluster::GetPreOutNum() +{ + return mixerNode_->GetPreOutNum(); +} + +int32_t HpaeOutputCluster::SetTimeoutStopThd(uint32_t timeoutThdMs) +{ + if (frameLenMs_ != 0) { + timeoutThdFrames_ = timeoutThdMs / frameLenMs_; + } + AUDIO_INFO_LOG( + "SetTimeoutStopThd: timeoutThdFrames_:%{public}u, timeoutThdMs :%{public}u", timeoutThdFrames_, timeoutThdMs); + return SUCCESS; +} + +bool HpaeOutputCluster::IsProcessClusterConnected(HpaeProcessorType sceneType) +{ + return connectedProcessCluster_.find(sceneType) != connectedProcessCluster_.end(); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_plugin_node.cpp b/services/audio_engine/node/src/hpae_plugin_node.cpp new file mode 100644 index 0000000000..ed58c365d2 --- /dev/null +++ b/services/audio_engine/node/src/hpae_plugin_node.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2025 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 "hpae_plugin_node.h" +#include "audio_errors.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaePluginNode::HpaePluginNode(HpaeNodeInfo& nodeInfo) + : HpaeNode(nodeInfo), outputStream_(this), enableProcess_(true), + pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), silenceData_(pcmBufferInfo_) + +{ + silenceData_.Reset(); + silenceData_.SetBufferValid(false); +} + +void HpaePluginNode::DoProcess() +{ + HpaePcmBuffer *tempOut = nullptr; + std::vector& preOutputs = inputStream_.ReadPreOutputData(); + // if buffer is not valid, write silence data(invalid) to output + if (enableProcess_ && !preOutputs.empty()) { + tempOut = SignalProcess(preOutputs); + outputStream_.WriteDataToOutput(tempOut); + } else if (!preOutputs.empty()) { + outputStream_.WriteDataToOutput(preOutputs[0]); + } else { + outputStream_.WriteDataToOutput(&silenceData_); + } +} + +bool HpaePluginNode::Reset() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + inputStream_.DisConnect(output); + } + return true; +} + +bool HpaePluginNode::ResetAll() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + std::shared_ptr hpaeNode = preOutput.second; + if (hpaeNode->ResetAll()) { + inputStream_.DisConnect(output); + } + } + return true; +} + +int32_t HpaePluginNode::EnableProcess(bool enable) +{ + enableProcess_ = enable; + return SUCCESS; +} + +bool HpaePluginNode::IsEnableProcess() +{ + return enableProcess_; +} + +std::shared_ptr HpaePluginNode::GetSharedInstance() +{ + return shared_from_this(); +} + +OutputPort* HpaePluginNode::GetOutputPort() +{ + return &outputStream_; +} + +void HpaePluginNode::Connect(const std::shared_ptr>& preNode) +{ + inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); +} + +void HpaePluginNode::DisConnect(const std::shared_ptr>& preNode) +{ + inputStream_.DisConnect(preNode->GetOutputPort()); +} + +size_t HpaePluginNode::GetPreOutNum() +{ + return inputStream_.GetPreOutputNum(); +} + +size_t HpaePluginNode::GetOutputPortNum() +{ + return outputStream_.GetInputNum(); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_process_cluster.cpp b/services/audio_engine/node/src/hpae_process_cluster.cpp new file mode 100644 index 0000000000..f22d5cee57 --- /dev/null +++ b/services/audio_engine/node/src/hpae_process_cluster.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2025 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 "HpaeProcessCluster" +#endif + +#include + +#include "audio_errors.h" +#include "hpae_process_cluster.h" +#include "hpae_node_common.h" +#include "audio_engine_log.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaeProcessCluster::HpaeProcessCluster(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &sinkInfo) + : HpaeNode(nodeInfo), mixerNode_(std::make_shared(nodeInfo)), sinkInfo_(sinkInfo) +{ + if (TransProcessorTypeToSceneType(nodeInfo.sceneType) != "SCENE_EXTRA") { + renderEffectNode_ = std::make_shared(nodeInfo); + } else { + renderEffectNode_ = nullptr; + } +#ifdef ENABLE_HIDUMP_DFX + if (nodeInfo.statusCallback.lock()) { + nodeInfo.nodeName = "HpaeMixerNode"; + nodeInfo.sessionId = 0; + nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); + AUDIO_INFO_LOG("HpaeProcessCluster, HpaeMixerNode id %{public}u ", nodeInfo.nodeId); + mixerNode_->SetNodeInfo(nodeInfo); + if (renderEffectNode_) { + nodeInfo.nodeName = "HpaeRenderEffectNode"; + nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); + nodeInfo.sessionId = 0; + renderEffectNode_->SetNodeInfo(nodeInfo); + AUDIO_INFO_LOG("HpaeProcessCluster, HpaeRenderEffectNode id %{public}u ", nodeInfo.nodeId); + } + } +#endif +} + +HpaeProcessCluster::~HpaeProcessCluster() +{ + AUDIO_INFO_LOG("process cluster destroyed, processor scene type is %{public}d", GetSceneType()); + Reset(); +} + +void HpaeProcessCluster::DoProcess() +{ + if (renderEffectNode_ != nullptr) { + renderEffectNode_->DoProcess(); + return; + } + mixerNode_->DoProcess(); +} + +bool HpaeProcessCluster::Reset() +{ + mixerNode_->Reset(); + for (auto converterNode : idConverterMap_) { + converterNode.second->Reset(); + } + for (auto gainNode : idGainMap_) { + gainNode.second->Reset(); + } + if (renderEffectNode_ != nullptr) { + renderEffectNode_->Reset(); + renderEffectNode_ = nullptr; + } + return true; +} + +bool HpaeProcessCluster::ResetAll() +{ + return renderEffectNode_ != nullptr ? renderEffectNode_->ResetAll() : mixerNode_->ResetAll(); +} + +std::shared_ptr HpaeProcessCluster::GetSharedInstance() +{ + if (renderEffectNode_ != nullptr) { + AUDIO_INFO_LOG("HpaeProcessCluster, GetSharedInstance renderEffectNode_ name %{public}s id: %{public}u ", + renderEffectNode_->GetNodeName().c_str(), + renderEffectNode_->GetNodeId()); + return renderEffectNode_; + } + AUDIO_INFO_LOG("HpaeProcessCluster, GetSharedInstance mixerNode_ name %{public}s id: %{public}u ", + mixerNode_->GetNodeName().c_str(), + mixerNode_->GetNodeId()); + return mixerNode_; +} + +OutputPort *HpaeProcessCluster::GetOutputPort() +{ + return renderEffectNode_ != nullptr ? renderEffectNode_->GetOutputPort() : mixerNode_->GetOutputPort(); +} + +int32_t HpaeProcessCluster::GetGainNodeCount() +{ + return idGainMap_.size(); +} + +int32_t HpaeProcessCluster::GetConverterNodeCount() +{ + return idConverterMap_.size(); +} + +int32_t HpaeProcessCluster::GetPreOutNum() +{ + return mixerNode_->GetPreOutNum(); +} + +void HpaeProcessCluster::Connect(const std::shared_ptr> &preNode) +{ + HpaeNodeInfo &preNodeInfo = preNode->GetNodeInfo(); + uint32_t sessionId = preNodeInfo.sessionId; + AUDIO_INFO_LOG("HpaeProcessCluster sessionId is %{public}u, streamType is %{public}d, " + "HpaeProcessCluster rate is %{public}u, ch is %{public}u, " + "HpaeProcessCluster preNodeId %{public}u, preNodeName is %{public}s", + preNodeInfo.sessionId, preNodeInfo.streamType, preNodeInfo.samplingRate, preNodeInfo.channels, + preNodeInfo.nodeId, preNodeInfo.nodeName.c_str()); + + if (renderEffectNode_ != nullptr && renderEffectNode_->GetPreOutNum() == 0) { + renderEffectNode_->Connect(mixerNode_); + AUDIO_INFO_LOG("Process Connect mixerNode_"); +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = renderEffectNode_->GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfo(true, renderEffectNode_->GetNodeId(), mixerNode_->GetNodeInfo()); + } +#endif + } + if (idGainMap_.find(sessionId) == idGainMap_.end()) { + HpaeNodeInfo gainNodeInfo = preNodeInfo; +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { + gainNodeInfo.nodeName = "HpaeGainNode"; + gainNodeInfo.nodeId = callBack->OnGetNodeId(); + } +#endif + idGainMap_[sessionId] = std::make_shared(gainNodeInfo); + } + HpaeNodeInfo outNodeInfo = preNodeInfo; + outNodeInfo.frameLen = sinkInfo_.frameLen; + outNodeInfo.samplingRate = sinkInfo_.samplingRate; + outNodeInfo.channels = sinkInfo_.channels; + outNodeInfo.channelLayout = (AudioChannelLayout)sinkInfo_.channelLayout; + outNodeInfo.format = sinkInfo_.format; +#ifdef ENABLE_HIDUMP_DFX + outNodeInfo.nodeName = "HpaeAudioFormatConverterNode"; + if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { + outNodeInfo.nodeId = callBack->OnGetNodeId(); + } +#endif + idConverterMap_[sessionId] = std::make_shared(preNodeInfo, outNodeInfo); + if (renderEffectNode_ != nullptr) { + idConverterMap_[sessionId]->RegisterCallback(this); + } + idGainMap_[sessionId]->Connect(preNode); + idConverterMap_[sessionId]->Connect(idGainMap_[sessionId]); + mixerNode_->Connect(idConverterMap_[sessionId]); +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfo(true, mixerNode_->GetNodeId(), idConverterMap_[sessionId]->GetNodeInfo()); + callBack->OnNotifyDfxNodeInfo( + true, idConverterMap_[sessionId]->GetNodeId(), idGainMap_[sessionId]->GetNodeInfo()); + callBack->OnNotifyDfxNodeInfo(true, idGainMap_[sessionId]->GetNodeId(), preNodeInfo); + } +#endif +} + +void HpaeProcessCluster::DisConnect(const std::shared_ptr> &preNode) +{ + uint32_t sessionId = preNode->GetNodeInfo().sessionId; + AUDIO_INFO_LOG( + "Process DisConnect sessionId is %{public}u, streamType is %{public}d", sessionId, preNode->GetNodeInfo().streamType); +#ifdef ENABLE_HIDUMP_DFX + auto callBack = mixerNode_->GetNodeStatusCallback().lock(); + if (callBack != nullptr && idConverterMap_.find(sessionId) != idConverterMap_.end()) { + callBack->OnNotifyDfxNodeInfo(false, idConverterMap_[sessionId]->GetNodeId(), idConverterMap_[sessionId]->GetNodeInfo()); + } +#endif + if (idConverterMap_.find(sessionId) != idConverterMap_.end()) { + idGainMap_[sessionId]->DisConnect(preNode); + idConverterMap_[sessionId]->DisConnect(idGainMap_[sessionId]); + mixerNode_->DisConnect(idConverterMap_[sessionId]); + idConverterMap_.erase(sessionId); + idGainMap_.erase(sessionId); + AUDIO_INFO_LOG("Process DisConnect Exist converterNode preOutNum is %{public}zu", mixerNode_->GetPreOutNum()); + } + if (renderEffectNode_ != nullptr && mixerNode_->GetPreOutNum() == 0) { + renderEffectNode_->DisConnect(mixerNode_); + AUDIO_INFO_LOG("Process DisConnect mixerNode_"); +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = renderEffectNode_->GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfo(false, renderEffectNode_->GetNodeId(), mixerNode_->GetNodeInfo()); + } +#endif + } +} + +int32_t HpaeProcessCluster::GetEffectNodeInputChannelInfo(uint32_t &channels, uint64_t &channelLayout) +{ + if (renderEffectNode_ == nullptr) { + return ERR_READ_FAILED; + } + int32_t ret = renderEffectNode_->GetExpectedInputChannelInfo(channels, channelLayout); + return ret; +} + +int32_t HpaeProcessCluster::AudioRendererCreate(HpaeNodeInfo &nodeInfo) +{ + if (renderEffectNode_ == nullptr) { + return 0; + } + return renderEffectNode_->AudioRendererCreate(nodeInfo); +} + +int32_t HpaeProcessCluster::AudioRendererStart(HpaeNodeInfo &nodeInfo) +{ + if (renderEffectNode_ == nullptr) { + return 0; + } + return renderEffectNode_->AudioRendererStart(nodeInfo); +} + +int32_t HpaeProcessCluster::AudioRendererStop(HpaeNodeInfo &nodeInfo) +{ + if (renderEffectNode_ == nullptr) { + return 0; + } + return renderEffectNode_->AudioRendererStop(nodeInfo); +} + +int32_t HpaeProcessCluster::AudioRendererRelease(HpaeNodeInfo &nodeInfo) +{ + if (renderEffectNode_ == nullptr) { + return 0; + } + return renderEffectNode_->AudioRendererRelease(nodeInfo); +} + +std::shared_ptr HpaeProcessCluster::GetGainNodeById(uint32_t sessionId) const +{ + auto it = idGainMap_.find(sessionId); + if (it != idGainMap_.end()) { + return it->second; + } + return nullptr; +} + +std::shared_ptr HpaeProcessCluster::GetConverterNodeById(uint32_t sessionId) const +{ + auto it = idConverterMap_.find(sessionId); + if (it != idConverterMap_.end()) { + return it->second; + } + return nullptr; +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_render_effect_node.cpp b/services/audio_engine/node/src/hpae_render_effect_node.cpp new file mode 100644 index 0000000000..716028fa22 --- /dev/null +++ b/services/audio_engine/node/src/hpae_render_effect_node.cpp @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2025 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 "HpaeRenderEffectNode" +#endif + +#include +#include "audio_errors.h" +#include "audio_engine_log.h" +#include "hpae_render_effect_node.h" +#include "hpae_pcm_buffer.h" +#include "audio_effect_chain_manager.h" +#include "audio_effect_map.h" +#include "audio_utils.h" + +static constexpr uint32_t DEFUALT_EFFECT_RATE = 48000; +static constexpr uint32_t DEFAULT_EFFECT_FRAMELEN = 960; + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +HpaeRenderEffectNode::HpaeRenderEffectNode(HpaeNodeInfo &nodeInfo) : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), + // DEFAUT effect out format + pcmBufferInfo_(nodeInfo.channels, DEFAULT_EFFECT_FRAMELEN, DEFUALT_EFFECT_RATE, nodeInfo.channelLayout), + effectOutput_(pcmBufferInfo_), + nodeInfo_(nodeInfo) +{ + const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); + if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != + audioSupportedSceneTypes.end()) { + sceneType_ = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); + } + AUDIO_INFO_LOG("render effect node created, scene type: %{public}s", sceneType_.c_str()); +#ifdef ENABLE_HOOK_PCM + inputPcmDumper_ = std::make_unique( + "HpaeRenderEffectNodeInput_id_" + std::to_string(GetNodeId()) + ".pcm"); + outputPcmDumper_ = std::make_unique( + "HpaeRenderEffectNodeOutput_id_" + std::to_string(GetNodeId()) + ".pcm"); +#endif +} + +HpaePcmBuffer *HpaeRenderEffectNode::SignalProcess(const std::vector &inputs) +{ + AUDIO_DEBUG_LOG("render effect node signal process in"); + if (inputs.empty()) { + AUDIO_WARNING_LOG("HpaeRenderEffectNode inputs size is empty"); + return nullptr; + } + auto rate = "rate[" + std::to_string(inputs[0]->GetSampleRate()) + "]_"; + auto ch = "ch[" + std::to_string(inputs[0]->GetChannelCount()) + "]_"; + auto len = "len[" + std::to_string(inputs[0]->GetFrameLen()) + "]"; + Trace trace("[" + sceneType_ + "]HpaeRenderEffectNode::SignalProcess " + rate + ch + len); + + if (AudioEffectChainManager::GetInstance()->GetOffloadEnabled()) { + return inputs[0]; + } + +#ifdef ENABLE_HOOK_PCM + if (inputPcmDumper_) { + inputPcmDumper_->Dump((int8_t *)inputs[0]->GetPcmDataBuffer(), + inputs[0]->GetFrameLen() * sizeof(float) * inputs[0]->GetChannelCount()); + } +#endif + + ReconfigOutputBuffer(); + + auto eBufferAttr = std::make_unique( + inputs[0]->GetPcmDataBuffer(), + effectOutput_.GetPcmDataBuffer(), + static_cast(inputs[0]->GetChannelCount()), + static_cast(inputs[0]->GetFrameLen()), + 0, + 0 + ); + + int32_t ret = AudioEffectChainManager::GetInstance()->ApplyAudioEffectChain(sceneType_, eBufferAttr); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, inputs[0], "apply audio effect chain fail"); + +#ifdef ENABLE_HOOK_PCM + if (outputPcmDumper_) { + outputPcmDumper_->Dump((int8_t *)effectOutput_.GetPcmDataBuffer(), + effectOutput_.GetFrameLen() * sizeof(float) * effectOutput_.GetChannelCount()); + } +#endif + + return &effectOutput_; +} + +int32_t HpaeRenderEffectNode::AudioRendererCreate(HpaeNodeInfo &nodeInfo) +{ + AUDIO_INFO_LOG("notify audio effect when audio renderer create in"); + int32_t ret = CreateAudioEffectChain(nodeInfo); + if (ret != 0) { + AUDIO_WARNING_LOG("create audio effect chain failed, ret: %{public}d", ret); + } + AUDIO_INFO_LOG("notify audio effect when audio renderer create out"); + return SUCCESS; +} + +int32_t HpaeRenderEffectNode::AudioRendererStart(HpaeNodeInfo &nodeInfo) +{ + AUDIO_INFO_LOG("notify audio effect when audio renderer start in"); + ModifyAudioEffectChainInfo(nodeInfo, ADD_AUDIO_EFFECT_CHAIN_INFO); + AUDIO_INFO_LOG("notify audio effect when audio renderer start out"); + return SUCCESS; +} + +int32_t HpaeRenderEffectNode::AudioRendererStop(HpaeNodeInfo &nodeInfo) +{ + AUDIO_INFO_LOG("notify audio effect when audio renderer stop in"); + ModifyAudioEffectChainInfo(nodeInfo, REMOVE_AUDIO_EFFECT_CHAIN_INFO); + AUDIO_INFO_LOG("notify audio effect when audio renderer stop out"); + return SUCCESS; +} + +int32_t HpaeRenderEffectNode::AudioRendererRelease(HpaeNodeInfo &nodeInfo) +{ + AUDIO_INFO_LOG("notify audio effect when audio renderer release in"); + int32_t ret = ReleaseAudioEffectChain(nodeInfo); + if (ret != 0) { + AUDIO_WARNING_LOG("release audio effect chain failed, ret: %{public}d", ret); + } + ModifyAudioEffectChainInfo(nodeInfo, REMOVE_AUDIO_EFFECT_CHAIN_INFO); + AUDIO_INFO_LOG("notify audio effect when audio renderer release out"); + return SUCCESS; +} + +int32_t HpaeRenderEffectNode::CreateAudioEffectChain(HpaeNodeInfo &nodeInfo) +{ + AUDIO_INFO_LOG("Create Audio Effect Chain In, sessionID is %{public}u, sceneType is %{public}d", + nodeInfo.sessionId, nodeInfo.effectInfo.effectScene); + // todo: deal with remote case + // todo: if boot music, do not create audio effect + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager"); + std::string sceneType = "EFFECT_NONE"; + const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); + if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != + audioSupportedSceneTypes.end()) { + sceneType = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); + } + // todo: could be removed + if (!audioEffectChainManager->CheckAndAddSessionID(std::to_string(nodeInfo.sessionId))) { + return SUCCESS; + } + audioEffectChainManager->UpdateSceneTypeList(sceneType, ADD_SCENE_TYPE); + // todo: should be considered + if (audioEffectChainManager->GetOffloadEnabled()) { + return SUCCESS; + } + int32_t ret = audioEffectChainManager->CreateAudioEffectChainDynamic(sceneType); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "create effect chain fail"); + AUDIO_INFO_LOG("Create Audio Effect Chain Success, sessionID is %{public}u, sceneType is %{public}d", + nodeInfo.sessionId, nodeInfo.effectInfo.effectScene); + return SUCCESS; +} + +int32_t HpaeRenderEffectNode::ReleaseAudioEffectChain(HpaeNodeInfo &nodeInfo) +{ + AUDIO_INFO_LOG("Release Audio Effect Chain In, sessionID is %{public}u, sceneType is %{public}d", + nodeInfo.sessionId, nodeInfo.effectInfo.effectScene); + // todo: deal with remote case + // todo: if boot music, do not release audio effect + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager"); + std::string sceneType = "EFFECT_NONE"; + const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); + if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != + audioSupportedSceneTypes.end()) { + sceneType = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); + } + // todo: could be removed + if (!audioEffectChainManager->CheckAndRemoveSessionID(std::to_string(nodeInfo.sessionId))) { + return SUCCESS; + } + audioEffectChainManager->UpdateSceneTypeList(sceneType, REMOVE_SCENE_TYPE); + // todo: should be considered + if (audioEffectChainManager->GetOffloadEnabled()) { + return SUCCESS; + } + int32_t ret = audioEffectChainManager->ReleaseAudioEffectChainDynamic(sceneType); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "release effect chain fail"); + AUDIO_INFO_LOG("Release Audio Effect Chain Success, sessionID is %{public}u, sceneType is %{public}d", + nodeInfo.sessionId, nodeInfo.effectInfo.effectScene); + return SUCCESS; +} + +void HpaeRenderEffectNode::ModifyAudioEffectChainInfo(HpaeNodeInfo &nodeInfo, + ModifyAudioEffectChainInfoReason reason) +{ + std::string sessionID = std::to_string(nodeInfo.sessionId); + std::string sceneType = "EFFECT_NONE"; + const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); + if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != + audioSupportedSceneTypes.end()) { + sceneType = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); + } + int32_t ret = 0; + switch (reason) { + case ADD_AUDIO_EFFECT_CHAIN_INFO: { + SessionEffectInfo info; + info.sceneMode = std::to_string(nodeInfo.effectInfo.effectMode); + info.sceneType = sceneType; + info.channels = static_cast(nodeInfo.channels); + info.channelLayout = nodeInfo.channelLayout; + info.streamUsage = nodeInfo.effectInfo.streamUsage; + info.systemVolumeType = nodeInfo.effectInfo.volumeType; + ret = AudioEffectChainManager::GetInstance()->SessionInfoMapAdd(sessionID, info); + break; + } + case REMOVE_AUDIO_EFFECT_CHAIN_INFO: + ret = AudioEffectChainManager::GetInstance()->SessionInfoMapDelete(sceneType, sessionID); + break; + default: + break; + } + CHECK_AND_RETURN_LOG(ret == SUCCESS, "modify session info failed"); + UpdateAudioEffectChainInfo(nodeInfo); +} + +void HpaeRenderEffectNode::UpdateAudioEffectChainInfo(HpaeNodeInfo &nodeInfo) +{ + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "null audioEffectChainManager"); + std::string sceneType = "EFFECT_NONE"; + const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); + if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != + audioSupportedSceneTypes.end()) { + sceneType = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); + } + audioEffectChainManager->UpdateMultichannelConfig(sceneType); + audioEffectChainManager->EffectVolumeUpdate(); + audioEffectChainManager->UpdateDefaultAudioEffect(); + audioEffectChainManager->UpdateStreamUsage(); +} + +void HpaeRenderEffectNode::ReconfigOutputBuffer() +{ + uint32_t channels = static_cast(nodeInfo_.channels); + uint64_t channelLayout = nodeInfo_.channelLayout; + int32_t ret = AudioEffectChainManager::GetInstance()->GetOutputChannelInfo(sceneType_, channels, channelLayout); + if (ret != SUCCESS || channels == 0 || channelLayout == 0) { + AUDIO_WARNING_LOG("output channel info incorrect, scene type: %{public}s, " + "channels: %{public}u, channelLayout: %{public}" PRIu64, sceneType_.c_str(), channels, channelLayout); + } else if (static_cast(nodeInfo_.channels) != channels || + static_cast(nodeInfo_.channelLayout) != channelLayout) { + AUDIO_INFO_LOG("output channel info changed, scene type: %{public}s, " + "channels change from %{public}u to %{public}u, " + "channelLayout change from %{public}" PRIu64 " to %{public}" PRIu64, + sceneType_.c_str(), nodeInfo_.channels, channels, nodeInfo_.channelLayout, channelLayout); + nodeInfo_.channels = static_cast(channels); + nodeInfo_.channelLayout = static_cast(channelLayout); + PcmBufferInfo pcmBufferInfo = PcmBufferInfo(channels, DEFAULT_EFFECT_FRAMELEN, + DEFUALT_EFFECT_RATE, channelLayout, effectOutput_.GetFrames(), effectOutput_.IsMultiFrames()); + effectOutput_.ReConfig(pcmBufferInfo); + nodeInfo_.channels = (AudioChannel)channels; + nodeInfo_.channelLayout = (AudioChannelLayout)channelLayout; + nodeInfo_.samplingRate = (AudioSamplingRate)DEFUALT_EFFECT_RATE; + nodeInfo_.frameLen = (uint32_t)DEFAULT_EFFECT_FRAMELEN; +#ifdef ENABLE_HIDUMP_DFX + if (auto callBack = GetNodeStatusCallback().lock()) { + callBack->OnNotifyDfxNodeInfoChanged(GetNodeId(), nodeInfo_); + } +#endif + } +} + +int32_t HpaeRenderEffectNode::GetExpectedInputChannelInfo(uint32_t &channels, uint64_t &channelLayout) +{ + return AudioEffectChainManager::GetInstance()->ReturnEffectChannelInfo(sceneType_, channels, channelLayout); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_resample_node.cpp b/services/audio_engine/node/src/hpae_resample_node.cpp new file mode 100644 index 0000000000..be57740c22 --- /dev/null +++ b/services/audio_engine/node/src/hpae_resample_node.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + */ +/* + * Copyright (c) 2025 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 "HpaeResampleNode" +#endif + +#include +#include +#include +#include "hpae_resample_node.h" +#include "hpae_pcm_buffer.h" +#include "audio_engine_log.h" +#include "audio_utils.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr int REASAMPLE_QUAILTY = 5; +HpaeResampleNode::HpaeResampleNode(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &nodeInfo, ResamplerType type) + : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), + pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), + resampleOuput_(pcmBufferInfo_), preNodeInfo_(preNodeInfo), tempOuput_(preNodeInfo.channels * nodeInfo.frameLen) +{ + if (type == ResamplerType::PRORESAMPLER) { + resampler_ = std::make_unique(preNodeInfo_.samplingRate, nodeInfo.samplingRate, + preNodeInfo_.channels, REASAMPLE_QUAILTY); + } +#ifdef ENABLE_HOOK_PCM + inputPcmDumper_ = std::make_unique("HpaeResampleNodeInput1_id_" + + std::to_string(GetSessionId()) + "_ch_" + std::to_string(preNodeInfo_.channels) + + "_rate_" + std::to_string(preNodeInfo_.samplingRate) + "_scene_" + + std::to_string(HpaeNode::GetSceneType()) + "_" + GetTime() + ".pcm"); + outputPcmDumper_ = std::make_unique("HpaeResampleNodeOutput1_id_" + + std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) + + "_rate_" + std::to_string(GetSampleRate()) + "_scene_" + + std::to_string(HpaeNode::GetSceneType())+ "_" + GetTime() + ".pcm"); +#endif +} + +HpaeResampleNode::HpaeResampleNode(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), + pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), + resampleOuput_(pcmBufferInfo_), preNodeInfo_(preNodeInfo), tempOuput_(preNodeInfo.channels * nodeInfo.frameLen) +{ // use ProResampler as default + resampler_ = std::make_unique(preNodeInfo_.samplingRate, nodeInfo.samplingRate, + preNodeInfo_.channels, REASAMPLE_QUAILTY); + +#ifdef ENABLE_HOOK_PCM + inputPcmDumper_ = std::make_unique("HpaeResampleNodeInput1_id_" + + std::to_string(HpaeNode::GetSessionId()) + "_ch_" + std::to_string(preNodeInfo_.channels) + "_rate_" + + std::to_string(preNodeInfo_.samplingRate) + "_scene_" + std::to_string(HpaeNode::GetSceneType())+".pcm"); + + outputPcmDumper_ = std::make_unique("HpaeResampleNodeOutput1_id_" + + std::to_string(HpaeNode::GetSessionId()) + "_ch_" + std::to_string(HpaeNode::GetChannelCount()) + + "_rate_" + std::to_string(HpaeNode::GetSampleRate()) + + "_scene_"+ std::to_string(HpaeNode::GetSceneType())+".pcm"); +#endif + AUDIO_INFO_LOG("input rate %{public}u, output rate %{public}u", preNodeInfo_.samplingRate, nodeInfo.samplingRate); + AUDIO_INFO_LOG("input SessionId %{public}u, output streamType %{public}u", HpaeNode::GetSessionId(), + nodeInfo.streamType); + AUDIO_INFO_LOG("input ch %{public}u, output ch %{public}u", preNodeInfo_.channels, HpaeNode::GetChannelCount()); +} + +bool HpaeResampleNode::Reset() +{ + if (resampler_ == nullptr) { + AUDIO_WARNING_LOG("resampler_ is nullptr, SessionId:%{public}d", GetSessionId()); + return false; + } + resampler_->Reset(); + return true; +} + +HpaePcmBuffer *HpaeResampleNode::SignalProcess(const std::vector &inputs) +{ + Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeResampleNode::SignalProcess"); + if (inputs.empty()) { + AUDIO_WARNING_LOG("HpaeResampleNode inputs size is empty, SessionId:%{public}d", GetSessionId()); + return nullptr; + } + if (inputs.size() != 1) { + AUDIO_WARNING_LOG("error inputs size is not eqaul to 1, SessionId:%{public}d", GetSessionId()); + } + if (resampler_ == nullptr) { + return &silenceData_; + } + resampleOuput_.Reset(); + uint32_t inputFrameLen = preNodeInfo_.frameLen; + uint32_t outputFrameLen = GetFrameLen(); + float *srcData = (*(inputs[0])).GetPcmDataBuffer(); + float *dstData = tempOuput_.data(); + if (preNodeInfo_.channels == GetChannelCount()) { + dstData = resampleOuput_.GetPcmDataBuffer(); + } +#ifdef ENABLE_HOOK_PCM + inputPcmDumper_->CheckAndReopenHandlde(); + if (inputPcmDumper_ != nullptr) { + inputPcmDumper_->Dump((int8_t *)(srcData), (inputFrameLen * sizeof(float) * preNodeInfo_.channels)); + } +#endif + ResampleProcess(srcData, inputFrameLen, dstData, outputFrameLen); + return &resampleOuput_; +} + +void HpaeResampleNode::ResampleProcess(float *srcData, uint32_t inputFrameLen, float *dstData, uint32_t outputFrameLen) +{ + resampler_->Process(srcData, &inputFrameLen, dstData, &outputFrameLen); + int32_t addZeroLen = GetFrameLen() - outputFrameLen > 0 ? GetFrameLen() - outputFrameLen : 0; + + if (preNodeInfo_.channels == GetChannelCount()) { +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_->CheckAndReopenHandlde(); + if (outputPcmDumper_ != nullptr) { + outputPcmDumper_->Dump( + (int8_t *)(resampleOuput_.GetPcmDataBuffer()), GetFrameLen() * sizeof(float) * GetChannelCount()); + } +#endif + return; + } + + float *targetData = resampleOuput_.GetPcmDataBuffer(); + size_t targetChannels = GetChannelCount(); + for (int32_t i = 0; i < (int32_t)outputFrameLen; ++i) { + for (int32_t ch = 0; ch < (int32_t)targetChannels; ++ch) { + size_t leftChIndex = std::min(ch, (preNodeInfo_.channels - 1)); + if (i < addZeroLen) { + targetData[i * targetChannels + ch] = 0; + } else { + targetData[i * targetChannels + ch] = + dstData[(i - addZeroLen) * preNodeInfo_.channels + leftChIndex]; + } + } + } + +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_->CheckAndReopenHandlde(); + if (outputPcmDumper_ != nullptr) { + outputPcmDumper_->Dump( + (int8_t *)(resampleOuput_.GetPcmDataBuffer()), GetFrameLen() * sizeof(float) * GetChannelCount()); + } +#endif +} + +void HpaeResampleNode::ConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) +{ + inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort(nodeInfo)); + resampleOuput_.SetSourceBufferType(preNode->GetOutputPortBufferType(nodeInfo)); +} + +void HpaeResampleNode::DisConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) +{ + inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true)); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_sinkInput_node.cpp b/services/audio_engine/node/src/hpae_sinkInput_node.cpp new file mode 100644 index 0000000000..e1755d28c9 --- /dev/null +++ b/services/audio_engine/node/src/hpae_sinkInput_node.cpp @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2025 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 "HpaeSinkInputNode" +#endif +#include "hpae_sink_input_node.h" +#include +#include "hpae_format_convert.h" +#include "hpae_node_common.h" +#include "audio_engine_log.h" +#include "audio_errors.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +static constexpr int32_t DEFAULT_BUFFER_MICROSECOND = 20000000; +static constexpr uint64_t AUDIO_NS_PER_S = 1000000000; + +HpaeSinkInputNode::HpaeSinkInputNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), + pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, (uint64_t)nodeInfo.channelLayout), + inputAudioBuffer_(pcmBufferInfo_), outputStream_(this), + interleveData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), framesWritten_(0), + totalFrames_(0) +{ + AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}lu, " + "frameLen %{public}d", nodeInfo.sessionId, inputAudioBuffer_.GetChannelCount(), + inputAudioBuffer_.GetChannelLayout(), inputAudioBuffer_.GetFrameLen()); + + handleTimeModel_ = std::make_unique(); + handleTimeModel_->ConfigSampleRate(nodeInfo.samplingRate); +#ifdef ENABLE_HOOK_PCM + inputPcmDumper_ = std::make_unique( + "HpaeSinkInputNode_id_" + std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) + + "_rate_" + std::to_string(GetSampleRate()) + "_bit_" + std::to_string(GetBitWidth()) + ".pcm"); +#endif + if (nodeInfo.historyFrameCount > 0) { + PcmBufferInfo pcmInfo = PcmBufferInfo{ + nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, + nodeInfo.historyFrameCount, true}; + historyBuffer_ = std::make_unique(pcmInfo); + AUDIO_INFO_LOG("HpaeSinkInputNode::historybuffer created"); + } else { + historyBuffer_ = nullptr; + } +} + +HpaeSinkInputNode::~HpaeSinkInputNode() +{} + +void HpaeSinkInputNode::CheckAndDestoryHistoryBuffer() +{ + HpaeNodeInfo nodeInfo = GetNodeInfo(); + // historyBuffer_ has no data, check if historyFrameCount is 0 and distory it + if (nodeInfo.historyFrameCount == 0) { + if (historyBuffer_) { + AUDIO_INFO_LOG("HpaeSinkInputNode::historyBuffer_ useless, distory it"); + } + historyBuffer_ = nullptr; + } else if (historyBuffer_ == nullptr) { // this case need to create historyBuffer_ + PcmBufferInfo pcmInfo = PcmBufferInfo{ + nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, + nodeInfo.historyFrameCount, true}; + historyBuffer_ = std::make_unique(pcmInfo); + AUDIO_INFO_LOG("HpaeSinkInputNode::historybuffer created"); + } +} + +void HpaeSinkInputNode::DoProcess() +{ + CHECK_AND_RETURN_LOG( + writeCallback_.lock(), "HpaeSinkInputNode writeCallback_ is nullptr, SessionId:%{public}d", GetSessionId()); + + auto nodeCallback = GetNodeStatusCallback().lock(); + if (nodeCallback) { + nodeCallback->OnRequestLatency(GetSessionId(), streamInfo_.latency); + } + + streamInfo_ = {.framesWritten = framesWritten_.load(), + .inputData = interleveData_.data(), + .requestDataLen = interleveData_.size(), + .deviceClass = GetDeviceClass(), + .deviceNetId = GetDeviceNetId(), + .needData = !(historyBuffer_ && historyBuffer_->GetCurFrames())}; + GetCurrentPosition(streamInfo_.framePosition, streamInfo_.timestamp); + int32_t ret = writeCallback_.lock()->OnStreamData(streamInfo_); + + // if historyBuffer has enough data, write to outputStream + if (!streamInfo_.needData) { + historyBuffer_->GetFrameData(inputAudioBuffer_); + outputStream_.WriteDataToOutput(&inputAudioBuffer_); + return; + } + CheckAndDestoryHistoryBuffer(); + if (nodeCallback && ret) { + nodeCallback->OnNodeStatusUpdate(GetSessionId(), OPERATION_UNDERFLOW); + if (isDrain_) { + AUDIO_INFO_LOG("OnNodeStatusUpdate Drain sessionId:%{public}u", GetSessionId()); + nodeCallback->OnNodeStatusUpdate(GetSessionId(), OPERATION_DRAINED); + isDrain_ = false; + } + } + inputAudioBuffer_.SetBufferValid(ret ? false : true); + +#ifdef ENABLE_HOOK_PCM + if (inputPcmDumper_ != nullptr && inputAudioBuffer_.IsValid()) { + inputPcmDumper_->CheckAndReopenHandlde(); + inputPcmDumper_->Dump(static_cast(interleveData_.data()), + GetChannelCount() * GetFrameLen() * GET_SIZE_FROM_FORMAT(GetBitWidth())); + } +#endif + + ConvertToFloat( + GetBitWidth(), GetChannelCount() * GetFrameLen(), interleveData_.data(), inputAudioBuffer_.GetPcmDataBuffer()); + if (ret != 0) { + AUDIO_WARNING_LOG("request data is not enough sessionId:%{public}u", GetSessionId()); + memset_s(inputAudioBuffer_.GetPcmDataBuffer(), inputAudioBuffer_.Size(), 0, inputAudioBuffer_.Size()); + } else { + totalFrames_ = totalFrames_ + GetFrameLen(); + framesWritten_.store(totalFrames_); + if (historyBuffer_) { + historyBuffer_->StoreFrameData(inputAudioBuffer_); + } + } + outputStream_.WriteDataToOutput(&inputAudioBuffer_); +} + +bool HpaeSinkInputNode::Reset() +{ + return true; +} + +bool HpaeSinkInputNode::ResetAll() +{ + return true; +} + +std::shared_ptr HpaeSinkInputNode::GetSharedInstance() +{ + return shared_from_this(); +} + +OutputPort *HpaeSinkInputNode::GetOutputPort() +{ + return &outputStream_; +} + +bool HpaeSinkInputNode::RegisterWriteCallback(const std::weak_ptr &callback) +{ + writeCallback_ = callback; + return true; +} +// reset historyBuffer +void HpaeSinkInputNode::Flush() +{ + if (GetNodeInfo().historyFrameCount == 0) { + historyBuffer_ = nullptr; + } else if (historyBuffer_ && historyBuffer_->GetFrames() == GetNodeInfo().historyFrameCount) { + historyBuffer_->Reset(); + } else { + HpaeNodeInfo nodeInfo = GetNodeInfo(); + PcmBufferInfo pcmInfo = PcmBufferInfo{ + nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, + nodeInfo.historyFrameCount, true}; + historyBuffer_ = std::make_unique(pcmInfo); + } +} + +bool HpaeSinkInputNode::Drain() +{ + isDrain_ = true; + return true; +} + +int32_t HpaeSinkInputNode::SetState(RendererState renderState) +{ + state_ = renderState; + return SUCCESS; +} + +RendererState HpaeSinkInputNode::GetState() +{ + return state_; +} + +uint64_t HpaeSinkInputNode::GetFramesWritten() +{ + return framesWritten_.load(); +} + +bool HpaeSinkInputNode::GetAudioTime(uint64_t &framePos, int64_t &sec, int64_t &nanoSec) +{ + framePos = GetFramesWritten(); + int64_t time = handleTimeModel_->GetTimeOfPos(framePos); + int64_t deltaTime = DEFAULT_BUFFER_MICROSECOND; // note: 20ms + time += deltaTime; + sec = time / AUDIO_NS_PER_S; + nanoSec = time % AUDIO_NS_PER_S; + return true; +} + +int32_t HpaeSinkInputNode::GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp) +{ + int64_t timeSec = 0; + int64_t timeNsec = 0; + bool ret = GetAudioTime(framePosition, timeSec, timeNsec); + if (historyBuffer_) { + framePosition = framePosition > historyBuffer_->GetCurFrames() * GetNodeInfo().frameLen + ? framePosition - historyBuffer_->GetCurFrames() * GetNodeInfo().frameLen + : 0; + } + CHECK_AND_RETURN_RET_LOG(ret, ERROR, "GetAudioTime error"); + timespec tm{}; + clock_gettime(CLOCK_MONOTONIC, &tm); + timestamp = static_cast(tm.tv_sec) * AUDIO_NS_PER_S + static_cast(tm.tv_nsec); + return SUCCESS; +} + +int32_t HpaeSinkInputNode::RewindHistoryBuffer(uint64_t rewindTime) +{ + CHECK_AND_RETURN_RET_LOG(historyBuffer_, ERROR, "historyBuffer_ is nullptr"); + AUDIO_INFO_LOG("HpaeSinkInputNode::rewind %{public}zu frames", ConvertUsToFrameCount(rewindTime, GetNodeInfo())); + return historyBuffer_->RewindBuffer(ConvertUsToFrameCount(rewindTime, GetNodeInfo())); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_sink_input_node.cpp b/services/audio_engine/node/src/hpae_sink_input_node.cpp new file mode 100644 index 0000000000..5eefc757f7 --- /dev/null +++ b/services/audio_engine/node/src/hpae_sink_input_node.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2025 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 "HpaeSinkInputNode" +#endif + +#include "hpae_sink_input_node.h" +#include +#include "hpae_format_convert.h" +#include "hpae_node_common.h" +#include "audio_engine_log.h" +#include "audio_errors.h" +#include "audio_utils.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +static constexpr int32_t DEFAULT_BUFFER_MICROSECOND = 20000000; +static constexpr uint64_t AUDIO_NS_PER_S = 1000000000; + +HpaeSinkInputNode::HpaeSinkInputNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), + pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, (uint64_t)nodeInfo.channelLayout), + inputAudioBuffer_(pcmBufferInfo_), outputStream_(this), + interleveData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), framesWritten_(0), + totalFrames_(0) +{ + AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}lu, " + "frameLen %{public}d", nodeInfo.sessionId, inputAudioBuffer_.GetChannelCount(), + inputAudioBuffer_.GetChannelLayout(), inputAudioBuffer_.GetFrameLen()); + + handleTimeModel_ = std::make_unique(); + handleTimeModel_->ConfigSampleRate(nodeInfo.samplingRate); +#ifdef ENABLE_HOOK_PCM + inputPcmDumper_ = std::make_unique( + "HpaeSinkInputNode_id_" + std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) + + "_rate_" + std::to_string(GetSampleRate()) + "_bit_" + std::to_string(GetBitWidth()) + ".pcm"); +#endif + if (nodeInfo.historyFrameCount > 0) { + PcmBufferInfo pcmInfo = PcmBufferInfo{ + nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, + nodeInfo.historyFrameCount, true}; + historyBuffer_ = std::make_unique(pcmInfo); + AUDIO_INFO_LOG("HpaeSinkInputNode::historybuffer created"); + } else { + historyBuffer_ = nullptr; + } +} + +HpaeSinkInputNode::~HpaeSinkInputNode() +{} + +void HpaeSinkInputNode::CheckAndDestoryHistoryBuffer() +{ + HpaeNodeInfo nodeInfo = GetNodeInfo(); + // historyBuffer_ has no data, check if historyFrameCount is 0 and distory it + if (nodeInfo.historyFrameCount == 0) { + if (historyBuffer_) { + AUDIO_INFO_LOG("HpaeSinkInputNode::historyBuffer_ useless, distory it"); + } + historyBuffer_ = nullptr; + } else if (historyBuffer_ == nullptr) { // this case need to create historyBuffer_ + PcmBufferInfo pcmInfo = PcmBufferInfo{ + nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, + nodeInfo.historyFrameCount, true}; + historyBuffer_ = std::make_unique(pcmInfo); + AUDIO_INFO_LOG("HpaeSinkInputNode::historybuffer created"); + } +} + +void HpaeSinkInputNode::DoProcess() +{ + auto rate = "rate[" + std::to_string(GetSampleRate()) + "]_"; + auto ch = "ch[" + std::to_string(GetChannelCount()) + "]_"; + auto len = "len[" + std::to_string(GetFrameLen()) + "]_"; + auto format = "bit[" + std::to_string(GetBitWidth()) + "]"; + Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeSinkInputNode::DoProcess " + + rate + ch + len + format); + CHECK_AND_RETURN_LOG( + writeCallback_.lock(), "HpaeSinkInputNode writeCallback_ is nullptr, SessionId:%{public}d", GetSessionId()); + + auto nodeCallback = GetNodeStatusCallback().lock(); + if (nodeCallback) { + nodeCallback->OnRequestLatency(GetSessionId(), streamInfo_.latency); + } + + streamInfo_ = {.framesWritten = framesWritten_.load(), + .inputData = interleveData_.data(), + .requestDataLen = interleveData_.size(), + .deviceClass = GetDeviceClass(), + .deviceNetId = GetDeviceNetId(), + .needData = !(historyBuffer_ && historyBuffer_->GetCurFrames())}; + GetCurrentPosition(streamInfo_.framePosition, streamInfo_.timestamp); + int32_t ret = writeCallback_.lock()->OnStreamData(streamInfo_); + + // if historyBuffer has enough data, write to outputStream + if (!streamInfo_.needData) { + historyBuffer_->GetFrameData(inputAudioBuffer_); + outputStream_.WriteDataToOutput(&inputAudioBuffer_); + return; + } + CheckAndDestoryHistoryBuffer(); + if (nodeCallback && ret) { + nodeCallback->OnNodeStatusUpdate(GetSessionId(), OPERATION_UNDERFLOW); + if (isDrain_) { + AUDIO_INFO_LOG("OnNodeStatusUpdate Drain sessionId:%{public}u", GetSessionId()); + nodeCallback->OnNodeStatusUpdate(GetSessionId(), OPERATION_DRAINED); + isDrain_ = false; + } + } + inputAudioBuffer_.SetBufferValid(ret ? false : true); + +#ifdef ENABLE_HOOK_PCM + if (inputPcmDumper_ != nullptr && inputAudioBuffer_.IsValid()) { + inputPcmDumper_->CheckAndReopenHandlde(); + inputPcmDumper_->Dump(static_cast(interleveData_.data()), + GetChannelCount() * GetFrameLen() * GET_SIZE_FROM_FORMAT(GetBitWidth())); + } +#endif + + ConvertToFloat( + GetBitWidth(), GetChannelCount() * GetFrameLen(), interleveData_.data(), inputAudioBuffer_.GetPcmDataBuffer()); + if (ret != 0) { + AUDIO_WARNING_LOG("request data is not enough sessionId:%{public}u", GetSessionId()); + memset_s(inputAudioBuffer_.GetPcmDataBuffer(), inputAudioBuffer_.Size(), 0, inputAudioBuffer_.Size()); + } else { + totalFrames_ = totalFrames_ + GetFrameLen(); + framesWritten_.store(totalFrames_); + if (historyBuffer_) { + historyBuffer_->StoreFrameData(inputAudioBuffer_); + } + } + outputStream_.WriteDataToOutput(&inputAudioBuffer_); +} + +bool HpaeSinkInputNode::Reset() +{ + return true; +} + +bool HpaeSinkInputNode::ResetAll() +{ + return true; +} + +std::shared_ptr HpaeSinkInputNode::GetSharedInstance() +{ + return shared_from_this(); +} + +OutputPort *HpaeSinkInputNode::GetOutputPort() +{ + return &outputStream_; +} + +bool HpaeSinkInputNode::RegisterWriteCallback(const std::weak_ptr &callback) +{ + writeCallback_ = callback; + return true; +} +// reset historyBuffer +void HpaeSinkInputNode::Flush() +{ + if (GetNodeInfo().historyFrameCount == 0) { + historyBuffer_ = nullptr; + } else if (historyBuffer_ && historyBuffer_->GetFrames() == GetNodeInfo().historyFrameCount) { + historyBuffer_->Reset(); + } else { + HpaeNodeInfo nodeInfo = GetNodeInfo(); + PcmBufferInfo pcmInfo = PcmBufferInfo{ + nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, + nodeInfo.historyFrameCount, true}; + historyBuffer_ = std::make_unique(pcmInfo); + } +} + +bool HpaeSinkInputNode::Drain() +{ + isDrain_ = true; + return true; +} + +int32_t HpaeSinkInputNode::SetState(RendererState renderState) +{ + state_ = renderState; + return SUCCESS; +} + +RendererState HpaeSinkInputNode::GetState() +{ + return state_; +} + +uint64_t HpaeSinkInputNode::GetFramesWritten() +{ + return framesWritten_.load(); +} + +bool HpaeSinkInputNode::GetAudioTime(uint64_t &framePos, int64_t &sec, int64_t &nanoSec) +{ + framePos = GetFramesWritten(); + int64_t time = handleTimeModel_->GetTimeOfPos(framePos); + int64_t deltaTime = DEFAULT_BUFFER_MICROSECOND; // note: 20ms + time += deltaTime; + sec = time / AUDIO_NS_PER_S; + nanoSec = time % AUDIO_NS_PER_S; + return true; +} + +int32_t HpaeSinkInputNode::GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp) +{ + int64_t timeSec = 0; + int64_t timeNsec = 0; + bool ret = GetAudioTime(framePosition, timeSec, timeNsec); + if (historyBuffer_) { + framePosition = framePosition > historyBuffer_->GetCurFrames() * GetNodeInfo().frameLen + ? framePosition - historyBuffer_->GetCurFrames() * GetNodeInfo().frameLen + : 0; + } + CHECK_AND_RETURN_RET_LOG(ret, ERROR, "GetAudioTime error"); + timespec tm{}; + clock_gettime(CLOCK_MONOTONIC, &tm); + timestamp = static_cast(tm.tv_sec) * AUDIO_NS_PER_S + static_cast(tm.tv_nsec); + return SUCCESS; +} + +int32_t HpaeSinkInputNode::RewindHistoryBuffer(uint64_t rewindTime) +{ + CHECK_AND_RETURN_RET_LOG(historyBuffer_, ERROR, "historyBuffer_ is nullptr"); + AUDIO_INFO_LOG("HpaeSinkInputNode::rewind %{public}zu frames", ConvertUsToFrameCount(rewindTime, GetNodeInfo())); + return historyBuffer_->RewindBuffer(ConvertUsToFrameCount(rewindTime, GetNodeInfo())); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_sink_output_node.cpp b/services/audio_engine/node/src/hpae_sink_output_node.cpp new file mode 100644 index 0000000000..6d11aefbc2 --- /dev/null +++ b/services/audio_engine/node/src/hpae_sink_output_node.cpp @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2025 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 "HpaeSinkOutputNode" +#endif + +#include +#include "audio_errors.h" +#include +#include "hpae_format_convert.h" +#include "audio_engine_log.h" +#include "audio_utils.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +namespace { +constexpr uint32_t SLEEP_TIME_IN_US = 2000; +} + +HpaeSinkOutputNode::HpaeSinkOutputNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), + renderFrameData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), + interleveData_(nodeInfo.frameLen * nodeInfo.channels) +{ +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_ = std::make_unique("HpaeSinkOutputNode_Out_bit_" + std::to_string(GetBitWidth()) + + "_ch_" + std::to_string(GetChannelCount()) + "_rate_" + + std::to_string(GetSampleRate()) + ".pcm"); + AUDIO_INFO_LOG("HpaeSinkOutputNode name is %{public}s", sinkOutAttr_.adapterName); +#endif +} + +void HpaeSinkOutputNode::HandleRemoteTiming() +{ + remoteTimer_.Stop(); + uint64_t remoteElapsed = remoteTimer_.Elapsed(); + auto now = std::chrono::high_resolution_clock::now(); + remoteTimePoint_ += std::chrono::milliseconds(20); + std::this_thread::sleep_for(remoteSleepTime_); + if (remoteTimePoint_ > now + std::chrono::milliseconds(remoteElapsed)) { + remoteSleepTime_ = std::chrono::duration_cast(remoteTimePoint_ - now) - + std::chrono::milliseconds(remoteElapsed); + } else { + remoteSleepTime_ = std::chrono::milliseconds(0); + } + remoteTimer_.Start(); +} + +void HpaeSinkOutputNode::DoProcess() +{ + auto rate = "rate[" + std::to_string(GetSampleRate()) + "]_"; + auto ch = "ch[" + std::to_string(GetChannelCount()) + "]_"; + auto len = "len[" + std::to_string(GetFrameLen()) + "]_"; + auto format = "bit[" + std::to_string(GetBitWidth()) + "]"; + Trace trace("HpaeSinkOutputNode::DoProcess " + rate + ch + len + format); + if (audioRendererSink_ == nullptr) { + AUDIO_WARNING_LOG("audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); + return; + } + std::vector &outputVec = inputStream_.ReadPreOutputData(); + if (outputVec.empty()) { + return; + } + HpaePcmBuffer *outputData = outputVec.front(); + ConvertFromFloat( + GetBitWidth(), GetChannelCount() * GetFrameLen(), outputData->GetPcmDataBuffer(), renderFrameData_.data()); + uint64_t writeLen = 0; + char *renderFrameData = (char *)renderFrameData_.data(); + +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); + intervalTimer_.Stop(); + uint64_t interval = intervalTimer_.Elapsed(); + AUDIO_DEBUG_LOG("HpaeSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, + interval); + outputPcmDumper_->CheckAndReopenHandlde(); + if (outputPcmDumper_) { + outputPcmDumper_->Dump((int8_t *)renderFrameData, renderFrameData_.size()); + } +#endif + if (GetDeviceClass() == "remote") { + HandleRemoteTiming(); + } + auto ret = audioRendererSink_->RenderFrame(*renderFrameData, renderFrameData_.size(), writeLen); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("HpaeSinkOutputNode: RenderFrame failed"); + usleep(SLEEP_TIME_IN_US); + return; + } +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t elapsed = timer.Elapsed(); + AUDIO_DEBUG_LOG("HpaeSinkOutputNode :name %{public}s, RenderFrame elapsed time: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, + elapsed); + intervalTimer_.Start(); +#endif + return; +} + +const char *HpaeSinkOutputNode::GetRenderFrameData(void) +{ + return renderFrameData_.data(); +} + +bool HpaeSinkOutputNode::Reset() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + inputStream_.DisConnect(output); + } + return true; +} + +bool HpaeSinkOutputNode::ResetAll() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + std::shared_ptr hpaeNode = preOutput.second; + if (hpaeNode->ResetAll()) { + inputStream_.DisConnect(output); + } + } + return true; +} + +void HpaeSinkOutputNode::Connect(const std::shared_ptr> &preNode) +{ + inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); +} + +void HpaeSinkOutputNode::DisConnect(const std::shared_ptr> &preNode) +{ + inputStream_.DisConnect(preNode->GetOutputPort()); +} + +int32_t HpaeSinkOutputNode::GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId) +{ + if (deviceNetId.empty()) { + renderId_ = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, HDI_ID_INFO_DEFAULT, true); + } else { + renderId_ = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, deviceNetId, true); + } + audioRendererSink_ = HdiAdapterManager::GetInstance().GetRenderSink(renderId_, true); + if (audioRendererSink_ == nullptr) { + AUDIO_ERR_LOG("get sink fail, deviceClass: %{public}s, deviceNetId: %{public}s, renderId_: %{public}u", + deviceClass.c_str(), + deviceNetId.c_str(), + renderId_); + HdiAdapterManager::GetInstance().ReleaseId(renderId_); + return ERROR; + } + return SUCCESS; +} + +int32_t HpaeSinkOutputNode::RenderSinkInit(IAudioSinkAttr &attr) +{ + if (audioRendererSink_ == nullptr) { + return ERROR; + } + + sinkOutAttr_ = attr; + state_ = RENDERER_PREPARED; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + int32_t ret = audioRendererSink_->Init(attr); +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkInit Elapsed: %{public}" PRIu64 + " ms ret: %{public}d", + sinkOutAttr_.adapterName, + interval, + ret); + std::string adapterName = sinkOutAttr_.adapterName; + outputPcmDumper_ = std::make_unique( + "HpaeSinkOutputNode_" + adapterName + "_bit_" + std::to_string(GetBitWidth()) + "_ch_" + + std::to_string(GetChannelCount()) + "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); +#endif + return ret; +} + +int32_t HpaeSinkOutputNode::RenderSinkDeInit(void) +{ + if (audioRendererSink_ == nullptr) { + return ERROR; + } + state_ = RENDERER_INVALID; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + audioRendererSink_->DeInit(); + audioRendererSink_ = nullptr; + HdiAdapterManager::GetInstance().ReleaseId(renderId_); +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkDeInit Elapsed: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, + interval); +#endif + return SUCCESS; +} + +int32_t HpaeSinkOutputNode::RenderSinkFlush(void) +{ + if (audioRendererSink_ == nullptr) { + return ERROR; + } + return audioRendererSink_->Flush(); +} + +int32_t HpaeSinkOutputNode::RenderSinkPause(void) +{ + if (audioRendererSink_ == nullptr) { + return ERROR; + } + audioRendererSink_->Pause(); + state_ = RENDERER_PAUSED; + return SUCCESS; +} + +int32_t HpaeSinkOutputNode::RenderSinkReset(void) +{ + if (audioRendererSink_ == nullptr) { + return ERROR; + } + return audioRendererSink_->Reset(); +} + +int32_t HpaeSinkOutputNode::RenderSinkResume(void) +{ + if (audioRendererSink_ == nullptr) { + return ERROR; + } + int32_t ret = audioRendererSink_->Resume(); + if (ret != SUCCESS) { + return ret; + } + state_ = RENDERER_RUNNING; + return SUCCESS; +} + +int32_t HpaeSinkOutputNode::RenderSinkStart(void) +{ + if (audioRendererSink_ == nullptr) { + return ERROR; + } + + int32_t ret; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + ret = audioRendererSink_->Start(); + if (ret != SUCCESS) { + return ERROR; + } +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkStart Elapsed: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, + interval); +#endif + state_ = RENDERER_RUNNING; + if (GetDeviceClass() == "remote") { + remoteTimePoint_ = std::chrono::high_resolution_clock::now(); + } + return SUCCESS; +} + +int32_t HpaeSinkOutputNode::RenderSinkStop(void) +{ + if (audioRendererSink_ == nullptr) { + return ERROR; + } + int32_t ret; +#ifdef ENABLE_HOOK_PCM + HighResolutionTimer timer; + timer.Start(); +#endif + ret = audioRendererSink_->Stop(); + if (ret != SUCCESS) { + return ret; + } +#ifdef ENABLE_HOOK_PCM + timer.Stop(); + uint64_t interval = timer.Elapsed(); + AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkStop Elapsed: %{public}" PRIu64 " ms", + sinkOutAttr_.adapterName, + interval); +#endif + state_ = RENDERER_STOPPED; + return SUCCESS; +} + +RendererState HpaeSinkOutputNode::GetSinkState(void) +{ + return state_; +} + +size_t HpaeSinkOutputNode::GetPreOutNum() +{ + return inputStream_.GetPreOutputNum(); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/node/src/hpae_source_input_cluster.cpp b/services/audio_engine/node/src/hpae_source_input_cluster.cpp new file mode 100644 index 0000000000..f1f063f127 --- /dev/null +++ b/services/audio_engine/node/src/hpae_source_input_cluster.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2025 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 "HpaeSourceInputCluster" +#endif + +#include "hpae_source_input_cluster.h" +#include "hpae_node_common.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +static std::string TransSourceBufferTypeToString(HpaeSourceBufferType &type) +{ + if (type == HPAE_SOURCE_BUFFER_TYPE_MIC) { + return "MIC"; + } else if (type == HPAE_SOURCE_BUFFER_TYPE_EC) { + return "EC"; + } else if (type == HPAE_SOURCE_BUFFER_TYPE_MICREF) { + return "MICREF"; + } + return "DEFAULT"; +} + +HpaeSourceInputCluster::HpaeSourceInputCluster(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), sourceInputNode_(std::make_shared(nodeInfo)) +{ +#ifdef ENABLE_HIDUMP_DFX + if (nodeInfo.statusCallback.lock()) { + nodeInfo.nodeName = "HpaeSourceInputNode[" + TransSourceBufferTypeToString(nodeInfo.sourceBufferType) + "]"; + nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); + sourceInputNode_->SetNodeInfo(nodeInfo); + nodeInfo.statusCallback.lock()->OnNotifyDfxNodeInfo(true, 0, nodeInfo); + } +#endif +} + +HpaeSourceInputCluster::HpaeSourceInputCluster(std::vector &nodeInfos) + : HpaeNode(*nodeInfos.begin()), sourceInputNode_(std::make_shared(nodeInfos)) +{ +#ifdef ENABLE_HIDUMP_DFX + auto nodeInfo = *nodeInfos.begin(); + nodeInfo.nodeName = "HpaeSourceInputNode[" + TransSourceBufferTypeToString(nodeInfo.sourceBufferType) + "]"; + nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); + sourceInputNode_->SetNodeInfo(nodeInfo); + nodeInfo.statusCallback.lock()->OnNotifyDfxNodeInfo(true, 0, nodeInfo); +#endif +} + +HpaeSourceInputCluster::~HpaeSourceInputCluster() +{ + Reset(); +} + +void HpaeSourceInputCluster::DoProcess() +{ +} + +bool HpaeSourceInputCluster::Reset() +{ + for (auto fmtConverterNode : fmtConverterNodeMap_) { + fmtConverterNode.second->Reset(); + } + sourceInputNode_->Reset(); + return true; +} + +bool HpaeSourceInputCluster::ResetAll() +{ + for (auto fmtConverterNode : fmtConverterNodeMap_) { + fmtConverterNode.second->ResetAll(); + } + sourceInputNode_->ResetAll(); + return true; +} + +std::shared_ptr HpaeSourceInputCluster::GetSharedInstance() +{ + return sourceInputNode_; +} + +std::shared_ptr HpaeSourceInputCluster::GetSharedInstance(HpaeNodeInfo &nodeInfo) +{ + // todo: change function name + std::string nodeKey = TransHpaeResampleNodeInfoToStringKey(nodeInfo); + std::string inputNodeKey = TransHpaeResampleNodeInfoToStringKey(GetNodeInfo()); + AUDIO_INFO_LOG("sourceinput nodekey:[%{public}s] effectnodekey:[%{public}s]", + inputNodeKey.c_str(), nodeKey.c_str()); + if (CheckHpaeNodeInfoIsSame(nodeInfo, GetNodeInfo())) { + AUDIO_INFO_LOG("sourceinputnode nodekey is same as capture effect"); + return sourceInputNode_; + } + if (fmtConverterNodeMap_.find(nodeKey) == fmtConverterNodeMap_.end()) { + fmtConverterNodeMap_[nodeKey] = std::make_shared(GetNodeInfo(), nodeInfo); + nodeInfo.nodeName = "HpaeAudioFormatConverterNode"; + nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); + fmtConverterNodeMap_[nodeKey]->SetNodeInfo(nodeInfo); + } + fmtConverterNodeMap_[nodeKey]->ConnectWithInfo(sourceInputNode_, fmtConverterNodeMap_[nodeKey]->GetNodeInfo()); +#ifdef ENABLE_HIDUMP_DFX + if (auto callback = sourceInputNode_->GetNodeInfo().statusCallback.lock()) { + callback->OnNotifyDfxNodeInfo( + true, sourceInputNode_->GetNodeId(), fmtConverterNodeMap_[nodeKey]->GetNodeInfo()); + } +#endif + return fmtConverterNodeMap_[nodeKey]; +} + +OutputPort *HpaeSourceInputCluster::GetOutputPort() +{ + return sourceInputNode_->GetOutputPort(); +} + +OutputPort *HpaeSourceInputCluster::GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect) +{ + std::string nodeKey = TransHpaeResampleNodeInfoToStringKey(nodeInfo); + std::string inputNodeKey = TransHpaeResampleNodeInfoToStringKey(GetNodeInfo()); + AUDIO_INFO_LOG("sourceinput nodekey:[%{public}s] effectnodekey:[%{public}s]", + inputNodeKey.c_str(), nodeKey.c_str()); + if (CheckHpaeNodeInfoIsSame(nodeInfo, GetNodeInfo())) { + AUDIO_INFO_LOG("sourceinputnode nodekey is same as capture effect"); + return sourceInputNode_->GetOutputPort(nodeInfo); + } + CHECK_AND_RETURN_RET_LOG(fmtConverterNodeMap_.find(nodeKey) != fmtConverterNodeMap_.end(), nullptr, + "HpaeSourceProcessCluster not find the nodeKey = %{public}s", nodeKey.c_str()); + if (isDisConnect && fmtConverterNodeMap_[nodeKey]->GetOutputPortNum() <= 1) { + AUDIO_INFO_LOG("disconnect fmtConverterNode between effectnode[[%{public}s] and sourceinputnode[%{public}s]", + nodeKey.c_str(), inputNodeKey.c_str()); + fmtConverterNodeMap_[nodeKey]->DisConnectWithInfo(sourceInputNode_, fmtConverterNodeMap_[nodeKey]->GetNodeInfo()); + } + return fmtConverterNodeMap_[nodeKey]->GetOutputPort(); +} + +int32_t HpaeSourceInputCluster::GetCapturerSourceInstance(const std::string &deviceClass, + const std::string &deviceNetId, const SourceType &sourceType, const std::string &sourceName) +{ + return sourceInputNode_->GetCapturerSourceInstance(deviceClass, deviceNetId, sourceType, sourceName); +} + +int32_t HpaeSourceInputCluster::CapturerSourceInit(IAudioSourceAttr &attr) +{ + return sourceInputNode_->CapturerSourceInit(attr); +} + +int32_t HpaeSourceInputCluster::CapturerSourceDeInit() +{ + return sourceInputNode_->CapturerSourceDeInit(); +} + +int32_t HpaeSourceInputCluster::CapturerSourceFlush(void) +{ + return sourceInputNode_->CapturerSourceFlush(); +} + +int32_t HpaeSourceInputCluster::CapturerSourcePause(void) +{ + return sourceInputNode_->CapturerSourcePause(); +} + +int32_t HpaeSourceInputCluster::CapturerSourceReset(void) +{ + return sourceInputNode_->CapturerSourceReset(); +} + +int32_t HpaeSourceInputCluster::CapturerSourceResume(void) +{ + return sourceInputNode_->CapturerSourceResume(); +} + +int32_t HpaeSourceInputCluster::CapturerSourceStart(void) +{ + return sourceInputNode_->CapturerSourceStart(); +} + +int32_t HpaeSourceInputCluster::CapturerSourceStop(void) +{ + return sourceInputNode_->CapturerSourceStop(); +} + +CapturerState HpaeSourceInputCluster::GetSourceState(void) +{ + return sourceInputNode_->GetSourceState(); +} + +size_t HpaeSourceInputCluster::GetOutputPortNum() +{ + return sourceInputNode_->GetOutputPortNum(); +} + +size_t HpaeSourceInputCluster::GetOutputPortNum(HpaeNodeInfo &nodeInfo) +{ + return sourceInputNode_->GetOutputPortNum(nodeInfo); +} + +HpaeSourceInputNodeType HpaeSourceInputCluster::GetSourceInputNodeType() +{ + return sourceInputNode_->GetSourceInputNodeType(); +} + +void HpaeSourceInputCluster::SetSourceInputNodeType(HpaeSourceInputNodeType type) +{ + sourceInputNode_->SetSourceInputNodeType(type); +} + +// for test +uint32_t HpaeSourceInputCluster::GetConverterNodeCount() +{ + return fmtConverterNodeMap_.size(); +} + +uint32_t HpaeSourceInputCluster::GetSourceInputNodeUseCount() +{ + return sourceInputNode_.use_count(); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_source_input_node.cpp b/services/audio_engine/node/src/hpae_source_input_node.cpp new file mode 100644 index 0000000000..91ee4f5f5d --- /dev/null +++ b/services/audio_engine/node/src/hpae_source_input_node.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2025 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 "HpaeSourceInputNode" +#endif + +#include "hpae_source_input_node.h" +#include "hpae_format_convert.h" +#include "hpae_node_common.h" +#include "audio_errors.h" +#include "audio_engine_log.h" + +#define BYTE_SIZE_SAMPLE_U8 1 +#define BYTE_SIZE_SAMPLE_S16 2 +#define BYTE_SIZE_SAMPLE_S24 3 +#define BYTE_SIZE_SAMPLE_S32 4 +#define FRAME_DURATION_DEFAULT 20 +#define MILLISECOND_PER_SECOND 1000 + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + static std::string TransSourceBufferTypeToString(HpaeSourceBufferType &type) +{ + switch (type) { + case HPAE_SOURCE_BUFFER_TYPE_EC: + return "_EC.pcm"; + case HPAE_SOURCE_BUFFER_TYPE_MICREF: + return "_MICREF.pcm"; + default: + return ".pcm"; + } +} + +HpaeSourceInputNode::HpaeSourceInputNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), sourceInputNodeType_(nodeInfo.sourceInputNodeType) +{ + HpaeSourceBufferType sourceBufferType = nodeInfo.sourceBufferType; + nodeInfoMap_.emplace(sourceBufferType, nodeInfo); + pcmBufferInfoMap_.emplace( + sourceBufferType, PcmBufferInfo(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate)); + inputAudioBufferMap_.emplace(sourceBufferType, HpaePcmBuffer(pcmBufferInfoMap_.at(sourceBufferType))); + inputAudioBufferMap_.at(sourceBufferType).SetSourceBufferType(sourceBufferType); + frameByteSizeMap_.emplace( + sourceBufferType, nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); + capturerFrameDataMap_.emplace(sourceBufferType, frameByteSizeMap_.at(sourceBufferType)); + outputStreamMap_.emplace(sourceBufferType, this); + +#ifdef ENABLE_HOOK_PCM + inputPcmDumperMap_.emplace(sourceBufferType, + std::make_unique("HpaeSourceInputNode_id_"+ std::to_string(GetSessionId()) + + "_ch_" + std::to_string(GetChannelCount()) + + "_rate_" + std::to_string(GetSampleRate()) + + "_bit_"+ std::to_string(GetBitWidth()) + TransSourceBufferTypeToString(sourceBufferType))); +#endif +} + +HpaeSourceInputNode::HpaeSourceInputNode(std::vector &nodeInfos) + : HpaeNode(*nodeInfos.begin()), sourceInputNodeType_((*nodeInfos.begin()).sourceInputNodeType) +{ + for (auto nodeInfo : nodeInfos) { + HpaeSourceBufferType sourceBufferType = nodeInfo.sourceBufferType; + nodeInfoMap_.emplace(sourceBufferType, nodeInfo); + pcmBufferInfoMap_.emplace( + sourceBufferType, PcmBufferInfo(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate)); + inputAudioBufferMap_.emplace(sourceBufferType, HpaePcmBuffer(pcmBufferInfoMap_.at(sourceBufferType))); + inputAudioBufferMap_.at(sourceBufferType).SetSourceBufferType(sourceBufferType); + frameByteSizeMap_.emplace( + sourceBufferType, nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); + capturerFrameDataMap_.emplace(sourceBufferType, frameByteSizeMap_.at(sourceBufferType)); + fdescMap_.emplace(sourceBufferType, + FrameDesc{capturerFrameDataMap_.at(sourceBufferType).data(), frameByteSizeMap_.at(sourceBufferType)}); + outputStreamMap_.emplace(sourceBufferType, this); +#ifdef ENABLE_HOOK_PCM + inputPcmDumperMap_.emplace(sourceBufferType, + std::make_unique("HpaeSourceInputNode_id_"+ std::to_string(GetSessionId()) + + "_ch_" + std::to_string(nodeInfo.channels) + + "_rate_" + std::to_string(nodeInfo.samplingRate) + + "_bit_"+ std::to_string(nodeInfo.format) + TransSourceBufferTypeToString(sourceBufferType))); +#endif + } +} + +void HpaeSourceInputNode::DoProcess() +{ + if (audioCapturerSource_ == nullptr) { + AUDIO_WARNING_LOG("audioCapturerSource_ is nullptr NodeId: %{public}u", GetNodeId()); + return; + } + uint64_t replyBytes = 0; + if (sourceInputNodeType_ == HpaeSourceInputNodeType::HPAE_SOURCE_MIC_EC) { + uint64_t replyBytesEc = 0; + audioCapturerSource_->CaptureFrameWithEc(&fdescMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC), replyBytes, + &fdescMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC), replyBytesEc); +#ifdef ENABLE_HOOK_PCM + if (inputPcmDumperMap_.find(HPAE_SOURCE_BUFFER_TYPE_MIC) != inputPcmDumperMap_.end() && + inputPcmDumperMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC)) { + inputPcmDumperMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC)->Dump( + (int8_t *) capturerFrameDataMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC).data(), replyBytes); + } + if (inputPcmDumperMap_.find(HPAE_SOURCE_BUFFER_TYPE_EC) != inputPcmDumperMap_.end() && + inputPcmDumperMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC)) { + inputPcmDumperMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC)->Dump( + (int8_t *) capturerFrameDataMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).data(), replyBytesEc); + } +#endif + // todo: do not convert to float in SourceInputNode + ConvertToFloat(GetBitWidth(), GetChannelCount() * GetFrameLen(), + capturerFrameDataMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC).data(), + inputAudioBufferMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC).GetPcmDataBuffer()); + ConvertToFloat(nodeInfoMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).format, + nodeInfoMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).channels * nodeInfoMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).frameLen, + capturerFrameDataMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).data(), + inputAudioBufferMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).GetPcmDataBuffer()); + outputStreamMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC).WriteDataToOutput( + &inputAudioBufferMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC)); + outputStreamMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).WriteDataToOutput( + &inputAudioBufferMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC)); + } else { + HpaeSourceBufferType sourceBufferType = nodeInfoMap_.begin()->second.sourceBufferType; + audioCapturerSource_->CaptureFrame(capturerFrameDataMap_.at(sourceBufferType).data(), + (uint64_t)frameByteSizeMap_.at(sourceBufferType), replyBytes); +#ifdef ENABLE_HOOK_PCM + if (inputPcmDumperMap_.find(sourceBufferType) != inputPcmDumperMap_.end() && + inputPcmDumperMap_.at(sourceBufferType)) { + inputPcmDumperMap_.at(sourceBufferType)->Dump( + (int8_t *) capturerFrameDataMap_.at(sourceBufferType).data(), replyBytes); + } +#endif + // todo: do not convert to float in SourceInputNode + ConvertToFloat(GetBitWidth(), GetChannelCount() * GetFrameLen(), capturerFrameDataMap_.at(sourceBufferType).data(), + inputAudioBufferMap_.at(sourceBufferType).GetPcmDataBuffer()); + outputStreamMap_.at(sourceBufferType).WriteDataToOutput(&inputAudioBufferMap_.at(sourceBufferType)); + } +} + +int32_t HpaeSourceInputNode::WriteCapturerData(char *data, int32_t dataSize) +{ + auto itCapturerFrameData = capturerFrameDataMap_.begin(); + auto itFrameByteSize = frameByteSizeMap_.begin(); + CHECK_AND_RETURN_RET_LOG( + itCapturerFrameData != capturerFrameDataMap_.end() && itFrameByteSize != frameByteSizeMap_.end(), + ERROR, "outStreamMap_ is empty.\n"); + memcpy_s(itCapturerFrameData->second.data(), itFrameByteSize->second, data, dataSize); + return 0; +} + +bool HpaeSourceInputNode::Reset() +{ + return true; +} + +bool HpaeSourceInputNode::ResetAll() +{ + return true; +} + +std::shared_ptr HpaeSourceInputNode::GetSharedInstance() +{ + return shared_from_this(); +} + +OutputPort *HpaeSourceInputNode::GetOutputPort() +{ + std::unordered_map>::iterator it; + if (sourceInputNodeType_ != HPAE_SOURCE_MIC_EC) { + it = outputStreamMap_.begin(); + } else { + it = outputStreamMap_.find(HPAE_SOURCE_BUFFER_TYPE_MIC); + } + CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), nullptr, "outStreamMap_ is empty.\n"); + return &(it->second); +} + +OutputPort *HpaeSourceInputNode::GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect) +{ + auto it = outputStreamMap_.find(nodeInfo.sourceBufferType); + CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), nullptr, + "can't find nodeKey in outStreamMap_, sourceBufferType = %{public}d.\n", + nodeInfo.sourceBufferType); + return &(it->second); +} + +HpaeSourceBufferType HpaeSourceInputNode::GetOutputPortBufferType(HpaeNodeInfo &nodeInfo) +{ + auto it = outputStreamMap_.find(nodeInfo.sourceBufferType); + CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), HPAE_SOURCE_BUFFER_TYPE_DEFAULT, + "can't find nodeKey in outStreamMap_, sourceBufferType = %{public}d.\n", nodeInfo.sourceBufferType); + // todo: rewrite this function + if (sourceInputNodeType_ == HpaeSourceInputNodeType::HPAE_SOURCE_MIC_EC) { + if (nodeInfo.sourceBufferType == HPAE_SOURCE_BUFFER_TYPE_MIC) { + return HPAE_SOURCE_BUFFER_TYPE_MIC; + } else { + return HPAE_SOURCE_BUFFER_TYPE_EC; + } + } else { + return inputAudioBufferMap_.at(nodeInfo.sourceBufferType).GetSourceBufferType(); + } +} + +int32_t HpaeSourceInputNode::GetCapturerSourceAdapter( + const std::string &deviceClass, const SourceType &sourceType, const std::string &info) { + captureId_ = HDI_INVALID_ID; + if (info.empty()) { + captureId_ = HdiAdapterManager::GetInstance().GetCaptureIdByDeviceClass( + deviceClass, sourceType, HDI_ID_INFO_DEFAULT, true); + } else { + captureId_ = HdiAdapterManager::GetInstance().GetCaptureIdByDeviceClass( + deviceClass, sourceType, info, true); + } + audioCapturerSource_ = HdiAdapterManager::GetInstance().GetCaptureSource(captureId_, true); + if (audioCapturerSource_ == nullptr) { + AUDIO_ERR_LOG("get source fail, deviceClass: %{public}s, info: %{public}s, captureId_: %{public}u", + deviceClass.c_str(), info.c_str(), captureId_); + HdiAdapterManager::GetInstance().ReleaseId(captureId_); + return ERROR; + } + return SUCCESS; +} + +int32_t HpaeSourceInputNode::GetCapturerSourceInstance(const std::string &deviceClass, const std::string &deviceNetId, + const SourceType &sourceType, const std::string &sourceName) +{ + if (sourceType == SOURCE_TYPE_WAKEUP || sourceName == HDI_ID_INFO_EC || sourceName == HDI_ID_INFO_MIC_REF) { + return GetCapturerSourceAdapter(deviceClass, sourceType, sourceName); + } + return GetCapturerSourceAdapter(deviceClass, sourceType, deviceNetId); +} + +int32_t HpaeSourceInputNode::CapturerSourceInit(IAudioSourceAttr &attr) +{ + if (audioCapturerSource_ == nullptr) { + return ERROR; + } + + if (audioCapturerSource_->IsInited()) { + return SUCCESS; + } + + audioSourceAttr_ = attr; + CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Init(attr) == SUCCESS, ERROR, "Source init fail"); + state_ = CAPTURER_NEW; + return SUCCESS; +} + +int32_t HpaeSourceInputNode::CapturerSourceDeInit() +{ + if (audioCapturerSource_ == nullptr) { + return ERROR; + } + audioCapturerSource_->DeInit(); + audioCapturerSource_ = nullptr; + // todo: check where to release captureId_ + HdiAdapterManager::GetInstance().ReleaseId(captureId_); + return SUCCESS; +} + +int32_t HpaeSourceInputNode::CapturerSourceFlush(void) +{ + if (audioCapturerSource_ == nullptr) { + return ERROR; + } + return audioCapturerSource_->Flush(); +} + +int32_t HpaeSourceInputNode::CapturerSourcePause(void) +{ + if (audioCapturerSource_ == nullptr) { + return ERROR; + } + CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Pause() == SUCCESS, ERROR, "Source pause fail"); + state_ = CAPTURER_PAUSED; + return SUCCESS; +} + +int32_t HpaeSourceInputNode::CapturerSourceReset(void) +{ + if (audioCapturerSource_ == nullptr) { + return ERROR; + } + return audioCapturerSource_->Reset(); +} + +int32_t HpaeSourceInputNode::CapturerSourceResume(void) +{ + if (audioCapturerSource_ == nullptr) { + return ERROR; + } + CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Resume() == SUCCESS, ERROR, "Source resume fail"); + state_ = CAPTURER_RUNNING; + return SUCCESS; +} + +int32_t HpaeSourceInputNode::CapturerSourceStart(void) +{ + if (audioCapturerSource_ == nullptr) { + return ERROR; + } + CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Start() == SUCCESS, ERROR, "Source start fail"); + state_ = CAPTURER_RUNNING; + return SUCCESS; +} + +int32_t HpaeSourceInputNode::CapturerSourceStop(void) +{ + if (audioCapturerSource_ == nullptr) { + return ERROR; + } + CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Stop() == SUCCESS, ERROR, "Source stop fail"); + state_ = CAPTURER_STOPPED; + return SUCCESS; +} + +CapturerState HpaeSourceInputNode::GetSourceState(void) +{ + return state_; +} + +size_t HpaeSourceInputNode::GetOutputPortNum() +{ + std::unordered_map>::iterator it; + if (sourceInputNodeType_ != HPAE_SOURCE_MIC_EC) { + it = outputStreamMap_.begin(); + } else { + it = outputStreamMap_.find(HPAE_SOURCE_BUFFER_TYPE_MIC); + } + CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), 0, "outStreamMap_ is empty.\n"); + return it->second.GetInputNum(); +} + +size_t HpaeSourceInputNode::GetOutputPortNum(HpaeNodeInfo &nodeInfo) +{ + auto it = outputStreamMap_.find(nodeInfo.sourceBufferType); + CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), 0, "can't find nodeKey in outStreamMap_.\n"); + return it->second.GetInputNum(); +} + +HpaeSourceInputNodeType HpaeSourceInputNode::GetSourceInputNodeType() +{ + return sourceInputNodeType_; +} + +void HpaeSourceInputNode::SetSourceInputNodeType(HpaeSourceInputNodeType type) +{ + sourceInputNodeType_ = type; +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_source_output_node.cpp b/services/audio_engine/node/src/hpae_source_output_node.cpp new file mode 100644 index 0000000000..db70e96c69 --- /dev/null +++ b/services/audio_engine/node/src/hpae_source_output_node.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2025 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 "HpaeSourceOutputNode" +#endif + +#include +#include "audio_engine_log.h" +#include "hpae_format_convert.h" +#include "audio_utils.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaeSourceOutputNode::HpaeSourceOutputNode(HpaeNodeInfo &nodeInfo) + : HpaeNode(nodeInfo), + sourceOuputData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), + interleveData_(nodeInfo.frameLen * nodeInfo.channels) +{ +#ifdef ENABLE_HOOK_PCM + outputPcmDumper_ = std::make_unique( + "HpaeSourceOutputNode_id_" + std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) + + "_rate_" + std::to_string(GetSampleRate()) + "_bit_" + std::to_string(GetBitWidth()) + ".pcm"); +#endif +} + +void HpaeSourceOutputNode::DoProcess() +{ + auto rate = "rate[" + std::to_string(GetSampleRate()) + "]_"; + auto ch = "ch[" + std::to_string(GetChannelCount()) + "]_"; + auto len = "len[" + std::to_string(GetFrameLen()) + "]_"; + auto format = "bit[" + std::to_string(GetBitWidth()) + "]"; + Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeSourceOutputNode::DoProcess " + + rate + ch + len + format); + if (readCallback_.lock() == nullptr) { + AUDIO_WARNING_LOG("HpaeSourceOutputNode readCallback_ is nullptr"); + return; + } + std::vector &outputVec = inputStream_.ReadPreOutputData(); + if (outputVec.empty()) { + return; + } + HpaePcmBuffer *outputData = outputVec.front(); + ConvertFromFloat( + GetBitWidth(), GetChannelCount() * GetFrameLen(), outputData->GetPcmDataBuffer(), sourceOuputData_.data()); +#ifdef ENABLE_HOOK_PCM + if (outputPcmDumper_) { + outputPcmDumper_->Dump( + (int8_t *)sourceOuputData_.data(), GetChannelCount() * GetFrameLen() * GET_SIZE_FROM_FORMAT(GetBitWidth())); + } +#endif + int32_t ret = readCallback_.lock()->OnReadData(sourceOuputData_, sourceOuputData_.size()); + if (ret != 0) { + AUDIO_WARNING_LOG("sessionId %{public}u, readCallback_ write read data error", GetSessionId()); + } + return; +} + +bool HpaeSourceOutputNode::Reset() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + inputStream_.DisConnect(output); + } + return true; +} + +bool HpaeSourceOutputNode::ResetAll() +{ + const auto preOutputMap = inputStream_.GetPreOuputMap(); + for (const auto &preOutput : preOutputMap) { + OutputPort *output = preOutput.first; + std::shared_ptr hpaeNode = preOutput.second; + if (hpaeNode->ResetAll()) { + inputStream_.DisConnect(output); + } + } + return true; +} + +bool HpaeSourceOutputNode::RegisterReadCallback(const std::weak_ptr &callback) +{ + if (callback.lock() == nullptr) { + return false; + } + readCallback_ = callback; + return true; +} + +void HpaeSourceOutputNode::Connect(const std::shared_ptr> &preNode) +{ + inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); +} + +void HpaeSourceOutputNode::ConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) +{ + std::shared_ptr realPreNode = preNode->GetSharedInstance(nodeInfo); + inputStream_.Connect(realPreNode, preNode->GetOutputPort(nodeInfo)); +#ifdef ENABLE_HIDUMP_DFX + if (auto callback = GetNodeInfo().statusCallback.lock()) { + callback->OnNotifyDfxNodeInfo( + true, realPreNode->GetNodeId(), GetNodeInfo()); + } +#endif +} + +void HpaeSourceOutputNode::DisConnect(const std::shared_ptr> &preNode) +{ + inputStream_.DisConnect(preNode->GetOutputPort()); +} + +void HpaeSourceOutputNode::DisConnectWithInfo(const std::shared_ptr> &preNode, + HpaeNodeInfo &nodeInfo) +{ + inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true)); +} + + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/node/src/hpae_source_process_cluster.cpp b/services/audio_engine/node/src/hpae_source_process_cluster.cpp new file mode 100644 index 0000000000..26ad3a9fb9 --- /dev/null +++ b/services/audio_engine/node/src/hpae_source_process_cluster.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2025 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 "HpaeSourceProcessCluster" +#endif + +#include "hpae_source_process_cluster.h" +#include "hpae_node_common.h" +#include "audio_engine_log.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +HpaeSourceProcessCluster::HpaeSourceProcessCluster(HpaeNodeInfo& nodeInfo) + : HpaeNode(nodeInfo), captureEffectNode_(std::make_shared(nodeInfo)) +{ + AUDIO_INFO_LOG("Create scene ProcessCluster, sceneType = %{public}u", nodeInfo.sceneType); +} + +HpaeSourceProcessCluster::~HpaeSourceProcessCluster() +{ + Reset(); +} + +void HpaeSourceProcessCluster::DoProcess() +{ +} + +bool HpaeSourceProcessCluster::Reset() +{ + captureEffectNode_->Reset(); + for (auto fmtConverterNode : fmtConverterNodeMap_) { + fmtConverterNode.second->Reset(); + } + return true; +} + +bool HpaeSourceProcessCluster::ResetAll() +{ + return captureEffectNode_->ResetAll(); +} + +std::shared_ptr HpaeSourceProcessCluster::GetSharedInstance() +{ + return captureEffectNode_; +} + +OutputPort *HpaeSourceProcessCluster::GetOutputPort() +{ + return captureEffectNode_->GetOutputPort(); +} + +std::shared_ptr HpaeSourceProcessCluster::GetSharedInstance(HpaeNodeInfo &nodeInfo) +{ + std::string nodeKey = TransHpaeResampleNodeInfoToStringKey(nodeInfo); + HpaeNodeInfo effectNodeInfo; + captureEffectNode_->GetCapturerEffectConfig(effectNodeInfo); + std::string effectNodeKey = TransHpaeResampleNodeInfoToStringKey(effectNodeInfo); + AUDIO_INFO_LOG("sourceoutput nodekey:[%{public}s] effectnodekey:[%{public}s]", + nodeKey.c_str(), effectNodeKey.c_str()); + if (CheckHpaeNodeInfoIsSame(nodeInfo, effectNodeInfo)) { + AUDIO_INFO_LOG("sourceoutputnode nodekey is same as capture effect"); + return captureEffectNode_; + } + if (fmtConverterNodeMap_.find(nodeKey) == fmtConverterNodeMap_.end()) { + fmtConverterNodeMap_[nodeKey] = std::make_shared(effectNodeInfo, nodeInfo); + nodeInfo.nodeName = "HpaeAudioFormatConverterNode"; + nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); + fmtConverterNodeMap_[nodeKey]->SetNodeInfo(nodeInfo); + } + fmtConverterNodeMap_[nodeKey]->Connect(captureEffectNode_); +#ifdef ENABLE_HIDUMP_DFX + if (auto callback = nodeInfo.statusCallback.lock()) { + callback->OnNotifyDfxNodeInfo( + true, captureEffectNode_->GetNodeId(), fmtConverterNodeMap_[nodeKey]->GetNodeInfo()); + } +#endif + return fmtConverterNodeMap_[nodeKey]; +} + +OutputPort *HpaeSourceProcessCluster::GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect) +{ + std::string nodeKey = TransHpaeResampleNodeInfoToStringKey(nodeInfo); + HpaeNodeInfo effectNodeInfo; + captureEffectNode_->GetCapturerEffectConfig(effectNodeInfo); + std::string effectNodeKey = TransHpaeResampleNodeInfoToStringKey(effectNodeInfo); + AUDIO_INFO_LOG("sourceoutput nodekey:[%{public}s] effectnodekey:[%{public}s]", + nodeKey.c_str(), effectNodeKey.c_str()); + if (CheckHpaeNodeInfoIsSame(nodeInfo, effectNodeInfo)) { + AUDIO_INFO_LOG("sourceoutputnode nodekey is same as capture effect"); + return captureEffectNode_->GetOutputPort(); + } + CHECK_AND_RETURN_RET_LOG(fmtConverterNodeMap_.find(nodeKey) != fmtConverterNodeMap_.end(), nullptr, + "HpaeSourceProcessCluster not find the nodeKey = %{public}s", nodeKey.c_str()); + if (isDisConnect && fmtConverterNodeMap_[nodeKey]->GetOutputPortNum() <= 1) { + // disconnect fmtConverterNode->upEffectNode + AUDIO_INFO_LOG("disconnect fmtConverterNode between effectnode[[%{public}s] and sourceoutputnode[%{public}s]", + effectNodeKey.c_str(), nodeKey.c_str()); + fmtConverterNodeMap_[nodeKey]->DisConnect(captureEffectNode_); + } + return fmtConverterNodeMap_[nodeKey]->GetOutputPort(); +} + +void HpaeSourceProcessCluster::Connect(const std::shared_ptr> &preNode) +{ + HpaeNodeInfo effectNodeInfo; + captureEffectNode_->GetCapturerEffectConfig(effectNodeInfo); + captureEffectNode_->ConnectWithInfo(preNode, effectNodeInfo); +} + +void HpaeSourceProcessCluster::DisConnect(const std::shared_ptr> &preNode) +{ + HpaeNodeInfo effectNodeInfo; + captureEffectNode_->GetCapturerEffectConfig(effectNodeInfo); + captureEffectNode_->DisConnectWithInfo(preNode, effectNodeInfo); +} + +void HpaeSourceProcessCluster::ConnectWithInfo(const std::shared_ptr>& preNode, + HpaeNodeInfo &nodeInfo) +{ + captureEffectNode_->ConnectWithInfo(preNode, nodeInfo); +} + +void HpaeSourceProcessCluster::DisConnectWithInfo(const std::shared_ptr>& preNode, + HpaeNodeInfo &nodeInfo) +{ + captureEffectNode_->DisConnectWithInfo(preNode, nodeInfo); +} + +bool HpaeSourceProcessCluster::GetCapturerEffectConfig(HpaeNodeInfo &nodeInfo, HpaeSourceBufferType type) +{ + return captureEffectNode_->GetCapturerEffectConfig(nodeInfo, type); +} + +size_t HpaeSourceProcessCluster::GetOutputPortNum() +{ + return captureEffectNode_->GetOutputPortNum(); +} + +int32_t HpaeSourceProcessCluster::CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr) +{ + CHECK_AND_RETURN_RET_LOG(captureEffectNode_, ERROR_ILLEGAL_STATE, "captureEffectNode_ is nullptr"); + return captureEffectNode_->CaptureEffectCreate(sceneKeyCode, attr); +} + +int32_t HpaeSourceProcessCluster::CaptureEffectRelease(uint64_t sceneKeyCode) +{ + CHECK_AND_RETURN_RET_LOG(captureEffectNode_, ERROR_ILLEGAL_STATE, "captureEffectNode_ is nullptr"); + return captureEffectNode_->CaptureEffectRelease(sceneKeyCode); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.c b/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.c new file mode 100644 index 0000000000..5bebe28106 --- /dev/null +++ b/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include +#include "bitdepth_converter.h" + +#ifndef NULL +#define NULL 0 +#endif + +#define INDEX_TWO 2 +#define INDEX_THREE 3 +#define SHIFTS_8BIT 8 +#define SHIFTS_16BIT 16 +#define SHIFTS_24BIT 24 + +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +static inline uint32_t READ24LE(const uint8_t *p) +{ + return ((uint32_t)p[INDEX_TWO] << SHIFTS_16BIT) | + ((uint32_t)p[1] << SHIFTS_8BIT) | + ((uint32_t)p[0]); +} + +static inline void WRITE24LE(uint8_t *p, uint32_t u) +{ + p[INDEX_TWO] = (uint8_t)(u >> SHIFTS_16BIT); + p[1] = (uint8_t)(u >> SHIFTS_8BIT); + p[0] = (uint8_t)u; +} + +// SAMPLE_U8 +// U8ToS16Le +static void U8ToS16Le(unsigned n, const uint8_t* a, int16_t* b) +{ + for (; n > 0; n--, a++, b++) { + *b = (int16_t)(*a - (uint8_t)0x80U) << SHIFTS_8BIT; + } +} +// U8ToS24Le +static void U8ToS24Le(unsigned n, const uint8_t* a, uint8_t* b) +{ + for (; n > 0; n--) { + WRITE24LE(b, (uint32_t)(*a - (uint8_t)0x80U) << SHIFTS_16BIT); + a++; + b += INDEX_THREE; + } +} +// U8ToS32Le +static void U8ToS32Le(unsigned n, const uint8_t* a, int32_t* b) +{ + for (; n > 0; n--, a++, b++) { + *b = (int32_t)(*a - (uint8_t)0x80U) << SHIFTS_24BIT; + } +} +// U8ToF32Le +static void U8ToF32Le(unsigned n, const uint8_t* a, float* b) +{ + for (; n > 0; n--, a++, b++) { + *b = (float)(*a - (uint8_t)0x80U) * (1.0 / 0x80U); + } +} + +// SAMPLE_S16LE +// S16LeToU8 +static void S16LeToU8(unsigned n, const int16_t* a, uint8_t* b) +{ + for (; n > 0; n--, a++, b++) { + *b = (uint8_t)((uint16_t)(*a) >> SHIFTS_8BIT) + (uint8_t)0x80U; + } +} +// S16LeToS24Le +static void S16LeToS24Le(unsigned n, const int16_t* a, uint8_t* b) +{ + for (; n > 0; n--) { + WRITE24LE(b, ((uint32_t)*a) << SHIFTS_8BIT); + a++; + b += INDEX_THREE; + } +} +// S16LeToS32Le +static void S16LeToS32Le(unsigned n, const int16_t* a, int32_t* b) +{ + for (; n > 0; n--, a++, b++) { + *b = ((int32_t)*a) << SHIFTS_16BIT; + } +} +// S16LeToF32Le +static void S16LeToF32Le(unsigned n, const int16_t* a, float* b) +{ + for (; n > 0; n--) { + *(b++) = *(a++) * (1.0f / (1 << 0x0F)); + } +} + +// SAMPLE_S24LE +// S24LeToU8 +static void S24LeToU8(unsigned n, const uint8_t* a, uint8_t* b) +{ + for (; n > 0; n--) { + *b = (uint8_t)(READ24LE(a) >> SHIFTS_16BIT) + (uint8_t)0x80U; + a += INDEX_THREE; + b++; + } +} +// S24LeToS16Le +static void S24LeToS16Le(unsigned n, const uint8_t* a, int16_t* b) +{ + for (; n > 0; n--) { + *b = (int16_t)(READ24LE(a) >> SHIFTS_8BIT); + a += INDEX_THREE; + b++; + } +} +// S24LeToS32Le +static void S24LeToS32Le(unsigned n, const uint8_t* a, int32_t* b) +{ + for (; n > 0; n--) { + *b = (int32_t)(READ24LE(a) << SHIFTS_8BIT); + a += INDEX_THREE; + b++; + } +} +// S24LeToF32Le +static void S24LeToF32Le(unsigned n, const uint8_t* a, float* b) +{ + for (; n > 0; n--) { + int32_t s = (int32_t)READ24LE(a) << SHIFTS_8BIT; + *b = s * (1.0f / (1U << 0x1F)); + a += INDEX_THREE; + b++; + } +} + +// SAMPLE_S32LE +// S32LeToU8 +static void S32LeToU8(unsigned n, const int32_t* a, uint8_t* b) +{ + for (; n > 0; n--, a++, b++) { + *b = (uint8_t)((int32_t)(*a) >> SHIFTS_24BIT) + (uint8_t)0x80U; + } +} +// S32LeToS16Le +static void S32LeToS16Le(unsigned n, const int32_t* a, int16_t* b) +{ + for (; n > 0; n--, a++, b++) { + *b = (int16_t)((int32_t)(*a) >> SHIFTS_16BIT); + } +} +// S32LeToS24Le +static void S32LeToS24Le(unsigned n, const int32_t* a, uint8_t* b) +{ + for (; n > 0; n--) { + WRITE24LE(b, ((uint32_t)*a) >> SHIFTS_8BIT); + a++; + b += INDEX_THREE; + } +} +// S32LeToF32Le +static void S32LeToF32Le(unsigned n, const int32_t* a, float* b) +{ + for (; n > 0; n--) { + *(b++) = *(a++) * (1.0f / (1U << 0x1F)); + } +} + +// SAMPLE_F32LE +// F32LeToU8 +static void F32LeToU8(unsigned n, const float* a, uint8_t* b) +{ + for (; n > 0; n--) { + float v = *(a++); + *(b++) = (uint8_t)(CLAMP(v, -1.0, 1.0) * 127.0f + 128.0f); + } +} +// F32LeToS16Le +static void F32LeToS16Le(unsigned n, const float* a, int16_t* b) +{ + for (; n > 0; n--) { + float v = *(a++) * (1 << 15); + *(b++) = (int16_t)CLAMP((int32_t)v, -0x8000, 0x7FFF); + } +} +// F32LeToS24Le +static void F32LeToS24Le(unsigned n, const float* a, uint8_t* b) +{ + for (; n > 0; n--) { + float v = *(a++) * (1 << 23); + WRITE24LE(b, (uint32_t)CLAMP((int32_t)v, -0x800000LL, 0x7FFFFFLL)); + b += INDEX_THREE; + } +} +// F32LeToS32Le +static void F32LeToS32Le(unsigned n, const float* a, int32_t* b) +{ + for (; n > 0; n--) { + float v = *(a++) * (1U << 31); + *(b++) = (int32_t)CLAMP((int64_t)v, -0x80000000LL, 0x7FFFFFFFLL); + } +} + +// function table +static FmtConversionFunction sample_u8_table[] = { + [SAMPLE_S16LE] = (FmtConversionFunction)S16LeToU8, + [SAMPLE_S24LE] = (FmtConversionFunction)S24LeToU8, + [SAMPLE_S32LE] = (FmtConversionFunction)S32LeToU8, + [SAMPLE_F32LE] = (FmtConversionFunction)F32LeToU8, +}; + +static FmtConversionFunction sample_s16le_table[] = { + [SAMPLE_U8] = (FmtConversionFunction)U8ToS16Le, + [SAMPLE_S24LE] = (FmtConversionFunction)S24LeToS16Le, + [SAMPLE_S32LE] = (FmtConversionFunction)S32LeToS16Le, + [SAMPLE_F32LE] = (FmtConversionFunction)F32LeToS16Le, +}; + +static FmtConversionFunction sample_s24le_table[] = { + [SAMPLE_U8] = (FmtConversionFunction)U8ToS24Le, + [SAMPLE_S16LE] = (FmtConversionFunction)S16LeToS24Le, + [SAMPLE_S32LE] = (FmtConversionFunction)S32LeToS24Le, + [SAMPLE_F32LE] = (FmtConversionFunction)F32LeToS24Le, +}; + +static FmtConversionFunction sample_s32le_table[] = { + [SAMPLE_U8] = (FmtConversionFunction)U8ToS32Le, + [SAMPLE_S16LE] = (FmtConversionFunction)S16LeToS32Le, + [SAMPLE_S24LE] = (FmtConversionFunction)S24LeToS32Le, + [SAMPLE_F32LE] = (FmtConversionFunction)F32LeToS32Le, +}; + +static FmtConversionFunction sample_f32le_table[] = { + [SAMPLE_U8] = (FmtConversionFunction)U8ToF32Le, + [SAMPLE_S16LE] = (FmtConversionFunction)S16LeToF32Le, + [SAMPLE_S24LE] = (FmtConversionFunction)S24LeToF32Le, + [SAMPLE_S32LE] = (FmtConversionFunction)S32LeToF32Le, +}; + +// choose function from function table +FmtConversionFunction GetFmtConversionU8(audio_sample_format_t fmt) +{ + return sample_u8_table[fmt]; +} + +FmtConversionFunction GetFmtConversionS16Le(audio_sample_format_t fmt) +{ + return sample_s16le_table[fmt]; +} + +FmtConversionFunction GetFmtConversionS24Le(audio_sample_format_t fmt) +{ + return sample_s24le_table[fmt]; +} + +FmtConversionFunction GetFmtConversionS32Le(audio_sample_format_t fmt) +{ + return sample_s32le_table[fmt]; +} + +FmtConversionFunction GetFmtConversionF32Le(audio_sample_format_t fmt) +{ + return sample_f32le_table[fmt]; +} + +// BitDepthConversion implementation +BitDepthConversionState* FmtConversionInit(uint32_t inputFormat, uint32_t outputFormat, + uint32_t numChannels, int* err) +{ + BitDepthConversionState* state; + + if (numChannels == 0 || inputFormat == outputFormat) { + if (err) { + *err = FMTCONV_ERR_INVALID_ARG; + } + return NULL; + } + state = (BitDepthConversionState*)calloc(sizeof(BitDepthConversionState), 1); + if (!state) { + if (err) { + *err = FMTCONV_ERR_ALLOC_FAILED; + } + return NULL; + } + state->inputFormat = inputFormat; + state->outputFormat = outputFormat; + state->numChannels = numChannels; + + if (inputFormat != outputFormat) { + switch (outputFormat) { + case SAMPLE_U8: + state->fmtConversionProcess = GetFmtConversionU8(inputFormat); + break; + case SAMPLE_S16LE: + state->fmtConversionProcess = GetFmtConversionS16Le(inputFormat); + break; + case SAMPLE_S24LE: + state->fmtConversionProcess = GetFmtConversionS24Le(inputFormat); + break; + case SAMPLE_S32LE: + state->fmtConversionProcess = GetFmtConversionS32Le(inputFormat); + break; + case SAMPLE_F32LE: + default: + state->fmtConversionProcess = GetFmtConversionF32Le(inputFormat); + break; + } + } + + return state; +} +void FmtConversionStateFree(BitDepthConversionState* state) +{ + free(state); + state = NULL; +} \ No newline at end of file diff --git a/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.h b/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.h new file mode 100644 index 0000000000..217fb25d7e --- /dev/null +++ b/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 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 BITDEPTH_CONVERTER_H +#define BITDEPTH_CONVERTER_H +#include + +#ifdef __cplusplus +extern "C" { +#endif + enum { + FMTCONV_ERR_SUCCESS = 0, + FMTCONV_ERR_ALLOC_FAILED = 1, + FMTCONV_ERR_INVALID_ARG = 2 + }; + + /** Audio sample format */ + typedef enum audio_sample_format { + SAMPLE_U8 = 0, + SAMPLE_S16LE = 1, + SAMPLE_S24LE = 2, + SAMPLE_S32LE = 3, + SAMPLE_F32LE = 4, + INVALID_WIDTH = -1 + } audio_sample_format_t; + + + typedef void (*FmtConversionFunction)(unsigned n, const void* in, const void* out); + + FmtConversionFunction GetFmtConversionU8(audio_sample_format_t fmt); + FmtConversionFunction GetFmtConversionS16Le(audio_sample_format_t fmt); + FmtConversionFunction GetFmtConversionS24Le(audio_sample_format_t fmt); + FmtConversionFunction GetFmtConversionS32Le(audio_sample_format_t fmt); + FmtConversionFunction GetFmtConversionF32Le(audio_sample_format_t fmt); + + typedef struct BitDepthConversionState BitDepthConversionState; + + struct BitDepthConversionState { + uint32_t inputFormat; + uint32_t outputFormat; + uint32_t numChannels; + uint32_t length; + + FmtConversionFunction fmtConversionProcess; + }; + + BitDepthConversionState* FmtConversionInit(uint32_t inputFormat, uint32_t outputFormat, + uint32_t numChannels, int* err); + + void FmtConversionStateFree(BitDepthConversionState* state); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/channel_converter/include/channel_converter.h b/services/audio_engine/plugin/channel_converter/include/channel_converter.h new file mode 100644 index 0000000000..9b3089ac45 --- /dev/null +++ b/services/audio_engine/plugin/channel_converter/include/channel_converter.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 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 CHANNEL_CONVERTER_H +#define CHANNEL_CONVERTER_H + +#include "down_mixer.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +class ChannelConverter { +public: + ChannelConverter() = default; + int32_t Process(uint32_t framesize, float* in, uint32_t inLen, float* out, uint32_t outLen); + // input and output stream format must be workFormat + int32_t SetParam(AudioChannelInfo inChannelInfo, AudioChannelInfo outChannelInfo, + AudioSampleFormat workFormat, bool mixLfe); + AudioChannelInfo GetInChannelInfo() const; + AudioChannelInfo GetOutChannelInfo() const; + int32_t SetInChannelInfo(AudioChannelInfo inChannelInfo); + int32_t SetOutChannelInfo(AudioChannelInfo outChannelInfo); + void Reset(); +private: + int32_t Upmix(uint32_t frameSize, float* in, uint32_t inLen, float* out, uint32_t outLen); + DownMixer downMixer_; + AudioChannelInfo inChannelInfo_; + AudioChannelInfo outChannelInfo_; + AudioSampleFormat workFormat_ = INVALID_WIDTH; // work format, for now only supports float + uint32_t workSize_ = 0; // work format, for now only supports float + bool mixLfe_ = true; +}; +} // HPAE +} // AudioStandard +} // OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/channel_converter/include/down_mixer.h b/services/audio_engine/plugin/channel_converter/include/down_mixer.h new file mode 100644 index 0000000000..63c13350f5 --- /dev/null +++ b/services/audio_engine/plugin/channel_converter/include/down_mixer.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2025 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 DOWN_MIXER_H +#define DOWN_MIXER_H +#include +#include "audio_stream_info.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr uint32_t MAX_CHANNELS = 16; + +constexpr float COEF_ZERO_F = 0.0f; +constexpr float COEF_0DB_F = 1.0f; +constexpr float COEF_M3DB_F = 0.7071f; +constexpr float COEF_M6DB_F = 0.5f; +constexpr float COEF_M435DB_F = 0.6057f; +constexpr float COEF_M45DB_F = 0.5946f; +constexpr float COEF_M9DB_F = 0.3544f; +constexpr float COEF_M899DB_F = 0.3552f; +constexpr float COEF_M12DB_F = 0.2509f; + +enum { + DMIX_ERR_SUCCESS = 0, + DMIX_ERR_ALLOC_FAILED = -1, + DMIX_ERR_INVALID_ARG = -2 +}; + +class DownMixer { +public: + DownMixer(); + int32_t Process(uint32_t framesize, float* in, uint32_t inLen, float* out, uint32_t outLen); + + int32_t SetParam(AudioChannelInfo inChannelInfo_, AudioChannelInfo outChannelInfo_, + uint32_t formatSize, bool mixLfe); + void Reset(); +private: + AudioChannelLayout inLayout_ = CH_LAYOUT_UNKNOWN; + uint32_t inChannels_ = 0; + AudioChannelLayout outLayout_ = CH_LAYOUT_UNKNOWN; + uint32_t outChannels_ = 0; + uint32_t formatSize_ = INVALID_WIDTH; // work format, for now only supports float + std::vector> downMixTable_; + bool mixLfe_ = true; + bool isInitialized_ = false; + void SetupStereoDmixTable(); + void Setup5Point1DmixTable(); + void Setup5Point1Point2DmixTable(); + void Setup5Point1Point4DmixTable(); + void Setup7Point1DmixTable(); + void Setup7Point1Point2DmixTable(); + void Setup7Point1Point4DmixTable(); + void SetupGeneralDmixTable(); + void ResetSelf(); + int32_t SetupDownMixTable(); + /**** helper functions for settiing up specific downmix table ***/ + void SetupStereoDmixTablePart1(uint64_t bit_t, uint32_t i); + void SetupStereoDmixTablePart2(uint64_t bit_t, uint32_t i); + void Setup5Point1DmixTablePart1(uint64_t bit_t, uint32_t i); + void Setup5Point1DmixTablePart2(uint64_t bit_t, uint32_t i); + void Setup5Point1Point2DmixTablePart1(uint64_t bit_t, uint32_t i); + void Setup5Point1Point2DmixTablePart2(uint64_t bit_t, uint32_t i); + void Setup5Point1Point4DmixTablePart1(uint64_t bit_t, uint32_t i); + void Setup5Point1Point4DmixTablePart2(uint64_t bit_t, uint32_t i); + void Setup7Point1DmixTablePart1(uint64_t bit_t, uint32_t i); + void Setup7Point1DmixTablePart2(uint64_t bit_t, uint32_t i); + void Setup7Point1Point2DmixTablePart1(uint64_t bit_t, uint32_t i); + void Setup7Point1Point2DmixTablePart2(uint64_t bit_t, uint32_t i); + void Setup7Point1Point4DmixTablePart1(uint64_t bit_t, uint32_t i); + void Setup7Point1Point4DmixTablePart2(uint64_t bit_t, uint32_t i); + /**** helper functions for setting up general downmix table ***/ + void DownMixBottom(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); + void DownMixLfe(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); + void DownMixMidFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); + void DownMixMidRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); + void DownMixTopCenter(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); + void DownMixTopFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); + void DownMixTopRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); + void NormalizeDMixTable(); +}; +} // HPAE +} // AudioStandard +} // OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/channel_converter/src/channel_converter.cpp b/services/audio_engine/plugin/channel_converter/src/channel_converter.cpp new file mode 100644 index 0000000000..0ebfa15c82 --- /dev/null +++ b/services/audio_engine/plugin/channel_converter/src/channel_converter.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2025 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 "HpaeChannelConverter" +#endif +#include "channel_converter.h" +#include "audio_engine_log.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +static inline uint32_t Min(uint32_t a, uint32_t b) +{ + return a < b ? a : b; +} + +static inline uint32_t GetFormatSize(AudioSampleFormat format) +{ + uint32_t sampleSize = 0; + switch (format) { + case SAMPLE_U8: + sampleSize = sizeof(uint8_t); + break; + case SAMPLE_S16LE: + sampleSize = sizeof(int16_t); + break; + case SAMPLE_S24LE: + sampleSize = SAMPLE_S24LE + 1; + break; + case SAMPLE_S32LE: + sampleSize = sizeof(int32_t); + break; + case SAMPLE_F32LE: + sampleSize = sizeof(float); + break; + default: + AUDIO_ERR_LOG("unsupported format %{public}d", format); + } + return sampleSize; +} + +int32_t ChannelConverter::SetParam(AudioChannelInfo inChannelInfo, AudioChannelInfo outChannelInfo, + AudioSampleFormat format, bool mixLfe) +{ + inChannelInfo_.channelLayout = inChannelInfo.channelLayout; + outChannelInfo_.channelLayout = outChannelInfo.channelLayout; + inChannelInfo_.numChannels = inChannelInfo.numChannels; + outChannelInfo_.numChannels = outChannelInfo.numChannels; + workFormat_ = format; + workSize_ = GetFormatSize(format); + mixLfe_ = mixLfe; + int32_t ret = DMIX_ERR_SUCCESS; + if (inChannelInfo_.numChannels > outChannelInfo_.numChannels) { + ret = downMixer_.SetParam(inChannelInfo, outChannelInfo, workSize_, mixLfe); + } + return ret; +} + +int32_t ChannelConverter::SetInChannelInfo(AudioChannelInfo inChannelInfo) +{ + inChannelInfo_.channelLayout = inChannelInfo.channelLayout; + inChannelInfo_.numChannels = inChannelInfo.numChannels; + if (inChannelInfo_.numChannels > outChannelInfo_.numChannels) { + return downMixer_.SetParam(inChannelInfo_, outChannelInfo_, workSize_, mixLfe_); + } + return DMIX_ERR_SUCCESS; +} + + +int32_t ChannelConverter::SetOutChannelInfo(AudioChannelInfo outChannelInfo) +{ + outChannelInfo_.channelLayout = outChannelInfo.channelLayout; + outChannelInfo_.numChannels = outChannelInfo.numChannels; + if (inChannelInfo_.numChannels > outChannelInfo_.numChannels) { + return downMixer_.SetParam(inChannelInfo_, outChannelInfo_, workSize_, mixLfe_); + } + return DMIX_ERR_SUCCESS; +} + +AudioChannelInfo ChannelConverter::GetInChannelInfo() const +{ + return inChannelInfo_; +} + +AudioChannelInfo ChannelConverter::GetOutChannelInfo() const +{ + return outChannelInfo_; +} + +int32_t ChannelConverter::Process(uint32_t frameSize, float* in, uint32_t inLen, float* out, uint32_t outLen) +{ + if ((in == nullptr) || (out == nullptr) || frameSize <= 0 || inLen <= 0 || outLen <= 0) { + return DMIX_ERR_ALLOC_FAILED; + } + if (inChannelInfo_.numChannels < outChannelInfo_.numChannels) { + return Upmix(frameSize, in, inLen, out, outLen); + } + return downMixer_.Process(frameSize, in, inLen, out, outLen); +} + +void ChannelConverter::Reset() +{ + downMixer_.Reset(); +} + +int32_t ChannelConverter::Upmix(uint32_t frameSize, float* in, uint32_t inLen, float* out, uint32_t outLen) +{ + uint32_t expectInLen = frameSize * inChannelInfo_.numChannels * workSize_; // to be added size of other formats + uint32_t expectOutLen = frameSize * outChannelInfo_.numChannels * workSize_; + if ((expectInLen > inLen) || (expectOutLen > outLen)) { + AUDIO_ERR_LOG("expect Input Len: %{public}d, inLen: %{public}d," + "expected output len: %{public}d, outLen %{public}d", + expectInLen, inLen, expectOutLen, outLen); + return DMIX_ERR_ALLOC_FAILED; + } + for (uint32_t i = 0; i < frameSize; ++i) { + for (uint32_t ch = 0; ch < outChannelInfo_.numChannels; ++ch) { + uint32_t leftChIndex = Min(ch, inChannelInfo_.numChannels - 1); + out[i * outChannelInfo_.numChannels + ch] = in[i * inChannelInfo_.numChannels + leftChIndex]; + } + } + return DMIX_ERR_SUCCESS; +} + +} // HPAE +} // AudioStandard +} // OHOS \ No newline at end of file diff --git a/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp b/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp new file mode 100644 index 0000000000..b49c882ade --- /dev/null +++ b/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp @@ -0,0 +1,1087 @@ +/* + * Copyright (c) 2025 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 "HpaeDownMixer" +#endif +#include +#include "securec.h" +#include "audio_engine_log.h" +#include "down_mixer.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +// Initial output channel index +enum OutChannelIndex : uint32_t { + FL = 0, + FR, + FC, + SW, +// Back channel should be placed before side channel + BL, + BR +}; + +static uint32_t SL = 6; +static uint32_t SR = 7; +static uint32_t TFL = 8; +static uint32_t TFR = 9; +static uint32_t TBL = 10; +static uint32_t TBR = 11; +static uint32_t TSL = 12; +static uint32_t TSR = 13; + +static constexpr uint32_t INDEX_SIX = 6; +static constexpr uint32_t INDEX_SEVEN = 7; +static constexpr uint32_t INDEX_EIGHT = 8; +static constexpr uint32_t INDEX_NINE = 9; +static constexpr uint32_t INDEX_TEN = 10; +static constexpr uint32_t INDEX_ELEVEN = 11; + +// channel masks for downmixing general output channel layout +static constexpr uint64_t MASK_MIDDLE_FRONT = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | +FRONT_LEFT_OF_CENTER | FRONT_RIGHT_OF_CENTER | WIDE_LEFT | WIDE_RIGHT; + +static constexpr uint64_t MASK_MIDDLE_REAR = BACK_LEFT | BACK_RIGHT | BACK_CENTER +| SIDE_LEFT +| SIDE_RIGHT; + +static constexpr uint64_t MASK_TOP_FRONT = TOP_FRONT_LEFT +| TOP_FRONT_CENTER +| TOP_FRONT_RIGHT; + +static constexpr uint64_t MASK_TOP_REAR = TOP_CENTER +| TOP_BACK_LEFT +| TOP_BACK_CENTER +| TOP_BACK_RIGHT +| TOP_SIDE_LEFT +| TOP_SIDE_RIGHT; + +static constexpr uint64_t MASK_BOTTOM = BOTTOM_FRONT_CENTER +| BOTTOM_FRONT_LEFT +| BOTTOM_FRONT_RIGHT; + +static constexpr uint64_t MASK_LFE = LOW_FREQUENCY +| LOW_FREQUENCY_2; + +static uint32_t bitCounts(uint64_t bits); +static bool isValidChLayout(AudioChannelLayout &chLayout, uint32_t chCounts); +static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels); + +// 改成默认构造 +DownMixer::DownMixer() +{ + downMixTable_.resize(MAX_CHANNELS, std::vector(MAX_CHANNELS, 0)); +} + +// setParam +int32_t DownMixer::SetParam(AudioChannelInfo inChannelInfo, AudioChannelInfo outChannelInfo, + uint32_t formatSize, bool mixLfe) +{ + ResetSelf(); + inLayout_ = inChannelInfo.channelLayout; + outLayout_ = outChannelInfo.channelLayout; + inChannels_ = inChannelInfo.numChannels; + outChannels_ = outChannelInfo.numChannels; + mixLfe_ = mixLfe; + + formatSize_ = formatSize; + int32_t ret = SetupDownMixTable(); + if (ret == DMIX_ERR_SUCCESS) { + isInitialized_ = true; + } + return ret; +} + +int32_t DownMixer::Process(uint32_t frameLen, float* in, uint32_t inLen, float* out, uint32_t outLen) +{ + if ((in == nullptr) || (out == nullptr) || frameLen <= 0) { + AUDIO_ERR_LOG("invalid input params for downmix process, frameLen %{public}d", frameLen); + return DMIX_ERR_ALLOC_FAILED; + } + if (!isInitialized_) { + AUDIO_DEBUG_LOG("Downmixe table has not been initialized!"); + return DMIX_ERR_ALLOC_FAILED; + } + uint32_t expectInLen = frameLen * inChannels_ * formatSize_; + uint32_t expectOutLen = frameLen * outChannels_ * formatSize_; + if ((expectInLen > inLen) || (expectOutLen > outLen)) { + memcpy_s(out, outLen, in, inLen); + AUDIO_ERR_LOG("expect Input Len: %{public}d, inLen: %{public}d," + "expected output len: %{public}d, outLen %{public}d", + expectInLen, inLen, expectOutLen, outLen); + return DMIX_ERR_ALLOC_FAILED; + } + AUDIO_DEBUG_LOG("Downmixing: frameLen: %{public}d,", frameLen); + float a; + for (; frameLen > 0; frameLen--) { + for (uint32_t i = 0; i < outChannels_; i++) { + a = 0.0f; + for (uint32_t j = 0; j < inChannels_; j++) { + a += in[j] * downMixTable_[i][j]; + } + *(out++) = a; + } + in += inChannels_; + } + return DMIX_ERR_SUCCESS; +} + +int32_t DownMixer::SetupDownMixTable() +{ + if ((!isValidChLayout(inLayout_, inChannels_)) || (!isValidChLayout(outLayout_, outChannels_)) + || inLayout_ == outLayout_ || inChannels_ <= outChannels_) { + AUDIO_ERR_LOG("invalid input or output channellayout: input channel count %{public}d, " + "inLayout_ %{public}lu. output channel count %{public}d, outLayout_ %{public}lu", + inChannels_, inLayout_, outChannels_, outLayout_); + return DMIX_ERR_INVALID_ARG; + } + switch (outLayout_) { + case CH_LAYOUT_STEREO: { + SetupStereoDmixTable(); + break; + } + case CH_LAYOUT_5POINT1: { + Setup5Point1DmixTable(); + break; + } + case CH_LAYOUT_5POINT1POINT2: { + Setup5Point1Point2DmixTable(); + break; + } + case CH_LAYOUT_5POINT1POINT4: { + Setup5Point1Point4DmixTable(); + break; + } + case CH_LAYOUT_7POINT1: { + Setup7Point1DmixTable(); + break; + } + case CH_LAYOUT_7POINT1POINT2: { + Setup7Point1Point2DmixTable(); + break; + } + case CH_LAYOUT_7POINT1POINT4: { + Setup7Point1Point4DmixTable(); + break; + } + default: { + SetupGeneralDmixTable(); + break; + } + } + NormalizeDMixTable(); + AUDIO_INFO_LOG("setup downmix table success!"); + isInitialized_ = true; + return DMIX_ERR_SUCCESS; +} + +void DownMixer::NormalizeDMixTable() +{ + float maxx = 0.0f; + for (uint32_t i = 0; i < outChannels_; i++) { + float summ = 0.0f; + for (uint32_t j = 0; j < inChannels_; j++) { + summ += downMixTable_[i][j]; + } + maxx = std::max(maxx, summ); + } + maxx = 1.0f / maxx; + for (uint32_t i = 0; i < outChannels_; i++) { + for (uint32_t j = 0; j < inChannels_; j++) { + downMixTable_[i][j] *= maxx; + } + } +} + +void DownMixer::ResetSelf() +{ + isInitialized_ = false; + inChannels_ = 0; + outChannels_ = 0; + inLayout_ = CH_LAYOUT_UNKNOWN; + outLayout_ = CH_LAYOUT_UNKNOWN; + for (auto &row : downMixTable_) { + std::fill(row.begin(), row.end(), 0.0f); + } +} + +void DownMixer::Reset() +{ + ResetSelf(); +} + +void DownMixer::SetupStereoDmixTable() +{ + uint64_t inChMsk = inLayout_; + for (uint32_t i = 0; i < inChannels_; i++) { + uint64_t bit = inChMsk & -(int64_t)inChMsk; + downMixTable_[FL][i] = 0.f; + downMixTable_[FR][i] = 0.f; + SetupStereoDmixTablePart1(bit, i); + SetupStereoDmixTablePart2(bit, i); + inChMsk ^= bit; + } +} + +void DownMixer::Setup5Point1DmixTable() +{ + uint64_t inChMsk = inLayout_; + for (uint32_t i = 0; i < inChannels_; i++) { + downMixTable_[FL][i] = 0.f; + downMixTable_[FR][i] = 0.f; + downMixTable_[FC][i] = 0.f; + downMixTable_[SW][i] = 0.f; + downMixTable_[BL][i] = 0.f; + downMixTable_[BR][i] = 0.f; + uint64_t bit = inChMsk & -(int64_t)inChMsk; + Setup5Point1DmixTablePart1(bit, i); + Setup5Point1DmixTablePart2(bit, i); + inChMsk ^= bit; + } +} +void DownMixer::Setup5Point1Point2DmixTable() +{ + TSL = INDEX_SIX; + TSR = INDEX_SEVEN; + uint64_t inChMsk = inLayout_; + for (unsigned i = 0; i < inChannels_; i++) { + uint64_t bit = inChMsk & -(int64_t)inChMsk; + downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; + downMixTable_[SW][i] = downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; + downMixTable_[TSL][i] = downMixTable_[TSR][i] = 0.f; + Setup5Point1Point2DmixTablePart1(bit, i); + Setup5Point1Point2DmixTablePart2(bit, i); + inChMsk ^= bit; + } +} +void DownMixer::Setup5Point1Point4DmixTable() +{ + TFL = INDEX_SIX; + TFR = INDEX_SEVEN; + TBL = INDEX_EIGHT; + TBR = INDEX_NINE; + uint64_t inChMsk = inLayout_; + for (unsigned i = 0; i < inChannels_; i++) { + uint64_t bit = inChMsk & -(int64_t)inChMsk; + downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; + downMixTable_[SW][i] = downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; + downMixTable_[TFL][i] = downMixTable_[TFR][i] = 0.f; + downMixTable_[TBL][i] = downMixTable_[TBR][i] = 0.f; + Setup5Point1Point4DmixTablePart1(bit, i); + Setup5Point1Point4DmixTablePart2(bit, i); + inChMsk ^= bit; + } +} +void DownMixer::Setup7Point1DmixTable() +{ + SL = INDEX_SIX; + SR = INDEX_SEVEN; + uint64_t inChMsk = inLayout_; + for (unsigned i = 0; i < inChannels_; i++) { + uint64_t bit = inChMsk & -(int64_t)inChMsk; + downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; + downMixTable_[SW][i] = downMixTable_[SL][i] = downMixTable_[SR][i] = 0.f; + downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; + Setup7Point1DmixTablePart1(bit, i); + Setup7Point1DmixTablePart2(bit, i); + inChMsk ^= bit; + } +} +void DownMixer::Setup7Point1Point2DmixTable() +{ + SL = INDEX_SIX; + SR = INDEX_SEVEN; + TSL = INDEX_EIGHT; + TSR = INDEX_NINE; + uint64_t inChMsk = inLayout_; + for (unsigned i = 0; i < inChannels_; i++) { + uint64_t bit = inChMsk & -(int64_t)inChMsk; + downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; + downMixTable_[SW][i] = downMixTable_[SL][i] = downMixTable_[SR][i] = 0.f; + downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; + downMixTable_[TSL][i] = downMixTable_[TSR][i] = 0.f; + Setup7Point1Point2DmixTablePart1(bit, i); + Setup7Point1Point2DmixTablePart2(bit, i); + inChMsk ^= bit; + } +} +void DownMixer::Setup7Point1Point4DmixTable() +{ + SL = INDEX_SIX; + SR = INDEX_SEVEN; + TFL = INDEX_EIGHT; + TFR = INDEX_NINE; + TBL = INDEX_TEN; + TBR = INDEX_ELEVEN; + uint64_t inChMsk = inLayout_; + for (unsigned i = 0; i < inChannels_; i++) { + uint64_t bit = inChMsk & -(int64_t)inChMsk; + downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; + downMixTable_[SW][i] = downMixTable_[SL][i] = downMixTable_[SR][i] = 0.f; + downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; + downMixTable_[TFL][i] = downMixTable_[TFR][i] = 0.f; + downMixTable_[TBL][i] = downMixTable_[TBR][i] = 0.f; + Setup7Point1Point4DmixTablePart1(bit, i); + Setup7Point1Point4DmixTablePart2(bit, i); + inChMsk ^= bit; + } +} + +void DownMixer::SetupGeneralDmixTable() +{ + // MONO + if (outLayout_ == CH_LAYOUT_MONO) { + for (uint32_t i = 0; i < inChannels_; i++) { + downMixTable_[0][i] = COEF_0DB_F; + } + } + // check invalid output musk later in init() + uint64_t outChMsk = outLayout_; + + for (uint32_t i = 0; i < outChannels_; i++) { + uint64_t outBit = outChMsk & -(int64_t)outChMsk; + uint64_t inChMsk = inLayout_; + for (uint32_t j = 0; j < inChannels_; j++) { + uint64_t inBit = inChMsk & -(int64_t)inChMsk; + if (inBit & outBit) { // if in channel and out channel is the same + downMixTable_[i][j] = COEF_0DB_F; + } else if (inBit == TOP_CENTER) { + // check general downmix table! + DownMixTopCenter(inBit, outBit, i, j); + } else if ((inBit & MASK_MIDDLE_FRONT) != 0) { + DownMixMidFront(inBit, outBit, i, j); + } else if ((inBit & MASK_MIDDLE_REAR) != 0) { + DownMixMidRear(inBit, outBit, i, j); + } else if ((inBit & MASK_BOTTOM) != 0) { + DownMixBottom(inBit, outBit, i, j); + } else if ((inBit & MASK_LFE) != 0) { + DownMixLfe(inBit, outBit, i, j); + } else if ((inBit & MASK_TOP_FRONT) != 0) { + DownMixTopFront(inBit, outBit, i, j); + } else if ((inBit & MASK_TOP_REAR) != 0) { + DownMixTopRear(inBit, outBit, i, j); + } + inChMsk ^= inBit; + } + outChMsk ^= outBit; + } +} + +void DownMixer::SetupStereoDmixTablePart1(uint64_t bit, uint32_t i) +{ + switch (bit) { + case FRONT_LEFT: + case TOP_FRONT_LEFT: + case BOTTOM_FRONT_LEFT: + downMixTable_[FL][i] = COEF_0DB_F; + downMixTable_[FR][i] = COEF_ZERO_F; + break; + case FRONT_RIGHT: + case TOP_FRONT_RIGHT: + case BOTTOM_FRONT_RIGHT: + downMixTable_[FL][i] = COEF_ZERO_F; + downMixTable_[FR][i] = COEF_0DB_F; + break; + case FRONT_CENTER: + case TOP_FRONT_CENTER: + case BOTTOM_FRONT_CENTER: + downMixTable_[FL][i] = COEF_M3DB_F; + downMixTable_[FR][i] = COEF_M3DB_F; + break; + case BACK_LEFT: + case SIDE_LEFT: + case TOP_BACK_LEFT: + case TOP_SIDE_LEFT: + case WIDE_LEFT: + downMixTable_[FL][i] = COEF_M3DB_F; + downMixTable_[FR][i] = COEF_ZERO_F; + break; + case BACK_RIGHT: + case SIDE_RIGHT: + case TOP_BACK_RIGHT: + case TOP_SIDE_RIGHT: + case WIDE_RIGHT: + downMixTable_[FL][i] = COEF_ZERO_F; + downMixTable_[FR][i] = COEF_M3DB_F; + break; + case BACK_CENTER: + downMixTable_[FL][i] = COEF_M6DB_F; + downMixTable_[FR][i] = COEF_M6DB_F; + break; + default: + break; + } +} + +void DownMixer::SetupStereoDmixTablePart2(uint64_t bit, uint32_t i) +{ + switch (bit) { + case FRONT_LEFT_OF_CENTER: + downMixTable_[FL][i] = COEF_M435DB_F; + downMixTable_[FR][i] = COEF_M12DB_F; + break; + case FRONT_RIGHT_OF_CENTER: + downMixTable_[FL][i] = COEF_M12DB_F; + downMixTable_[FR][i] = COEF_M435DB_F; + break; + case TOP_BACK_CENTER: + downMixTable_[FL][i] = COEF_M9DB_F; + downMixTable_[FR][i] = COEF_M9DB_F; + break; + case TOP_CENTER: + downMixTable_[FL][i] = COEF_M899DB_F; + downMixTable_[FR][i] = COEF_M899DB_F; + break; + case LOW_FREQUENCY_2: + if (mixLfe_) { + downMixTable_[FL][i] = COEF_ZERO_F; + downMixTable_[FR][i] = COEF_M6DB_F; + } + break; + case LOW_FREQUENCY: + if ((mixLfe_) & (inLayout_ & (LOW_FREQUENCY_2))) { + downMixTable_[FL][i] = COEF_M6DB_F; + downMixTable_[FR][i] = COEF_ZERO_F; + } else if (mixLfe_) { + downMixTable_[FL][i] = COEF_M6DB_F; + downMixTable_[FR][i] = COEF_M6DB_F; + } + break; + default: + break; + } +} + +void DownMixer::Setup5Point1DmixTablePart1(uint64_t bit, uint32_t i) +{ + switch (bit) { + case FRONT_LEFT: + case TOP_FRONT_LEFT: + case BOTTOM_FRONT_LEFT: + case WIDE_LEFT: + downMixTable_[FL][i] = COEF_0DB_F; + break; + case FRONT_RIGHT: + case TOP_FRONT_RIGHT: + case BOTTOM_FRONT_RIGHT: + case WIDE_RIGHT: + downMixTable_[FR][i] = COEF_0DB_F; + break; + case FRONT_CENTER: + case TOP_FRONT_CENTER: + case BOTTOM_FRONT_CENTER: + downMixTable_[FC][i] = COEF_0DB_F; + break; + case SIDE_LEFT: + case BACK_LEFT: + case TOP_BACK_LEFT: + case TOP_SIDE_LEFT: + downMixTable_[BL][i] = COEF_0DB_F; + break; + case (SIDE_RIGHT): + case (BACK_RIGHT): + case (TOP_BACK_RIGHT): + case (TOP_SIDE_RIGHT): + downMixTable_[BR][i] = COEF_0DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup5Point1DmixTablePart2(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (LOW_FREQUENCY): + case (LOW_FREQUENCY_2): + if (mixLfe_) { + downMixTable_[SW][i] = COEF_0DB_F; + } + break; + case (FRONT_LEFT_OF_CENTER): + downMixTable_[FL][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (FRONT_RIGHT_OF_CENTER): + downMixTable_[FR][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (BACK_CENTER): + case (TOP_BACK_CENTER): + downMixTable_[BL][i] = COEF_M3DB_F; + downMixTable_[BR][i] = COEF_M3DB_F; + break; + case (TOP_CENTER): + downMixTable_[FC][i] = COEF_M6DB_F; + downMixTable_[BL][i] = COEF_M6DB_F; + downMixTable_[BR][i] = COEF_M6DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup5Point1Point2DmixTablePart1(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (FRONT_LEFT): + case (TOP_FRONT_LEFT): + case (BOTTOM_FRONT_LEFT): + case (WIDE_LEFT): + downMixTable_[FL][i] = COEF_0DB_F; + break; + case (FRONT_RIGHT): + case (TOP_FRONT_RIGHT): + case (BOTTOM_FRONT_RIGHT): + case (WIDE_RIGHT): + downMixTable_[FR][i] = COEF_0DB_F; + break; + case (FRONT_CENTER): + case (TOP_FRONT_CENTER): + case (BOTTOM_FRONT_CENTER): + downMixTable_[FC][i] = COEF_0DB_F; + break; + case (SIDE_LEFT): + case (BACK_LEFT): + downMixTable_[BL][i] = COEF_0DB_F; + break; + case (SIDE_RIGHT): + case (BACK_RIGHT): + downMixTable_[BR][i] = COEF_0DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup5Point1Point2DmixTablePart2(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (TOP_BACK_LEFT): + case (TOP_SIDE_LEFT): + downMixTable_[TSL][i] = COEF_0DB_F; + break; + case (TOP_BACK_RIGHT): + case (TOP_SIDE_RIGHT): + downMixTable_[TSR][i] = COEF_0DB_F; + break; + case (LOW_FREQUENCY): + case (LOW_FREQUENCY_2): + if (mixLfe_) { + downMixTable_[SW][i] = COEF_0DB_F; + } + break; + case (FRONT_LEFT_OF_CENTER): + downMixTable_[FL][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (FRONT_RIGHT_OF_CENTER): + downMixTable_[FR][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (BACK_CENTER): + downMixTable_[BL][i] = COEF_M3DB_F; + downMixTable_[BR][i] = COEF_M3DB_F; + break; + case (TOP_BACK_CENTER): + case (TOP_CENTER): + downMixTable_[TSL][i] = COEF_M3DB_F; + downMixTable_[TSR][i] = COEF_M3DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup5Point1Point4DmixTablePart1(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (FRONT_LEFT): + case (BOTTOM_FRONT_LEFT): + case (WIDE_LEFT): + downMixTable_[FL][i] = COEF_0DB_F; + break; + case (FRONT_RIGHT): + case (BOTTOM_FRONT_RIGHT): + case (WIDE_RIGHT): + downMixTable_[FR][i] = COEF_0DB_F; + break; + case (FRONT_CENTER): + case (BOTTOM_FRONT_CENTER): + downMixTable_[FC][i] = COEF_0DB_F; + break; + case (SIDE_LEFT): + case (BACK_LEFT): + downMixTable_[BL][i] = COEF_0DB_F; + break; + case (SIDE_RIGHT): + case (BACK_RIGHT): + downMixTable_[BR][i] = COEF_0DB_F; + break; + case (TOP_FRONT_LEFT): + downMixTable_[TFL][i] = COEF_0DB_F; + break; + case (TOP_FRONT_RIGHT): + downMixTable_[TFR][i] = COEF_0DB_F; + break; + case (TOP_BACK_LEFT): + case (TOP_SIDE_LEFT): + downMixTable_[TBL][i] = COEF_0DB_F; + break; + case (TOP_BACK_RIGHT): + case (TOP_SIDE_RIGHT): + downMixTable_[TBR][i] = COEF_0DB_F; + break; + case (LOW_FREQUENCY): + case (LOW_FREQUENCY_2): + if (mixLfe_) { + downMixTable_[SW][i] = COEF_0DB_F; + } + break; + } +} + +void DownMixer::Setup5Point1Point4DmixTablePart2(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (FRONT_LEFT_OF_CENTER): + downMixTable_[FL][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (FRONT_RIGHT_OF_CENTER): + downMixTable_[FR][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (BACK_CENTER): + downMixTable_[BL][i] = COEF_M3DB_F; + downMixTable_[BR][i] = COEF_M3DB_F; + break; + case (TOP_FRONT_CENTER): + downMixTable_[TFL][i] = COEF_M3DB_F; + downMixTable_[TFR][i] = COEF_M3DB_F; + break; + case (TOP_BACK_CENTER): + downMixTable_[TBL][i] = COEF_M3DB_F; + downMixTable_[TBR][i] = COEF_M3DB_F; + break; + case (TOP_CENTER): + downMixTable_[TFL][i] = COEF_M6DB_F; + downMixTable_[TFR][i] = COEF_M6DB_F; + downMixTable_[TBL][i] = COEF_M6DB_F; + downMixTable_[TBR][i] = COEF_M6DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup7Point1DmixTablePart1(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (FRONT_LEFT): + case (TOP_FRONT_LEFT): + case (BOTTOM_FRONT_LEFT): + case (WIDE_LEFT): + downMixTable_[FL][i] = COEF_0DB_F; + break; + case (FRONT_RIGHT): + case (TOP_FRONT_RIGHT): + case (BOTTOM_FRONT_RIGHT): + case (WIDE_RIGHT): + downMixTable_[FR][i] = COEF_0DB_F; + break; + case (FRONT_CENTER): + case (TOP_FRONT_CENTER): + case (BOTTOM_FRONT_CENTER): + downMixTable_[FC][i] = COEF_0DB_F; + break; + case (SIDE_LEFT): + case (TOP_SIDE_LEFT): + downMixTable_[SL][i] = COEF_0DB_F; + break; + case (SIDE_RIGHT): + case (TOP_SIDE_RIGHT): + downMixTable_[SR][i] = COEF_0DB_F; + break; + case (BACK_LEFT): + case (TOP_BACK_LEFT): + downMixTable_[BL][i] = COEF_0DB_F; + break; + case (BACK_RIGHT): + case (TOP_BACK_RIGHT): + downMixTable_[BR][i] = COEF_0DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup7Point1DmixTablePart2(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (LOW_FREQUENCY): + case (LOW_FREQUENCY_2): + if (mixLfe_) { + downMixTable_[SW][i] = COEF_0DB_F; + } + break; + case (FRONT_LEFT_OF_CENTER): + downMixTable_[FL][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (FRONT_RIGHT_OF_CENTER): + downMixTable_[FR][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (BACK_CENTER): + case (TOP_BACK_CENTER): + downMixTable_[BL][i] = COEF_M3DB_F; + downMixTable_[BR][i] = COEF_M3DB_F; + break; + case (TOP_CENTER): + downMixTable_[FC][i] = COEF_M6DB_F; + downMixTable_[SL][i] = COEF_M6DB_F; + downMixTable_[SR][i] = COEF_M6DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup7Point1Point2DmixTablePart1(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (FRONT_LEFT): + case (TOP_FRONT_LEFT): + case (BOTTOM_FRONT_LEFT): + case (WIDE_LEFT): + downMixTable_[FL][i] = COEF_0DB_F; + break; + case (FRONT_RIGHT): + case (TOP_FRONT_RIGHT): + case (BOTTOM_FRONT_RIGHT): + case (WIDE_RIGHT): + downMixTable_[FR][i] = COEF_0DB_F; + break; + case (FRONT_CENTER): + case (TOP_FRONT_CENTER): + case (BOTTOM_FRONT_CENTER): + downMixTable_[FC][i] = COEF_0DB_F; + break; + case (SIDE_LEFT): + downMixTable_[SL][i] = COEF_0DB_F; + break; + case (SIDE_RIGHT): + downMixTable_[SR][i] = COEF_0DB_F; + break; + case (BACK_LEFT): + downMixTable_[BL][i] = COEF_0DB_F; + break; + case (BACK_RIGHT): + downMixTable_[BR][i] = COEF_0DB_F; + break; + case (TOP_BACK_LEFT): + case (TOP_SIDE_LEFT): + downMixTable_[TSL][i] = COEF_0DB_F; + break; + case (TOP_BACK_RIGHT): + case (TOP_SIDE_RIGHT): + downMixTable_[TSR][i] = COEF_0DB_F; + break; + case (LOW_FREQUENCY): + case (LOW_FREQUENCY_2): + if (mixLfe_) { + downMixTable_[SW][i] = COEF_0DB_F; + } + break; + default: + break; + } +} + +void DownMixer::Setup7Point1Point2DmixTablePart2(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (FRONT_LEFT_OF_CENTER): + downMixTable_[FL][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (FRONT_RIGHT_OF_CENTER): + downMixTable_[FR][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (BACK_CENTER): + downMixTable_[BL][i] = COEF_M3DB_F; + downMixTable_[BR][i] = COEF_M3DB_F; + break; + case (TOP_BACK_CENTER): + case (TOP_CENTER): + downMixTable_[TSL][i] = COEF_M3DB_F; + downMixTable_[TSR][i] = COEF_M3DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup7Point1Point4DmixTablePart1(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (FRONT_LEFT): + case (BOTTOM_FRONT_LEFT): + case (WIDE_LEFT): + downMixTable_[FL][i] = COEF_0DB_F; + break; + case (FRONT_RIGHT): + case (BOTTOM_FRONT_RIGHT): + case (WIDE_RIGHT): + downMixTable_[FR][i] = COEF_0DB_F; + break; + case (FRONT_CENTER): + case (BOTTOM_FRONT_CENTER): + downMixTable_[FC][i] = COEF_0DB_F; + break; + case (SIDE_LEFT): + downMixTable_[SL][i] = COEF_0DB_F; + break; + case (SIDE_RIGHT): + downMixTable_[SR][i] = COEF_0DB_F; + break; + case (BACK_LEFT): + downMixTable_[BL][i] = COEF_0DB_F; + break; + case (BACK_RIGHT): + downMixTable_[BR][i] = COEF_0DB_F; + break; + case (TOP_FRONT_LEFT): + downMixTable_[TFL][i] = COEF_0DB_F; + break; + case (TOP_FRONT_RIGHT): + downMixTable_[TFR][i] = COEF_0DB_F; + break; + case (TOP_BACK_LEFT): + case (TOP_SIDE_LEFT): + downMixTable_[TBL][i] = COEF_0DB_F; + break; + case (TOP_BACK_RIGHT): + case (TOP_SIDE_RIGHT): + downMixTable_[TBR][i] = COEF_0DB_F; + break; + default: + break; + } +} + +void DownMixer::Setup7Point1Point4DmixTablePart2(uint64_t bit, uint32_t i) +{ + switch (bit) { + case (LOW_FREQUENCY): + case (LOW_FREQUENCY_2): + if (mixLfe_) { + downMixTable_[SW][i] = COEF_0DB_F; + } + break; + case (FRONT_LEFT_OF_CENTER): + downMixTable_[FL][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (FRONT_RIGHT_OF_CENTER): + downMixTable_[FR][i] = COEF_M45DB_F; + downMixTable_[FC][i] = COEF_M3DB_F; + break; + case (BACK_CENTER): + downMixTable_[BL][i] = COEF_M3DB_F; + downMixTable_[BR][i] = COEF_M3DB_F; + break; + case (TOP_FRONT_CENTER): + downMixTable_[TFL][i] = COEF_M3DB_F; + downMixTable_[TFR][i] = COEF_M3DB_F; + break; + case (TOP_BACK_CENTER): + downMixTable_[TBL][i] = COEF_M3DB_F; + downMixTable_[TBR][i] = COEF_M3DB_F; + break; + case (TOP_CENTER): + downMixTable_[TFL][i] = COEF_M6DB_F; + downMixTable_[TFR][i] = COEF_M6DB_F; + downMixTable_[TBL][i] = COEF_M6DB_F; + downMixTable_[TBR][i] = COEF_M6DB_F; + break; + default: + break; + } +} + +void DownMixer::DownMixBottom(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) +{ + if ((inBit & MASK_BOTTOM) && (outBit & MASK_BOTTOM)) { + downMixTable_[i][j] = COEF_M3DB_F; + } else { + DownMixMidFront(inBit, outBit, i, j); + } +} + +void DownMixer::DownMixMidFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) +{ + if ((inBit & MASK_MIDDLE_FRONT) && (outBit & MASK_MIDDLE_FRONT)) { + downMixTable_[i][j] = COEF_M3DB_F; + } +} + +void DownMixer::DownMixMidRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) +{ + // Middle layer + switch (inBit) { + case BACK_CENTER: + if ((outBit == BACK_LEFT) || (outBit == SIDE_LEFT) || (outBit == WIDE_LEFT) || (outBit == FRONT_LEFT) || + (outBit == BACK_RIGHT) || outBit == SIDE_RIGHT || outBit == WIDE_RIGHT || outBit == FRONT_RIGHT) { + downMixTable_[i][j] = COEF_M3DB_F; + } + break; + case BACK_LEFT: + if (outBit == SIDE_LEFT) { + downMixTable_[i][j] = COEF_0DB_F; + } else if (outBit == BACK_CENTER) { + downMixTable_[i][j] = COEF_0DB_F; + } else { + DownMixMidFront(WIDE_LEFT, outBit, i, j); + } + break; + case BACK_RIGHT: + if (outBit == SIDE_RIGHT) { + downMixTable_[i][j] = COEF_0DB_F; + } else if (outBit == BACK_CENTER) { + downMixTable_[i][j] = COEF_0DB_F; + } else { + DownMixMidFront(WIDE_RIGHT, outBit, i, j); + } + break; + } +} + +void DownMixer::DownMixLfe(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) +{ + if ((MASK_LFE & inBit) && (MASK_LFE & outBit)) { + downMixTable_[i][j] = COEF_0DB_F; + } else { + if ((inBit == LOW_FREQUENCY) && ((outBit & CH_LAYOUT_STEREO)!= 0)) { + downMixTable_[i][j] = COEF_M6DB_F; + } else if ((inBit == LOW_FREQUENCY_2) && ((outBit & CH_LAYOUT_STEREO) != 0)) { + downMixTable_[i][j] = COEF_M6DB_F; + } + } +} + +void DownMixer::DownMixTopCenter(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) +{ + uint64_t exitTopOuts = outLayout_ & (MASK_TOP_FRONT | MASK_TOP_REAR); + uint64_t exitMiddleOuts = outLayout_ & (MASK_MIDDLE_FRONT | MASK_MIDDLE_REAR); + if (exitTopOuts != 0) { // exist top outs + uint32_t numChannels = bitCounts(exitTopOuts); + uint32_t coeff = 1.0f / sqrt((float)numChannels); + if ((outBit & exitTopOuts) != 0) { + downMixTable_[i][j] = coeff; + } + } else if (exitMiddleOuts != 0) { + uint32_t numChannels = bitCounts(exitMiddleOuts); + uint32_t coeff = 1.0f / sqrt((float)numChannels); + if ((outBit & exitMiddleOuts) != 0) { + downMixTable_[i][j] = coeff; + } + } +} + +void DownMixer::DownMixTopFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) +{ + uint64_t existTopFrontOuts = outLayout_ & MASK_TOP_FRONT; + if (existTopFrontOuts != 0) { + if ((outBit & MASK_TOP_FRONT) != 0) { + downMixTable_[i][j] = COEF_M3DB_F; + } + } else { + DownMixMidFront(TOP_FRONT_CENTER, outBit, i, j); + } +} + +void DownMixer::DownMixTopRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) +{ + uint64_t existTopRearOuts = outLayout_ & MASK_TOP_REAR; + if (existTopRearOuts != 0) { + if ((outBit & MASK_TOP_REAR) != 0) { + downMixTable_[i][j] = COEF_M3DB_F; + } + } else { + DownMixMidRear(BACK_CENTER, outBit, i, j); + } +} + +static uint32_t bitCounts(uint64_t bits) +{ + uint32_t num = 0; + for (; bits != 0; bits &= bits - 1) { + num++; + } + return num; +} + +static bool isValidChLayout(AudioChannelLayout &chLayout, uint32_t chCounts) +{ + if (chCounts < MONO || chCounts > CHANNEL_16) { + return false; + } + if (chLayout == CH_LAYOUT_UNKNOWN || bitCounts(chLayout) != chCounts) { + chLayout = SetDefaultChannelLayout((AudioChannel)chCounts); + } + return true; +} + +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; + } +} + +} // HPAE +} // AudioStandard +} // OHOS \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/include/audio_proresampler.h b/services/audio_engine/plugin/resample/include/audio_proresampler.h new file mode 100644 index 0000000000..0b3aa0f00e --- /dev/null +++ b/services/audio_engine/plugin/resample/include/audio_proresampler.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 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 AUDIO_PRORESAMPLER_H +#define AUDIO_PRORESAMPLER_H + +#include "resampler.h" +#include "audio_proresampler_process.h" +#include +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class ProResampler : public Resampler { +public: + ProResampler(uint32_t inRate, uint32_t outRate, uint32_t channels, uint32_t quality); + ~ProResampler() override; + // disable deep copy, enable move semantics to manage memory allocated by C malloc + ProResampler(const ProResampler &) = delete; + ProResampler &operator=(const ProResampler &) = delete; + ProResampler(ProResampler &&) noexcept; + ProResampler &operator=(ProResampler &&) noexcept; + void Reset() override; + int Process(const float *inBuffer, uint32_t *inFrameSize, float *outBuffer, uint32_t *outFrameSize) + override; + int32_t UpdateRates(uint32_t inRate, uint32_t outRate) override; + void UpdateChannels(uint32_t channels) override; + uint32_t GetInRate() const override; + uint32_t GetOutRate() const override; + uint32_t GetChannels() const override; + uint32_t GetQuality() const; +private: + std::string ErrCodeToString(int32_t errCode); + uint32_t inRate_; + uint32_t outRate_; + uint32_t channels_; + uint32_t quality_; + SingleStagePolyphaseResamplerState* state_ = nullptr; +}; +} // HPAE +} // AudioStandard +} // OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/include/audio_proresampler_process.h b/services/audio_engine/plugin/resample/include/audio_proresampler_process.h new file mode 100644 index 0000000000..67067a7eef --- /dev/null +++ b/services/audio_engine/plugin/resample/include/audio_proresampler_process.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2025 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 AUDIO_PRORESAMPLER_PROCESS_H +#define AUDIO_PRORESAMPLER_PROCESS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef enum MultiplyFilterFunMethod { + MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP, + MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP, + MULTIPLY_FILTER_FUN_UP, + MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN, + MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN, + MULTIPLY_FILTER_FUN_DOWN, + MULTIPLY_FILTER_FUN_MAX + } MultiplyFilterFun_t; + + enum { + RESAMPLER_ERR_SUCCESS = 0, + RESAMPLER_ERR_ALLOC_FAILED = -1, + RESAMPLER_ERR_INVALID_ARG = -2, + RESAMPLER_ERR_OVERFLOW = -3 + }; + + #define MAX_RATIO_INTEGRAL_METHOD 32 + + typedef struct SingleStagePolyphaseResamplerState SingleStagePolyphaseResamplerState; + + typedef int32_t (*ResamplerMethod)(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength); + typedef void (*MultiplyFilterFun)(SingleStagePolyphaseResamplerState* state, + const float* coeffs, const float* inputs, float* outputs, int32_t subfilterNum); + + + /** + * @brief Resampler state + * + */ + struct SingleStagePolyphaseResamplerState { + uint32_t decimateFactor; /** Integer decimation factor */ + uint32_t interpolateFactor; /** Integer interpolation factor */ + + int32_t quality; /** Parameter for resampler quality (0~10) */ + uint32_t numChannels; /** Number of channels */ + uint32_t filterLength; /** Number of taps of anti-aliasing/imaging filter */ + uint32_t bufferSize; /** Number of buffer samples for each channel */ + int32_t quoSamplerateRatio; /** Quotient of (input sampling frequency)/(output sampling frequency) */ + int32_t remSamplerateRatio; /** remainder of (input sampling frequency)/(output sampling frequency) */ + float cutoff; /** Normalized cutoff frequency of anti-aliasing/imaging filter */ + float coshParameter; /** Parameter of cosh window for adjusting side-lobe decay of filter */ + int32_t isInitialized; /** If the state is initialized, isInitialized=1. */ + int32_t isStarted; /** Once the resampler has processed, isStarted = 1. */ + + int32_t inputIndex; /** Index of the input to be processed. */ + uint32_t subfilterNum; /** What number of polyphase subfilters to use. */ + uint32_t magicSamples; /** Used for variable sampling frequency (don't need this?) */ + + float* inputMemory; /** An array that stores the inputs to be processed. */ + uint32_t inputMemorySize; /** Size of inputMemory. (bufferSize + filterLength + 1) */ + float* filterCoefficients; /** An array that stores the polyphase filters. */ + uint32_t filterCoefficientsSize; /** Size of filterCoefficients. */ + ResamplerMethod resamplerFunction; /** A pointer to the function used for resampling. */ + MultiplyFilterFun multiplyFunSeq[MAX_RATIO_INTEGRAL_METHOD]; + }; + +/** + * @brief Create a new resampler state. + * + * @param numChannels Number of channels. + * @param decimateFactor Integer decimation factor (input sampling frequency). + * @param interpolateFactor Integer interpolation factor (output sampling frequency). + * @param quality Parameter for determining resampling quality level between 0 (poor) and 10 (best). + * @param err + * @return SingleStagePolyphaseResamplerState* Created resampler state used for process + */ + SingleStagePolyphaseResamplerState* SingleStagePolyphaseResamplerInit(uint32_t numChannels, + uint32_t decimateFactor, uint32_t interpolateFactor, int32_t quality, int32_t* err); + + + /** + * @brief Set (update) the input/output sampling rates. + * + * @param state Resampler state + * @param decimateFactor Integer decimation factor (input sampling frequency). + * @param interpolateFactor Integer interpolation factor (output sampling frequency). + * @return int32_t returns 0 if the function terminates normally. + */ + int32_t SingleStagePolyphaseResamplerSetRate(SingleStagePolyphaseResamplerState* state, + uint32_t decimateFactor, uint32_t interpolateFactor); + + /** + * @brief + * + * @param state Resampler state. + * @return int32_t returns 0 if the function terminates normally. + */ + int32_t SingleStagePolyphaseResamplerSkipHalfTaps(SingleStagePolyphaseResamplerState* state); + + + /** + * @brief Reset the buffers of the resampler. + * + * @param state Resampler state. + * @return int32_t returns 0 if the function terminates normally. + */ + int32_t SingleStagePolyphaseResamplerResetMem(SingleStagePolyphaseResamplerState* state); + + /** + * @brief Release the memory for the resampler state + * + * @param state Resampler state. + */ + void SingleStagePolyphaseResamplerFree(SingleStagePolyphaseResamplerState* state); + + + /** + * @brief Resample an input array. + * + * @param state resampler state + * @param in Input array. + * @param inputLength Number of input samples. + * @param out Output array. + * @param outputLength Number of input samples. + * @return int32_t returns 0 if the function terminates normally. + */ + int32_t SingleStagePolyphaseResamplerProcess(SingleStagePolyphaseResamplerState* state, + const float* in, uint32_t* inputLength, float* out, uint32_t* outputLength); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/include/resampler.h b/services/audio_engine/plugin/resample/include/resampler.h new file mode 100644 index 0000000000..7c088a2f97 --- /dev/null +++ b/services/audio_engine/plugin/resample/include/resampler.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 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 RESAMPLER_H +#define RESAMPLER_H +#include +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class Resampler { +public: + virtual ~Resampler() = default; + virtual void Reset() = 0; + virtual int Process(const float *in_buffer, uint32_t *inFrameSize, float *out_buffer, + uint32_t *outFrameSize) = 0; + virtual int32_t UpdateRates(uint32_t inRate, uint32_t outRate) = 0; + virtual uint32_t GetInRate() const = 0; + virtual uint32_t GetOutRate() const = 0; + virtual uint32_t GetChannels() const = 0; + virtual void UpdateChannels(uint32_t channels) = 0; +}; + +} // HPAE +} // AudioStandard +} // OHOS + +#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp new file mode 100644 index 0000000000..0bd3810102 --- /dev/null +++ b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2025 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 "audio_proresampler.h" +#include "audio_policy_log.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +ProResampler::ProResampler(uint32_t inRate, uint32_t outRate, uint32_t channels, uint32_t quality) + : inRate_(inRate), outRate_(outRate), channels_(channels), quality_(quality) +{ + int32_t errRet; + state_ = SingleStagePolyphaseResamplerInit(channels_, inRate_, outRate_, quality_, &errRet); + if (state_) { + SingleStagePolyphaseResamplerSkipHalfTaps(state_); + AUDIO_INFO_LOG("Proresampler: Init success inRate: %{public}d, outRate: %{public}d, channels: %{public}d, " + "quality: %{public}d.", inRate_, outRate_, channels_, quality_); + } else { + AUDIO_ERR_LOG("Proresampler: Init failed! failed with error %{public}s.", + ErrCodeToString(errRet).c_str()); + } +} + +int32_t ProResampler::Process(const float *inBuffer, uint32_t *inFrameSize, float *outBuffer, + uint32_t *outFrameSize) +{ + CHECK_AND_RETURN_RET_LOG(state_ != nullptr, RESAMPLER_ERR_ALLOC_FAILED, + "ProResampler Process: resampler is %{public}s", ErrCodeToString(RESAMPLER_ERR_ALLOC_FAILED).c_str()); + uint32_t expectedOutFrameSize = *outFrameSize; + std::vector tmpOutBuf(expectedOutFrameSize * channels_, 0.0f); + int32_t ret = + SingleStagePolyphaseResamplerProcess(state_, inBuffer, inFrameSize, tmpOutBuf.data(), outFrameSize); + if (ret != 0) { + 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)); + ret += memcpy_s(outBuffer + fillZeroSize * channels_, + (expectedOutFrameSize - fillZeroSize) * channels_ * sizeof(float), + tmpOutBuf.data(), *outFrameSize * channels_ * sizeof(float)); + if (ret != EOK) { + ret = RESAMPLER_ERR_ALLOC_FAILED; + } + return ret; +} + +int32_t ProResampler::UpdateRates(uint32_t inRate, uint32_t outRate) +{ + inRate_ = inRate; + outRate_ = outRate; + CHECK_AND_RETURN_RET_LOG(state_ != nullptr, RESAMPLER_ERR_ALLOC_FAILED, "ProResampler: resampler is null"); + int32_t ret = SingleStagePolyphaseResamplerSetRate(state_, inRate_, outRate_); + if (ret != 0) { + AUDIO_WARNING_LOG("ProResampler update rate failed with error code %{public}s", ErrCodeToString(ret).c_str()); + } + return ret; +} + +void ProResampler::UpdateChannels(uint32_t channels) +{ + uint32_t oldChannels = channels_; + channels_ = channels; + SingleStagePolyphaseResamplerFree(state_); + int32_t errRet; + state_ = SingleStagePolyphaseResamplerInit(channels_, inRate_, outRate_, quality_, &errRet); + if (state_) { + SingleStagePolyphaseResamplerSkipHalfTaps(state_); + AUDIO_INFO_LOG("Proresampler: update work channel success old channels: %{public}d, new channels: %{public}d", + oldChannels, channels_); + } else { + AUDIO_ERR_LOG("Proresampler: update work channels failed with error %{public}s.", + ErrCodeToString(errRet).c_str()); + } +} + +ProResampler::ProResampler(ProResampler &&other) noexcept + : inRate_(other.inRate_), outRate_(other.outRate_), channels_(other.channels_), + quality_(other.quality_), state_(other.state_) +{ + other.state_ = nullptr; +} + +ProResampler &ProResampler::operator=(ProResampler &&other) noexcept +{ + if (this != &other) { + if (state_ != nullptr) { + SingleStagePolyphaseResamplerFree(state_); + } + inRate_ = other.inRate_; + outRate_ = other.outRate_; + channels_ = other.channels_; + quality_ = other.quality_; + state_ = other.state_; + other.state_ = nullptr; + } + return *this; +} + +void ProResampler::Reset() +{ + CHECK_AND_RETURN_LOG(state_ != nullptr, "ProResampler: resampler is null"); + SingleStagePolyphaseResamplerResetMem(state_); + SingleStagePolyphaseResamplerSkipHalfTaps(state_); +} + +uint32_t ProResampler::GetInRate() const +{ + return inRate_; +} + +uint32_t ProResampler::GetOutRate() const +{ + return outRate_; +} + +uint32_t ProResampler::GetChannels() const +{ + return channels_; +} + +uint32_t ProResampler::GetQuality() const +{ + return quality_; +} + +ProResampler::~ProResampler() +{ + if (state_ != nullptr) { + SingleStagePolyphaseResamplerFree(state_); + state_ = nullptr; + } +} + +std::string ProResampler::ErrCodeToString(int32_t errCode) +{ + switch (errCode) { + case RESAMPLER_ERR_SUCCESS: { + return "RESAMPLER_ERR_SUCCESS"; + break; + } + case RESAMPLER_ERR_ALLOC_FAILED: { + return "RESAMPLER_ERR_ALLOC_FAILED"; + break; + } + case RESAMPLER_ERR_INVALID_ARG: { + return "RESAMPLER_ERR_INVALID_ARG"; + break; + } + case RESAMPLER_ERR_OVERFLOW: { + return "RESAMPLER_ERR_OVERFLOW"; + break; + } + default: { + return "Unknown Error Code"; + } + } +} + +} // HPAE +} // AudioStandard +} // OHOS \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/proresampler/audio_proresampler_process.c b/services/audio_engine/plugin/resample/proresampler/audio_proresampler_process.c new file mode 100644 index 0000000000..db518888d0 --- /dev/null +++ b/services/audio_engine/plugin/resample/proresampler/audio_proresampler_process.c @@ -0,0 +1,1490 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ + + +#include +#include +#include +#include +#include "audio_proresampler_process.h" +#include "securec.h" +/** + * @brief Ratio of circumference to diameter + * + */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/** + * @brief Maximum number of numChannels + * + */ +#define MAX_NUM_CHANNEL 16 + + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef MONO +#define MONO 1 +#endif + +#ifndef STEREO +#define STEREO 2 +#endif + +#define TWO_STEPS 2 +#define THREE_STEPS 3 +#define FOUR_STEPS 4 +#define QUALITY_LEVEL_TEN 10 +#define BUFFER_SIZE 160 + +// WARNING: Code for support to sudden changes in sampling frequency is deprecated! +// It is disabled because it is complex and untested. +// It is desirable to re-initialize for such a change in the sampling frequency. + +/** + * @brief A function that compares two values and returns the smaller one + * + */ +#define COMPARE_MIN(a, b) ((a) > (b) ? (b) : (a)) + +/** + * @brief A function that compares two values and returns the larger one + * + */ +#define COMPARE_MAX(a, b) ((a) < (b) ? (b) : (a)) + +/** + * @brief A function that helps update resampler state + * +*/ +static int32_t UpdateFilterMemory(SingleStagePolyphaseResamplerState* state, uint32_t oldFilterLength); +struct QualityTable { + int32_t filterLength; + float coshParameter; +}; + + +/** + * @brief This table contains internal parameters corresponding to quality levels. + * + * The relationship between coshParameter and side lobe decay is as follows: + * coshParameter = -8.722e-5 * attenuation^TWO_STEPS + 0.1335 * attenuation - 1.929 (50 < attenuation) + */ +static const struct QualityTable qualityTable[11] = { + { 8, 5.767008}, /* Q0 */ + { 16, 5.767008}, /* Q1 */ + { 32, 5.767008}, /* Q2 */ /* ( ~60 dB stop) 6 */ + { 48, 8.192792}, /* Q3 */ /* ( ~80 dB stop) 8 */ + { 64, 8.192792}, /* Q4 */ /* ( ~80 dB stop) 8 */ + { 80, 10.5488}, /* Q5 */ /* (~100 dB stop) 10 */ + { 96, 10.5488}, /* Q6 */ /* (~100 dB stop) 10 */ + {128, 10.5488}, /* Q7 */ /* (~100 dB stop) 10 */ + {160, 10.5488}, /* Q8 */ /* (~100 dB stop) 10 */ + {192, 10.5488}, /* Q9 */ /* (~100 dB stop) 10 */ + {256, 10.5488}, /* Q10 */ /* (~100 dB stop) 10 */ +}; + + +static double CompHyperbolicCosineWindow(double x, float alpha) +{ + double x2; + double w; + + x2 = x * x; + if (x2 >= 1.0) { + return 0.f; + } + + w = alpha * sqrt(1.0f - x2); + w = cosh(w) / cosh(alpha); + return w; +} + + +static float Sinc(float x) +{ + if (fabs(x) < 1e-6) { + return 1.0f; + } + return sin(M_PI * x) / (M_PI * x); +} + + +static int32_t CalculateFilter(SingleStagePolyphaseResamplerState* state) +{ + uint32_t i; + int32_t j; + float phi0 = 0; + float phi = 0; + double w; + uint32_t requiredFilterCoefficientsSize; + float cutoff = state->cutoff; + + if (INT_MAX / sizeof(float) / state->interpolateFactor < state->filterLength) { + return RESAMPLER_ERR_ALLOC_FAILED; + } + + requiredFilterCoefficientsSize = state->filterLength * state->interpolateFactor; + + if (state->filterCoefficientsSize < requiredFilterCoefficientsSize) { + if (state->filterCoefficients == NULL) { + state->filterCoefficients = (float*)malloc(requiredFilterCoefficientsSize * sizeof(float)); + if (!state->filterCoefficients) { + return RESAMPLER_ERR_ALLOC_FAILED; + } + } else { + float* filterCoefficients = (float*)malloc(requiredFilterCoefficientsSize * sizeof(float)); + if (!filterCoefficients) { + return RESAMPLER_ERR_ALLOC_FAILED; + } + if (memcpy_s(filterCoefficients, requiredFilterCoefficientsSize * sizeof(float), + state->filterCoefficients, state->filterCoefficientsSize * sizeof(float)) != 0) { + return RESAMPLER_ERR_ALLOC_FAILED; + } + free(state->filterCoefficients); + state->filterCoefficients = filterCoefficients; + } + state->filterCoefficientsSize = requiredFilterCoefficientsSize; + } + + for (i = 0; i < state->interpolateFactor; i++) { + for (j = 0; j < state->filterLength; j++) { + phi = (j - (int32_t)state->filterLength / TWO_STEPS + 1) - phi0; + w = CompHyperbolicCosineWindow(fabs((double)TWO_STEPS * phi / state->filterLength), + state->coshParameter); + state->filterCoefficients[i * state->filterLength + j] = w * cutoff * Sinc(cutoff * phi); + } + phi0 += 1.0 / state->interpolateFactor; + } + return 0; +} + +/*====== Filter multiplication function for general cases =====*/ +static void MultiplyFilterMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + float sum = 0; + + for (int32_t j = 0; j < state->filterLength; j += FOUR_STEPS) { + sum += (*coeffs++) * (*inputs++); + sum += (*coeffs++) * (*inputs++); + sum += (*coeffs++) * (*inputs++); + sum += (*coeffs++) * (*inputs++); + } + *outputs = sum; +} + +static void MultiplyFilterStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + float sumL = 0; + float sumR = 0; + float h; + + for (int32_t j = 0; j < state->filterLength; j += FOUR_STEPS) { + h = *coeffs++; + sumL += h * (*inputs++); + sumR += h * (*inputs++); + + h = *coeffs++; + sumL += h * (*inputs++); + sumR += h * (*inputs++); + + h = *coeffs++; + sumL += h * (*inputs++); + sumR += h * (*inputs++); + + h = *coeffs++; + sumL += h * (*inputs++); + sumR += h * (*inputs++); + } + *outputs++ = sumL; + *outputs = sumR; +} + +static void MultiplyFilterMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t numChannels = state->numChannels; + int32_t ch, j; + float h; + float sum[MAX_NUM_CHANNEL]; + + for (ch = 0; ch < numChannels; ch++) { + sum[ch] = 0; + } + for (j = 0; j < state->filterLength; j += FOUR_STEPS) { + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (*inputs++); + } + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (*inputs++); + } + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (*inputs++); + } + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (*inputs++); + } + } + for (ch = 0; ch < numChannels; ch++) { + *outputs++ = sum[ch]; + } +} + +/*===== Filter multiplication function for coarse (integral) upsampling =====*/ +static void MultiplyFilterSymmetricOddUpMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + *outputs = inputs[state->filterLength / TWO_STEPS - 1]; +} + +static void MultiplyFilterSymmetricOddUpStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + *outputs++ = inputs[state->filterLength - TWO_STEPS]; + *outputs = inputs[state->filterLength - 1]; +} + +static void MultiplyFilterSymmetricOddUpMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t indCenter = state->filterLength / TWO_STEPS - 1; + for (int32_t ch = 0; ch < state->numChannels; ch++) { + *outputs++ = inputs[state->numChannels * indCenter + ch]; + } +} + +static void MultiplyFilterSymmetricEvenUpMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + float sum = 0; + + for (int32_t j = 0; j < N / TWO_STEPS; j += FOUR_STEPS) { + sum += (*coeffs++) * (inputs[j] + inputs[(N - j - 1)]); + sum += (*coeffs++) * (inputs[j + 1] + inputs[(N - (j + 1) - 1)]); + sum += (*coeffs++) * (inputs[j + TWO_STEPS] + inputs[(N - (j + TWO_STEPS) - 1)]); + sum += (*coeffs++) * (inputs[j + THREE_STEPS] + inputs[(N - (j + THREE_STEPS) - 1)]); + } + *outputs = sum; +} + +static void MultiplyFilterSymmetricEvenUpStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + float sumL = 0; + float sumR = 0; + float h; + + for (int32_t j = 0; j < N / TWO_STEPS; j += FOUR_STEPS) { + h = *coeffs++; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - 1) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - 1) * STEREO + 1]); + h = *coeffs++; + sumL += h * (inputs[(j + 1) * STEREO] + inputs[(N - (j + 1) - 1) * STEREO]); + sumR += h * (inputs[(j + 1) * STEREO + 1] + inputs[(N - (j + 1) - 1) * STEREO + 1]); + h = *coeffs++; + sumL += h * (inputs[(j + TWO_STEPS) * STEREO] + inputs[(N - (j + TWO_STEPS) - 1) * STEREO]); + sumR += h * (inputs[(j + TWO_STEPS) * STEREO + 1] + inputs[(N - (j + TWO_STEPS) - 1) * STEREO + 1]); + h = *coeffs++; + sumL += h * (inputs[(j + THREE_STEPS) * STEREO] + inputs[(N - (j + THREE_STEPS) - 1) * STEREO]); + sumR += h * (inputs[(j + THREE_STEPS) * STEREO + 1] + inputs[(N - (j + THREE_STEPS) - 1) * STEREO + 1]); + } + *outputs++ = sumL; + *outputs++ = sumR; +} + +static void MultiplyFilterSymmetricEvenUpMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const int32_t numChannels = state->numChannels; + int32_t ch, j; + float sum[MAX_NUM_CHANNEL]; + float h; + + for (ch = 0; ch < numChannels; ch++) { + sum[ch] = 0; + } + for (j = 0; j < N / TWO_STEPS; j++) { + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - 1) * numChannels + ch]); + } + } + for (ch = 0; ch < numChannels; ch++) { + *outputs++ = sum[ch]; + } +} + +static void MultiplyFilterSymmetricOddDownMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + const uint32_t decimateFactor = state->decimateFactor; + float sum; + int32_t rem = indCenter % decimateFactor; + int32_t L = indCenter / decimateFactor; + int32_t i, j, l; + // center index + sum = coeffs[indCenter] * inputs[indCenter]; + // symmetric indices + for (j = 0; j < rem; j++) { + sum += (*coeffs++) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); + } + for (l = 0; l < L; l++) { + coeffs++; + j++; + for (i = 1; i < decimateFactor; i++) { + sum += (*coeffs++) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); + j++; + } + } + + *outputs = sum; +} + +static void MultiplyFilterSymmetricOddDownStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + const uint32_t decimateFactor = state->decimateFactor; + float sumL, sumR, h; + int32_t rem = indCenter % decimateFactor; + int32_t L = indCenter / decimateFactor; + int32_t i, j, l; + + // center + h = coeffs[indCenter]; + sumL = h * inputs[N - TWO_STEPS]; + sumR = h * inputs[N - 1]; + // symmetric indices + for (j = 0; j < rem; j++) { + h = *coeffs++; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); + } + for (l = 0; l < L; l++) { + coeffs++; + j++; + for (i = 1; i < decimateFactor; i++) { + h = *coeffs++; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); + j++; + } + } + + *outputs++ = sumL; + *outputs = sumR; +} + +static void MultiplyFilterSymmetricOddDownMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const int32_t numChannels = state->numChannels; + const int32_t indCenter = N / TWO_STEPS - 1; + const uint32_t decimateFactor = state->decimateFactor; + int32_t i, j, l, ch; + float sum[MAX_NUM_CHANNEL]; + float h; + int32_t rem = indCenter % decimateFactor; + int32_t L = indCenter / decimateFactor; + + // center index + h = coeffs[indCenter]; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] = h * (inputs[indCenter * numChannels + ch]); + } + // symmetric indices + for (j = 0; j < rem; j++) { + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); + } + } + for (l = 0; l < L; l++) { + coeffs++; + j++; + for (i = 1; i < decimateFactor; i++) { + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); + } + j++; + } + } + + for (ch = 0; ch < numChannels; ch++) { + *outputs++ = sum[ch]; + } +} + + +static void MultiplyFilterSymmetricEvenDownMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const uint32_t decimateFactor = state->decimateFactor; + int32_t i, j, l; + int32_t rem = (N / TWO_STEPS) % decimateFactor; + int32_t L = (N / TWO_STEPS) / decimateFactor; + float h; + + float sum = 0; + + // symmetric indices + for (j = 0; j < rem; j++) { + h = *coeffs++; + sum += h * (inputs[j] + inputs[(N - j - 1)]); + } + for (l = 0; l < L; l++) { + for (i = 0; i < decimateFactor / TWO_STEPS; i++) { + h = *coeffs++; + sum += h * (inputs[j] + inputs[(N - j - 1)]); + j++; + } + // Skip zero + coeffs++; + j++; + for (i = 0; i < decimateFactor / TWO_STEPS; i++) { + h = *coeffs++; + sum += h * (inputs[j] + inputs[(N - j - 1)]); + j++; + } + } + *outputs = sum; +} + +static void MultiplyFilterSymmetricEvenDownStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const uint32_t decimateFactor = state->decimateFactor; + int32_t i, j, l; + int32_t rem = (N / TWO_STEPS) % decimateFactor; + int32_t L = (N / TWO_STEPS) / decimateFactor; + float h; + + float sumL = 0; + float sumR = 0; + + // symmetric indices + for (j = 0; j < rem; j++) { + h = *coeffs++; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - 1) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - 1) * STEREO + 1]); + } + for (l = 0; l < L; l++) { + for (i = 0; i < decimateFactor / TWO_STEPS; i++) { + h = *coeffs++; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - 1) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - 1) * STEREO + 1]); + j++; + } + // Skip zero + coeffs++; + j++; + for (i = 0; i < decimateFactor / TWO_STEPS; i++) { + h = *coeffs++; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - 1) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - 1) * STEREO + 1]); + j++; + } + } + *outputs++ = sumL; + *outputs++ = sumR; +} + + +static void MultiplyFilterSymmetricEvenDownMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const int32_t numChannels = state->numChannels; + const uint32_t decimateFactor = state->decimateFactor; + int32_t i, j, l, ch; + float sum[MAX_NUM_CHANNEL]; + float h; + int32_t rem = (N / TWO_STEPS) % decimateFactor; + int32_t L = (N / TWO_STEPS) / decimateFactor; + + for (ch = 0; ch < numChannels; ch++) { + sum[ch] = 0; + } + // symmetric indices + for (j = 0; j < rem; j++) { + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - 1) * numChannels + ch]); + } + } + for (l = 0; l < L; l++) { + for (i = 0; i < decimateFactor / TWO_STEPS; i++) { + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - 1) * numChannels + ch]); + } + j++; + } + //Skip zero + coeffs++; + j++; + for (i = 0; i < decimateFactor / TWO_STEPS; i++) { + h = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - 1) * numChannels + ch]); + } + j++; + } + } + + for (ch = 0; ch < numChannels; ch++) { + *outputs++ = sum[ch]; + } +} + +static void MultiplyFilterDownMono(SingleStagePolyphaseResamplerState *state, const float *coeffs, + const float *inputs, float *outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + const uint32_t decimateFactor = state->decimateFactor; + int32_t j; + float h; + float sum = 0; + + int32_t counts = indCenter % decimateFactor - subfilterNum; + if (counts < 0) { + counts += state->interpolateFactor; + } + + for (j = 0; j < N; j++) { + h = *coeffs++; + if (counts == 0) { // Skip zero coefficients + counts = decimateFactor - 1; + inputs++; + continue; + } + sum += h * (*inputs++); + counts--; + } + *outputs = sum; +} + +static void MultiplyFilterDownStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, + const float* inputs, float* outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + const uint32_t decimateFactor = state->decimateFactor; + int32_t j; + float sumL = 0; + float sumR = 0; + float h; + + int32_t counts = indCenter % decimateFactor - subfilterNum; + if (counts < 0) { + counts += state->interpolateFactor; + } + + for (j = 0; j < N; j++) { + h = *coeffs++; + if (counts == 0) { // Skip zero coefficients + counts = decimateFactor - 1; + inputs += STEREO; + continue; + } + sumL += h * (*inputs++); + sumR += h * (*inputs++); + counts--; + } + *outputs++ = sumL; + *outputs = sumR; +} + +static void MultiplyFilterDownMultichannel(SingleStagePolyphaseResamplerState *state, const float *coeffs, + const float *inputs, float *outputs, int32_t subfilterNum) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + const uint32_t decimateFactor = state->decimateFactor; + const int32_t numChannels = state->numChannels; + int32_t j, ch; + float h; + float sum[MAX_NUM_CHANNEL]; + + int32_t counts = indCenter % decimateFactor - subfilterNum; + if (counts < 0) { + counts += state->interpolateFactor; + } + + for (ch = 0; ch < numChannels; ch++) { + sum[ch] = 0; + } + for (j = 0; j < N; j++) { + h = *coeffs++; + if (counts == 0) { // Skip zero coefficients + counts = decimateFactor - 1; + inputs += numChannels; + continue; + } + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (*inputs++); + } + counts--; + } + for (ch = 0; ch < numChannels; ch++) { + *outputs++ = sum[ch]; + } +} + + +/*===== Function pointers of filter multiplication functions =====*/ +static MultiplyFilterFun multiplyFilterFunTable[] = { + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP] = MultiplyFilterSymmetricOddUpMono, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP + 1] = MultiplyFilterSymmetricOddUpStereo, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP + TWO_STEPS] = MultiplyFilterSymmetricOddUpMultichannel, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP] = MultiplyFilterSymmetricEvenUpMono, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP + 1] = MultiplyFilterSymmetricEvenUpStereo, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP + TWO_STEPS] = MultiplyFilterSymmetricEvenUpMultichannel, + [THREE_STEPS * MULTIPLY_FILTER_FUN_UP] = MultiplyFilterMono, + [THREE_STEPS * MULTIPLY_FILTER_FUN_UP + 1] = MultiplyFilterStereo, + [THREE_STEPS * MULTIPLY_FILTER_FUN_UP + TWO_STEPS] = MultiplyFilterMultichannel, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN] = MultiplyFilterSymmetricOddDownMono, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN + 1] = MultiplyFilterSymmetricOddDownStereo, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN + TWO_STEPS] = + MultiplyFilterSymmetricOddDownMultichannel, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN] = MultiplyFilterSymmetricEvenDownMono, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN + 1] = MultiplyFilterSymmetricEvenDownStereo, + [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN + TWO_STEPS] = + MultiplyFilterSymmetricEvenDownMultichannel, + [THREE_STEPS * MULTIPLY_FILTER_FUN_DOWN] = MultiplyFilterDownMono, + [THREE_STEPS * MULTIPLY_FILTER_FUN_DOWN + 1] = MultiplyFilterDownStereo, + [THREE_STEPS * MULTIPLY_FILTER_FUN_DOWN + TWO_STEPS] = MultiplyFilterDownMultichannel +}; + +static int32_t PolyphaseResamplerMono(SingleStagePolyphaseResamplerState *state, const float *in, uint32_t *inputLength, + float *out, uint32_t *outputLength) +{ + const int32_t N = state->filterLength; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + uint32_t subfilterNum = state->subfilterNum; + const float* filterCoefficients = state->filterCoefficients; + const int32_t quoSamplerateRatio = state->quoSamplerateRatio; + const int32_t remSamplerateRatio = state->remSamplerateRatio; + const uint32_t decimateFactor = state->decimateFactor; + const uint32_t interpolateFactor = state->interpolateFactor; + int32_t i; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - + subfilterNum) - 1) / decimateFactor + 1); + } + + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[subfilterNum * N]; + const float* inputs = &in[inputIndex * MONO]; + MultiplyFilterMono(state, coeffs, inputs, out, subfilterNum); + out++; + + inputIndex += quoSamplerateRatio; + subfilterNum += remSamplerateRatio; + if (subfilterNum >= interpolateFactor) { + subfilterNum -= interpolateFactor; + inputIndex++; + } + } + + state->inputIndex = inputIndex; + state->subfilterNum = subfilterNum; + return outSample; +} + +static int32_t PolyphaseResamplerStereo(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + uint32_t subfilterNum = state->subfilterNum; + const float* filterCoefficients = state->filterCoefficients; + const int32_t quoSamplerateRatio = state->quoSamplerateRatio; + const int32_t remSamplerateRatio = state->remSamplerateRatio; + const uint32_t decimateFactor = state->decimateFactor; + const uint32_t interpolateFactor = state->interpolateFactor; + int32_t i; + + if (inputIndex < (int32_t) (*inputLength)) { + outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - + subfilterNum) - 1) / decimateFactor + 1); + } + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[subfilterNum * N]; + const float* inputs = &in[inputIndex * STEREO]; + MultiplyFilterStereo(state, coeffs, inputs, out, subfilterNum); + out += STEREO; + + inputIndex += quoSamplerateRatio; + subfilterNum += remSamplerateRatio; + if (subfilterNum >= interpolateFactor) { + subfilterNum -= interpolateFactor; + inputIndex++; + } + } + + state->inputIndex = inputIndex; + state->subfilterNum = subfilterNum; + return outSample; +} + +static int32_t PolyphaseResamplerMultichannel(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + uint32_t subfilterNum = state->subfilterNum; + const float* filterCoefficients = state->filterCoefficients; + const int32_t quoSamplerateRatio = state->quoSamplerateRatio; + const int32_t remSamplerateRatio = state->remSamplerateRatio; + const uint32_t decimateFactor = state->decimateFactor; + const uint32_t interpolateFactor = state->interpolateFactor; + const int32_t numChannels = state->numChannels; + int32_t i; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) + - subfilterNum) - 1) / decimateFactor + 1); + } + + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[subfilterNum * N]; + const float* inputs = &in[inputIndex * numChannels]; + MultiplyFilterMultichannel(state, coeffs, inputs, out, subfilterNum); + out += numChannels; + + inputIndex += quoSamplerateRatio; + subfilterNum += remSamplerateRatio; + if (subfilterNum >= interpolateFactor) { + subfilterNum -= interpolateFactor; + inputIndex++; + } + } + + state->inputIndex = inputIndex; + state->subfilterNum = subfilterNum; + return outSample; +} + +static int32_t PolyphaseDownsamplerHalfbandMono(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + const float* filterCoefficients = state->filterCoefficients; + float hCenter = filterCoefficients[indCenter]; + int32_t i, j; + float sum; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / TWO_STEPS + 1); + } + + for (i = 0; i < outSample; i++) { + const float *coeffs = &filterCoefficients[0]; + + const float *inputs = &in[inputIndex]; + // center + sum = hCenter * inputs[indCenter]; + // symmetric indices + for (j = 0; j < indCenter; j += TWO_STEPS) { + sum += (*coeffs) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); + coeffs += TWO_STEPS; + } + *out++ = sum; + inputIndex += TWO_STEPS; + } + + state->inputIndex = inputIndex; + return outSample; +} + +static int32_t PolyphaseDownsamplerHalfbandStereo(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + const float* filterCoefficients = state->filterCoefficients; + float hCenter = filterCoefficients[indCenter]; + int32_t i, j; + float sumL, sumR, h; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / TWO_STEPS + 1); + } + + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[0]; + const float* inputs = &in[inputIndex * STEREO]; + + // center + sumL = hCenter * inputs[N - TWO_STEPS]; + sumR = hCenter * inputs[N - 1]; + // symmetric indices + for (j = 0; j < indCenter; j += TWO_STEPS) { + h = *coeffs; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); + coeffs += TWO_STEPS; + } + *out++ = sumL; + *out++ = sumR; + inputIndex += TWO_STEPS; + } + + state->inputIndex = inputIndex; + return outSample; +} + +static int32_t PolyphaseDownsamplerHalfbandMultichannel(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + const float* filterCoefficients = state->filterCoefficients; + float hCenter = filterCoefficients[indCenter]; + int32_t i, j, ch; + float h; + float sum[MAX_NUM_CHANNEL]; + const int32_t numChannels = state->numChannels; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / TWO_STEPS + 1); + } + + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[0]; + const float* inputs = &in[inputIndex * numChannels]; + + // center + for (ch = 0; ch < numChannels; ch++) { + sum[ch] = hCenter * inputs[indCenter * numChannels + ch]; + } + // symmetric indices + for (j = 0; j < indCenter; j += TWO_STEPS) { + h = *coeffs; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); + } + coeffs += TWO_STEPS; + } + for (ch = 0; ch < numChannels; ch++) { + *out++ = sum[ch]; + } + inputIndex += TWO_STEPS; + } + + state->inputIndex = inputIndex; + return outSample; +} + +static int32_t PolyphaseDownsamplerThirdbandMono(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + const float* filterCoefficients = state->filterCoefficients; + int32_t i, j; + float sum; + int32_t rem = indCenter % THREE_STEPS; + float hCenter = filterCoefficients[indCenter]; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / THREE_STEPS + 1); + } + + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[0]; + const float* inputs = &in[inputIndex]; + + // center + sum = hCenter * inputs[indCenter]; + // symmetric indices + for (j = 0; j < rem; j++) { + sum += (*coeffs++) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); + } + coeffs++; + for (j = rem + 1; j < indCenter; j += THREE_STEPS) { + sum += (*coeffs++) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); + sum += (*coeffs++) * (inputs[(j + 1)] + inputs[(N - (j + 1) - TWO_STEPS)]); + coeffs++; + } + *out++ = sum; + inputIndex += THREE_STEPS; + } + + state->inputIndex = inputIndex; + return outSample; +} + +static int32_t PolyphaseDownsamplerThirdbandStereo(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + const float* filterCoefficients = state->filterCoefficients; + int32_t i, j; + float sumL, sumR, h; + int32_t rem = indCenter % THREE_STEPS; + float hCenter = filterCoefficients[indCenter]; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / THREE_STEPS + 1); + } + + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[0]; + const float* inputs = &in[inputIndex * STEREO]; + + // center + sumL = hCenter * inputs[N - TWO_STEPS]; + sumR = hCenter * inputs[N - 1]; + + // symmetric indices + for (j = 0; j < rem; j++) { + h = *coeffs++; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); + } + coeffs++; + for (j = rem + 1; j < indCenter; j += THREE_STEPS) { + h = *coeffs++; + sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); + sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); + h = *coeffs++; + sumL += h * (inputs[(j + 1) * STEREO] + inputs[(N - (j + 1) - TWO_STEPS) * STEREO]); + sumR += h * (inputs[(j + 1) * STEREO + 1] + inputs[(N - (j + 1) - TWO_STEPS) * STEREO + 1]); + coeffs++; + } + *out++ = sumL; + *out++ = sumR; + inputIndex += THREE_STEPS; + } + + state->inputIndex = inputIndex; + return outSample; +} + +static int32_t PolyphaseDownsamplerThirdbandMultichannel(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + const int32_t indCenter = N / TWO_STEPS - 1; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + const float* filterCoefficients = state->filterCoefficients; + int32_t i, j, ch; + float h1, h2; + float sum[MAX_NUM_CHANNEL]; + const int32_t numChannels = state->numChannels; + int32_t rem = indCenter % THREE_STEPS; + float hCenter = filterCoefficients[indCenter]; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / THREE_STEPS + 1); + } + + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[0]; + const float* inputs = &in[inputIndex * numChannels]; + + // center + for (ch = 0; ch < numChannels; ch++) { + sum[ch] = hCenter * (inputs[indCenter * numChannels + ch]); + } + + // symmetric indices + for (j = 0; j < rem; j++) { + h1 = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h1 * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); + } + } + coeffs++; + for (j = rem + 1; j < indCenter; j += THREE_STEPS) { + h1 = *coeffs++; + h2 = *coeffs++; + for (ch = 0; ch < numChannels; ch++) { + sum[ch] += h1 * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); + sum[ch] += h2 * (inputs[(j + 1) * numChannels + ch] + inputs[(N - (j + 1) - TWO_STEPS) * + numChannels + ch]); + } + coeffs++; + } + for (ch = 0; ch < numChannels; ch++) { + *out++ = sum[ch]; + } + inputIndex += THREE_STEPS; + } + + state->inputIndex = inputIndex; + return outSample; +} + +static int32_t PolyphaseResamplerCoarse(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + uint32_t subfilterNum = state->subfilterNum; + const float* filterCoefficients = state->filterCoefficients; + const int32_t quoSamplerateRatio = state->quoSamplerateRatio; + const int32_t remSamplerateRatio = state->remSamplerateRatio; + const uint32_t decimateFactor = state->decimateFactor; + const uint32_t interpolateFactor = state->interpolateFactor; + const int32_t numChannels = state->numChannels; + int32_t i; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - + subfilterNum) - 1) / decimateFactor + 1); + } + + for (i = 0; i < outSample; i++) { + const float* coeffs = &filterCoefficients[subfilterNum * N]; + const float* inputs = &in[inputIndex * numChannels]; + + state->multiplyFunSeq[subfilterNum](state, coeffs, inputs, out, subfilterNum); + out += numChannels; + + inputIndex += quoSamplerateRatio; + subfilterNum += remSamplerateRatio; + if (subfilterNum >= interpolateFactor) { + subfilterNum -= interpolateFactor; + inputIndex++; + } + } + + state->inputIndex = inputIndex; + state->subfilterNum = subfilterNum; + return outSample; +} + +/* + * This resampler is used to produce zero output in situations where memory for the filter could not be allocated. + */ +static int32_t PolyphaseResamplerZero(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + int32_t outSample = 0; + int32_t inputIndex = state->inputIndex; + uint32_t subfilterNum = state->subfilterNum; + const int32_t quoSamplerateRatio = state->quoSamplerateRatio; + const int32_t remSamplerateRatio = state->remSamplerateRatio; + const uint32_t decimateFactor = state->decimateFactor; + const uint32_t interpolateFactor = state->interpolateFactor; + const int32_t numChannels = state->numChannels; + int32_t i, ch; + + (void)in; + + if (inputIndex < (int32_t)(*inputLength)) { + outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - + subfilterNum) - 1) / decimateFactor + 1); + } + + for (i = 0; i < outSample; i++) { + for (ch = 0; ch < numChannels; ch++) { + *out++ = 0; + } + + inputIndex += quoSamplerateRatio; + subfilterNum += remSamplerateRatio; + if (subfilterNum >= interpolateFactor) { + subfilterNum -= interpolateFactor; + inputIndex++; + } + } + + state->inputIndex = inputIndex; + state->subfilterNum = subfilterNum; + return outSample; +} + +static MultiplyFilterFun GetMultiplyFilterFun(SingleStagePolyphaseResamplerState* state, int32_t i) +{ + int32_t channelMode = COMPARE_MIN(state->numChannels - 1, STEREO); + + if (state->interpolateFactor < state->decimateFactor) { // downsampling + if (i == 0) { + return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN + channelMode]; + } + if (TWO_STEPS * i == state->interpolateFactor) { + return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN + channelMode]; + } + return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_DOWN + channelMode]; + } else { // upsampling + if (i == 0) { + return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP + channelMode]; + } + if (TWO_STEPS * i == state->interpolateFactor) { + return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP + channelMode]; + } + return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_UP + channelMode]; + } +} + +static ResamplerMethod SetResamplerFunctionCoarse(SingleStagePolyphaseResamplerState* state) +{ + if (TWO_STEPS * state->interpolateFactor == state->decimateFactor) { + // Specific function for downsample by 2 + switch (state->numChannels) { + case MONO: + return PolyphaseDownsamplerHalfbandMono; + case STEREO: + return PolyphaseDownsamplerHalfbandStereo; + default: + return PolyphaseDownsamplerHalfbandMultichannel; + } + } + if (THREE_STEPS * state->interpolateFactor == state->decimateFactor) { + // Specific function for downsample by 3 + switch (state->numChannels) { + case MONO: + return PolyphaseDownsamplerThirdbandMono; + case STEREO: + return PolyphaseDownsamplerThirdbandStereo; + default: + return PolyphaseDownsamplerThirdbandMultichannel; + } + } + + for (int32_t j = 0; j < state->interpolateFactor; j++) { + state->multiplyFunSeq[j] = GetMultiplyFilterFun(state, j); + } + return PolyphaseResamplerCoarse; +} + +static int32_t UpdateResamplerState(SingleStagePolyphaseResamplerState* state) +{ + uint32_t oldFilterLength = state->filterLength; + + state->quoSamplerateRatio = state->decimateFactor / state->interpolateFactor; + state->remSamplerateRatio = state->decimateFactor % state->interpolateFactor; + state->filterLength = qualityTable[state->quality].filterLength; + state->coshParameter = qualityTable[state->quality].coshParameter; + + if (state->interpolateFactor < state->decimateFactor) { // downsampling + state->cutoff = (float)state->interpolateFactor / state->decimateFactor; + state->filterLength = state->filterLength * state->decimateFactor / state->interpolateFactor; + + // Round up to make sure filterLength be multiple of 8 + state->filterLength = 8 * ((state->filterLength - 1) / 8) + 8; + } else { // upsampling + state->cutoff = 1; + } + + // modified for new requirements (extended i/o sample rate combination) 2025.2.28 + if ((COMPARE_MAX(state->decimateFactor, state->interpolateFactor) <= MAX_RATIO_INTEGRAL_METHOD) & + ((state->decimateFactor == 1 || state->interpolateFactor == 1) || + ((float)state->decimateFactor / (float)state->interpolateFactor < 2.0f))) { + state->resamplerFunction = SetResamplerFunctionCoarse(state); + } else { // fine (non-integral) sampling rate ratio + switch (state->numChannels) { + case MONO: + state->resamplerFunction = PolyphaseResamplerMono; + break; + case STEREO: + state->resamplerFunction = PolyphaseResamplerStereo; + break; + default: + state->resamplerFunction = PolyphaseResamplerMultichannel; + } + } + + CalculateFilter(state); + + /* Here's the place where we update the filter memory to take into account + the change in filter length. It's probably the messiest part of the code + due to handling of lots of corner cases. */ + return UpdateFilterMemory(state, oldFilterLength); +} + +static int32_t UpdateFilterMemory(SingleStagePolyphaseResamplerState* state, uint32_t oldFilterLength) +{ + /* Adding bufferSize to filterLength won't overflow here because filterLength + could be multiplied by sizeof(float) above. */ + uint32_t requiredInputMemorySize = state->filterLength - 1 + state->bufferSize; + if (requiredInputMemorySize > state->inputMemorySize) { + if (state->inputMemory == NULL) { // first time initiaization + state->inputMemory = (float*)malloc(state->numChannels * requiredInputMemorySize * sizeof(float)); + if (state->inputMemory == NULL) { + return RESAMPLER_ERR_ALLOC_FAILED; + } + } else { + float* inputMemory = (float*)malloc(state->numChannels * requiredInputMemorySize * sizeof(float)); + int32_t ret = memcpy_s(inputMemory, requiredInputMemorySize * state->numChannels * sizeof(float), + state->inputMemory, state->inputMemorySize * state->numChannels * sizeof(float)); + if (INT_MAX / sizeof(float) / state->numChannels < requiredInputMemorySize || ret != 0) { + state->resamplerFunction = PolyphaseResamplerZero; + /* state->mem may still contain consumed input samples for the filter. + Restore filterLength so that filterLength - 1 still points to the position after + the last of these samples. */ + state->filterLength = oldFilterLength; + return RESAMPLER_ERR_ALLOC_FAILED; + } + free(state->inputMemory); + state->inputMemory = inputMemory; + } + state->inputMemorySize = requiredInputMemorySize; + } + /* codes for sudden sample rate change are deprecated and deleted so far */ + uint32_t i; + for (i = 0; i < state->numChannels * state->inputMemorySize; i++) { + state->inputMemory[i] = 0; + } + return RESAMPLER_ERR_SUCCESS; +} + +static int32_t SingleStagePolyphaseResamplerSetQuality(SingleStagePolyphaseResamplerState* state, int32_t quality) +{ + if (quality > QUALITY_LEVEL_TEN || quality < 0) { + return RESAMPLER_ERR_INVALID_ARG; + } + if (state->quality == quality) { + return RESAMPLER_ERR_SUCCESS; + } + state->quality = quality; + if (state->isInitialized) { + return UpdateResamplerState(state); + } + return RESAMPLER_ERR_SUCCESS; +} + +SingleStagePolyphaseResamplerState* SingleStagePolyphaseResamplerInit(uint32_t numChannels, + uint32_t decimateFactor, uint32_t interpolateFactor, int32_t quality, int32_t* err) +{ + SingleStagePolyphaseResamplerState* state; + int32_t filterErr; + + if (numChannels == 0 || decimateFactor == 0 || interpolateFactor == 0 || quality > QUALITY_LEVEL_TEN || + quality < 0) { + if (err) { + *err = RESAMPLER_ERR_INVALID_ARG; + } + return NULL; + } + state = (SingleStagePolyphaseResamplerState*)calloc(sizeof(SingleStagePolyphaseResamplerState), 1); + if (!state) { + if (err) { + *err = RESAMPLER_ERR_ALLOC_FAILED; + } + return NULL; + } + state->isInitialized = 0; + state->isStarted = 0; + state->decimateFactor = 0; + state->interpolateFactor = 0; + state->quality = -1; + state->filterCoefficientsSize = 0; + state->inputMemorySize = 0; + state->filterLength = 0; + state->filterCoefficients = NULL; + state->inputMemory = NULL; + state->resamplerFunction = 0; + + state->cutoff = 1.f; + state->numChannels = numChannels; + + state->bufferSize = BUFFER_SIZE; + + state->inputIndex = 0; + state->magicSamples = 0; + state->subfilterNum = 0; + + SingleStagePolyphaseResamplerSetQuality(state, quality); + filterErr = SingleStagePolyphaseResamplerSetRate(state, decimateFactor, interpolateFactor); + filterErr = UpdateResamplerState(state); + if (filterErr == RESAMPLER_ERR_SUCCESS) { + state->isInitialized = 1; + } else { + SingleStagePolyphaseResamplerFree(state); + state = NULL; + } + if (err) { + *err = filterErr; + } + return state; +} + +static void ApplyResampler(SingleStagePolyphaseResamplerState* state, uint32_t* inputLength, + float* out, uint32_t* outputLength) +{ + const int32_t N = state->filterLength; + int32_t outSample = 0; + float* inputMemory = state->inputMemory; + uint32_t inputSize; + const int32_t numChannels = state->numChannels; + int32_t j; + + state->isStarted = 1; + /* Call resampler function */ + outSample = state->resamplerFunction(state, inputMemory, inputLength, out, outputLength); + + if (state->inputIndex < (int32_t)*inputLength) { + *inputLength = state->inputIndex; + } + *outputLength = outSample; + state->inputIndex -= *inputLength; + + inputSize = (*inputLength) * numChannels; + for (j = 0; j < (N - 1) * numChannels; j++) { + inputMemory[j] = inputMemory[j + inputSize]; + } +} + + +static inline uint32_t ComputeGcd(uint32_t a, uint32_t b) +{ + while (b != 0) { + uint32_t temp = a; + + a = b; + b = temp % b; + } + return a; +} + + +int32_t SingleStagePolyphaseResamplerProcess(SingleStagePolyphaseResamplerState* state, const float* in, + uint32_t* inputLength, float* out, uint32_t* outputLength) +{ + int32_t j; + uint32_t remainingInputLength = *inputLength; + uint32_t remainingOutputLength = *outputLength; + const int32_t filtOffs = state->filterLength - 1; + const uint32_t bufferLen = state->inputMemorySize - filtOffs; + const int32_t numChannels = state->numChannels; + float* buf = state->inputMemory + filtOffs * numChannels; + + while (remainingInputLength && remainingOutputLength) { + uint32_t processInputLength = (remainingInputLength > bufferLen) ? bufferLen : remainingInputLength; + uint32_t processOutputLength = remainingOutputLength; + + if (in) { + for (j = 0; j < processInputLength * numChannels; j++) { + buf[j] = in[j]; + } + } else { + for (j = 0; j < processInputLength * numChannels; j++) { + buf[j] = 0; + } + } + ApplyResampler(state, &processInputLength, out, &processOutputLength); + remainingInputLength -= processInputLength; + remainingOutputLength -= processOutputLength; + out += processOutputLength * numChannels; + if (in) { + in += processInputLength * numChannels; + } + } + + *inputLength -= remainingInputLength; + *outputLength -= remainingOutputLength; + return state->resamplerFunction == PolyphaseResamplerZero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS; +} + +int32_t SingleStagePolyphaseResamplerSetRate(SingleStagePolyphaseResamplerState* state, uint32_t decimateFactor, + uint32_t interpolateFactor) +{ + uint32_t fact; + uint32_t oldInterpolateFactor; + + if (decimateFactor == 0 || interpolateFactor == 0) { + return RESAMPLER_ERR_INVALID_ARG; + } + + if (state->decimateFactor == decimateFactor && state->interpolateFactor == interpolateFactor) { + return RESAMPLER_ERR_SUCCESS; + } + + oldInterpolateFactor = state->interpolateFactor; + state->decimateFactor = decimateFactor; + state->interpolateFactor = interpolateFactor; + + fact = ComputeGcd(state->decimateFactor, state->interpolateFactor); + state->decimateFactor /= fact; + state->interpolateFactor /= fact; + + if (oldInterpolateFactor > 0) { + state->subfilterNum = state->subfilterNum * state->interpolateFactor / oldInterpolateFactor; + + /* Safety net */ + if (state->subfilterNum >= state->interpolateFactor) { + state->subfilterNum = state->interpolateFactor - 1; + } + } + + if (state->isInitialized) { + return UpdateResamplerState(state); + } + return RESAMPLER_ERR_SUCCESS; +} + +int32_t SingleStagePolyphaseResamplerSkipHalfTaps(SingleStagePolyphaseResamplerState* state) +{ + state->inputIndex = state->filterLength / TWO_STEPS; + return RESAMPLER_ERR_SUCCESS; +} + + +void SingleStagePolyphaseResamplerFree(SingleStagePolyphaseResamplerState* state) +{ + free(state->inputMemory); + state->inputMemory = NULL; + free(state->filterCoefficients); + state->filterCoefficients = NULL; + free(state); + state = NULL; +} + + +int32_t SingleStagePolyphaseResamplerResetMem(SingleStagePolyphaseResamplerState* state) +{ + uint32_t i; + state->inputIndex = 0; + state->magicSamples = 0; + state->subfilterNum = 0; + + for (i = 0; i < state->numChannels * state->inputMemorySize; i++) { + state->inputMemory[i] = 0; + } + return RESAMPLER_ERR_SUCCESS; +} \ No newline at end of file diff --git a/services/audio_engine/simd/SimdUtils.cpp b/services/audio_engine/simd/SimdUtils.cpp new file mode 100644 index 0000000000..97abfc5944 --- /dev/null +++ b/services/audio_engine/simd/SimdUtils.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2025 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 "SimdUtils.h" +#include +#include + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +#if USE_ARM_NEON == 1 +constexpr int ALIGIN_FLOAT_SIZE = 4; +#endif +void SimdPointByPointAdd(size_t length, const float* inputLeft, const float* inputRight, float* output) +{ +#if USE_ARM_NEON == 1 + if (length < ALIGIN_FLOAT_SIZE) { + for (size_t i = 0; i < length; i++) { + output[i] = inputLeft[i] + inputRight[i]; + } + } else { + size_t procLen = length >> 2; + float32x4_t left32x4, right32x4, out32x4; + for (size_t i = 0; i < procLen; i++) { + left32x4 = vld1q_f32(inputLeft + i * ALIGIN_FLOAT_SIZE); + right32x4 = vld1q_f32(inputRight + i * ALIGIN_FLOAT_SIZE); + out32x4 = vaddq_f32(left32x4, right32x4); + vst1q_f32(output + i * ALIGIN_FLOAT_SIZE, out32x4); + } + size_t odd = length - procLen * ALIGIN_FLOAT_SIZE; + if (odd) { + for (size_t j = length - odd; j < length; j++) { + output[j] = inputLeft[j] + inputRight[j]; + } + } + } +#else + for (size_t i = 0; i < length; i++) { + output[i] = inputLeft[i] + inputRight[i]; + } +#endif +} +void SimdPointByPointSub(size_t length, const float* inputLeft, const float* inputRight, float* output) +{ +#if USE_ARM_NEON == 1 + if (length < ALIGIN_FLOAT_SIZE) { + for (size_t i = 0; i < length; i++) { + output[i] = inputLeft[i] - inputRight[i]; + } + } else { + size_t procLen = length >> 2; + float32x4_t left32x4, right32x4, out32x4; + for (size_t i = 0; i < procLen; i++) { + left32x4 = vld1q_f32(inputLeft + i * ALIGIN_FLOAT_SIZE); + right32x4 = vld1q_f32(inputRight + i * ALIGIN_FLOAT_SIZE); + out32x4 = vsubq_f32(left32x4, right32x4); + vst1q_f32(output + i * ALIGIN_FLOAT_SIZE, out32x4); + } + size_t odd = length - procLen * ALIGIN_FLOAT_SIZE; + if (odd) { + for (size_t j = length - odd; j < length; j++) { + output[j] = inputLeft[j] - inputRight[j]; + } + } + } +#else + for (size_t i = 0; i < length; i++) { + output[i] = inputLeft[i] - inputRight[i]; + } +#endif +} + +void SimdPointByPointMul(size_t length, const float* inputLeft, const float* inputRight, float* output) +{ +#if USE_ARM_NEON == 1 + if (length < ALIGIN_FLOAT_SIZE) { + for (size_t i = 0; i < length; i++) { + output[i] = inputLeft[i] * inputRight[i]; + } + } else { + size_t procLen = length >> 2; + float32x4_t left32x4, right32x4, out32x4; + for (size_t i = 0; i < procLen; i++) { + left32x4 = vld1q_f32(inputLeft + i * ALIGIN_FLOAT_SIZE); + right32x4 = vld1q_f32(inputRight + i * ALIGIN_FLOAT_SIZE); + out32x4 = vmulq_f32(left32x4, right32x4); + vst1q_f32(output + i * ALIGIN_FLOAT_SIZE, out32x4); + } + size_t odd = length - procLen * ALIGIN_FLOAT_SIZE; + if (odd) { + for (size_t j = length - odd; j < length; j++) { + output[j] = inputLeft[j] * inputRight[j]; + } + } + } +#else + for (size_t i = 0; i < length; i++) { + output[i] = inputLeft[i] * inputRight[i]; + } +#endif +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/simd/SimdUtils.h b/services/audio_engine/simd/SimdUtils.h new file mode 100644 index 0000000000..beb7e889f1 --- /dev/null +++ b/services/audio_engine/simd/SimdUtils.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 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 SIMD_UTILS_H +#define SIMD_UTILS_H + +#include +#include + +#if !defined(DISABLE_SIMD) && \ + (defined(__aarch64__) || (defined(__arm__) && defined(__ARM_NEON__))) +// enable arm Simd +#include +#define USE_ARM_NEON 1 +#else +// disable SIMD. +#define USE_ARM_NEON 0 +#endif +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +void SimdPointByPointAdd(size_t length, const float* inputLeft, const float* inputRight, float* output); +void SimdPointByPointSub(size_t length, const float* inputLeft, const float* inputRight, float* output); +void SimdPointByPointMul(size_t length, const float* inputLeft, const float* inputRight, float* output); +}}} + +#endif \ No newline at end of file diff --git a/services/audio_engine/test/unittest/BUILD.gn b/services/audio_engine/test/unittest/BUILD.gn new file mode 100644 index 0000000000..03f927f0c4 --- /dev/null +++ b/services/audio_engine/test/unittest/BUILD.gn @@ -0,0 +1,90 @@ +# Copyright (c) 2022 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("//build/test.gni") +import("../../../../config.gni") + +module_output_path = "multimedia_audio_framework/audio_engine" + +config("audio_engine_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "./common", + "./unittest/include", + "../../simd", + "../../dfx", + "../../buffer", + "../../node/include", + "../../common", + "../../utils", + "../../plugin/resample/include", + "../../plugin/channel_converter/include", + "../../plugin/bitdepth_converter", + "../../manager/include", + "../../../../interfaces/inner_api/native/audiocommon/include", + "../../../audio_service/server/include", + "../../../audio_service/common/include", + "../../../audio_policy/server/include/service/common", + "../../../../frameworks/native/audioeffect/include", + "../../../../frameworks/native/hdiadapter_new/include", + ] +} + +ohos_unittest("audio_engine_unit_test") { + module_out_path = module_output_path + sources = [ + "common/test_case_common.cpp", + "dfx/hpae_dfx_tree_test.cpp", + "node/hpae_pcm_process_test.cpp", + "node/hpae_pcm_buffer_test.cpp", + "node/hpae_sink_input_node_test.cpp", + "node/hpae_sink_output_node_test.cpp", + "node/hpae_mixer_node_test.cpp", + "node/hpae_source_input_cluster_test.cpp", + "node/hpae_source_input_node_test.cpp", + "node/hpae_source_output_node_test.cpp", + "node/hpae_resample_node_test.cpp", + "node/hpae_process_cluster_test.cpp", + "node/hpae_output_cluster_test.cpp", + "node/hpae_gain_node_test.cpp", + "manager/hpae_manager_test.cpp", + "manager/hpae_render_manager_test.cpp", + "manager/hpae_capturer_manager_test.cpp", + "manager/hpae_audio_service_callback_unit_test.cpp", + "manager/hpae_inner_capturer_unit_test.cpp", + ] + + configs = [ ":audio_engine_private_config" ] + + deps = [ + "../../:audio_engine_node", + "../../:audio_engine_buffer", + "../../:audio_engine_manager", + "../../:audio_engine_utils", + ] + + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + resource_config_file = "./resource/ohos_test.xml" +} + diff --git a/services/audio_engine/test/unittest/common/hpae_audio_service_callback_unit_test.h b/services/audio_engine/test/unittest/common/hpae_audio_service_callback_unit_test.h new file mode 100644 index 0000000000..4935a1e879 --- /dev/null +++ b/services/audio_engine/test/unittest/common/hpae_audio_service_callback_unit_test.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025 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 HPAE_AUDIO_AUDIO_SERVICE_CALLBACK_UNIT_TEST_H +#define HPAE_AUDIO_AUDIO_SERVICE_CALLBACK_UNIT_TEST_H +#include "audio_service_hpae_callback.h" + +namespace OHOS { +namespace AudioStandard { +class HpaeAudioServiceCallbackUnitTest : public AudioServiceHpaeCallback { +public: + ~HpaeAudioServiceCallbackUnitTest() override; + + void OnOpenAudioPortCb(int32_t portId) override; + + void OnCloseAudioPortCb(int32_t result) override; + + void OnSetSinkMuteCb(int32_t result) override; + + void OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) override; + + void OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) override; + + void OnGetAllSinksCb(int32_t result, std::vector &sinks) override; + + void OnMoveSinkInputByIndexOrNameCb(int32_t result) override; + + void OnMoveSourceOutputByIndexOrNameCb(int32_t result) override; + + void OnSetSourceOutputMuteCb(int32_t result) override; + + void OnGetAudioEffectPropertyCbV3(int32_t result) override; + + void OnGetAudioEffectPropertyCb(int32_t result) override; + + void OnGetAudioEnhancePropertyCbV3(int32_t result) override; + + void OnGetAudioEnhancePropertyCb(int32_t result) override; + + void HandleSourceAudioStreamRemoved(uint32_t sessionId) override; + + int32_t GetPortId() const noexcept; + + int32_t GetCloseAudioPortResult() const noexcept; + + int32_t GetSetSinkMuteResult() const noexcept; + + int32_t GetGetAllSinkInputsResult() const noexcept; + + int32_t GetGetAllSourceOutputsResult() const noexcept; + + int32_t GetGetAllSinksResult() const noexcept; + + int32_t GetMoveSinkInputByIndexOrNameResult() const noexcept; + + int32_t GetMoveSourceOutputByIndexOrNameResult() const noexcept; + + int32_t GetSetSourceOutputMuteResult() const noexcept; + + int32_t GetGetAudioEffectPropertyResult() const noexcept; + + int32_t GetGetAudioEnhancePropertyResult() const noexcept; + + std::vector GetSinkInputs() const noexcept; + + std::vector GetSourceOutputs() const noexcept; + + std::vector GetSinks() const noexcept; + +private: + int32_t portId_ = -1; + int32_t closeAudioPortResult_ = -1; + int32_t setSinkMuteResult_ = -1; + int32_t getAllSinkInputsResult_ = -1; + int32_t getAllSourceOutputsResult_ = -1; + int32_t getAllSinksResult_ = -1; + int32_t moveSinkInputByIndexOrNameResult_ = -1; + int32_t moveSourceOutputByIndexOrNameResult_ = -1; + int32_t setSourceOutputMuteResult_ = -1; + int32_t getAudioEffectPropertyResult_ = -1; + int32_t getAudioEnhancePropertyResult_ = -1; + std::vector sinkInputs_; + std::vector sourceOutputs_; + std::vector sinks_; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/test/unittest/common/hpae_manager_unit_test.h b/services/audio_engine/test/unittest/common/hpae_manager_unit_test.h new file mode 100644 index 0000000000..d4d23c4fee --- /dev/null +++ b/services/audio_engine/test/unittest/common/hpae_manager_unit_test.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 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 HPAE_MANAGER_UNIT_TEST_H +#define HPAE_MANAGER_UNIT_TEST_H +#include "gtest/gtest.h" +#include "hpae_manager.h" +#include "hpae_info.h" +#include "hpae_audio_service_callback_unit_test.h" + +namespace OHOS { +namespace AudioStandard { +class HpaeManagerUnitTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + +protected: + std::shared_ptr hpaeManager_; + +protected: + void WaitForMsgProcessing(); + AudioModuleInfo GetSinkAudioModeInfo(); + AudioModuleInfo GetSourceAudioModeInfo(); + HPAE::HpaeStreamInfo GetRenderStreamInfo(); + HPAE::HpaeStreamInfo GetCaptureStreamInfo(); +}; +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/test/unittest/common/test_case_common.cpp b/services/audio_engine/test/unittest/common/test_case_common.cpp new file mode 100644 index 0000000000..aa0ab3fbca --- /dev/null +++ b/services/audio_engine/test/unittest/common/test_case_common.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2025 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 "TestCaseCommon" +#endif + +#include "test_case_common.h" +#include "hpae_info.h" +#include "audio_engine_log.h" + +namespace OHOS { +namespace AudioStandard { + +int32_t WriteFixedDataCb::OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) +{ + size_t sampleSize = GET_SIZE_FROM_FORMAT(format_); + for (size_t i = 0; i < callBackStremInfo.requestDataLen / sampleSize; i++) { + switch (format_) { + case AudioSampleFormat::SAMPLE_U8: { + *(callBackStremInfo.inputData + i) = writeNum_; + break; + } + case SAMPLE_S16LE: { + *((int16_t*)callBackStremInfo.inputData + i) = writeNum_; + break; + } + case SAMPLE_S24LE: { + uint8_t *p = (uint8_t *)(callBackStremInfo.inputData + OFFSET_BIT_24 * i); + p[BIT_DEPTH_TWO] = (uint8_t) (writeNum_ >> BIT_16); + p[1] = (uint8_t) (writeNum_ >> BIT_8); + p[0] = (uint8_t) writeNum_; + break; + } + case SAMPLE_S32LE: { + *((int32_t*)callBackStremInfo.inputData + i) = writeNum_; + break; + } + case SAMPLE_F32LE: { + *((float*)callBackStremInfo.inputData + i) = writeNum_; + break; + } + default: + break; + } + } + writeNum_++; + return 0; +} + +int32_t WriteFixedValueCb::OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) +{ + size_t sampleSize = GET_SIZE_FROM_FORMAT(format_); + for (size_t i = 0; i < callBackStremInfo.requestDataLen / sampleSize; i++) { + switch (format_) { + case AudioSampleFormat::SAMPLE_U8: { + *(callBackStremInfo.inputData + i) = fixValue_; + break; + } + case SAMPLE_S16LE: { + *((int16_t*)callBackStremInfo.inputData + i) = fixValue_; + break; + } + case SAMPLE_S24LE: { + uint8_t *p = (uint8_t *)(callBackStremInfo.inputData + OFFSET_BIT_24 * i); + p[BIT_DEPTH_TWO] = (uint8_t) (fixValue_ >> BIT_16); + p[1] = (uint8_t) (fixValue_ >> BIT_8); + p[0] = (uint8_t) fixValue_; + break; + } + case SAMPLE_S32LE: { + *((int32_t*)callBackStremInfo.inputData + i) = fixValue_; + break; + } + case SAMPLE_F32LE: { + *((float*)callBackStremInfo.inputData + i) = fixValue_; + break; + } + default: + break; + } + } + return 0; +} + +int32_t WriteIncDataCb::OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) +{ + for (size_t i = 0; i < callBackStremInfo.requestDataLen / GET_SIZE_FROM_FORMAT(format_); i++) { + switch (format_) { + case AudioSampleFormat::SAMPLE_U8: { + *(callBackStremInfo.inputData + i) = i; + break; + } + case SAMPLE_S16LE: { + *((int16_t*)callBackStremInfo.inputData + i) = i; + break; + } + case SAMPLE_S24LE: { + uint8_t *p = (uint8_t *)(callBackStremInfo.inputData + OFFSET_BIT_24 * i); + p[BIT_DEPTH_TWO] = (uint8_t) (i >> BIT_16); + p[1] = (uint8_t) (i >> BIT_8); + p[0] = (uint8_t) i; + break; + } + case SAMPLE_S32LE: { + *((int32_t*)callBackStremInfo.inputData + i) = i; + break; + } + case SAMPLE_F32LE: { + *((float*)callBackStremInfo.inputData + i) = i; + break; + } + default: + break; + } + } + writeNum_++; + return 0; +} + +void StatusChangeCb::OnStatusUpdate(IOperation operation) +{ + switch (operation) { + case OPERATION_STARTED: + status_ = I_STATUS_STARTED; + break; + case OPERATION_PAUSED: + status_ = I_STATUS_PAUSED; + break; + case OPERATION_STOPPED: + status_ = I_STATUS_STOPPED; + break; + default: + status_ = I_STATUS_INVALID; + } +} + +IStatus StatusChangeCb::GetStatus() +{ + return status_; +} + +ReadDataCb::ReadDataCb(const std::string &fileName) +{ + testFile_ = fopen(fileName.c_str(), "ab"); + if (testFile_ == nullptr) { + AUDIO_ERR_LOG("Open file failed"); + } +} + +ReadDataCb::~ReadDataCb() +{ + if (testFile_) { + fclose(testFile_); + testFile_ = nullptr; + } +} + +int32_t ReadDataCb::OnReadData(size_t length) +{ + AUDIO_WARNING_LOG("ProAudio do not support!"); + return SUCCESS; +} + +int32_t ReadDataCb::OnReadData(std::vector& outputData, size_t requestDataLen) +{ + CHECK_AND_RETURN_RET_LOG(testFile_ != nullptr, ERROR, "testFile_ is nullptr"); + fwrite(outputData.data(), 1, requestDataLen, testFile_); + return SUCCESS; +} +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/common/test_case_common.h b/services/audio_engine/test/unittest/common/test_case_common.h new file mode 100644 index 0000000000..237846f9ec --- /dev/null +++ b/services/audio_engine/test/unittest/common/test_case_common.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025 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 TEST_CASE_COMMON_H +#define TEST_CASE_COMMON_H +#include +#include "i_renderer_stream.h" +#include "i_capturer_stream.h" +#include "audio_errors.h" +#include "hpae_info.h" + +namespace OHOS { +namespace AudioStandard { +constexpr int OFFSET_BIT_24 = 3; +constexpr int BIT_DEPTH_TWO = 2; +constexpr int BIT_16 = 16; +constexpr int BIT_8 = 8; +constexpr float TEST_VALUE_PRESION = 0.001; +constexpr int TEST_FREAME_LEN = 125; +constexpr int TEST_SUB_FREAME_LEN = 50; + +#define DEFAULT_TEST_SINK_NAME "hdi_output" +#define DEFAULT_TEST_AUDIO_DEVICE_NAME "Speaker" +#define DEFAULT_TEST_DEVICE_CLASS "file_io" +#define DEFAULT_TEST_DEVICE_NETWORKID "LocalDevice" + +class WriteFixedDataCb : public IStreamCallback, public std::enable_shared_from_this { +public: + int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) override; + + explicit WriteFixedDataCb(AudioSampleFormat format) : format_(format) + {} + virtual ~WriteFixedDataCb() + {} + +private: + int32_t writeNum_ = 0; + AudioSampleFormat format_ = SAMPLE_F32LE; +}; + +class WriteFixedValueCb : public IStreamCallback, public std::enable_shared_from_this { +public: + int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) override; + WriteFixedValueCb(AudioSampleFormat format, int32_t fixedValue) : format_(format), fixValue_(fixedValue) + {} + virtual ~WriteFixedValueCb() + {} + +private: + AudioSampleFormat format_ = SAMPLE_F32LE; + int32_t fixValue_ = 0; +}; + +class WriteIncDataCb : public IStreamCallback, public std::enable_shared_from_this { +public: + int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) override; + explicit WriteIncDataCb(AudioSampleFormat format) : format_(format) + {} + virtual ~WriteIncDataCb() + {} + +private: + int32_t writeNum_ = 0; + AudioSampleFormat format_ = SAMPLE_F32LE; +}; + +class StatusChangeCb : public IStatusCallback, public std::enable_shared_from_this { +public: + void OnStatusUpdate(IOperation operation) override; + IStatus GetStatus(); + virtual ~StatusChangeCb() = default; +private: + IStatus status_; +}; + +class ReadDataCb : public IReadCallback, public std::enable_shared_from_this { +public: + explicit ReadDataCb(const std::string &fileName); + virtual ~ReadDataCb(); + int32_t OnReadData(size_t length) override; + int32_t OnReadData(std::vector& outputData, size_t requestDataLen) override; +private: + FILE *testFile_ = nullptr; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/test/unittest/dfx/hpae_dfx_tree_test.cpp b/services/audio_engine/test/unittest/dfx/hpae_dfx_tree_test.cpp new file mode 100644 index 0000000000..b9d4479fa2 --- /dev/null +++ b/services/audio_engine/test/unittest/dfx/hpae_dfx_tree_test.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include +#include +#include +#include +#include +#include "hpae_dfx_tree.h" +#include + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +class HpaeDfxTreeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeDfxTreeTest::SetUp() +{ + std::locale::global(std::locale("")); + std::wcout.imbue(std::locale()); +} + +void HpaeDfxTreeTest::TearDown() +{} + +TEST_F(HpaeDfxTreeTest, constructHpaeDfxTreeTest) +{ + HpaeDfxTree hpaeDfxTree; + HpaeNodeInfo info; + uint32_t nodeId = 123; + uint32_t sessionId = 12345; + size_t frameLen = 960; + uint32_t preNodeId = 0; + int32_t testNum = 10; + for (int32_t i = 0; i < testNum; i++) { + preNodeId = info.nodeId; + info.nodeId = nodeId + i; + info.sessionId = sessionId + i; + info.nodeName = "testNode1"; + info.frameLen = frameLen; + info.channels = STEREO; + info.samplingRate = SAMPLE_RATE_48000; + info.format = SAMPLE_F32LE; + info.sceneType = HPAE_SCENE_DEFAULT; + EXPECT_EQ(hpaeDfxTree.Insert(preNodeId, info), true); + } + std::vector> result = hpaeDfxTree.LevelOrderTraversal(); + std::string outStr; + hpaeDfxTree.PrintTree(outStr); + std::cout << outStr.c_str() << std::endl; + int32_t index = 0; + for (int32_t i = 0; i < result.size(); i++) { + for (int32_t j = 0; j < result[i].size(); j++) { + EXPECT_EQ(result[i][j].nodeId, index + nodeId); + EXPECT_EQ(result[i][j].sessionId, index + sessionId); + EXPECT_EQ(result[i][j].frameLen, frameLen); + EXPECT_EQ(result[i][j].samplingRate, SAMPLE_RATE_48000); + EXPECT_EQ(result[i][j].channels, STEREO); + EXPECT_EQ(result[i][j].format, SAMPLE_F32LE); + index++; + } + } +} + +TEST_F(HpaeDfxTreeTest, RemoveDfxTreeTest) +{ + HpaeDfxTree hpaeDfxTree; + HpaeNodeInfo info; + uint32_t nodeId = 123; + uint32_t sessionId = 12345; + size_t frameLen = 960; + uint32_t preNodeId = 0; + int32_t testNum = 10; + for (int32_t i = 0; i < testNum; i++) { + preNodeId = info.nodeId; + info.nodeId = nodeId + i; + info.sessionId = sessionId + i; + info.nodeName = "testNode2"; + info.frameLen = frameLen; + info.channels = MONO; + info.samplingRate = SAMPLE_RATE_16000; + info.format = SAMPLE_F32LE; + info.sceneType = HPAE_SCENE_MUSIC; + EXPECT_EQ(hpaeDfxTree.Insert(preNodeId, info), true); + } + std::vector> result = hpaeDfxTree.LevelOrderTraversal(); + EXPECT_EQ(result.size(), testNum); + uint32_t removeNodeIndex = 3; + EXPECT_EQ(hpaeDfxTree.Remove(nodeId + removeNodeIndex), true); + std::string outStr; + hpaeDfxTree.PrintTree(outStr); + std::cout << outStr.c_str() << std::endl; + result = hpaeDfxTree.LevelOrderTraversal(); + EXPECT_EQ(result.size(), removeNodeIndex); +} diff --git a/services/audio_engine/test/unittest/manager/hpae_audio_service_callback_unit_test.cpp b/services/audio_engine/test/unittest/manager/hpae_audio_service_callback_unit_test.cpp new file mode 100644 index 0000000000..545fa94f7f --- /dev/null +++ b/services/audio_engine/test/unittest/manager/hpae_audio_service_callback_unit_test.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2025 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 "hpae_audio_service_callback_unit_test.h" +namespace OHOS { +namespace AudioStandard { +HpaeAudioServiceCallbackUnitTest::~HpaeAudioServiceCallbackUnitTest() +{} + +void HpaeAudioServiceCallbackUnitTest::OnOpenAudioPortCb(int32_t portId) +{ + portId_ = portId; +} + +void HpaeAudioServiceCallbackUnitTest::OnCloseAudioPortCb(int32_t result) +{ + closeAudioPortResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::OnSetSinkMuteCb(int32_t result) +{ + setSinkMuteResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) +{ + getAllSinkInputsResult_ = result; + sinkInputs_ = sinkInputs; +} + +void HpaeAudioServiceCallbackUnitTest::OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) +{ + getAllSourceOutputsResult_ = result; + sourceOutputs_ = sourceOutputs; +} + +void HpaeAudioServiceCallbackUnitTest::OnGetAllSinksCb(int32_t result, std::vector &sinks) +{ + getAllSinksResult_ = result; + sinks_ = sinks; +} + +void HpaeAudioServiceCallbackUnitTest::OnMoveSinkInputByIndexOrNameCb(int32_t result) +{ + moveSinkInputByIndexOrNameResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::OnMoveSourceOutputByIndexOrNameCb(int32_t result) +{ + moveSourceOutputByIndexOrNameResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::OnSetSourceOutputMuteCb(int32_t result) +{ + setSourceOutputMuteResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::OnGetAudioEffectPropertyCbV3(int32_t result) +{ + getAudioEffectPropertyResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::OnGetAudioEffectPropertyCb(int32_t result) +{ + getAudioEffectPropertyResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::OnGetAudioEnhancePropertyCbV3(int32_t result) +{ + getAudioEnhancePropertyResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::OnGetAudioEnhancePropertyCb(int32_t result) +{ + getAudioEnhancePropertyResult_ = result; +} + +void HpaeAudioServiceCallbackUnitTest::HandleSourceAudioStreamRemoved(uint32_t sessionId) +{} + +int32_t HpaeAudioServiceCallbackUnitTest::GetPortId() const noexcept +{ + return portId_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetCloseAudioPortResult() const noexcept +{ + return closeAudioPortResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetSetSinkMuteResult() const noexcept +{ + return setSinkMuteResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetGetAllSinkInputsResult() const noexcept +{ + return getAllSinkInputsResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetGetAllSourceOutputsResult() const noexcept +{ + return getAllSourceOutputsResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetGetAllSinksResult() const noexcept +{ + return getAllSinksResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetMoveSinkInputByIndexOrNameResult() const noexcept +{ + return moveSinkInputByIndexOrNameResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetMoveSourceOutputByIndexOrNameResult() const noexcept +{ + return moveSourceOutputByIndexOrNameResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetSetSourceOutputMuteResult() const noexcept +{ + return setSourceOutputMuteResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetGetAudioEffectPropertyResult() const noexcept +{ + return getAudioEffectPropertyResult_; +} + +int32_t HpaeAudioServiceCallbackUnitTest::GetGetAudioEnhancePropertyResult() const noexcept +{ + return getAudioEnhancePropertyResult_; +} + +std::vector HpaeAudioServiceCallbackUnitTest::GetSinkInputs() const noexcept +{ + return sinkInputs_; +} + +std::vector HpaeAudioServiceCallbackUnitTest::GetSourceOutputs() const noexcept +{ + return sourceOutputs_; +} + +std::vector HpaeAudioServiceCallbackUnitTest::GetSinks() const noexcept +{ + return sinks_; +} + +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/manager/hpae_capturer_manager_test.cpp b/services/audio_engine/test/unittest/manager/hpae_capturer_manager_test.cpp new file mode 100644 index 0000000000..5fd90472b5 --- /dev/null +++ b/services/audio_engine/test/unittest/manager/hpae_capturer_manager_test.cpp @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include +#include "test_case_common.h" +#include "audio_errors.h" +#include "hpae_capturer_manager.h" + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +std::string g_rootCapturerPath = "/data/data/.pulse_dir/"; +const uint32_t DEFAULT_FRAME_LENGTH = 960; +const uint32_t DEFAULT_SESSION_ID = 123456; + +class HpaeCapturerManagerTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeCapturerManagerTest::SetUp() +{} + +void HpaeCapturerManagerTest::TearDown() +{} + +static void TestCheckSourceOutputInfo(HpaeSourceOutputInfo& sourceOutputInfo, const HpaeStreamInfo& streamInfo) +{ + EXPECT_EQ(sourceOutputInfo.nodeInfo.channels == streamInfo.channels, true); + EXPECT_EQ(sourceOutputInfo.nodeInfo.format == streamInfo.format, true); + EXPECT_EQ(sourceOutputInfo.nodeInfo.frameLen == streamInfo.frameLen, true); + EXPECT_EQ(sourceOutputInfo.nodeInfo.sessionId == streamInfo.sessionId, true); + EXPECT_EQ(sourceOutputInfo.nodeInfo.samplingRate == streamInfo.samplingRate, true); + EXPECT_EQ(sourceOutputInfo.nodeInfo.streamType == streamInfo.streamType, true); +} + +static void WaitForMsgProcessing(std::shared_ptr &capturerManager) +{ + int waitCount = 0; + const int WAIT_COUNT_THD = 5; + while (capturerManager->IsMsgProcessing()) { + std::this_thread::sleep_for(std::chrono::milliseconds(20)); // 20 for sleep + waitCount++; + if (waitCount >= WAIT_COUNT_THD) { + break; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(40)); // 40 for sleep + EXPECT_EQ(capturerManager->IsMsgProcessing(), false); + EXPECT_EQ(waitCount < WAIT_COUNT_THD, true); +} + +TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerConstructTest) +{ + HpaeSourceInfo sourceInfo; + sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sourceInfo.sourceType = SOURCE_TYPE_MIC; + sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; + + sourceInfo.samplingRate = SAMPLE_RATE_48000; + sourceInfo.channels = STEREO; + sourceInfo.format = SAMPLE_S16LE; + sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; + sourceInfo.ecType = HPAE_EC_TYPE_NONE; + sourceInfo.micRef = HPAE_REF_OFF; + + std::shared_ptr capturerManager = std::make_shared(sourceInfo); + HpaeSourceInfo dstSourceInfo = capturerManager->GetSourceInfo(); + EXPECT_EQ(dstSourceInfo.deviceNetId == sourceInfo.deviceNetId, true); + EXPECT_EQ(dstSourceInfo.deviceClass == sourceInfo.deviceClass, true); + EXPECT_EQ(dstSourceInfo.frameLen == sourceInfo.frameLen, true); + EXPECT_EQ(dstSourceInfo.samplingRate == sourceInfo.samplingRate, true); + EXPECT_EQ(dstSourceInfo.format == sourceInfo.format, true); + EXPECT_EQ(dstSourceInfo.channels == sourceInfo.channels, true); + EXPECT_EQ(dstSourceInfo.ecType == sourceInfo.ecType, true); + EXPECT_EQ(dstSourceInfo.micRef == sourceInfo.micRef, true); +} + +TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerInitTest) +{ + HpaeSourceInfo sourceInfo; + sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sourceInfo.sourceType = SOURCE_TYPE_MIC; + sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; + + sourceInfo.samplingRate = SAMPLE_RATE_48000; + sourceInfo.channels = STEREO; + sourceInfo.format = SAMPLE_S16LE; + sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; + sourceInfo.ecType = HPAE_EC_TYPE_NONE; + sourceInfo.micRef = HPAE_REF_OFF; + + std::shared_ptr capturerManager = std::make_shared(sourceInfo); + EXPECT_EQ(capturerManager->Init() == SUCCESS, true); +} + +TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerCreateDestoryStreamTest) +{ + HpaeSourceInfo sourceInfo; + sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sourceInfo.sourceType = SOURCE_TYPE_MIC; + sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; + + sourceInfo.samplingRate = SAMPLE_RATE_48000; + sourceInfo.channels = STEREO; + sourceInfo.format = SAMPLE_S16LE; + sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; + sourceInfo.ecType = HPAE_EC_TYPE_NONE; + sourceInfo.micRef = HPAE_REF_OFF; + + std::shared_ptr capturerManager = std::make_shared(sourceInfo); + EXPECT_EQ(capturerManager->Init() == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager->IsInit(), true); + HpaeStreamInfo streamInfo; + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_48000; + streamInfo.format = SAMPLE_S16LE; + streamInfo.frameLen = DEFAULT_FRAME_LENGTH; + streamInfo.sessionId = DEFAULT_SESSION_ID; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; + streamInfo.deviceName = "Built_in_mic"; + EXPECT_EQ(capturerManager->CreateStream(streamInfo) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager.use_count() == 1, true); + HpaeSourceOutputInfo sourceOutputInfo; + EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); + TestCheckSourceOutputInfo(sourceOutputInfo, streamInfo); + EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_NEW); + EXPECT_EQ(capturerManager->DestroyStream(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ( + capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == ERR_INVALID_OPERATION, true); +} + +static void StateControlTest(std::shared_ptr &capturerManager, HpaeStreamInfo &streamInfo, + HpaeSourceOutputInfo &sourceOutputInfo) +{ + EXPECT_EQ(capturerManager->Start(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); + EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_RUNNING); + EXPECT_EQ(capturerManager->IsRunning(), true); + + EXPECT_EQ(capturerManager->Pause(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); + EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_PAUSED); + EXPECT_EQ(capturerManager->IsRunning(), false); + + EXPECT_EQ(capturerManager->Start(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); + EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_RUNNING); + EXPECT_EQ(capturerManager->IsRunning(), true); + + EXPECT_EQ(capturerManager->Stop(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); + EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_STOPPED); + EXPECT_EQ(capturerManager->IsRunning(), false); + + EXPECT_EQ(capturerManager->DestroyStream(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ( + capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == ERR_INVALID_OPERATION, true); + EXPECT_EQ(capturerManager->IsRunning(), false); +} + +TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerStartStopTest) +{ + HpaeSourceInfo sourceInfo; + sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sourceInfo.sourceType = SOURCE_TYPE_MIC; + sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; + + sourceInfo.samplingRate = SAMPLE_RATE_48000; + sourceInfo.channels = STEREO; + sourceInfo.format = SAMPLE_S16LE; + sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; + sourceInfo.ecType = HPAE_EC_TYPE_NONE; + sourceInfo.micRef = HPAE_REF_OFF; + + std::shared_ptr capturerManager = std::make_shared(sourceInfo); + EXPECT_EQ(capturerManager->Init() == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager->IsInit(), true); + + HpaeStreamInfo streamInfo; + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_48000; + streamInfo.format = SAMPLE_S16LE; + streamInfo.frameLen = DEFAULT_FRAME_LENGTH; + streamInfo.sessionId = DEFAULT_SESSION_ID; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; + streamInfo.deviceName = "Built_in_mic"; + EXPECT_EQ(capturerManager->CreateStream(streamInfo) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager.use_count() == 1, true); + + HpaeSourceOutputInfo sourceOutputInfo; + EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); + TestCheckSourceOutputInfo(sourceOutputInfo, streamInfo); + EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_NEW); + EXPECT_EQ(capturerManager->IsRunning(), false); + + std::shared_ptr readDataCb = + std::make_shared(g_rootCapturerPath + "HpaeCapturerManagerTest.pcm"); + EXPECT_EQ(capturerManager->RegisterReadCallback(streamInfo.sessionId, readDataCb), SUCCESS); + EXPECT_EQ(readDataCb.use_count() == 1, true); + + StateControlTest(capturerManager, streamInfo, sourceOutputInfo); +} + +static void InitReloadSourceInfo(HpaeSourceInfo &sourceInfo, HpaeSourceInfo &newSourceInfo) +{ + sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sourceInfo.sourceType = SOURCE_TYPE_MIC; + sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; + + sourceInfo.samplingRate = SAMPLE_RATE_48000; + sourceInfo.channels = STEREO; + sourceInfo.format = SAMPLE_S16LE; + sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; + sourceInfo.ecType = HPAE_EC_TYPE_NONE; + sourceInfo.micRef = HPAE_REF_OFF; + + newSourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + newSourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + newSourceInfo.sourceType = SOURCE_TYPE_VOICE_TRANSCRIPTION; + newSourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; + + newSourceInfo.samplingRate = SAMPLE_RATE_48000; + newSourceInfo.channels = STEREO; + newSourceInfo.format = SAMPLE_S16LE; + newSourceInfo.frameLen = DEFAULT_FRAME_LENGTH; + newSourceInfo.ecType = HPAE_EC_TYPE_SAME_ADAPTER; + newSourceInfo.micRef = HPAE_REF_OFF; +} + +static void InitReloadStreamInfo(HpaeStreamInfo &streamInfo) +{ + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_48000; + streamInfo.format = SAMPLE_S16LE; + streamInfo.frameLen = DEFAULT_FRAME_LENGTH; + streamInfo.sessionId = DEFAULT_SESSION_ID; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; + streamInfo.deviceName = "Built_in_mic"; +} + +TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerReloadTest) +{ + HpaeSourceInfo sourceInfo; + HpaeSourceInfo newSourceInfo; + InitReloadSourceInfo(sourceInfo, newSourceInfo); + + std::shared_ptr capturerManager = std::make_shared(sourceInfo); + EXPECT_EQ(capturerManager->Init() == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager->IsInit(), true); + HpaeStreamInfo streamInfo; + InitReloadStreamInfo(streamInfo); + EXPECT_EQ(capturerManager->CreateStream(streamInfo) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager.use_count() == 1, true); + HpaeSourceOutputInfo sourceOutputInfo; + EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); + TestCheckSourceOutputInfo(sourceOutputInfo, streamInfo); + EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_NEW); + EXPECT_EQ(capturerManager->ReloadCaptureManager(newSourceInfo) == SUCCESS, true); + WaitForMsgProcessing(capturerManager); + EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/manager/hpae_inner_capturer_unit_test.cpp b/services/audio_engine/test/unittest/manager/hpae_inner_capturer_unit_test.cpp new file mode 100644 index 0000000000..db2e5f8032 --- /dev/null +++ b/services/audio_engine/test/unittest/manager/hpae_inner_capturer_unit_test.cpp @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2025 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 +#include "test_case_common.h" +#include "hpae_inner_capturer_manager.h" +#include +#include "audio_errors.h" +#include +#include + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +namespace OHOS { +namespace AudioStandard { +namespace HPAE{ +const uint32_t DEFAULT_SESSION_ID = 123456; +const float FRAME_LENGTH_IN_SECOND = 0.02; +std::string rootPath = "/data/data/.pulse_dir/"; + + +static HpaeSinkInfo GetInCapSinkInfo() +{ + HpaeSinkInfo sinkInfo; + sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.filePath = rootPath + "constructHpaeInnerCapturerManagerTest.pcm"; + sinkInfo.samplingRate = SAMPLE_RATE_48000; + sinkInfo.frameLen = SAMPLE_RATE_48000 * FRAME_LENGTH_IN_SECOND; + sinkInfo.format = SAMPLE_F32LE; + sinkInfo.channels = STEREO; + sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; + return sinkInfo; +} + +class HpaeInnerCapturerManagerUnitTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + std::shared_ptr hpaeInnerCapturerManager_ = nullptr; +}; + +void HpaeInnerCapturerManagerUnitTest::SetUp(void) +{ + HpaeSinkInfo sinkInfo; + sinkInfo = GetInCapSinkInfo(); + hpaeInnerCapturerManager_ = std::make_shared(sinkInfo); +} + +void HpaeInnerCapturerManagerUnitTest::TearDown(void) +{ + hpaeInnerCapturerManager_->DeInit(); + hpaeInnerCapturerManager_ = nullptr; +} + +static HpaeStreamInfo GetInCapPlayStreamInfo() +{ + HpaeStreamInfo streamInfo; + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_44100; + streamInfo.frameLen = SAMPLE_RATE_44100 * FRAME_LENGTH_IN_SECOND; + streamInfo.format = SAMPLE_S16LE; + streamInfo.sessionId = DEFAULT_SESSION_ID + 1; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; + streamInfo.sourceType = SOURCE_TYPE_PLAYBACK_CAPTURE; + return streamInfo; +} + +static HpaeStreamInfo GetInCapRecordStreamInfo() +{ + HpaeStreamInfo streamInfo; + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_44100; + streamInfo.frameLen = SAMPLE_RATE_44100 * FRAME_LENGTH_IN_SECOND; + streamInfo.format = SAMPLE_S16LE; + streamInfo.sessionId = DEFAULT_SESSION_ID; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; + streamInfo.sourceType = SOURCE_TYPE_PLAYBACK_CAPTURE; + return streamInfo; +} + +static void WaitForMsgProcessing(std::shared_ptr& hpaeInnerCapturerManager) +{ + int waitCount = 0; + const int32_t WAIT_COUNT_THD = 5; + while(hpaeInnerCapturerManager->IsMsgProcessing()) { + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + waitCount++; + if (waitCount >= WAIT_COUNT_THD) { + break; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(40)); + EXPECT_EQ(hpaeInnerCapturerManager->IsMsgProcessing(), false); + EXPECT_EQ(waitCount < WAIT_COUNT_THD, true); +} + +/** + * @tc.name : Test Construct + * @tc.type : FUNC + * @tc.number: Construct_001 + * @tc.desc : Test Construct when config in vaild. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, Construct_001) +{ + EXPECT_NE(hpaeInnerCapturerManager_, nullptr); + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSinkInfo sinkInfo; + sinkInfo = GetInCapSinkInfo(); + HpaeSinkInfo dstSinkInfo = hpaeInnerCapturerManager_->GetSinkInfo(); + EXPECT_EQ(dstSinkInfo.deviceNetId == sinkInfo.deviceNetId, true); + EXPECT_EQ(dstSinkInfo.deviceClass == sinkInfo.deviceClass, true); + EXPECT_EQ(dstSinkInfo.adapterName == sinkInfo.adapterName, true); + EXPECT_EQ(dstSinkInfo.frameLen == sinkInfo.frameLen, true); + EXPECT_EQ(dstSinkInfo.samplingRate == sinkInfo.samplingRate, true); + EXPECT_EQ(dstSinkInfo.format == sinkInfo.format, true); + EXPECT_EQ(dstSinkInfo.channels == sinkInfo.channels, true); + EXPECT_EQ(dstSinkInfo.deviceType == sinkInfo.deviceType, true); +} + +/** + * @tc.name : Test Init + * @tc.type : FUNC + * @tc.number: Init_001 + * @tc.desc : Test Init. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, Init_001) +{ + EXPECT_NE(hpaeInnerCapturerManager_, nullptr); + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), true); +} + +/** + * @tc.name : Test DeInit + * @tc.type : FUNC + * @tc.number: DeInit_001 + * @tc.desc : Test DeInit. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, DeInit_001) +{ + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->DeInit(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), false); +} + +/** + * @tc.name : Test CreateStream + * @tc.type : FUNC + * @tc.number: CreateStream_001 + * @tc.desc : Test CreateRendererStream when config in vaild. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, CreateStream_001) +{ + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), true); + HpaeStreamInfo streamInfo; + streamInfo = GetInCapPlayStreamInfo(); + EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(streamInfo), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSinkInputInfo sinkInputInfo; + EXPECT_EQ(hpaeInnerCapturerManager_->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo), SUCCESS); +} + +/** + * @tc.name : Test CreateStream + * @tc.type : FUNC + * @tc.number: CreateStream_002 + * @tc.desc : Test CreateCapturerStream when config in vaild. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, CreateStream_002) +{ + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), true); + HpaeStreamInfo streamInfo; + streamInfo = GetInCapRecordStreamInfo(); + EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(streamInfo), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSourceOutputInfo sourceOutoputInfo; + EXPECT_EQ(hpaeInnerCapturerManager_->GetSourceOutputInfo(streamInfo.sessionId, sourceOutoputInfo), SUCCESS); +} + +/** + * @tc.name : Test DestroyStream + * @tc.type : FUNC + * @tc.number: DestroyStream_001 + * @tc.desc : Test DestroyRendererStream when config in vaild. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, DestroyStream_001) +{ + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), true); + HpaeStreamInfo streamInfo; + streamInfo = GetInCapPlayStreamInfo(); + EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(streamInfo), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->Start(streamInfo.sessionId), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSinkInputInfo sinkInputInfo; + EXPECT_EQ(hpaeInnerCapturerManager_->GetSinkInputInfo(streamInfo.sessionId, + sinkInputInfo) == ERR_INVALID_OPERATION, true); +} + +/** + * @tc.name : Test DestroyStream + * @tc.type : FUNC + * @tc.number: DestroyStream_002 + * @tc.desc : Test DestroyCapturerStream when config in vaild. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, DestroyStream_002) +{ + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeStreamInfo streamInfo; + streamInfo = GetInCapRecordStreamInfo(); + EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(streamInfo), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSourceOutputInfo sourceOutoputInfo; + EXPECT_EQ(hpaeInnerCapturerManager_->GetSourceOutputInfo(streamInfo.sessionId, sourceOutoputInfo) + == ERR_INVALID_OPERATION, SUCCESS); +} + +/** + * @tc.name : Test StreamStartPauseChange_001 + * @tc.type : FUNC + * @tc.number: StreamStartPauseChange_001 + * @tc.desc : Test StartRendererStream when config in vaild. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, StreamStartPauseChange_001) +{ + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeStreamInfo recordStreamInfo; + recordStreamInfo = GetInCapRecordStreamInfo(); + EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(recordStreamInfo), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->Start(recordStreamInfo.sessionId), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSourceOutputInfo sourceOutoputInfo; + + HpaeStreamInfo playStreamInfo; + playStreamInfo = GetInCapPlayStreamInfo(); + EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(playStreamInfo), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + std::shared_ptr writeInPlayDataCb = std::make_shared(SAMPLE_S16LE); + EXPECT_EQ(hpaeInnerCapturerManager_->RegisterWriteCallback(playStreamInfo.sessionId, writeInPlayDataCb), SUCCESS); + EXPECT_EQ(hpaeInnerCapturerManager_->Start(playStreamInfo.sessionId), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSinkInputInfo sinkInputInfo; + + EXPECT_EQ(hpaeInnerCapturerManager_->Pause(recordStreamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->IsRunning(), true); + EXPECT_EQ(hpaeInnerCapturerManager_->Pause(playStreamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->IsRunning(), true); + EXPECT_EQ(hpaeInnerCapturerManager_->GetSinkInputInfo(playStreamInfo.sessionId, sinkInputInfo) == SUCCESS, true); + EXPECT_EQ(hpaeInnerCapturerManager_->GetSourceOutputInfo(recordStreamInfo.sessionId, sourceOutoputInfo), SUCCESS); + EXPECT_EQ(sourceOutoputInfo.capturerSessionInfo.state, CAPTURER_PAUSED); + EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_PAUSED); + EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(recordStreamInfo.sessionId) == SUCCESS, true); + EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(playStreamInfo.sessionId) == SUCCESS, true); +} + +/** + * @tc.name : Test StreamStartStopChange_001 + * @tc.type : FUNC + * @tc.number: StreamStartStopChange_001 + * @tc.desc : Test StartCapturerStream when config in vaild. + */ +TEST_F(HpaeInnerCapturerManagerUnitTest, StreamStartStopChange_001) +{ + EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeStreamInfo recordStreamInfo; + recordStreamInfo.channels = STEREO; + recordStreamInfo.samplingRate = SAMPLE_RATE_44100; + recordStreamInfo.frameLen = SAMPLE_RATE_44100 * FRAME_LENGTH_IN_SECOND; + recordStreamInfo.format = SAMPLE_S16LE; + recordStreamInfo.sessionId = DEFAULT_SESSION_ID; + recordStreamInfo.streamType = STREAM_MUSIC; + recordStreamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; + recordStreamInfo.sourceType = SOURCE_TYPE_PLAYBACK_CAPTURE; + EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(recordStreamInfo), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->Start(recordStreamInfo.sessionId), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSourceOutputInfo sourceOutoputInfo; + + HpaeStreamInfo playStreamInfo; + playStreamInfo = GetInCapPlayStreamInfo(); + EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(playStreamInfo), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + std::shared_ptr writeInPlayDataCb = std::make_shared(SAMPLE_S16LE); + EXPECT_EQ(hpaeInnerCapturerManager_->RegisterWriteCallback(playStreamInfo.sessionId, writeInPlayDataCb), SUCCESS); + EXPECT_EQ(hpaeInnerCapturerManager_->Start(playStreamInfo.sessionId), SUCCESS); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + HpaeSinkInputInfo sinkInputInfo; + + EXPECT_EQ(hpaeInnerCapturerManager_->Stop(recordStreamInfo.sessionId) == SUCCESS, true); + EXPECT_EQ(hpaeInnerCapturerManager_->Stop(playStreamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeInnerCapturerManager_); + EXPECT_EQ(hpaeInnerCapturerManager_->IsRunning(), true); + EXPECT_EQ(hpaeInnerCapturerManager_->GetSinkInputInfo(playStreamInfo.sessionId, sinkInputInfo) == SUCCESS, true); + EXPECT_EQ(hpaeInnerCapturerManager_->GetSourceOutputInfo(recordStreamInfo.sessionId, sourceOutoputInfo), SUCCESS); + EXPECT_EQ(sourceOutoputInfo.capturerSessionInfo.state, CAPTURER_STOPPED); + EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_STOPPED); + EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(recordStreamInfo.sessionId) == SUCCESS, true); + EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(playStreamInfo.sessionId) == SUCCESS, true); +} +}; +} // namespace OHOS::AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/manager/hpae_manager_test.cpp b/services/audio_engine/test/unittest/manager/hpae_manager_test.cpp new file mode 100644 index 0000000000..5c0ca34a6c --- /dev/null +++ b/services/audio_engine/test/unittest/manager/hpae_manager_test.cpp @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include +#include +#include +#include +#include +#include "test_case_common.h" +#include "audio_errors.h" +#include "hpae_manager_unit_test.h" + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; +namespace { +static std::string g_rootPath = "/data/data/.pulse_dir/"; +constexpr int32_t FRAME_LENGTH = 882; +constexpr int32_t TEST_STREAM_SESSION_ID = 123456; +constexpr int32_t TEST_SLEEP_TIME_20 = 20; +constexpr int32_t TEST_SLEEP_TIME_40 = 40; + +class HpaeManagerUnitTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + std::shared_ptr hpaeManager_ = nullptr; +}; +void HpaeManagerUnitTest::SetUp() +{ + hpaeManager_ = std::make_shared(); +} + +void HpaeManagerUnitTest::TearDown() +{ + hpaeManager_->DeInit(); + hpaeManager_ = nullptr; +} + +void WaitForMsgProcessing(std::shared_ptr &hpaeManager) +{ + int waitCount = 0; + const int WAIT_COUNT_THD = 5; + while (hpaeManager->IsMsgProcessing()) { + std::this_thread::sleep_for(std::chrono::milliseconds(TEST_SLEEP_TIME_20)); + waitCount++; + if (waitCount >= WAIT_COUNT_THD) { + break; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(TEST_SLEEP_TIME_40)); + EXPECT_EQ(hpaeManager->IsMsgProcessing(), false); + EXPECT_EQ(waitCount < WAIT_COUNT_THD, true); +} + +AudioModuleInfo GetSinkAudioModeInfo() +{ + AudioModuleInfo audioModuleInfo; + audioModuleInfo.lib = "libmodule-hdi-sink.z.so"; + audioModuleInfo.channels = "2"; + audioModuleInfo.rate = "48000"; + audioModuleInfo.name = "Speaker_File"; + audioModuleInfo.adapterName = "file_io"; + audioModuleInfo.className = "file_io"; + audioModuleInfo.bufferSize = "7680"; + audioModuleInfo.format = "s32le"; + audioModuleInfo.fixedLatency = "1"; + audioModuleInfo.offloadEnable = "0"; + audioModuleInfo.networkId = "LocalDevice"; + audioModuleInfo.fileName = g_rootPath + audioModuleInfo.adapterName + "_" + audioModuleInfo.rate + "_" + + audioModuleInfo.channels + "_" + audioModuleInfo.format + ".pcm"; + std::stringstream typeValue; + typeValue << static_cast(DEVICE_TYPE_SPEAKER); + audioModuleInfo.deviceType = typeValue.str(); + return audioModuleInfo; +} + +AudioModuleInfo GetSourceAudioModeInfo() +{ + AudioModuleInfo audioModuleInfo; + audioModuleInfo.lib = "libmodule-hdi-source.z.so"; + audioModuleInfo.channels = "2"; + audioModuleInfo.rate = "48000"; + audioModuleInfo.name = "mic"; + audioModuleInfo.adapterName = "file_io"; + audioModuleInfo.className = "file_io"; + audioModuleInfo.bufferSize = "3840"; + audioModuleInfo.format = "s16le"; + audioModuleInfo.fixedLatency = "1"; + audioModuleInfo.offloadEnable = "0"; + audioModuleInfo.networkId = "LocalDevice"; + audioModuleInfo.fileName = g_rootPath + "source_" + audioModuleInfo.adapterName + "_" + audioModuleInfo.rate + "_" + + audioModuleInfo.channels + "_" + audioModuleInfo.format + ".pcm"; + std::stringstream typeValue; + typeValue << static_cast(DEVICE_TYPE_FILE_SOURCE); + audioModuleInfo.deviceType = typeValue.str(); + return audioModuleInfo; +} + +HpaeStreamInfo GetRenderStreamInfo() +{ + HpaeStreamInfo streamInfo; + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_44100; + streamInfo.format = SAMPLE_S16LE; + streamInfo.frameLen = FRAME_LENGTH; + streamInfo.sessionId = TEST_STREAM_SESSION_ID; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; + return streamInfo; +} + +HpaeStreamInfo GetCaptureStreamInfo() +{ + HpaeStreamInfo streamInfo; + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_48000; + streamInfo.format = SAMPLE_S16LE; + streamInfo.frameLen = FRAME_LENGTH; + streamInfo.sessionId = TEST_STREAM_SESSION_ID; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; + return streamInfo; +} + +TEST_F(HpaeManagerUnitTest, constructHpaeManagerTest) +{ + EXPECT_NE(hpaeManager_, nullptr); + hpaeManager_->Init(); + EXPECT_EQ(hpaeManager_->IsInit(), true); + sleep(1); + EXPECT_EQ(hpaeManager_->IsRunning(), true); + hpaeManager_->DeInit(); + EXPECT_EQ(hpaeManager_->IsInit(), false); + sleep(1); + EXPECT_EQ(hpaeManager_->IsRunning(), false); +} + +TEST_F(HpaeManagerUnitTest, GetHpaeRenderManagerTest) +{ + EXPECT_NE(hpaeManager_, nullptr); + hpaeManager_->Init(); + EXPECT_EQ(hpaeManager_->IsInit(), true); + sleep(1); + EXPECT_EQ(hpaeManager_->IsRunning(), true); + + std::shared_ptr callback = std::make_shared(); + hpaeManager_->RegisterSerivceCallback(callback); + AudioModuleInfo audioModuleInfo = GetSinkAudioModeInfo(); + EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + int32_t portId = callback->GetPortId(); + + hpaeManager_->CloseAudioPort(portId); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(callback->GetCloseAudioPortResult(), SUCCESS); + + hpaeManager_->DeInit(); + EXPECT_EQ(hpaeManager_->IsInit(), false); + EXPECT_EQ(hpaeManager_->IsRunning(), false); +} + +TEST_F(HpaeManagerUnitTest, IHpaeRenderManagerTest) +{ + IHpaeManager::GetHpaeManager()->Init(); + EXPECT_EQ(IHpaeManager::GetHpaeManager()->IsInit(), true); + sleep(1); + EXPECT_EQ(IHpaeManager::GetHpaeManager()->IsRunning(), true); + + AudioModuleInfo audioModuleInfo = GetSinkAudioModeInfo(); + EXPECT_EQ(IHpaeManager::GetHpaeManager()->OpenAudioPort(audioModuleInfo), SUCCESS); + IHpaeManager::GetHpaeManager()->DeInit(); + EXPECT_EQ(IHpaeManager::GetHpaeManager()->IsInit(), false); + EXPECT_EQ(IHpaeManager::GetHpaeManager()->IsRunning(), false); +} + +TEST_F(HpaeManagerUnitTest, IHpaeRenderStreamManagerTest) +{ + EXPECT_NE(hpaeManager_, nullptr); + hpaeManager_->Init(); + EXPECT_EQ(hpaeManager_->IsInit(), true); + sleep(1); + AudioModuleInfo audioModuleInfo = GetSinkAudioModeInfo(); + std::shared_ptr callback = std::make_shared(); + int32_t result = hpaeManager_->RegisterSerivceCallback(callback); + EXPECT_EQ(result, SUCCESS); + EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); + hpaeManager_->SetDefaultSink(audioModuleInfo.name); + WaitForMsgProcessing(hpaeManager_); + HpaeStreamInfo streamInfo = GetRenderStreamInfo(); + hpaeManager_->CreateStream(streamInfo); + WaitForMsgProcessing(hpaeManager_); + + EXPECT_EQ(hpaeManager_->SetSinkMute(audioModuleInfo.name, true, true), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(callback->GetSetSinkMuteResult(), SUCCESS); + EXPECT_EQ(hpaeManager_->SetSinkMute(audioModuleInfo.name, false, true), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(callback->GetSetSinkMuteResult(), SUCCESS); + + EXPECT_EQ(hpaeManager_->SuspendAudioDevice(audioModuleInfo.name, true), SUCCESS); + EXPECT_EQ(hpaeManager_->SuspendAudioDevice(audioModuleInfo.name, false), SUCCESS); + + EXPECT_EQ(hpaeManager_->GetAllSinkInputs(), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(callback->GetGetAllSinkInputsResult(), SUCCESS); + std::vector sinkInputs = callback->GetSinkInputs(); + EXPECT_EQ(sinkInputs.size(), 1); + for (const auto &it : sinkInputs) { + std::cout << "sinkInputs.sinkName:" << it.sinkName << std::endl; + EXPECT_EQ(it.paStreamId, streamInfo.sessionId); + EXPECT_EQ(it.sinkName, audioModuleInfo.name); + } + hpaeManager_->Release(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + + EXPECT_EQ(hpaeManager_->GetAllSinkInputs(), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(callback->GetGetAllSinkInputsResult(), SUCCESS); + sinkInputs = callback->GetSinkInputs(); + EXPECT_EQ(sinkInputs.size(), 0); +} + +TEST_F(HpaeManagerUnitTest, IHpaeCaptureStreamManagerTest) +{ + EXPECT_NE(hpaeManager_, nullptr); + hpaeManager_->Init(); + EXPECT_EQ(hpaeManager_->IsInit(), true); + sleep(1); + std::shared_ptr callback = std::make_shared(); + int32_t result = hpaeManager_->RegisterSerivceCallback(callback); + EXPECT_EQ(result, SUCCESS); + + AudioModuleInfo audioModuleInfo = GetSourceAudioModeInfo(); + EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + hpaeManager_->SetDefaultSource(audioModuleInfo.name); + int32_t portId = callback->GetPortId(); + HpaeStreamInfo streamInfo = GetCaptureStreamInfo(); + hpaeManager_->CreateStream(streamInfo); + WaitForMsgProcessing(hpaeManager_); + + EXPECT_EQ(hpaeManager_->SetSourceOutputMute(portId, true), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(callback->GetSetSourceOutputMuteResult(), SUCCESS); + EXPECT_EQ(hpaeManager_->SetSourceOutputMute(portId, false), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(callback->GetSetSourceOutputMuteResult(), SUCCESS); + + EXPECT_EQ(hpaeManager_->GetAllSourceOutputs(), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(callback->GetGetAllSourceOutputsResult(), SUCCESS); + std::vector sourceOutputs = callback->GetSourceOutputs(); + EXPECT_EQ(sourceOutputs.size(), 1); + for (const auto &it : sourceOutputs) { + std::cout << "deviceSourceId:" << it.deviceSourceId << std::endl; + EXPECT_EQ(it.paStreamId, streamInfo.sessionId); + EXPECT_EQ(it.deviceSourceId, portId); + } + + hpaeManager_->Release(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); +} + +TEST_F(HpaeManagerUnitTest, IHpaeRenderStreamManagerTest002) +{ + EXPECT_NE(hpaeManager_, nullptr); + hpaeManager_->Init(); + EXPECT_EQ(hpaeManager_->IsInit(), true); + sleep(1); + AudioModuleInfo audioModuleInfo = GetSinkAudioModeInfo(); + EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); + hpaeManager_->SetDefaultSink(audioModuleInfo.name); + WaitForMsgProcessing(hpaeManager_); + HpaeStreamInfo streamInfo = GetRenderStreamInfo(); + hpaeManager_->CreateStream(streamInfo); + WaitForMsgProcessing(hpaeManager_); + int32_t fixedNum = 100; + std::shared_ptr writeFixedValueCb = std::make_shared(SAMPLE_S16LE, fixedNum); + hpaeManager_->RegisterWriteCallback(streamInfo.sessionId, writeFixedValueCb); + std::shared_ptr statusChangeCb = std::make_shared(); + hpaeManager_->RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_PLAY, streamInfo.sessionId, statusChangeCb); + WaitForMsgProcessing(hpaeManager_); + HpaeSessionInfo sessionInfo; + EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); + EXPECT_EQ(sessionInfo.streamInfo.sessionId, streamInfo.sessionId); + EXPECT_EQ(sessionInfo.streamInfo.streamType, streamInfo.streamType); + EXPECT_EQ(sessionInfo.streamInfo.frameLen, streamInfo.frameLen); + EXPECT_EQ(sessionInfo.streamInfo.format, streamInfo.format); + EXPECT_EQ(sessionInfo.streamInfo.samplingRate, streamInfo.samplingRate); + EXPECT_EQ(sessionInfo.streamInfo.channels, streamInfo.channels); + EXPECT_EQ(sessionInfo.streamInfo.streamClassType, streamInfo.streamClassType); + EXPECT_EQ(sessionInfo.state, I_STATUS_IDLE); + + hpaeManager_->Start(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo); + EXPECT_EQ(sessionInfo.state, I_STATUS_STARTING); + EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_STARTED); + + hpaeManager_->Pause(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); + EXPECT_EQ(sessionInfo.state, I_STATUS_PAUSING); + EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_PAUSED); + + hpaeManager_->Stop(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); + EXPECT_EQ(sessionInfo.state, I_STATUS_STOPPING); + EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_STOPPED); + + hpaeManager_->Release(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), ERROR); +} + +TEST_F(HpaeManagerUnitTest, IHpaeCaptureStreamManagerTest002) +{ + EXPECT_NE(hpaeManager_, nullptr); + hpaeManager_->Init(); + EXPECT_EQ(hpaeManager_->IsInit(), true); + sleep(1); + AudioModuleInfo audioModuleInfo = GetSourceAudioModeInfo(); + EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); + WaitForMsgProcessing(hpaeManager_); + hpaeManager_->SetDefaultSource(audioModuleInfo.name); + HpaeStreamInfo streamInfo = GetCaptureStreamInfo(); + hpaeManager_->CreateStream(streamInfo); + WaitForMsgProcessing(hpaeManager_); + int32_t fixedNum = 100; + std::shared_ptr writeFixedValueCb = std::make_shared(SAMPLE_S16LE, fixedNum); + hpaeManager_->RegisterWriteCallback(streamInfo.sessionId, writeFixedValueCb); + std::shared_ptr statusChangeCb = std::make_shared(); + hpaeManager_->RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_RECORD, streamInfo.sessionId, statusChangeCb); + WaitForMsgProcessing(hpaeManager_); + HpaeSessionInfo sessionInfo; + EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); + EXPECT_EQ(sessionInfo.streamInfo.sessionId, streamInfo.sessionId); + EXPECT_EQ(sessionInfo.streamInfo.streamType, streamInfo.streamType); + EXPECT_EQ(sessionInfo.streamInfo.frameLen, streamInfo.frameLen); + EXPECT_EQ(sessionInfo.streamInfo.streamClassType, streamInfo.streamClassType); + EXPECT_EQ(sessionInfo.state, I_STATUS_IDLE); + hpaeManager_->Start(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo); + EXPECT_EQ(sessionInfo.state, I_STATUS_STARTING); + EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_STARTED); + hpaeManager_->Pause(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); + EXPECT_EQ(sessionInfo.state, I_STATUS_PAUSING); + EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_PAUSED); + hpaeManager_->Stop(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); + EXPECT_EQ(sessionInfo.state, I_STATUS_STOPPING); + EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_STOPPED); + hpaeManager_->Release(streamInfo.streamClassType, streamInfo.sessionId); + WaitForMsgProcessing(hpaeManager_); + EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), ERROR); +} +} // namespace \ No newline at end of file diff --git a/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp b/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp new file mode 100644 index 0000000000..7030997955 --- /dev/null +++ b/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2025 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 +#include +#include "test_case_common.h" +#include "audio_errors.h" +#include "hpae_renderer_manager.h" +#include "hpae_offload_renderer_manager.h" +#include +#include +#include +#include +#include +#include + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; +namespace { +static std::string g_rootPath = "/data/data/.pulse_dir/"; +constexpr int32_t FRAME_LENGTH_882 = 882; +constexpr int32_t FRAME_LENGTH_960 = 960; +constexpr int32_t TEST_STREAM_SESSION_ID = 123456; +constexpr int32_t TEST_SLEEP_TIME_20 = 20; +constexpr int32_t TEST_SLEEP_TIME_40 = 40; +class HpaeRendererManagerTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeRendererManagerTest::SetUp() +{} + +void HpaeRendererManagerTest::TearDown() +{} + +static void TestCheckSinkInputInfo(HpaeSinkInputInfo &sinkInputInfo, const HpaeStreamInfo &streamInfo) +{ + EXPECT_EQ(sinkInputInfo.nodeInfo.channels == streamInfo.channels, true); + EXPECT_EQ(sinkInputInfo.nodeInfo.format == streamInfo.format, true); + EXPECT_EQ(sinkInputInfo.nodeInfo.frameLen == streamInfo.frameLen, true); + EXPECT_EQ(sinkInputInfo.nodeInfo.sessionId == streamInfo.sessionId, true); + EXPECT_EQ(sinkInputInfo.nodeInfo.samplingRate == streamInfo.samplingRate, true); + EXPECT_EQ(sinkInputInfo.nodeInfo.streamType == streamInfo.streamType, true); +} + +static void WaitForMsgProcessing(std::shared_ptr &hpaeRendererManager) +{ + int waitCount = 0; + const int WAIT_COUNT_THD = 5; + while (hpaeRendererManager->IsMsgProcessing()) { + std::this_thread::sleep_for(std::chrono::milliseconds(TEST_SLEEP_TIME_20)); + waitCount++; + if (waitCount >= WAIT_COUNT_THD) { + break; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(TEST_SLEEP_TIME_40)); + EXPECT_EQ(hpaeRendererManager->IsMsgProcessing(), false); + EXPECT_EQ(waitCount < WAIT_COUNT_THD, true); +} + +template +void TestIRendererManagerConstruct() +{ + HpaeSinkInfo sinkInfo; + sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.filePath = g_rootPath + "constructHpaeRendererManagerTest.pcm"; + sinkInfo.frameLen = FRAME_LENGTH_960; + sinkInfo.samplingRate = SAMPLE_RATE_48000; + sinkInfo.format = SAMPLE_F32LE; + sinkInfo.channels = STEREO; + sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; + std::shared_ptr hpaeRendererManager = std::make_shared(sinkInfo); + HpaeSinkInfo dstSinkInfo = hpaeRendererManager->GetSinkInfo(); + EXPECT_EQ(dstSinkInfo.deviceNetId == sinkInfo.deviceNetId, true); + EXPECT_EQ(dstSinkInfo.deviceClass == sinkInfo.deviceClass, true); + EXPECT_EQ(dstSinkInfo.adapterName == sinkInfo.adapterName, true); + EXPECT_EQ(dstSinkInfo.frameLen == sinkInfo.frameLen, true); + EXPECT_EQ(dstSinkInfo.samplingRate == sinkInfo.samplingRate, true); + EXPECT_EQ(dstSinkInfo.format == sinkInfo.format, true); + EXPECT_EQ(dstSinkInfo.channels == sinkInfo.channels, true); + EXPECT_EQ(dstSinkInfo.deviceType == sinkInfo.deviceType, true); +} + +template +void TestIRendererManagerInit() +{ + HpaeSinkInfo sinkInfo; + sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.filePath = g_rootPath + "constructHpaeRendererManagerTest.pcm"; + sinkInfo.frameLen = FRAME_LENGTH_960; + sinkInfo.samplingRate = SAMPLE_RATE_48000; + sinkInfo.format = SAMPLE_F32LE; + sinkInfo.channels = STEREO; + sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; + std::shared_ptr hpaeRendererManager = std::make_shared(sinkInfo); + EXPECT_EQ(hpaeRendererManager->Init() == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager->IsInit(), true); + EXPECT_EQ(hpaeRendererManager->DeInit() == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager->IsInit(), false); +} + +void TestRendererManagerCrteateStream( + std::shared_ptr &hpaeRendererManager, HpaeStreamInfo &streamInfo) +{ + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_44100; + streamInfo.format = SAMPLE_S16LE; + streamInfo.frameLen = FRAME_LENGTH_882; + streamInfo.sessionId = TEST_STREAM_SESSION_ID; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; + EXPECT_EQ(hpaeRendererManager->CreateStream(streamInfo) == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager.use_count() == 1, true); + HpaeSinkInputInfo sinkInputInfo; + int32_t ret = hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo); + EXPECT_EQ(ret == SUCCESS, true); + TestCheckSinkInputInfo(sinkInputInfo, streamInfo); +} + +template +void TestIRendererManagerCreateDestoryStream() +{ + HpaeSinkInfo sinkInfo; + sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.filePath = g_rootPath + "constructHpaeRendererManagerTest.pcm"; + sinkInfo.frameLen = FRAME_LENGTH_960; + sinkInfo.samplingRate = SAMPLE_RATE_48000; + sinkInfo.format = SAMPLE_F32LE; + sinkInfo.channels = STEREO; + sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; + std::shared_ptr hpaeRendererManager = std::make_shared(sinkInfo); + EXPECT_EQ(hpaeRendererManager->Init() == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager->IsInit(), true); + HpaeStreamInfo streamInfo; + TestRendererManagerCrteateStream(hpaeRendererManager, streamInfo); + int32_t ret = hpaeRendererManager->DestroyStream(streamInfo.sessionId); + EXPECT_EQ(ret == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + HpaeSinkInputInfo sinkInputInfo; + ret = hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo); + EXPECT_EQ(ret == ERR_INVALID_OPERATION, true); + streamInfo.channels = STEREO; + streamInfo.samplingRate = SAMPLE_RATE_48000; + streamInfo.format = SAMPLE_F32LE; + streamInfo.frameLen = FRAME_LENGTH_960; + streamInfo.sessionId = TEST_STREAM_SESSION_ID; + streamInfo.streamType = STREAM_MUSIC; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; + EXPECT_EQ(hpaeRendererManager->CreateStream(streamInfo) == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager.use_count() == 1, true); + EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); + TestCheckSinkInputInfo(sinkInputInfo, streamInfo); + EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_NEW); + EXPECT_EQ(hpaeRendererManager->DestroyStream(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + ret = hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo); + EXPECT_EQ(ret == ERR_INVALID_OPERATION, true); +} + +template +static void TestIRendererManagerStartPuaseStream() +{ + HpaeSinkInfo sinkInfo; + sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; + sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; + sinkInfo.filePath = g_rootPath + "constructHpaeRendererManagerTest.pcm"; + sinkInfo.frameLen = FRAME_LENGTH_960; + sinkInfo.samplingRate = SAMPLE_RATE_48000; + sinkInfo.format = SAMPLE_F32LE; + sinkInfo.channels = STEREO; + sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; + std::shared_ptr hpaeRendererManager = std::make_shared(sinkInfo); + EXPECT_EQ(hpaeRendererManager->Init() == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager->IsInit(), true); + HpaeStreamInfo streamInfo; + TestRendererManagerCrteateStream(hpaeRendererManager, streamInfo); + HpaeSinkInputInfo sinkInputInfo; + std::shared_ptr writeIncDataCb = std::make_shared(SAMPLE_S16LE); + EXPECT_EQ(hpaeRendererManager->RegisterWriteCallback(streamInfo.sessionId, writeIncDataCb), SUCCESS); + EXPECT_EQ(writeIncDataCb.use_count() == 1, true); + EXPECT_EQ(hpaeRendererManager->Start(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); + EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_RUNNING); + EXPECT_EQ(hpaeRendererManager->IsRunning(), true); + EXPECT_EQ(hpaeRendererManager->Pause(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); + EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_PAUSED); + EXPECT_EQ(hpaeRendererManager->Start(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); + EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_RUNNING); + EXPECT_EQ(hpaeRendererManager->IsRunning(), true); + EXPECT_EQ(hpaeRendererManager->Stop(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); + EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_STOPPED); + EXPECT_EQ(hpaeRendererManager->DestroyStream(streamInfo.sessionId) == SUCCESS, true); + WaitForMsgProcessing(hpaeRendererManager); + EXPECT_EQ( + hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == ERR_INVALID_OPERATION, true); +} + +TEST_F(HpaeRendererManagerTest, constructHpaeRendererManagerTest) +{ + TestIRendererManagerConstruct(); + std::cout << "test offload" << std::endl; + TestIRendererManagerConstruct(); +} + +TEST_F(HpaeRendererManagerTest, HpaeRendererManagerInitTest) +{ + TestIRendererManagerInit(); + std::cout << "test offload" << std::endl; + TestIRendererManagerInit(); +} + +TEST_F(HpaeRendererManagerTest, HpaeRendererManagerCreateDestoryStreamTest) +{ + TestIRendererManagerCreateDestoryStream(); + std::cout << "test offload" << std::endl; + TestIRendererManagerCreateDestoryStream(); +} + +TEST_F(HpaeRendererManagerTest, HpaeRendererManagerStartPuaseStreamTest) +{ + TestIRendererManagerStartPuaseStream(); + std::cout << "test offload" << std::endl; + TestIRendererManagerStartPuaseStream(); +} +} // namespace \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_gain_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_gain_node_test.cpp new file mode 100644 index 0000000000..29bc6c6649 --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_gain_node_test.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include "hpae_sink_input_node.h" +#include "hpae_sink_output_node.h" +#include "hpae_gain_node.h" +#include "test_case_common.h" +#include "audio_errors.h" + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +class HpaeGainNodeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeGainNodeTest::SetUp() +{} + +void HpaeGainNodeTest::TearDown() +{} + +static int32_t g_testValue = 0; + +namespace { + +constexpr uint32_t DEFAULT_NODE_ID = 1234; +constexpr uint32_t DEFAULT_FRAME_LEN = 960; +constexpr uint32_t DEFAULT_NUM_TWO = 2; + +TEST_F(HpaeGainNodeTest, constructHpaeGainNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODE_ID; + nodeInfo.frameLen = DEFAULT_FRAME_LEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + nodeInfo.deviceClass = "primary"; + std::shared_ptr hpaeGainNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeGainNode->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeGainNode->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeGainNode->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeGainNode->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeGainNode->GetBitWidth(), nodeInfo.format); + std::cout << "HpaeGainNodeTest::GetNodeInfo" << std::endl; + HpaeNodeInfo &retNi = hpaeGainNode->GetNodeInfo(); + EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); + std::cout << "samplingRate: " << retNi.samplingRate << std::endl; + EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); + std::cout << "nodeId: " << retNi.nodeId << std::endl; + EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); + std::cout << "frameLen: " << retNi.frameLen << std::endl; + EXPECT_EQ(retNi.channels, nodeInfo.channels); + std::cout << "channels: " << retNi.channels << std::endl; + EXPECT_EQ(retNi.format, nodeInfo.format); + std::cout << "format: " << retNi.format << std::endl; + EXPECT_EQ(retNi.deviceClass, nodeInfo.deviceClass); + std::cout << "deviceClass: " << retNi.deviceClass << std::endl; + std::cout << "HpaeGainNodeTest::GetNodeInfo end" << std::endl; +} +static int32_t TestRendererRenderFrame(const char *data, uint64_t len) +{ + float curGain = 0.0f; + float targetGain = 1.0f; + float stepGain = targetGain - curGain; + uint64_t frameLen = len / (SAMPLE_F32LE * STEREO); + stepGain = stepGain / frameLen; + const float *tempData = reinterpret_cast(data); + for (int32_t i = 0; i < frameLen; i++) { + const float left = tempData[DEFAULT_NUM_TWO * i]; + const float right = tempData[DEFAULT_NUM_TWO * i + 1]; + const float expectedValue = g_testValue * (curGain + i * stepGain); + EXPECT_EQ(left, expectedValue); + EXPECT_EQ(right, expectedValue); + } + return 0; +} + +TEST_F(HpaeGainNodeTest, testHpaeGainTestNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODE_ID; + nodeInfo.frameLen = DEFAULT_FRAME_LEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + nodeInfo.streamType = STREAM_MUSIC; + std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); + std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); + std::shared_ptr hpaeGainNode = std::make_shared(nodeInfo); + hpaeGainNode->Connect(hpaeSinkInputNode); + hpaeSinkOutputNode->Connect(hpaeGainNode); + std::string deviceClass = "file_io"; + std::string deviceNetId = "LocalDevice"; + EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0); + EXPECT_EQ(hpaeSinkInputNode.use_count(), DEFAULT_NUM_TWO); + EXPECT_EQ(hpaeGainNode.use_count(), DEFAULT_NUM_TWO); + EXPECT_EQ(hpaeSinkOutputNode.use_count(), 1); + g_testValue = 0; + int32_t testValue = 100; + std::shared_ptr writeFixedValueCb0 = + std::make_shared(SAMPLE_F32LE, testValue); + g_testValue = testValue; + hpaeSinkInputNode->RegisterWriteCallback(writeFixedValueCb0); + hpaeSinkOutputNode->DoProcess(); + TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), + nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); + hpaeSinkOutputNode->DoProcess(); + TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), + nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); + hpaeSinkOutputNode->DisConnect(hpaeGainNode); + EXPECT_EQ(hpaeGainNode.use_count(), 1); + hpaeGainNode->DisConnect(hpaeSinkInputNode); + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); +} +} // namespace diff --git a/services/audio_engine/test/unittest/node/hpae_mixer_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_mixer_node_test.cpp new file mode 100644 index 0000000000..16a543aaba --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_mixer_node_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include "hpae_sink_input_node.h" +#include "hpae_mixer_node.h" +#include "hpae_sink_output_node.h" +#include "test_case_common.h" +#include "audio_errors.h" + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; +namespace { +static constexpr int32_t TEST_VALUE1 = 100; +static constexpr int32_t TEST_VALUE2 = 200; +static constexpr uint32_t TEST_ID = 1243; +static constexpr uint32_t TEST_FRAMELEN = 960; +class HpaeMixerNodeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeMixerNodeTest::SetUp() +{} + +void HpaeMixerNodeTest::TearDown() +{} + +static int32_t g_testValue = 0; + +TEST_F(HpaeMixerNodeTest, constructHpaeMixerNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = TEST_ID; + nodeInfo.frameLen = TEST_FRAMELEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeMixerNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeMixerNode->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeMixerNode->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeMixerNode->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeMixerNode->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeMixerNode->GetBitWidth(), nodeInfo.format); + HpaeNodeInfo &retNi = hpaeMixerNode->GetNodeInfo(); + EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); + EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); + EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); + EXPECT_EQ(retNi.channels, nodeInfo.channels); + EXPECT_EQ(retNi.format, nodeInfo.format); +} +static int32_t TestRendererRenderFrame(const char *data, uint64_t len) +{ + for (int32_t i = 0; i < len / SAMPLE_F32LE; i++) { + float diff = *((float*)data + i) - g_testValue; + EXPECT_EQ(fabs(diff) < TEST_VALUE_PRESION, true); + } + return 0; +} + +TEST_F(HpaeMixerNodeTest, testHpaePlayOutConnectNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = TEST_ID; + nodeInfo.frameLen = TEST_FRAMELEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); + std::shared_ptr hpaeSinkInputNode0 = std::make_shared(nodeInfo); + std::shared_ptr hpaeSinkInputNode1 = std::make_shared(nodeInfo); + std::shared_ptr hpaeMixerNode = std::make_shared(nodeInfo); + hpaeMixerNode->Connect(hpaeSinkInputNode0); + hpaeMixerNode->Connect(hpaeSinkInputNode1); + std::cout << "hpaeMixerNode->GetPreOutNum():" << hpaeMixerNode->GetPreOutNum() << std::endl; + EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); + hpaeSinkOutputNode->Connect(hpaeMixerNode); + std::string deviceClass = "file_io"; + std::string deviceNetId = "LocalDevice"; + EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 1); + EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0); + EXPECT_EQ(hpaeSinkInputNode0.use_count(), 1 + 1); + EXPECT_EQ(hpaeSinkInputNode1.use_count(), 1 + 1); + EXPECT_EQ(hpaeMixerNode.use_count(), 1 + 1); + g_testValue = 0; + int32_t testValue = TEST_VALUE1; + std::shared_ptr writeFixedValueCb0 = + std::make_shared(SAMPLE_F32LE, testValue); + g_testValue = g_testValue + testValue; + hpaeSinkInputNode0->RegisterWriteCallback(writeFixedValueCb0); + testValue = TEST_VALUE2; + std::shared_ptr writeFixedValueCb1 = + std::make_shared(SAMPLE_F32LE, testValue); + g_testValue = g_testValue + testValue; + hpaeSinkInputNode1->RegisterWriteCallback(writeFixedValueCb1); + hpaeSinkOutputNode->DoProcess(); + TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), nodeInfo.frameLen * nodeInfo.channels * + GET_SIZE_FROM_FORMAT(nodeInfo.format)); + hpaeSinkOutputNode->DisConnect(hpaeMixerNode); + EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); + EXPECT_EQ(hpaeMixerNode.use_count(), 1); + hpaeMixerNode->DisConnect(hpaeSinkInputNode0); + EXPECT_EQ(hpaeSinkInputNode0.use_count(), 1); + EXPECT_EQ(hpaeMixerNode->GetPreOutNum(), 1); + hpaeMixerNode->DisConnect(hpaeSinkInputNode1); + EXPECT_EQ(hpaeSinkInputNode1.use_count(), 1); + EXPECT_EQ(hpaeMixerNode->GetPreOutNum(), 0); +} + +} // namespace \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_output_cluster_test.cpp b/services/audio_engine/test/unittest/node/hpae_output_cluster_test.cpp new file mode 100644 index 0000000000..4e52290b49 --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_output_cluster_test.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include "hpae_process_cluster.h" +#include "test_case_common.h" +#include "audio_errors.h" +#include "hpae_sink_input_node.h" +#include "hpae_output_cluster.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr uint32_t NODE_ID = 1243; +constexpr uint32_t SESSION_ID_1 = 12345; +constexpr uint32_t SESSION_ID_2 = 12346; +constexpr uint32_t FRAME_LEN = 960; +constexpr uint32_t FRAME_LEN_2 = 820; +constexpr uint32_t NUM_TWO = 2; +constexpr int32_t TEST_VALUE_1 = 300; +constexpr int32_t TEST_VALUE_2 = 400; + +static std::string g_deviceClass = "file_io"; +static std::string g_deviceNetId = "LocalDevice"; + +static int32_t g_testValue1 = 0; +static int32_t g_testValue2 = 0; + +static int32_t TestRendererRenderFrame(const char *data, uint64_t len) +{ + float curGain = 0.0f; + float targetGain = 1.0f; + uint64_t frameLen = len / (SAMPLE_F32LE * STEREO); + float stepGain = (targetGain - curGain) / frameLen; + + const float *tempData = reinterpret_cast(data); + for (int32_t i = 0; i < frameLen; i++) { + const float left = tempData[NUM_TWO * i]; + const float right = tempData[NUM_TWO * i + 1]; + const float expectedValue = g_testValue1 * (curGain + i * stepGain) + g_testValue2 * (curGain + i * stepGain); + EXPECT_EQ(left, expectedValue); + EXPECT_EQ(right, expectedValue); + } + return 0; +} + +static void InitHpaeWriteDataOutSessionTest(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &dummySinkInfo) +{ + nodeInfo.nodeId = NODE_ID; + nodeInfo.frameLen = FRAME_LEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + + dummySinkInfo.frameLen = FRAME_LEN; + dummySinkInfo.samplingRate = SAMPLE_RATE_48000; + dummySinkInfo.channels = STEREO; + dummySinkInfo.format = SAMPLE_F32LE; + dummySinkInfo.deviceClass = g_deviceClass; + dummySinkInfo.deviceNetId = g_deviceNetId; +} + +class HpaeOutputClusterTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeOutputClusterTest::SetUp() +{} + +void HpaeOutputClusterTest::TearDown() +{} + +TEST_F(HpaeOutputClusterTest, constructHpaeOutputClusterNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = NODE_ID; + nodeInfo.frameLen = FRAME_LEN; + nodeInfo.sessionId = SESSION_ID_1; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + + std::shared_ptr hpaeoutputCluster = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeoutputCluster->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeoutputCluster->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeoutputCluster->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeoutputCluster->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeoutputCluster->GetBitWidth(), nodeInfo.format); + + std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); + hpaeoutputCluster->Connect(hpaeSinkInputNode); + EXPECT_EQ(hpaeSinkInputNode.use_count(), NUM_TWO); + EXPECT_EQ(hpaeoutputCluster->GetConverterNodeCount(), 1); + nodeInfo.frameLen = FRAME_LEN_2; + nodeInfo.sessionId = SESSION_ID_2; + nodeInfo.samplingRate = SAMPLE_RATE_44100; + std::shared_ptr hpaeSinkInputNode1 = std::make_shared(nodeInfo); + hpaeoutputCluster->Connect(hpaeSinkInputNode1); + EXPECT_EQ(hpaeSinkInputNode1.use_count(), NUM_TWO); + EXPECT_EQ(hpaeoutputCluster->GetConverterNodeCount(), 1); +} + +TEST_F(HpaeOutputClusterTest, testHpaeWriteDataOutSessionTest) +{ + HpaeNodeInfo nodeInfo; + HpaeSinkInfo dummySinkInfo; + InitHpaeWriteDataOutSessionTest(nodeInfo, dummySinkInfo); + std::shared_ptr hpaeOutputCluster = std::make_shared(nodeInfo); + nodeInfo.sessionId = SESSION_ID_1; + nodeInfo.streamType = STREAM_MUSIC; + std::shared_ptr musicSinkInputNode = std::make_shared(nodeInfo); + nodeInfo.sessionId = SESSION_ID_2; + nodeInfo.streamType = STREAM_RING; + std::shared_ptr ringSinkInputNode = std::make_shared(nodeInfo); + nodeInfo.sceneType = HPAE_SCENE_MUSIC; + std::shared_ptr muiscProcessCluster = + std::make_shared(nodeInfo, dummySinkInfo); + nodeInfo.sceneType = HPAE_SCENE_RING; + std::shared_ptr ringProcessCluster = + std::make_shared(nodeInfo, dummySinkInfo); + muiscProcessCluster->Connect(musicSinkInputNode); + ringProcessCluster->Connect(ringSinkInputNode); + hpaeOutputCluster->Connect(muiscProcessCluster); + hpaeOutputCluster->Connect(ringProcessCluster); + + EXPECT_EQ(ringProcessCluster->GetGainNodeCount(), 1); + EXPECT_EQ(muiscProcessCluster->GetGainNodeCount(), 1); + EXPECT_EQ(muiscProcessCluster->GetConverterNodeCount(), 1); + EXPECT_EQ(ringProcessCluster->GetConverterNodeCount(), 1); + EXPECT_EQ(hpaeOutputCluster->GetConverterNodeCount(), NUM_TWO); + EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), NUM_TWO); + + EXPECT_EQ(hpaeOutputCluster->GetInstance(g_deviceClass, g_deviceNetId), 0); + EXPECT_EQ(musicSinkInputNode.use_count(), NUM_TWO); + EXPECT_EQ(ringSinkInputNode.use_count(), NUM_TWO); + EXPECT_EQ(muiscProcessCluster.use_count(), 1); + g_testValue1 = TEST_VALUE_1; + std::shared_ptr writeFixedValueCb0 = + std::make_shared(SAMPLE_F32LE, g_testValue1); + musicSinkInputNode->RegisterWriteCallback(writeFixedValueCb0); + g_testValue2 = TEST_VALUE_2; + std::shared_ptr writeFixedValueCb1 = + std::make_shared(SAMPLE_F32LE, g_testValue2); + ringSinkInputNode->RegisterWriteCallback(writeFixedValueCb1); + hpaeOutputCluster->DoProcess(); + TestRendererRenderFrame(hpaeOutputCluster->GetFrameData(), + nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); + muiscProcessCluster->DisConnect(musicSinkInputNode); + EXPECT_EQ(musicSinkInputNode.use_count(), 1); + EXPECT_EQ(muiscProcessCluster->GetGainNodeCount(), 0); + ringProcessCluster->DisConnect(ringSinkInputNode); + EXPECT_EQ(ringSinkInputNode.use_count(), 1); + EXPECT_EQ(ringProcessCluster->GetGainNodeCount(), 0); + hpaeOutputCluster->DisConnect(muiscProcessCluster); + EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), 1); + hpaeOutputCluster->DisConnect(ringProcessCluster); + EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), 0); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_pcm_buffer_test.cpp b/services/audio_engine/test/unittest/node/hpae_pcm_buffer_test.cpp new file mode 100644 index 0000000000..90be2886b1 --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_pcm_buffer_test.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2025 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 +#include +#include "hpae_pcm_buffer.h" +#include "test_case_common.h" + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +class HpaePcmBufferTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaePcmBufferTest::SetUp() +{} + +void HpaePcmBufferTest::TearDown() +{} + +namespace { + +constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2; +constexpr uint32_t DEFAULT_FRAME_LEN = 480; +constexpr uint32_t DEFAULT_SAMPLE_RATE = 48000; +constexpr uint32_t DEFAULT_FRAME_NUM = 2; + + +TEST_F(HpaePcmBufferTest, constructHpaePcmBufferTest) +{ + PcmBufferInfo pcmBufferInfo; + pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT; + pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN; + pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE; + pcmBufferInfo.frames = DEFAULT_FRAME_NUM; + HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo); + EXPECT_EQ(reinterpret_cast(hpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); + EXPECT_EQ(hpaePcmBuffer.GetChannelCount(), pcmBufferInfo.ch); + EXPECT_EQ(hpaePcmBuffer.GetFrameLen(), pcmBufferInfo.frameLen); + EXPECT_EQ(hpaePcmBuffer.GetSampleRate(), pcmBufferInfo.rate); + EXPECT_EQ(hpaePcmBuffer.GetFrames(), pcmBufferInfo.frames); + EXPECT_EQ(hpaePcmBuffer.GetReadPos(), 0); + EXPECT_EQ(hpaePcmBuffer.GetWritePos(), 0); + EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), 0); + EXPECT_EQ(hpaePcmBuffer.IsMultiFrames(), false); + size_t addBytes = MEMORY_ALIGN_BYTE_NUM - + (pcmBufferInfo.frameLen * sizeof(float) * pcmBufferInfo.ch) % MEMORY_ALIGN_BYTE_NUM; + size_t frameByteSize = pcmBufferInfo.frameLen * sizeof(float) * pcmBufferInfo.ch + addBytes; + size_t bufferSize = frameByteSize * pcmBufferInfo.frames; + EXPECT_EQ(hpaePcmBuffer.Size(), bufferSize); +} + +TEST_F(HpaePcmBufferTest, assignHpaePcmBufferTest) +{ + PcmBufferInfo pcmBufferInfo; + pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT; + pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN; + pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE; + pcmBufferInfo.frames = DEFAULT_FRAME_NUM; + HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo); + EXPECT_EQ(reinterpret_cast(hpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); + size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch; + std::vector> testVec; + for (size_t i = 0; i < pcmBufferInfo.frames; i++) { + testVec.push_back(std::vector(tempFrameLen, 3.14f)); + } + hpaePcmBuffer = testVec; + for (size_t i = 0; i < pcmBufferInfo.frames; i++) { + for (size_t j = 0; j < tempFrameLen; j++) { + EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 3.14f) < TEST_VALUE_PRESION, true); + } + } +} + +TEST_F(HpaePcmBufferTest, calHpaePcmBufferTest) +{ + PcmBufferInfo pcmBufferInfo; + pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT; + pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN; + pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE; + pcmBufferInfo.frames = DEFAULT_FRAME_NUM; + HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo); + EXPECT_EQ(reinterpret_cast(hpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); + size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch; + for (size_t i = 0; i < pcmBufferInfo.frames; i++) { + for (size_t j = 0; j < tempFrameLen; j++) { + hpaePcmBuffer[i][j] = 3.14f; + } + } + std::vector> testVec; + for (size_t i = 0; i < pcmBufferInfo.frames; i++) { + testVec.push_back(std::vector(tempFrameLen, 3.14f)); + } + HpaePcmBuffer hpaePcmBuffer2(pcmBufferInfo); + EXPECT_EQ(reinterpret_cast(hpaePcmBuffer2.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); + hpaePcmBuffer2 = testVec; + hpaePcmBuffer += hpaePcmBuffer2; + for (size_t i = 0; i < pcmBufferInfo.frames; i++) { + for (size_t j = 0; j < tempFrameLen; j++) { + EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 6.28f) < TEST_VALUE_PRESION, true); + } + } + hpaePcmBuffer -= hpaePcmBuffer2; + for (size_t i = 0; i < pcmBufferInfo.frames; i++) { + for (size_t j = 0; j < tempFrameLen; j++) { + EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 3.14f) < TEST_VALUE_PRESION, true); + } + } + hpaePcmBuffer.Reset(); + for (size_t i = 0; i < pcmBufferInfo.frames; i++) { + for (size_t j = 0; j < tempFrameLen; j++) { + EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 0.0f) < TEST_VALUE_PRESION, true); + } + } +} + +TEST_F(HpaePcmBufferTest, calHpaePcmBufferMultiFrameTest) +{ + PcmBufferInfo pcmBufferInfo; + size_t inputFrames = 4; + pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT; + pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN; + pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE; + pcmBufferInfo.frames = inputFrames; + pcmBufferInfo.isMultiFrames = true; + HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo); + EXPECT_EQ(reinterpret_cast(hpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); + EXPECT_EQ(hpaePcmBuffer.IsMultiFrames(), true); + + size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch; + EXPECT_EQ(hpaePcmBuffer.GetFrameSample(), tempFrameLen); + for (size_t i = 0; i < inputFrames; i++) { + std::vector testVec(tempFrameLen, 3.14f); + hpaePcmBuffer = testVec; + } + std::cout << "tempFrameLen is: " << tempFrameLen << std::endl; + + EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), inputFrames); + EXPECT_EQ(hpaePcmBuffer.GetWritePos(), 0); + + std::vector testVec2(tempFrameLen, 0.0f); + EXPECT_EQ(hpaePcmBuffer.GetFrameSample(), tempFrameLen); + EXPECT_EQ(hpaePcmBuffer.PushFrameData(testVec2), false); + pcmBufferInfo.frames = 1; + pcmBufferInfo.isMultiFrames = false; + HpaePcmBuffer testHpaePcmBuffer(pcmBufferInfo); + EXPECT_EQ(reinterpret_cast(testHpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); + EXPECT_EQ(hpaePcmBuffer.PushFrameData(testHpaePcmBuffer), false); + size_t curFrames = inputFrames; + std::cout << "inputFrames is: " << inputFrames << std::endl; + for (size_t i = 0; i < inputFrames; i++) { + EXPECT_EQ(hpaePcmBuffer.GetFrameData(testHpaePcmBuffer), true); + curFrames--; + EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), curFrames); + for (size_t j = 0; j < tempFrameLen; j++) { + EXPECT_EQ(testHpaePcmBuffer[0][j], 3.14f); + } + } + EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), 0); + EXPECT_EQ(hpaePcmBuffer.GetReadPos(), 0); + EXPECT_EQ(hpaePcmBuffer.GetFrameData(testHpaePcmBuffer), false); + EXPECT_EQ(hpaePcmBuffer.GetFrameData(testVec2), false); +} +} \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_pcm_process_test.cpp b/services/audio_engine/test/unittest/node/hpae_pcm_process_test.cpp new file mode 100644 index 0000000000..609b189442 --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_pcm_process_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2025 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 +#include +#include "hpae_pcm_process.h" +#include "test_case_common.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +constexpr uint32_t NUM_TWO = 2; + +class HpaePcmProcessTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaePcmProcessTest::SetUp() +{} + +void HpaePcmProcessTest::TearDown() +{} + +std::aligned_storage aligned_memory; + +TEST_F(HpaePcmProcessTest, constructHpaePcmProcess) +{ + std::vector testData(TEST_FREAME_LEN); + HpaePcmProcess hpaePcmProcess(testData.data(), TEST_FREAME_LEN); + EXPECT_EQ(hpaePcmProcess.Size(), TEST_FREAME_LEN); + for (int i = 0; i < TEST_FREAME_LEN; i++) { + testData[i] = i; + EXPECT_EQ(hpaePcmProcess[i], i); + const float testValue = hpaePcmProcess[i]; + EXPECT_EQ(hpaePcmProcess[i], testValue); + } + EXPECT_EQ(&testData[0], hpaePcmProcess.begin()); + EXPECT_EQ(&testData[TEST_FREAME_LEN - 1], hpaePcmProcess.end() - 1); +} + +TEST_F(HpaePcmProcessTest, assignHpaeProcessTest) +{ + std::vector testData(TEST_FREAME_LEN); + for (int i = 0; i < TEST_FREAME_LEN; i++) { + testData[i] = i; + } + std::vector testData2(TEST_SUB_FREAME_LEN); + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + testData2[i] = i; + } + std::vector tmpData(TEST_FREAME_LEN); + for (int i = 0; i < TEST_FREAME_LEN; i++) { + tmpData[i] = i; + } + HpaePcmProcess tmpPcmProcess(tmpData.data(), TEST_FREAME_LEN); + std::vector pcmData(TEST_SUB_FREAME_LEN); + std::vector pcmData2(TEST_FREAME_LEN); + HpaePcmProcess hpaePcmProcessTest(pcmData.data(), TEST_SUB_FREAME_LEN); + hpaePcmProcessTest = testData; + // errcase + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + EXPECT_EQ(hpaePcmProcessTest[i], 0); + } + hpaePcmProcessTest = testData2; + // normalcase + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + EXPECT_EQ(hpaePcmProcessTest[i], i); + } + HpaePcmProcess hpaePcmProcessTest2(pcmData2.data(), TEST_SUB_FREAME_LEN); + hpaePcmProcessTest2 = tmpPcmProcess; + // errcase + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + EXPECT_EQ(hpaePcmProcessTest2[i], 0); + } + hpaePcmProcessTest2 = hpaePcmProcessTest; + // normalcase + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + EXPECT_EQ(hpaePcmProcessTest2[i], i); + } +} + +TEST_F(HpaePcmProcessTest, calHpaeProcessTest) +{ + std::vector testData(TEST_SUB_FREAME_LEN); + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + testData[i] = i; + } + HpaePcmProcess hpaePcmProcessTest(testData.data(), TEST_SUB_FREAME_LEN); + std::vector testData2(TEST_SUB_FREAME_LEN, NUM_TWO); + HpaePcmProcess hpaePcmProcessTest2(testData2.data(), TEST_SUB_FREAME_LEN); + hpaePcmProcessTest2 += hpaePcmProcessTest; + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + EXPECT_EQ(hpaePcmProcessTest2[i], i + NUM_TWO); + } + hpaePcmProcessTest2 -= hpaePcmProcessTest; + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + EXPECT_EQ(hpaePcmProcessTest2[i], NUM_TWO); + } + hpaePcmProcessTest2 *= hpaePcmProcessTest; + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + EXPECT_EQ(hpaePcmProcessTest2[i], NUM_TWO * i); + } + hpaePcmProcessTest2.Reset(); + for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { + EXPECT_EQ(hpaePcmProcessTest2[i], 0); + } +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_process_cluster_test.cpp b/services/audio_engine/test/unittest/node/hpae_process_cluster_test.cpp new file mode 100644 index 0000000000..ebaadaff0f --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_process_cluster_test.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include "hpae_process_cluster.h" +#include "test_case_common.h" +#include "audio_errors.h" +#include "hpae_sink_input_node.h" +#include "hpae_sink_output_node.h" + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +namespace OHOS { +namespace AudioStandard { + +const int32_t DEFAULT_VALUE_TWO = 2; +const uint32_t DEFAULT_SESSIONID_NUM_FIRST = 12345; +const uint32_t DEFAULT_SESSIONID_NUM_SECOND = 12346; +const uint32_t DEFAULT_NODEID_NUM_FIRST = 1243; +const size_t DEFAULT_FRAMELEN_FIRST = 820; +const size_t DEFAULT_FRAMELEN_SECOND = 960; +const int32_t DEFAULT_TEST_VALUE_FIRST = 100; +const int32_t DEFAULT_TEST_VALUE_SECOND = 200; + + +class HpaeProcessClusterTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeProcessClusterTest::SetUp() +{} + +void HpaeProcessClusterTest::TearDown() +{} + +TEST_F(HpaeProcessClusterTest, constructHpaeProcessClusterNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODEID_NUM_FIRST; + nodeInfo.frameLen = DEFAULT_FRAMELEN_SECOND; + nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_FIRST; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + + HpaeSinkInfo dummySinkInfo; + + std::shared_ptr hpaeProcessCluster = + std::make_shared(nodeInfo, dummySinkInfo); + EXPECT_EQ(hpaeProcessCluster->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeProcessCluster->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeProcessCluster->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeProcessCluster->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeProcessCluster->GetBitWidth(), nodeInfo.format); + HpaeNodeInfo &retNi = hpaeProcessCluster->GetNodeInfo(); + EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); + EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); + EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); + EXPECT_EQ(retNi.channels, nodeInfo.channels); + EXPECT_EQ(retNi.format, nodeInfo.format); + + std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); + hpaeProcessCluster->Connect(hpaeSinkInputNode); + EXPECT_EQ(hpaeSinkInputNode.use_count(), static_cast(DEFAULT_VALUE_TWO)); + EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 1); + EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), 1); + nodeInfo.frameLen = DEFAULT_FRAMELEN_FIRST; + nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_SECOND; + nodeInfo.samplingRate = SAMPLE_RATE_44100; + std::shared_ptr hpaeSinkInputNode1 = std::make_shared(nodeInfo); + hpaeProcessCluster->Connect(hpaeSinkInputNode1); + EXPECT_EQ(hpaeSinkInputNode1.use_count(), static_cast(DEFAULT_VALUE_TWO)); + EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), (DEFAULT_VALUE_TWO)); + EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), 2); +} +static int32_t g_testValue1 = 0; +static int32_t g_testValue2 = 0; +static int32_t TestRendererRenderFrame(const char *data, uint64_t len) +{ + float curGain = 0.0f; + float targetGain = 1.0f; + uint64_t frameLen = len / (SAMPLE_F32LE * STEREO); + float stepGain = (targetGain - curGain) / frameLen; + for (int32_t i = 0; i < frameLen; i++) { + EXPECT_EQ(*((float *)data + i * STEREO + 1), (g_testValue1 * (curGain + i * stepGain) + + g_testValue2 * (curGain + i * stepGain))); + EXPECT_EQ(*((float *)data + i * STEREO), (g_testValue1 * (curGain + i * stepGain) + + g_testValue2 * (curGain + i * stepGain))); + } + return 0; +} + +TEST_F(HpaeProcessClusterTest, testHpaeWriteDataProcessSessionTest) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODEID_NUM_FIRST; + nodeInfo.frameLen = DEFAULT_FRAMELEN_SECOND; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + HpaeSinkInfo dummySinkInfo; + dummySinkInfo.channels = STEREO; + dummySinkInfo.frameLen = DEFAULT_FRAMELEN_SECOND; + dummySinkInfo.format = SAMPLE_F32LE; + dummySinkInfo.samplingRate = SAMPLE_RATE_48000; + std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); + nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_FIRST; + std::shared_ptr hpaeSinkInputNode0 = std::make_shared(nodeInfo); + nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_SECOND; + std::shared_ptr hpaeSinkInputNode1 = std::make_shared(nodeInfo); + std::shared_ptr hpaeProcessCluster = + std::make_shared(nodeInfo, dummySinkInfo); + hpaeProcessCluster->Connect(hpaeSinkInputNode0); + hpaeProcessCluster->Connect(hpaeSinkInputNode1); + EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); + EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), DEFAULT_VALUE_TWO); + EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), DEFAULT_VALUE_TWO); + EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); + hpaeSinkOutputNode->Connect(hpaeProcessCluster); + std::string deviceClass = "file_io"; + std::string deviceNetId = "LocalDevice"; + EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 1); + EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0); + EXPECT_EQ(hpaeSinkInputNode0.use_count(), static_cast(DEFAULT_VALUE_TWO)); + EXPECT_EQ(hpaeSinkInputNode1.use_count(), static_cast(DEFAULT_VALUE_TWO)); + EXPECT_EQ(hpaeProcessCluster.use_count(), 1); + g_testValue1 = DEFAULT_TEST_VALUE_FIRST; + std::shared_ptr writeFixedValueCb0 = + std::make_shared(SAMPLE_F32LE, g_testValue1); + hpaeSinkInputNode0->RegisterWriteCallback(writeFixedValueCb0); + g_testValue2 = DEFAULT_TEST_VALUE_SECOND; + std::shared_ptr writeFixedValueCb1 = + std::make_shared(SAMPLE_F32LE, g_testValue2); + hpaeSinkInputNode1->RegisterWriteCallback(writeFixedValueCb1); + hpaeSinkOutputNode->DoProcess(); + TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), + nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); + hpaeSinkOutputNode->DisConnect(hpaeProcessCluster); + EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); + EXPECT_EQ(hpaeProcessCluster.use_count(), 1); + hpaeProcessCluster->DisConnect(hpaeSinkInputNode0); + EXPECT_EQ(hpaeSinkInputNode0.use_count(), 1); + EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 1); + hpaeProcessCluster->DisConnect(hpaeSinkInputNode1); + EXPECT_EQ(hpaeSinkInputNode1.use_count(), 1); + EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 0); +} + +} //AudioStandard +} //OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_resample_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_resample_node_test.cpp new file mode 100644 index 0000000000..c5aec9a2b9 --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_resample_node_test.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include +#include "hpae_sink_input_node.h" +#include "hpae_resample_node.h" +#include "hpae_sink_output_node.h" +#include +#include +#include +#include "test_case_common.h" +#include "audio_errors.h" + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +static constexpr uint32_t TEST_ID = 1243; +static constexpr uint32_t TEST_ID2 = 1246; +static constexpr uint32_t TEST_FRAMELEN1 = 960; +static constexpr uint32_t TEST_FRAMELEN2 = 640; +namespace { +class HpaeResampleNodeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeResampleNodeTest::SetUp() +{} + +void HpaeResampleNodeTest::TearDown() +{} + +TEST_F(HpaeResampleNodeTest, constructHpaeResampleNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = TEST_ID; + nodeInfo.frameLen = TEST_FRAMELEN1; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + HpaeNodeInfo dstNodeInfo; + dstNodeInfo.nodeId = TEST_ID2; + dstNodeInfo.frameLen = TEST_FRAMELEN1; + dstNodeInfo.samplingRate = SAMPLE_RATE_44100; + dstNodeInfo.channels = CHANNEL_4; + dstNodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeResampleNode = std::make_shared(nodeInfo, dstNodeInfo); + EXPECT_EQ(hpaeResampleNode->GetSampleRate(), dstNodeInfo.samplingRate); + EXPECT_EQ(hpaeResampleNode->GetNodeId(), dstNodeInfo.nodeId); + EXPECT_EQ(hpaeResampleNode->GetFrameLen(), dstNodeInfo.frameLen); + EXPECT_EQ(hpaeResampleNode->GetChannelCount(), dstNodeInfo.channels); + EXPECT_EQ(hpaeResampleNode->GetBitWidth(), dstNodeInfo.format); + HpaeNodeInfo &retNi = hpaeResampleNode->GetNodeInfo(); + EXPECT_EQ(retNi.samplingRate, dstNodeInfo.samplingRate); + EXPECT_EQ(retNi.nodeId, dstNodeInfo.nodeId); + EXPECT_EQ(retNi.frameLen, dstNodeInfo.frameLen); + EXPECT_EQ(retNi.channels, dstNodeInfo.channels); + EXPECT_EQ(retNi.format, dstNodeInfo.format); +} + +TEST_F(HpaeResampleNodeTest, testHpaeReampleNodeProcess) +{ + HpaeNodeInfo srcNodeInfo; + srcNodeInfo.nodeId = TEST_ID; + srcNodeInfo.frameLen = TEST_FRAMELEN1; + srcNodeInfo.samplingRate = SAMPLE_RATE_48000; + srcNodeInfo.channels = STEREO; + srcNodeInfo.format = SAMPLE_S32LE; + std::shared_ptr hpaeSinkInputNode = std::make_shared(srcNodeInfo); + HpaeNodeInfo dstNodeInfo; + dstNodeInfo.nodeId = TEST_ID; + dstNodeInfo.frameLen = TEST_FRAMELEN2; + dstNodeInfo.samplingRate = SAMPLE_RATE_32000; + dstNodeInfo.channels = CHANNEL_4; + dstNodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeResampleNode = std::make_shared(srcNodeInfo, dstNodeInfo); +} +} // namespace diff --git a/services/audio_engine/test/unittest/node/hpae_sink_input_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_sink_input_node_test.cpp new file mode 100644 index 0000000000..5338027799 --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_sink_input_node_test.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include "hpae_sink_input_node.h" +#include "hpae_sink_output_node.h" +#include "test_case_common.h" +#include "audio_errors.h" +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +class HpaeSinkInputNodeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeSinkInputNodeTest::SetUp() +{} + +void HpaeSinkInputNodeTest::TearDown() +{} + +namespace { +constexpr int32_t NORMAL_FRAME_LEN = 960; +constexpr int32_t NORMAL_ID = 1243; +TEST_F(HpaeSinkInputNodeTest, constructHpaeSinkInputNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = NORMAL_ID; + nodeInfo.frameLen = NORMAL_FRAME_LEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::unique_ptr hpaeSinkInputNode = std::make_unique(nodeInfo); + EXPECT_EQ(hpaeSinkInputNode->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeSinkInputNode->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeSinkInputNode->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeSinkInputNode->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeSinkInputNode->GetBitWidth(), nodeInfo.format); + HpaeNodeInfo &retNi = hpaeSinkInputNode->GetNodeInfo(); + EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); + EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); + EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); + EXPECT_EQ(retNi.channels, nodeInfo.channels); + EXPECT_EQ(retNi.format, nodeInfo.format); +} + +TEST_F(HpaeSinkInputNodeTest, testSinkInputOutputCase) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = NORMAL_ID; + nodeInfo.frameLen = NORMAL_FRAME_LEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); + { + std::shared_ptr> outputNode = hpaeSinkInputNode; + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1 + 1); // add 1 count because outputNode + std::shared_ptr hpaeNode = outputNode->GetSharedInstance(); + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1 + 1 + 1); // add 1 count because hpaeNode + EXPECT_EQ(hpaeNode->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeNode->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeNode->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeNode->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeNode->GetBitWidth(), nodeInfo.format); + } + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); + std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeSinkOutputNode.use_count(), 1); + hpaeSinkOutputNode->Connect(hpaeSinkInputNode); + EXPECT_EQ(hpaeSinkOutputNode.use_count(), 1); + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1 + 1); + OutputPort *outputPort = hpaeSinkInputNode->GetOutputPort(); + EXPECT_EQ(outputPort->GetInputNum(), 1); + hpaeSinkOutputNode->DisConnect(hpaeSinkInputNode); + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); + outputPort = hpaeSinkInputNode->GetOutputPort(); + EXPECT_EQ(outputPort->GetInputNum(), 0); +} + +TEST_F(HpaeSinkInputNodeTest, testWriteDataToSinkInputDataCase) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = NORMAL_ID; + nodeInfo.frameLen = NORMAL_FRAME_LEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + int32_t testNum = 10; + std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); + std::shared_ptr writeFixedDataCb = std::make_shared(SAMPLE_F32LE); + hpaeSinkInputNode->RegisterWriteCallback(writeFixedDataCb); + for (int32_t i = 0; i < testNum; i++) { + OutputPort *outputPort = hpaeSinkInputNode->GetOutputPort(); + HpaePcmBuffer* outPcmBuffer = outputPort->PullOutputData(); + float* outputPcmData = outPcmBuffer->GetPcmDataBuffer(); + for (int32_t j = 0; j < nodeInfo.frameLen; j++) { + for (int32_t k = 0; k < nodeInfo.channels; k++) { + float diff = outputPcmData[j * nodeInfo.channels + k] - i; + EXPECT_EQ(fabs(diff) < TEST_VALUE_PRESION, true); + } + } + } +} + +TEST_F(HpaeSinkInputNodeTest, testWriteDataToSinkInputAndSinkOutputDataCase) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = NORMAL_ID; + nodeInfo.frameLen = NORMAL_FRAME_LEN; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + int32_t testNum = 10; + std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); + std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); + std::shared_ptr writeFixedDataCb = std::make_shared(SAMPLE_F32LE); + hpaeSinkInputNode->RegisterWriteCallback(writeFixedDataCb); + hpaeSinkOutputNode->Connect(hpaeSinkInputNode); + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1 + 1); + for (int32_t i = 0; i < testNum; i++) { + OutputPort *outputPort = hpaeSinkInputNode->GetOutputPort(); + HpaePcmBuffer* outPcmBuffer = outputPort->PullOutputData(); + float* outputPcmData = outPcmBuffer->GetPcmDataBuffer(); + for (int32_t j = 0; j < nodeInfo.frameLen; j++) { + for (int32_t k = 0; k < nodeInfo.channels; k++) { + float diff = outputPcmData[j * nodeInfo.channels + k] - i; + EXPECT_EQ(fabs(diff) < TEST_VALUE_PRESION, true); + } + } + } + + hpaeSinkOutputNode->DisConnect(hpaeSinkInputNode); + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); +} +} \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_sink_output_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_sink_output_node_test.cpp new file mode 100644 index 0000000000..ceb968287f --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_sink_output_node_test.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include "hpae_sink_input_node.h" +#include "hpae_sink_output_node.h" +#include "test_case_common.h" +#include "audio_errors.h" +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; +namespace { +class HpaeSinkOutputNodeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeSinkOutputNodeTest::SetUp() +{} + +void HpaeSinkOutputNodeTest::TearDown() +{} + +TEST_F(HpaeSinkOutputNodeTest, constructHpaeSinkOutputNode) +{ + size_t frameLen = 960; + uint32_t nodeId = 1243; + uint32_t sessionId = 10001; + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = nodeId; + nodeInfo.frameLen = frameLen; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + nodeInfo.sessionId = sessionId; + std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeSinkOutputNode->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeSinkOutputNode->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeSinkOutputNode->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeSinkOutputNode->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeSinkOutputNode->GetBitWidth(), nodeInfo.format); + EXPECT_EQ(hpaeSinkOutputNode->GetSessionId(), nodeInfo.sessionId); + + HpaeNodeInfo &retNi = hpaeSinkOutputNode->GetNodeInfo(); + EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); + EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); + EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); + EXPECT_EQ(retNi.channels, nodeInfo.channels); + EXPECT_EQ(retNi.format, nodeInfo.format); + EXPECT_EQ(retNi.sessionId, nodeInfo.sessionId); +} +static int32_t TestRendererRenderFrame(const char *data, uint64_t len) +{ + for (int32_t i = 0; i < len / SAMPLE_F32LE; i++) { + float diff = *((float *)data + i) - i; + EXPECT_EQ(diff, 0); + } + return 0; +} + +TEST_F(HpaeSinkOutputNodeTest, testHpaeSinkOutConnectNode) +{ + size_t frameLen = 960; + uint32_t nodeId = 1243; + size_t usedCount = 2; + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = nodeId; + nodeInfo.frameLen = frameLen; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); + std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); + hpaeSinkOutputNode->Connect(hpaeSinkInputNode); + std::shared_ptr writeIncDataCb = std::make_shared(SAMPLE_F32LE); + hpaeSinkInputNode->RegisterWriteCallback(writeIncDataCb); + std::string deviceClass = "file_io"; + std::string deviceNetId = "LocalDevice"; + EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0); + EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_NEW, true); + IAudioSinkAttr attr; + attr.adapterName = "file_io"; + attr.openMicSpeaker = 0; + attr.format = nodeInfo.format; + attr.sampleRate = nodeInfo.samplingRate; + attr.channel = nodeInfo.channels; + attr.volume = 0.0f; + attr.filePath = nullptr; + attr.deviceNetworkId = deviceNetId.c_str(); + attr.deviceType = 0; + attr.channelLayout = 0; + attr.audioStreamFlag = 0; + + EXPECT_EQ(hpaeSinkOutputNode->RenderSinkInit(attr), ERROR); + EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_PREPARED, true); + EXPECT_EQ(hpaeSinkOutputNode->RenderSinkStart(), ERROR); + EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_RUNNING, false); + EXPECT_EQ(hpaeSinkOutputNode->RenderSinkPause(), SUCCESS); + EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_PAUSED, true); + EXPECT_EQ(hpaeSinkOutputNode->RenderSinkStop(), SUCCESS); + EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_STOPPED, true); + hpaeSinkOutputNode->DoProcess(); + TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), + nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); + EXPECT_EQ(hpaeSinkInputNode.use_count(), usedCount); + hpaeSinkOutputNode->DisConnect(hpaeSinkInputNode); + EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); +} +} // namespace \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_source_input_cluster_test.cpp b/services/audio_engine/test/unittest/node/hpae_source_input_cluster_test.cpp new file mode 100644 index 0000000000..a9cc960284 --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_source_input_cluster_test.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include "hpae_process_cluster.h" +#include "test_case_common.h" +#include "audio_errors.h" +#include "hpae_source_input_node.h" +#include "hpae_source_input_cluster.h" +#include "hpae_source_output_node.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +const uint32_t DEFAULT_FRAME_LENGTH = 960; + +class TestStatusCallback : public INodeCallback, public std::enable_shared_from_this { +public: + std::weak_ptr GetWeakPtr(); + virtual ~TestStatusCallback() = default; +}; + +std::weak_ptr TestStatusCallback::GetWeakPtr() +{ + return weak_from_this(); +} + + +class HpaeSourceInputClusterTest : public ::testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeSourceInputClusterTest::SetUp() +{} + +void HpaeSourceInputClusterTest::TearDown() +{} + +TEST_F(HpaeSourceInputClusterTest, constructHpaeSourceInputClusterNode) +{ + std::shared_ptr g_testStatuscallback = std::make_shared(); + HpaeNodeInfo nodeInfo; + nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + nodeInfo.statusCallback = g_testStatuscallback->GetWeakPtr(); + + std::shared_ptr hpaeSourceInputCluster = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeSourceInputCluster->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeSourceInputCluster->GetNodeId(), 0); + EXPECT_EQ(hpaeSourceInputCluster->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeSourceInputCluster->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeSourceInputCluster->GetBitWidth(), nodeInfo.format); + EXPECT_EQ(hpaeSourceInputCluster->GetSourceInputNodeUseCount(), 1); + std::shared_ptr hpaeSourceOutputNode = std::make_shared(nodeInfo); + hpaeSourceOutputNode->Connect(hpaeSourceInputCluster); + EXPECT_EQ(hpaeSourceInputCluster->GetSourceInputNodeUseCount(), 1 + 1); + EXPECT_EQ(hpaeSourceInputCluster->GetConverterNodeCount(), 0); + + nodeInfo.samplingRate = SAMPLE_RATE_16000; + std::shared_ptr hpaeSourceOutputNode1 = std::make_shared(nodeInfo); + hpaeSourceOutputNode1->ConnectWithInfo(hpaeSourceInputCluster, nodeInfo); + EXPECT_EQ(hpaeSourceInputCluster->GetSourceInputNodeUseCount(), 1 + 1 + 1); + EXPECT_EQ(hpaeSourceInputCluster->GetConverterNodeCount(), 1); +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_source_input_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_source_input_node_test.cpp new file mode 100644 index 0000000000..f91eec8b18 --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_source_input_node_test.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include +#include "hpae_source_input_node.h" +#include "hpae_source_output_node.h" +#include "test_case_common.h" +#include "audio_errors.h" + +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +const uint32_t DEFAULT_FRAME_LENGTH = 960; +const uint32_t DEFAULT_NODE_ID = 1243; + +class HpaeSourceInputNodeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeSourceInputNodeTest::SetUp() +{} + +void HpaeSourceInputNodeTest::TearDown() +{} + +TEST_F(HpaeSourceInputNodeTest, constructHpaeSourceInputNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODE_ID; + nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeSoruceInputNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeSoruceInputNode->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeSoruceInputNode->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeSoruceInputNode->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeSoruceInputNode->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeSoruceInputNode->GetBitWidth(), nodeInfo.format); + HpaeNodeInfo &retNi = hpaeSoruceInputNode->GetNodeInfo(); + EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); + EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); + EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); + EXPECT_EQ(retNi.channels, nodeInfo.channels); + EXPECT_EQ(retNi.format, nodeInfo.format); +} + +TEST_F(HpaeSourceInputNodeTest, testSourceInputOutputCase) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODE_ID; + nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeSoruceInputNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeSoruceInputNode.use_count(), 1); + { + std::shared_ptr> ouputNode = hpaeSoruceInputNode; + EXPECT_EQ(hpaeSoruceInputNode.use_count(), 2); // 2 for test + std::shared_ptr hpaeNode = ouputNode->GetSharedInstance(); + EXPECT_EQ(hpaeSoruceInputNode.use_count(), 3); // 3 for test + EXPECT_EQ(hpaeNode->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeNode->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeNode->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeNode->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeNode->GetBitWidth(), nodeInfo.format); + } + EXPECT_EQ(hpaeSoruceInputNode.use_count(), 1); + std::shared_ptr hpaeSourceOutputNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeSourceOutputNode.use_count(), 1); + hpaeSourceOutputNode->Connect(hpaeSoruceInputNode); + EXPECT_EQ(hpaeSourceOutputNode.use_count(), 1); + EXPECT_EQ(hpaeSoruceInputNode.use_count(), 2); // 2 for test + OutputPort *outputPort = hpaeSoruceInputNode->GetOutputPort(); + EXPECT_EQ(outputPort->GetInputNum(), 1); + hpaeSourceOutputNode->DisConnect(hpaeSoruceInputNode); + EXPECT_EQ(hpaeSoruceInputNode.use_count(), 1); + outputPort = hpaeSoruceInputNode->GetOutputPort(); + EXPECT_EQ(outputPort->GetInputNum(), 0); +} + +static int32_t TestCapturerSourceFrame(char *frame, uint64_t requestBytes, uint64_t *replyBytes) +{ + for (int32_t i = 0; i < requestBytes / SAMPLE_F32LE; i++) { + *(float *)(frame + i * sizeof(float)) = i; + } + *replyBytes = requestBytes; + return 0; +} + +TEST_F(HpaeSourceInputNodeTest, testWriteDataToSourceInputDataCase) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODE_ID; + nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeSoruceInputNode = std::make_shared(nodeInfo); + uint64_t requestBytes = nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format); + std::vector testData(requestBytes); + uint64_t replyBytes = 0; + std::string deviceClass = "file_io"; + std::string deviceNetId = "LocalDevice"; + SourceType sourceType = SOURCE_TYPE_MIC; + std::string sourceName = "mic"; + EXPECT_EQ(hpaeSoruceInputNode->GetCapturerSourceInstance(deviceClass, deviceNetId, sourceType, sourceName), 0); + IAudioSourceAttr attr; + attr.adapterName = NULL; + attr.openMicSpeaker = 0; + attr.format = AudioSampleFormat::INVALID_WIDTH; + attr.sampleRate = nodeInfo.samplingRate; + attr.channel = nodeInfo.channels; + attr.volume = 0.0f; + attr.bufferSize = 0; + attr.isBigEndian = false; + attr.filePath = NULL; + attr.deviceNetworkId = NULL; + attr.deviceType = 0; + attr.sourceType = 0; + attr.channelLayout = 0; + attr.audioStreamFlag = 0; + EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceInit(attr), ERROR); + EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceStart(), SUCCESS); + EXPECT_EQ(hpaeSoruceInputNode->GetSourceState() == CAPTURER_RUNNING, true); + EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceStop(), SUCCESS); + EXPECT_EQ(hpaeSoruceInputNode->GetSourceState() == CAPTURER_STOPPED, true); + TestCapturerSourceFrame(testData.data(), requestBytes, &replyBytes); + hpaeSoruceInputNode->WriteCapturerData(testData.data(), requestBytes); + OutputPort *outputPort = hpaeSoruceInputNode->GetOutputPort(); + HpaePcmBuffer* outPcmBuffer = outputPort->PullOutputData(); + float* outputPcmData = outPcmBuffer->GetPcmDataBuffer(); + for (int32_t j = 0; j < nodeInfo.frameLen; j++) { + for (int32_t k = 0; k < nodeInfo.channels; k++) { + float diff = outputPcmData[(j * nodeInfo.channels + k)] - (j * nodeInfo.channels + k); + EXPECT_EQ(fabs(diff) < TEST_VALUE_PRESION, true); + } + } +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_source_output_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_source_output_node_test.cpp new file mode 100644 index 0000000000..86b25a3dca --- /dev/null +++ b/services/audio_engine/test/unittest/node/hpae_source_output_node_test.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include "hpae_source_input_node.h" +#include "hpae_source_output_node.h" +#include "test_case_common.h" +#include "audio_errors.h" +using namespace OHOS; +using namespace AudioStandard; +using namespace HPAE; + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +const uint32_t DEFAULT_FRAME_LENGTH = 960; +const uint32_t DEFAULT_NODE_ID = 1243; + +class HpaeSourceOutputNodeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void HpaeSourceOutputNodeTest::SetUp() +{} + +void HpaeSourceOutputNodeTest::TearDown() +{} + +class TestReadDataCb : public IReadCallback, public std::enable_shared_from_this { +public: + int32_t OnReadData(std::vector &inputData, size_t requestDataLen) override; + int32_t OnReadData(size_t length) override + { + return SUCCESS; + } + TestReadDataCb() + {} + virtual ~TestReadDataCb() + {} +}; + +int32_t TestReadDataCb::OnReadData(std::vector &inputData, size_t requestDataLen) +{ + for (int32_t i = 0; i < requestDataLen / SAMPLE_F32LE; i++) { + EXPECT_EQ(*(float *)(inputData.data() + i * sizeof(float)), i); + } + return 0; +} + +static int32_t TestCapturerSourceFrame(char *frame, uint64_t requestBytes, uint64_t *replyBytes) +{ + for (int32_t i = 0; i < requestBytes / SAMPLE_F32LE; i++) { + *(float *)(frame + i * sizeof(float)) = i; + } + *replyBytes = requestBytes; + return 0; +} + +TEST_F(HpaeSourceOutputNodeTest, constructHpaeSourceOutputNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODE_ID; + nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeSoruceOutputNode = std::make_shared(nodeInfo); + EXPECT_EQ(hpaeSoruceOutputNode->GetSampleRate(), nodeInfo.samplingRate); + EXPECT_EQ(hpaeSoruceOutputNode->GetNodeId(), nodeInfo.nodeId); + EXPECT_EQ(hpaeSoruceOutputNode->GetFrameLen(), nodeInfo.frameLen); + EXPECT_EQ(hpaeSoruceOutputNode->GetChannelCount(), nodeInfo.channels); + EXPECT_EQ(hpaeSoruceOutputNode->GetBitWidth(), nodeInfo.format); + HpaeNodeInfo &retNi = hpaeSoruceOutputNode->GetNodeInfo(); + EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); + EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); + EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); + EXPECT_EQ(retNi.channels, nodeInfo.channels); + EXPECT_EQ(retNi.format, nodeInfo.format); +} + +TEST_F(HpaeSourceOutputNodeTest, connectHpaeSourceInputAndOutputNode) +{ + HpaeNodeInfo nodeInfo; + nodeInfo.nodeId = DEFAULT_NODE_ID; + nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; + nodeInfo.samplingRate = SAMPLE_RATE_48000; + nodeInfo.channels = STEREO; + nodeInfo.format = SAMPLE_F32LE; + std::shared_ptr hpaeSoruceInputNode = std::make_shared(nodeInfo); + uint64_t requestBytes = nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format); + std::vector testData(requestBytes); + uint64_t replyBytes = 0; + std::string deviceClass = "file_io"; + std::string deviceNetId = "LocalDevice"; + SourceType sourceType = SOURCE_TYPE_MIC; + std::string sourceName = "mic"; + EXPECT_EQ(hpaeSoruceInputNode->GetCapturerSourceInstance(deviceClass, deviceNetId, sourceType, sourceName), 0); + IAudioSourceAttr attr; + attr.adapterName = NULL; + attr.openMicSpeaker = 0; + attr.format = AudioSampleFormat::INVALID_WIDTH; + attr.sampleRate = nodeInfo.samplingRate; + attr.channel = nodeInfo.channels; + attr.volume = 0.0f; + attr.bufferSize = 0; + attr.isBigEndian = false; + attr.filePath = NULL; + attr.deviceNetworkId = NULL; + attr.deviceType = 0; + attr.sourceType = 0; + attr.channelLayout = 0; + attr.audioStreamFlag = 0; + EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceInit(attr), ERROR); + EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceStart(), 0); + EXPECT_EQ(hpaeSoruceInputNode->GetSourceState() == CAPTURER_RUNNING, true); + EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceStop(), 0); + EXPECT_EQ(hpaeSoruceInputNode->GetSourceState() == CAPTURER_STOPPED, true); + TestCapturerSourceFrame(testData.data(), requestBytes, &replyBytes); + hpaeSoruceInputNode->WriteCapturerData(testData.data(), requestBytes); + std::shared_ptr hpaeSoruceOutputNode = std::make_shared(nodeInfo); + std::shared_ptr testReadDataCb = std::make_shared(); + hpaeSoruceOutputNode->RegisterReadCallback(testReadDataCb); + hpaeSoruceOutputNode->Connect(hpaeSoruceInputNode); + EXPECT_EQ(hpaeSoruceInputNode.use_count(), 2); // 2 for test + hpaeSoruceOutputNode->DoProcess(); + hpaeSoruceOutputNode->DisConnect(hpaeSoruceInputNode); + EXPECT_EQ(hpaeSoruceInputNode.use_count(), 1); +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/resource/ohos_test.xml b/services/audio_engine/test/unittest/resource/ohos_test.xml new file mode 100644 index 0000000000..21512912b0 --- /dev/null +++ b/services/audio_engine/test/unittest/resource/ohos_test.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/services/audio_engine/utils/high_resolution_timer.h b/services/audio_engine/utils/high_resolution_timer.h new file mode 100644 index 0000000000..e7f55c0e58 --- /dev/null +++ b/services/audio_engine/utils/high_resolution_timer.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 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 HIGH_RRSOLUTION_TIMER_H +#define HIGH_RRSOLUTION_TIMER_H +#include +#include +#include +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +typedef std::chrono::high_resolution_clock::time_point TimePoint; +class HighResolutionTimer { +public: + HighResolutionTimer() : startTime_(), endTime_() + {} + + void Start() + { + startTime_ = std::chrono::high_resolution_clock::now(); + } + + void Stop() + { + endTime_ = std::chrono::high_resolution_clock::now(); + } + + template + auto Elapsed() const + { + return std::chrono::duration_cast(endTime_ - startTime_).count(); + } + +private: + std::chrono::high_resolution_clock::time_point startTime_; + std::chrono::high_resolution_clock::time_point endTime_; +}; + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS + +#endif // __HIGH_RRSOLUTION_TIMER_H__ \ No newline at end of file diff --git a/services/audio_engine/utils/hpae_format_convert.cpp b/services/audio_engine/utils/hpae_format_convert.cpp new file mode 100644 index 0000000000..9ddcde6c03 --- /dev/null +++ b/services/audio_engine/utils/hpae_format_convert.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2025 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 "securec.h" +#include "hpae_format_convert.h" + + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr float FLOAT_EPS = 1e-9f; +constexpr int OFFSET_BIT_24 = 3; +constexpr int BIT_DEPTH_TWO = 2; +constexpr int BIT_8 = 8; +constexpr int BIT_16 = 16; +constexpr int BIT_32 = 32; + +static uint32_t Read24Bit(const uint8_t *p) +{ + return ((uint32_t) p[BIT_DEPTH_TWO] << BIT_16) | ((uint32_t) p[1] << BIT_8) | ((uint32_t) p[0]); +} + +static void Write24Bit(uint8_t *p, uint32_t u) +{ + p[BIT_DEPTH_TWO] = (uint8_t) (u >> BIT_16); + p[1] = (uint8_t) (u >> BIT_8); + p[0] = (uint8_t) u; +} + +static void ConvertFrom16BitToFloat(unsigned n, const int16_t *a, float *b) +{ + for (; n > 0; n--) { + *(b++) = *(a++) * (1.0f / (1 << (BIT_16 - 1))); + } +} + +static void ConvertFrom24BitToFloat(unsigned n, const uint8_t *a, float *b) +{ + for (; n > 0; n--) { + int32_t s = Read24Bit(a) << BIT_8; + *b = s * (1.0f / (1U << (BIT_32 - 1))); + a += OFFSET_BIT_24; + b++; + } +} + +static void ConvertFrom32BitToFloat(unsigned n, const int32_t *a, float *b) +{ + for (; n > 0; n--) { + *(b++) = *(a++) * (1.0f / (1U << (BIT_32 - 1))); + } +} + +static float CapMax(float v) +{ + float value = v; + if (v > 1.0f) { + value = 1.0f - FLOAT_EPS; + } else if (v < -1.0f) { + value = -1.0f + FLOAT_EPS; + } + return value; +} + +static void ConvertFromFloatTo16Bit(unsigned n, const float *a, int16_t *b) +{ + for (; n > 0; n--) { + float tmp = *a++; + float v = CapMax(tmp) * (1 << (BIT_16 - 1)); + *(b++) = (int16_t) v; + } +} + +static void ConvertFromFloatTo24Bit(unsigned n, const float *a, uint8_t *b) +{ + for (; n > 0; n--) { + float tmp = *a++; + float v = CapMax(tmp) * (1U << (BIT_32 - 1)); + Write24Bit(b, ((int32_t) v) >> BIT_8); + b += OFFSET_BIT_24; + } +} + +static void ConvertFromFloatTo32Bit(unsigned n, const float *a, int32_t *b) +{ + for (; n > 0; n--) { + float tmp = *a++; + float v = CapMax(tmp) * (1U << (BIT_32 - 1)); + *(b++) = (int32_t) v; + } +} + +void ConvertToFloat(AudioSampleFormat format, unsigned n, void *src, float *dst) +{ + int32_t ret; + switch (format) { + case SAMPLE_S16LE: + ConvertFrom16BitToFloat(n, (const int16_t *)src, dst); + break; + case SAMPLE_S24LE: + ConvertFrom24BitToFloat(n, (const uint8_t *)src, dst); + break; + case SAMPLE_S32LE: + ConvertFrom32BitToFloat(n, (const int32_t *)src, dst); + break; + default: + ret = memcpy_s(dst, n * sizeof(float), (const float *)src, n * sizeof(float)); + if (ret != 0) { + float *srcFloat = (float *)src; + for (uint32_t i = 0; i < n; i++) { + dst[i] = srcFloat[i]; + } + } + break; + } +} + +void ConvertFromFloat(AudioSampleFormat format, unsigned n, float *src, void *dst) +{ + int32_t ret; + switch (format) { + case SAMPLE_S16LE: + ConvertFromFloatTo16Bit(n, src, (int16_t *)dst); + break; + case SAMPLE_S24LE: + ConvertFromFloatTo24Bit(n, src, (uint8_t *)dst); + break; + case SAMPLE_S32LE: + ConvertFromFloatTo32Bit(n, src, (int32_t *)dst); + break; + default: + ret = memcpy_s(dst, n * sizeof(float), src, n * sizeof(float)); + if (ret != 0) { + float *dstFloat = (float *)dst; + for (uint32_t i = 0; i < n; i++) { + dstFloat[i] = src[i]; + } + } + break; + } +} +}}} \ No newline at end of file diff --git a/services/audio_engine/utils/hpae_format_convert.h b/services/audio_engine/utils/hpae_format_convert.h new file mode 100644 index 0000000000..3f9ad18fd9 --- /dev/null +++ b/services/audio_engine/utils/hpae_format_convert.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 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 HPAE_FORMAT_CONVERT_H +#define HPAE_FORMAT_CONVERT_H +#include "audio_stream_info.h" +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +void ConvertToFloat(AudioSampleFormat format, unsigned n, void *src, float *dst); + +void ConvertFromFloat(AudioSampleFormat format, unsigned n, float *src, void *dst); +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/audio_engine/utils/hpae_no_lock_queue.cpp b/services/audio_engine/utils/hpae_no_lock_queue.cpp new file mode 100644 index 0000000000..4128a6b4ed --- /dev/null +++ b/services/audio_engine/utils/hpae_no_lock_queue.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2025 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 +#include "audio_engine_log.h" +#include + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +constexpr uint32_t MAX_REQUEST_COUNT = std::numeric_limits::max() - 1; +constexpr uint32_t INVALID_REQUEST_ID = std::numeric_limits::max(); +constexpr uint64_t SHIFT_32_OFFSET = 32; +HpaeNoLockQueue::HpaeNoLockQueue(size_t maxRequestCount) +{ + if (maxRequestCount > MAX_REQUEST_COUNT) { + AUDIO_WARNING_LOG("[HpaeNoLockQueue] maxRequestCount %{public}zu is beyound Max Count", maxRequestCount); + maxRequestCount = MAX_REQUEST_COUNT; + } + if (maxRequestCount <= 0) { + AUDIO_WARNING_LOG("[HpaeNoLockQueue] maxRequestCount can not be zero"); + return; + } + InitQueue(maxRequestCount); +} + +HpaeNoLockQueue::~HpaeNoLockQueue() +{ + AUDIO_INFO_LOG("HpaeNoLockQueue destroyed"); +} +void HpaeNoLockQueue::InitQueue(size_t maxRequestCount) +{ + requestQueue_.resize(maxRequestCount); + tempRequestQueue_.reserve(maxRequestCount); + + freeRequestHeadIndex_ = 0; + for (size_t i = 0; i < maxRequestCount - 1; ++i) { + requestQueue_[i].nextRequestIndex = i + 1; + } + requestQueue_[maxRequestCount - 1].nextRequestIndex = INVALID_REQUEST_ID; + requestHeadIndex_ = INVALID_REQUEST_ID; + AUDIO_INFO_LOG("Init Queue size is %{public}zu", maxRequestCount); +} +void HpaeNoLockQueue::PushRequest(Request &&request) +{ + const uint64_t freeRequestIndex = GetRequestNode(&freeRequestHeadIndex_); + if (GetRequsetIndex(freeRequestIndex) == INVALID_REQUEST_ID) { + AUDIO_WARNING_LOG("reached Queue Capacity: drop this request"); + return; + } + requestQueue_[GetRequsetIndex(freeRequestIndex)].request = std::move(request); + PushRequestNode(&requestHeadIndex_, freeRequestIndex); +} + +void HpaeNoLockQueue::HandleRequests() +{ + const uint64_t oldRequestFlag = (GetRequsetFlag(requestHeadIndex_) << 32) + INVALID_REQUEST_ID; + const uint64_t oldRequestHeadindex = requestHeadIndex_.exchange(oldRequestFlag); + ProcessRequests(oldRequestHeadindex, true); +} + +void HpaeNoLockQueue::Reset() +{ + const uint64_t oldRequestFlag = (GetRequsetFlag(requestHeadIndex_) << 32) + INVALID_REQUEST_ID; + const uint64_t oldRequestHeadindex = requestHeadIndex_.exchange(oldRequestFlag); + ProcessRequests(oldRequestHeadindex, false); +} + +uint64_t HpaeNoLockQueue::IncRequsetIndex(uint64_t requestIndex) +{ + return requestIndex + (static_cast(1) << SHIFT_32_OFFSET); +} + +uint64_t HpaeNoLockQueue::GetRequsetIndex(uint64_t requestIndex) +{ + return requestIndex & std::numeric_limits::max(); +} + +uint64_t HpaeNoLockQueue::GetRequsetFlag(uint64_t requestFlag) +{ + return requestFlag >> SHIFT_32_OFFSET; +} + +void HpaeNoLockQueue::PushRequestNode(std::atomic *pRequestHeadIndex, uint64_t index) +{ + if (pRequestHeadIndex == nullptr) { + return; + } + uint64_t requestHeadIndex; + do { + requestHeadIndex = pRequestHeadIndex->load(); + requestQueue_[GetRequsetIndex(index)].nextRequestIndex = requestHeadIndex; + } while (!std::atomic_compare_exchange_strong(pRequestHeadIndex, &requestHeadIndex, index)); +} + +uint64_t HpaeNoLockQueue::GetRequestNode(std::atomic *pRequestHeadIndex) +{ + if (pRequestHeadIndex == nullptr) { + return std::numeric_limits::max(); + } + uint64_t requestHeadIndex; + uint64_t nextRequestIndex; + do { + requestHeadIndex = pRequestHeadIndex->load(); + if (GetRequsetIndex(requestHeadIndex) == INVALID_REQUEST_ID) { + return INVALID_REQUEST_ID; + } + nextRequestIndex = requestQueue_[GetRequsetIndex(requestHeadIndex)].nextRequestIndex; + } while (!std::atomic_compare_exchange_strong(pRequestHeadIndex, &requestHeadIndex, nextRequestIndex)); + return IncRequsetIndex(requestHeadIndex); +} + +void HpaeNoLockQueue::ProcessRequests(uint64_t requestHeadIndex, bool isProcess) +{ + uint64_t tempIndex = requestHeadIndex; + while (GetRequsetIndex(tempIndex) != INVALID_REQUEST_ID) { + RequestNode *tempRequest = &requestQueue_[GetRequsetIndex(tempIndex)]; + uint64_t nextRequest = tempRequest->nextRequestIndex; + tempRequestQueue_.emplace_back(std::move(tempRequest->request)); + tempRequest->request = nullptr; + PushRequestNode(&freeRequestHeadIndex_, tempIndex); + tempIndex = nextRequest; + } + + if (isProcess) { + for (std::vector::reverse_iterator requestIter = tempRequestQueue_.rbegin(); + requestIter != tempRequestQueue_.rend(); + ++requestIter) { + if (*requestIter != nullptr) { + (*requestIter)(); + } + } + } + tempRequestQueue_.clear(); +} + +bool HpaeNoLockQueue::IsFinishProcess() +{ + if (GetRequsetIndex(requestHeadIndex_) == INVALID_REQUEST_ID) { + return true; + } else { + return false; + } +} +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/utils/hpae_no_lock_queue.h b/services/audio_engine/utils/hpae_no_lock_queue.h new file mode 100644 index 0000000000..47d45b86dc --- /dev/null +++ b/services/audio_engine/utils/hpae_no_lock_queue.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 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 NOLOCK_REQUEST_QUEUE_H +#define NOLOCK_REQUEST_QUEUE_H +#include +#include +#include +#include + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +const size_t CURRENT_REQUEST_COUNT = 1000; +using Request = std::function; +struct RequestNode { + RequestNode() = default; + RequestNode(const RequestNode &requestNode) : nextRequestIndex() + {} + RequestNode& operator=(const RequestNode& requestNode) = delete; + Request request; + std::atomic nextRequestIndex; +}; +class HpaeNoLockQueue { +public: + explicit HpaeNoLockQueue(size_t maxRequestCount); + ~HpaeNoLockQueue(); + + void PushRequest(Request &&request); + void HandleRequests(); + void Reset(); + bool IsFinishProcess(); + +private: + void InitQueue(size_t maxRequestCount); + uint64_t IncRequsetIndex(uint64_t requestIndex); + uint64_t GetRequsetIndex(uint64_t requestIndex); + uint64_t GetRequsetFlag(uint64_t requestFlag); + + void PushRequestNode(std::atomic *pRequestHeadIndex, uint64_t index); + uint64_t GetRequestNode(std::atomic *pRequestHeadIndex); + void ProcessRequests(uint64_t requestHeadIndex, bool isProcess); + +private: + std::atomic freeRequestHeadIndex_; + std::atomic requestHeadIndex_; + std::vector requestQueue_; + std::vector tempRequestQueue_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif diff --git a/services/audio_engine/utils/hpae_pcm_dumper.cpp b/services/audio_engine/utils/hpae_pcm_dumper.cpp new file mode 100644 index 0000000000..04080e56a7 --- /dev/null +++ b/services/audio_engine/utils/hpae_pcm_dumper.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 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 +#include "hpae_pcm_dumper.h" +#include "audio_errors.h" +#include "audio_engine_log.h" +#include "audio_utils.h" +#include "securec.h" + +namespace OHOS { +namespace AudioStandard { +namespace HPAE { + +HpaePcmDumper::HpaePcmDumper(const std::string &filename) +{ + DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, filename, &dumpFile_); + filename_ = filename; +} + +HpaePcmDumper::~HpaePcmDumper() +{ + DumpFileUtil::CloseDumpFile(&dumpFile_); +} + +int32_t HpaePcmDumper::Dump(const int8_t *buffer, int32_t length) +{ + DumpFileUtil::WriteDumpFile(dumpFile_, (void *)(buffer), length); + return SUCCESS; +} + +bool HpaePcmDumper::CheckAndReopenHandlde() +{ + if (dumpFile_ != nullptr) { + return true; + } else { + DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, filename_, &dumpFile_); + AUDIO_DEBUG_LOG("Reopen dump file: %{public}s", filename_.c_str()); + } + return false; +} + +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_engine/utils/hpae_pcm_dumper.h b/services/audio_engine/utils/hpae_pcm_dumper.h new file mode 100644 index 0000000000..ca7d5e3732 --- /dev/null +++ b/services/audio_engine/utils/hpae_pcm_dumper.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 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 HPAE_PCM_DUMPER_H +#define HPAE_PCM_DUMPER_H +#include +namespace OHOS { +namespace AudioStandard { +namespace HPAE { +class HpaePcmDumper { +public: + explicit HpaePcmDumper(const std::string &filename); + ~HpaePcmDumper(); + int32_t Dump(const int8_t *buffer, int32_t length); + bool CheckAndReopenHandlde(); +private: + FILE *dumpFile_ = nullptr; + std::string filename_; +}; +} // namespace HPAE +} // namespace AudioStandard +} // namespace OHOS +#endif \ No newline at end of file -- Gitee From 72387fc8322f3468acdc99c2fd27aef18effb0f0 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Sat, 12 Apr 2025 11:57:16 +0800 Subject: [PATCH 02/40] upload proaudio adapter files Signed-off-by: c00657214 --- .../include/pro_audio_service_adapter_impl.h | 107 ++++ .../src/audio_service_adapter.cpp | 57 +++ .../src/pro_audio_service_adapter_impl.cpp | 482 ++++++++++++++++++ .../audioadapter/test/unittest/BUILD.gn | 69 +++ .../pro_audio_service_adapter_unit_test.h | 54 ++ .../pro_audio_service_adapter_unit_test.cpp | 329 ++++++++++++ .../audiocommon/include/audio_engine_log.h | 23 + .../server/include/audio_server_hpae_dump.h | 66 +++ .../include/hpae_capturer_stream_impl.h | 74 +++ .../include/hpae_renderer_stream_impl.h | 111 ++++ .../server/include/pro_adapter_manager.h | 63 +++ .../server/src/audio_server_hpae_dump.cpp | 196 +++++++ .../server/src/hpae_capturer_stream_impl.cpp | 212 ++++++++ .../server/src/hpae_renderer_stream_impl.cpp | 480 +++++++++++++++++ .../server/src/pro_adapter_manager.cpp | 289 +++++++++++ 15 files changed, 2612 insertions(+) create mode 100644 frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h create mode 100644 frameworks/native/audioadapter/src/audio_service_adapter.cpp create mode 100644 frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp create mode 100644 frameworks/native/audioadapter/test/unittest/BUILD.gn create mode 100644 frameworks/native/audioadapter/test/unittest/include/pro_audio_service_adapter_unit_test.h create mode 100644 frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp create mode 100644 interfaces/inner_api/native/audiocommon/include/audio_engine_log.h create mode 100644 services/audio_service/server/include/audio_server_hpae_dump.h create mode 100644 services/audio_service/server/include/hpae_capturer_stream_impl.h create mode 100644 services/audio_service/server/include/hpae_renderer_stream_impl.h create mode 100644 services/audio_service/server/include/pro_adapter_manager.h create mode 100644 services/audio_service/server/src/audio_server_hpae_dump.cpp create mode 100644 services/audio_service/server/src/hpae_capturer_stream_impl.cpp create mode 100644 services/audio_service/server/src/hpae_renderer_stream_impl.cpp create mode 100644 services/audio_service/server/src/pro_adapter_manager.cpp diff --git a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h new file mode 100644 index 0000000000..486df97b7e --- /dev/null +++ b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2025 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 ST_PRO_AUDIO_SERVICE_ADAPTER_H +#define ST_PRO_AUDIO_SERVICE_ADAPTER_H +#include +#include "safe_map.h" +#include +#include "audio_service_adapter.h" +#include "audio_module_info.h" +#include "audio_service_hpae_callback.h" + +namespace OHOS { +namespace AudioStandard { + +class ProAudioServiceAdapterImpl : public AudioServiceAdapter, public AudioServiceHpaeCallback, public std::enable_shared_from_this { +public: + explicit ProAudioServiceAdapterImpl(std::unique_ptr &cb); + ~ProAudioServiceAdapterImpl(); + + bool Connect() override; + uint32_t OpenAudioPort(std::string audioPortName, std::string moduleArgs) override; + int32_t OpenAudioPort(std::string audioPortName, const AudioModuleInfo& audioModuleInfo) override; + int32_t CloseAudioPort(int32_t audioHandleIndex, bool isSync = false) override; + int32_t SetDefaultSink(std::string name) override; + int32_t SetDefaultSource(std::string name) override; + int32_t SetSourceOutputMute(int32_t uid, bool setMute) override; + int32_t SuspendAudioDevice(std::string &audioPortName, bool isSuspend) override; + bool SetSinkMute(const std::string &sinkName, bool isMute, bool isSync = false) override; + std::vector GetAllSinkInputs() override; + std::vector GetAllSourceOutputs() override; + void Disconnect() override; + + std::vector GetTargetSinks(std::string adapterName) override; + std::vector GetAllSinks() override; + int32_t SetLocalDefaultSink(std::string name) override; + int32_t MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) override; + int32_t MoveSourceOutputByIndexOrName( + uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) override; + int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) override; + int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) override; + int32_t GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) override; + int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) override; + // callback Member functions + virtual void OnOpenAudioPortCb(int32_t portId) override; + virtual void OnCloseAudioPortCb(int32_t result) override; + virtual void OnSetSinkMuteCb(int32_t result) override; + virtual void OnSetSourceOutputMuteCb(int32_t result) override; + + virtual void OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) override; + virtual void OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) override; + virtual void OnGetAllSinksCb(int32_t result, std::vector &sinks) override; + + virtual void OnMoveSinkInputByIndexOrNameCb(int32_t result) override; + virtual void OnMoveSourceOutputByIndexOrNameCb(int32_t result) override; + + virtual void OnGetAudioEffectPropertyCbV3(int32_t result) override; + virtual void OnGetAudioEffectPropertyCb(int32_t result) override; + virtual void OnGetAudioEnhancePropertyCbV3(int32_t result) override; + virtual void OnGetAudioEnhancePropertyCb(int32_t result) override; + virtual void HandleSourceAudioStreamRemoved(uint32_t sessionId) override; + +private: + std::mutex lock_; + // for status operation wait and notify + std::mutex callbackMutex_; + std::condition_variable callbackCV_; + + bool isFinishOpenAudioPort_ = false; + int32_t AudioPortIndex_ = 0; + bool isFinishCloseAudioPort_ = false; + + bool isFinishGetAllSinkInputs_ = false; + std::vector sinkInputs_; + bool isFinishGetAllSourceOutputs_ = false; + std::vector sourceOutputs_; + bool isFinishGetAllSinks_ = false; + std::vector sinks_; + bool isFinishMoveSinkInputByIndexOrName_ = false; + bool isFinishMoveSourceOutputByIndexOrName_ = false; + + int32_t SourceOutputMuteStreamSet_ = 0; + bool isFinishSetSourceOutputMute_ = false; + bool isFinishSetSinkMute_ = false; + + bool isFinishGetAudioEffectPropertyV3_ = false; + bool isFinishGetAudioEffectProperty_ = false; + bool isFinishGetAudioEnhancePropertyV3_ = false; + bool isFinishGetAudioEnhanceProperty_ = false; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // ST_PULSEAUDIO_AUDIO_SERVICE_ADAPTER_H diff --git a/frameworks/native/audioadapter/src/audio_service_adapter.cpp b/frameworks/native/audioadapter/src/audio_service_adapter.cpp new file mode 100644 index 0000000000..930a7ece1b --- /dev/null +++ b/frameworks/native/audioadapter/src/audio_service_adapter.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025-2025 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 "AudioServiceAdapter" +#endif + +#include "pro_audio_service_adapter_impl.h" +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#include + +#include "audio_errors.h" +#include "audio_common_log.h" +#include "audio_info.h" +#include "audio_utils.h" +#include +#include + +#include "pulse_audio_service_adapter_impl.h" +#include "pro_audio_service_adapter_impl.h" + +using namespace std; + +namespace OHOS { +namespace AudioStandard { + +AudioServiceAdapter::~AudioServiceAdapter() = default; + +std::shared_ptr AudioServiceAdapter::CreateAudioAdapter(std::unique_ptr cb) +{ + CHECK_AND_RETURN_RET_LOG(cb != nullptr, nullptr, "CreateAudioAdapter cb is nullptr!"); + AUDIO_INFO_LOG("CreateAudioAdapter"); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return make_shared(cb); + } else { + return make_shared(cb); + } +} + +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp new file mode 100644 index 0000000000..ce16d2dc30 --- /dev/null +++ b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2025 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 ST_PRO_AUDIO_SERVICE_ADAPTER_IMPL_H +#define ST_PRO_AUDIO_SERVICE_ADAPTER_IMPL_H +#ifndef LOG_TAG +#define LOG_TAG "ProAudioServiceAdapterImpl" +#endif + +#include "pro_audio_service_adapter_impl.h" +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#include + +#include "audio_errors.h" +#include "audio_common_log.h" +#include "audio_info.h" +#include "audio_utils.h" +#include +#include +#include "i_hpae_manager.h" + +using namespace std; +using namespace OHOS::AudioStandard::HPAE; +namespace OHOS { +namespace AudioStandard { +static unique_ptr g_audioServiceAdapterCallback; +static const int32_t OPERATION_TIMEOUT_IN_MS = 1000; // 1000ms + +ProAudioServiceAdapterImpl::~ProAudioServiceAdapterImpl() = default; + +ProAudioServiceAdapterImpl::ProAudioServiceAdapterImpl(unique_ptr &cb) +{ + g_audioServiceAdapterCallback = move(cb); +} + +bool ProAudioServiceAdapterImpl::Connect() +{ + AUDIO_INFO_LOG("Connected RegiesterServiceCallback"); + IHpaeManager::GetHpaeManager()->RegisterSerivceCallback(shared_from_this()); + return true; +} + +uint32_t ProAudioServiceAdapterImpl::OpenAudioPort(string audioPortName, string moduleArgs) +{ + AUDIO_PRERELEASE_LOGI("ERROR OpenAudioPort enter."); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::OpenAudioPort(string audioPortName, const AudioModuleInfo &audioModuleInfo) +{ + AUDIO_PRERELEASE_LOGI("OpenAudioPort enter."); + Trace trace("OpenAudioPort"); + lock_guard lock(lock_); + IHpaeManager::GetHpaeManager()->OpenAudioPort(audioModuleInfo); + isFinishOpenAudioPort_ = false; + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishOpenAudioPort_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("OpenAudioPort timeout"); + return ERROR; + } + AUDIO_INFO_LOG("OpenAudioPort leave"); + return AudioPortIndex_; +} + +int32_t ProAudioServiceAdapterImpl::CloseAudioPort(int32_t audioHandleIndex, bool isSync) +{ + AUDIO_INFO_LOG("try to close module:%{public}d", audioHandleIndex); + Trace trace("CloseAudioPort"); + lock_guard lock(lock_); + IHpaeManager::GetHpaeManager()->CloseAudioPort(audioHandleIndex); + AUDIO_INFO_LOG("CloseAudioPort: audioHandleIndex: [%{public}d] isSync [%{public}d]", audioHandleIndex, isSync); + if (isSync) { + isFinishCloseAudioPort_ = false; + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishCloseAudioPort_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("CloseAudioPort timeout"); + return ERROR; + } + } + AUDIO_INFO_LOG("CloseAudioPort leave"); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::SuspendAudioDevice(string &audioPortName, bool isSuspend) +{ + lock_guard lock(lock_); + Trace trace("SuspendAudioDevice"); + AUDIO_INFO_LOG("SuspendAudioDevice [%{public}s] : [%{public}d]", audioPortName.c_str(), isSuspend); + IHpaeManager::GetHpaeManager()->SuspendAudioDevice(audioPortName, isSuspend); + return SUCCESS; +} + +bool ProAudioServiceAdapterImpl::SetSinkMute(const std::string &sinkName, bool isMute, bool isSync) +{ + AUDIO_INFO_LOG("SetSinkMute: [%{public}s] : [%{public}d] isSync [%{public}d]", sinkName.c_str(), isMute, isSync); + lock_guard lock(lock_); + Trace trace("SetSinkMute:" + sinkName + "isMute:" + std::to_string(isMute)); + IHpaeManager::GetHpaeManager()->SetSinkMute(sinkName, isMute, isSync); + if (isSync) { + isFinishSetSinkMute_ = false; + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishSetSinkMute_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("SetSinkMute timeout"); + return ERROR; + } + } + AUDIO_INFO_LOG("SetSinkMute leave"); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::SetDefaultSink(string name) +{ + lock_guard lock(lock_); + Trace trace("SetDefaultSink:" + name); + IHpaeManager::GetHpaeManager()->SetDefaultSink(name); + AUDIO_INFO_LOG("SetDefaultSink: [%{public}s]", name.c_str()); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::SetDefaultSource(string name) +{ + lock_guard lock(lock_); + Trace trace("SetDefaultSource:" + name); + IHpaeManager::GetHpaeManager()->SetDefaultSource(name); + AUDIO_INFO_LOG("SetDefaultSink: [%{public}s]", name.c_str()); + return SUCCESS; +} + +std::vector ProAudioServiceAdapterImpl::GetAllSinks() +{ + AUDIO_INFO_LOG("GetAllSinks: enter"); + lock_guard lock(lock_); + Trace trace("GetAllSinks"); + isFinishGetAllSinks_ = false; + IHpaeManager::GetHpaeManager()->GetAllSinks(); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetAllSinks_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("GetAllSinks timeout"); + sinks_.clear(); + } + AUDIO_INFO_LOG("GetAllSinks leave"); + return sinks_; +} + +std::vector ProAudioServiceAdapterImpl::GetTargetSinks(std::string adapterName) +{ + std::vector sinkInfos = GetAllSinks(); + Trace trace("GetTargetSinks:" + adapterName); + std::vector targetSinkIds = {}; + for (size_t i = 0; i < sinkInfos.size(); i++) { + if (sinkInfos[i].adapterName == adapterName) { + targetSinkIds.push_back(sinkInfos[i].sinkId); + } + } + AUDIO_INFO_LOG("GetTargetSinks: adapterName %{public}s", adapterName.c_str()); + return targetSinkIds; +} + +int32_t ProAudioServiceAdapterImpl::SetLocalDefaultSink(std::string name) +{ + AUDIO_INFO_LOG("SetLocalDefaultSink sink name: %{public}s", name.c_str()); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::MoveSinkInputByIndexOrName( + uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) +{ + AUDIO_INFO_LOG("MoveSinkInputByIndexOrName sinkInputId %{public}d, sinkIndex %{public}d, sinkName %{public}s", + sinkInputId, + sinkIndex, + sinkName.c_str()); + lock_guard lock(lock_); + Trace trace("MoveSinkInputByIndexOrName: " + std::to_string(sinkInputId) + " index:" + std::to_string(sinkIndex) + + " sink:" + sinkName); + isFinishMoveSinkInputByIndexOrName_ = false; + IHpaeManager::GetHpaeManager()->MoveSinkInputByIndexOrName(sinkInputId, sinkIndex, sinkName); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishMoveSinkInputByIndexOrName_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("MoveSinkInputByIndexOrName timeout"); + return ERROR; + } + AUDIO_INFO_LOG("MoveSinkInputByIndexOrName leave"); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::MoveSourceOutputByIndexOrName( + uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) +{ + AUDIO_INFO_LOG( + "MoveSourceOutputByIndexOrName sourceOutputId %{public}d, sourceIndex %{public}d, sourceName %{public}s", + sourceOutputId, + sourceIndex, + sourceName.c_str()); + lock_guard lock(lock_); + Trace trace("MoveSourceOutputByIndexOrName: " + std::to_string(sourceOutputId) + + " index:" + std::to_string(sourceIndex) + " source:" + sourceName); + isFinishMoveSourceOutputByIndexOrName_ = false; + IHpaeManager::GetHpaeManager()->MoveSourceOutputByIndexOrName(sourceOutputId, sourceIndex, sourceName); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishMoveSourceOutputByIndexOrName_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("MoveSourceOutputByIndexOrName timeout"); + return ERROR; + } + AUDIO_INFO_LOG("MoveSourceOutputByIndexOrName leave"); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::SetSourceOutputMute(int32_t uid, bool setMute) +{ + AUDIO_INFO_LOG("SetSourceOutputMute uid %{public}d, setMute %{public}d", uid, setMute); + lock_guard lock(lock_); + isFinishSetSourceOutputMute_ = false; + SourceOutputMuteStreamSet_ = 0; + IHpaeManager::GetHpaeManager()->SetSourceOutputMute(uid, setMute); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishSetSourceOutputMute_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("SetSourceOutputMute timeout"); + return ERROR; + } + AUDIO_INFO_LOG("SetSourceOutputMute leave"); + return SourceOutputMuteStreamSet_; +} + +std::vector ProAudioServiceAdapterImpl::GetAllSinkInputs() +{ + AUDIO_INFO_LOG("GetAllSinkInputs Enter"); + lock_guard lock(lock_); + isFinishGetAllSinkInputs_ = false; + IHpaeManager::GetHpaeManager()->GetAllSinkInputs(); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetAllSinkInputs_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("GetAllSinkInputs timeout"); + sinkInputs_.clear(); + } + AUDIO_INFO_LOG("GetAllSinkInputs leave"); + return sinkInputs_; +} + +std::vector ProAudioServiceAdapterImpl::GetAllSourceOutputs() +{ + AUDIO_INFO_LOG("GetAllSourceOutputs"); + lock_guard lock(lock_); + isFinishGetAllSourceOutputs_ = false; + IHpaeManager::GetHpaeManager()->GetAllSourceOutputs(); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetAllSourceOutputs_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("GetAllSourceOutputs timeout"); + sourceOutputs_.clear(); + } + AUDIO_INFO_LOG("GetAllSourceOutputs leave"); + return sourceOutputs_; +} + +void ProAudioServiceAdapterImpl::Disconnect() +{ + AUDIO_INFO_LOG("Disconnect not support"); +} + +int32_t ProAudioServiceAdapterImpl::GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) +{ + AUDIO_INFO_LOG("GetAudioEffectProperty"); + lock_guard lock(lock_); + isFinishGetAudioEffectPropertyV3_ = false; + IHpaeManager::GetHpaeManager()->GetAudioEffectProperty(propertyArray); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetAudioEffectPropertyV3_; + }); + if (!stopWaiting) { + AUDIO_WARNING_LOG("wait for notify timeout"); + } + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) +{ + AUDIO_INFO_LOG("GetAudioEffectProperty"); + lock_guard lock(lock_); + isFinishGetAudioEffectProperty_ = false; + IHpaeManager::GetHpaeManager()->GetAudioEffectProperty(propertyArray); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetAudioEffectProperty_; + }); + if (!stopWaiting) { + AUDIO_WARNING_LOG("wait for notify timeout"); + } + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, + DeviceType deviceType) +{ + AUDIO_INFO_LOG("GetAudioEnhancePropertyV3"); + lock_guard lock(lock_); + isFinishGetAudioEnhancePropertyV3_ = false; + IHpaeManager::GetHpaeManager()->GetAudioEnhanceProperty(propertyArray); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetAudioEnhancePropertyV3_; + }); + if (!stopWaiting) { + AUDIO_WARNING_LOG("wait for notify timeout"); + } + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType) +{ + AUDIO_INFO_LOG("GetAudioEnhanceProperty"); + lock_guard lock(lock_); + isFinishGetAudioEnhanceProperty_ = false; + IHpaeManager::GetHpaeManager()->GetAudioEnhanceProperty(propertyArray); + std::unique_lock waitLock(callbackMutex_); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetAudioEnhanceProperty_; + }); + if (!stopWaiting) { + AUDIO_WARNING_LOG("wait for notify timeout"); + } + return SUCCESS; +} + +void ProAudioServiceAdapterImpl::OnOpenAudioPortCb(int32_t portId) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnOpenAudioPortCb portId: %{public}d", portId); + isFinishOpenAudioPort_ = true; + AudioPortIndex_ = portId; + callbackCV_.notify_all(); +} +void ProAudioServiceAdapterImpl::OnCloseAudioPortCb(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnCloseAudioPortCb result: %{public}d", result); + isFinishCloseAudioPort_ = true; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnSetSinkMuteCb(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnSetSinkMuteCb result: %{public}d", result); + isFinishSetSinkMute_ = true; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnGetAllSinkInputsCb result: %{public}d", result); + isFinishGetAllSinkInputs_ = true; + sinkInputs_ = sinkInputs; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnSetSourceOutputMuteCb(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnSetSourceOutputMuteCb result: %{public}d", result); + isFinishSetSourceOutputMute_ = true; + SourceOutputMuteStreamSet_ = result; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnGetAllSourceOutputsCb result: %{public}d", result); + isFinishGetAllSourceOutputs_ = true; + sourceOutputs_ = sourceOutputs; + callbackCV_.notify_all(); +} +void ProAudioServiceAdapterImpl::OnGetAllSinksCb(int32_t result, std::vector &sinks) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnGetAllSinksCb result: %{public}d", result); + isFinishGetAllSinks_ = true; + sinks_ = sinks; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnMoveSinkInputByIndexOrNameCb(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnMoveSinkInputByIndexOrNameCb result: %{public}d", result); + isFinishMoveSinkInputByIndexOrName_ = true; + callbackCV_.notify_all(); +} +void ProAudioServiceAdapterImpl::OnMoveSourceOutputByIndexOrNameCb(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnMoveSourceOutputByIndexOrNameCb result: %{public}d", result); + isFinishMoveSourceOutputByIndexOrName_ = true; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnGetAudioEffectPropertyCbV3(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnGetAudioEffectPropertyCbV3 result: %{public}d", result); + isFinishGetAudioEffectPropertyV3_ = true; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnGetAudioEffectPropertyCb(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnGetAudioEffectPropertyCb result: %{public}d", result); + isFinishGetAudioEffectProperty_ = true; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnGetAudioEnhancePropertyCbV3(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnGetAudioEnhancePropertyCbV3 result: %{public}d", result); + isFinishGetAudioEnhancePropertyV3_ = true; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::OnGetAudioEnhancePropertyCb(int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + AUDIO_INFO_LOG("OnGetAudioEnhancePropertyCb result: %{public}d", result); + isFinishGetAudioEnhanceProperty_ = true; + callbackCV_.notify_all(); +} + +void ProAudioServiceAdapterImpl::HandleSourceAudioStreamRemoved(uint32_t sessionId) +{ + // todo: code check + CHECK_AND_RETURN_LOG(g_audioServiceAdapterCallback != nullptr, "g_audioServiceAdapterCallback is nullptr"); + g_audioServiceAdapterCallback->OnAudioStreamRemoved(sessionId); +} +} // namespace AudioStandard +} // namespace OHOS + +#endif // ST_PULSEAUDIO_AUDIO_SERVICE_ADAPTER_IMPL_H diff --git a/frameworks/native/audioadapter/test/unittest/BUILD.gn b/frameworks/native/audioadapter/test/unittest/BUILD.gn new file mode 100644 index 0000000000..d61e4a17cb --- /dev/null +++ b/frameworks/native/audioadapter/test/unittest/BUILD.gn @@ -0,0 +1,69 @@ +# Copyright (c) 2025 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("//build/test.gni") +import("../../../../../config.gni") + +module_output_path = "multimedia_audio_framework/audio_engine" + +config("audio_engine_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "../../../audioutils/include", + "../../../../../interfaces/inner_api/native/audiocommon/include", + "../../../../../services/audio_service/server/include", + "../../../hdiadapter/common/include", + "../../../hdiadapter/sink/common", + "../../../hdiadapter/source/common", + "../../../../../services/audio_policy/server/include/service/common", + "../../../../../services/audio_engine/manager/include", + "../../../../../services/audio_service/common/include", + "./include", + "../../include" + ] +} + +############################################################################################# +ohos_unittest("pro_audio_service_adapter_unit_test") { + module_out_path = module_output_path + testonly = true + cflags = [ + "-Wall", + "-Werror", + "-fno-access-control", + ] + sources = [ + "src/pro_audio_service_adapter_unit_test.cpp", + ] + + configs = [ ":audio_engine_private_config" ] + + deps = [ + "../../../audioutils:audio_utils", + "../../../../../services/audio_engine:audio_engine_manager", + "../../:pulse_audio_service_adapter", + ] + + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] +} + diff --git a/frameworks/native/audioadapter/test/unittest/include/pro_audio_service_adapter_unit_test.h b/frameworks/native/audioadapter/test/unittest/include/pro_audio_service_adapter_unit_test.h new file mode 100644 index 0000000000..9570b10bce --- /dev/null +++ b/frameworks/native/audioadapter/test/unittest/include/pro_audio_service_adapter_unit_test.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 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 PRO_AUDIO_SERVICE_ADAPTER_UNIT_TEST_H +#define PRO_AUDIO_SERVICE_ADAPTER_UNIT_TEST_H +#include +#include "gtest/gtest.h" +#include "pro_audio_service_adapter_impl.h" +#include "audio_service_adapter.h" +namespace OHOS { +namespace AudioStandard { +class ProAudioServiceCallbackTest : public AudioServiceAdapterCallback { +public: + ProAudioServiceCallbackTest() {} + ~ProAudioServiceCallbackTest() { + AUDIO_WARNING_LOG("Destructor ProAudioServiceCallbackTest"); + } + void OnAudioStreamRemoved(const uint64_t sessionId) + {} + void OnSetVolumeDbCb() + {} +}; + +class ProAudioServiceAdapterUnitTest : public testing::Test { +public: + ProAudioServiceAdapterUnitTest(); + ~ProAudioServiceAdapterUnitTest(); + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(void); + void TearDown(void); + AudioModuleInfo InitSinkAudioModeInfo(); + AudioModuleInfo InitSourceAudioModeInfo(); +private: + void Init(); +protected: + std::shared_ptr impl_; + int32_t engineFlag_; +}; +} // namespace AudioStandard +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp b/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp new file mode 100644 index 0000000000..9cfa538225 --- /dev/null +++ b/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2025 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 +#include +#include "gtest/gtest.h" +#include "audio_errors.h" +#include "audio_utils.h" +#include "i_hpae_manager.h" +#include "pro_audio_service_adapter_unit_test.h" +using namespace testing::ext; +namespace OHOS { +namespace AudioStandard { +static std::string g_rootPath = "/data/data/.pulse_dir/"; + +void ProAudioServiceAdapterUnitTest::SetUpTestCase(void) +{} +void ProAudioServiceAdapterUnitTest::TearDownTestCase(void) +{} +void ProAudioServiceAdapterUnitTest::SetUp(void) +{ + std::unique_ptr cb = std::make_unique(); + impl_ = AudioServiceAdapter::CreateAudioAdapter(std::move(cb)); + impl_->Connect(); + HPAE::IHpaeManager::GetHpaeManager()->Init(); +} +void ProAudioServiceAdapterUnitTest::TearDown(void) +{ + impl_ = nullptr; + if (engineFlag_ != 1) { + const char *key = "sys.audio.engine.proaudio.enable"; + SetSysPara(key, engineFlag_); + } +} + +ProAudioServiceAdapterUnitTest::ProAudioServiceAdapterUnitTest() +{ + engineFlag_ = GetEngineFlag(); + std::cout<<"engine flag:"<(DEVICE_TYPE_SPEAKER); + audioModuleInfo.deviceType = typeValue.str(); + return audioModuleInfo; +} + +AudioModuleInfo ProAudioServiceAdapterUnitTest::InitSourceAudioModeInfo() +{ + AudioModuleInfo audioModuleInfo; + audioModuleInfo.lib = "libmodule-hdi-source.z.so"; + audioModuleInfo.channels = "2"; + audioModuleInfo.rate = "48000"; + audioModuleInfo.name = "mic"; + audioModuleInfo.adapterName = "file_io"; + audioModuleInfo.className = "file_io"; + audioModuleInfo.bufferSize = "3840"; + audioModuleInfo.format = "s16le"; + audioModuleInfo.fixedLatency = "1"; + audioModuleInfo.offloadEnable = "0"; + audioModuleInfo.networkId = "LocalDevice"; + audioModuleInfo.fileName = g_rootPath + audioModuleInfo.adapterName + "_" + audioModuleInfo.rate + "_" + + audioModuleInfo.channels + "_" + audioModuleInfo.format + ".pcm"; + std::stringstream typeValue; + typeValue << static_cast(DEVICE_TYPE_SPEAKER); + audioModuleInfo.deviceType = typeValue.str(); + return audioModuleInfo; +} + +/** + * @tc.name: Pro_Audio_OpenAudioPort_001 + * @tc.desc: test open audio port sink + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_OpenAudioPort_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); +} + +/** + * @tc.name: Pro_Audio_OpenAudioPort_002 + * @tc.desc: test open audio port source + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_OpenAudioPort_002, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); +} + +/** + * @tc.name: Pro_Audio_CloseAudioPort_001 + * @tc.desc: test close audio port + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_CloseAudioPort_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->CloseAudioPort(portId); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_CloseAudioPort_002 + * @tc.desc: test close audio port source + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_CloseAudioPort_002, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->CloseAudioPort(portId); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SetDefaultSink_001 + * @tc.desc: test set default sink + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetDefaultSink_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SetDefaultSink(moduleInfo.name); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SetDefaultSource_001 + * @tc.desc: test set default source + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetDefaultSource_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SetDefaultSource(moduleInfo.name); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SetSinkMute_001 + * @tc.desc: test set sink mute + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetSinkMute_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SetSinkMute(moduleInfo.name, true); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SetSinkMute_002 + * @tc.desc: test set sink unmute + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetSinkMute_002, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SetSinkMute(moduleInfo.name, false); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SetSourceMute_001 + * @tc.desc: test set source mute + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetSourceMute_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SetSourceOutputMute(portId, true); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SetSourceMute_002 + * @tc.desc: test set source unmute + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetSourceMute_002, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SetSourceOutputMute(portId, false); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SuspendedSink_001 + * @tc.desc: test suspended sink + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SuspendedSink_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SuspendAudioDevice(moduleInfo.name, true); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SuspendedSink_002 + * @tc.desc: test suspended sink + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SuspendedSink_002, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SuspendAudioDevice(moduleInfo.name, false); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SuspendedSource_001 + * @tc.desc: test suspended source + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SuspendedSource_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SuspendAudioDevice(moduleInfo.name, true); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_SuspendedSource_002 + * @tc.desc: test suspended source + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SuspendedSource_002, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + int32_t ret = impl_->SuspendAudioDevice(moduleInfo.name, false); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: Pro_Audio_GetAllSinks_001 + * @tc.desc: test get all sinks + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_GetAllSinks_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + std::vector sinkInputs = impl_->GetAllSinkInputs(); + EXPECT_EQ(0, sinkInputs.size()); +} + +/** + * @tc.name: Pro_Audio_GetAllSources_001 + * @tc.desc: test get all sources + * @tc.type: FUNC + */ +HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_GetAllSources_001, TestSize.Level1) +{ + AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); + int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); + EXPECT_GE(0, portId); + std::vector sourceOutputs = impl_->GetAllSourceOutputs(); + EXPECT_EQ(0, sourceOutputs.size()); +} +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_api/native/audiocommon/include/audio_engine_log.h b/interfaces/inner_api/native/audiocommon/include/audio_engine_log.h new file mode 100644 index 0000000000..c3da2f651b --- /dev/null +++ b/interfaces/inner_api/native/audiocommon/include/audio_engine_log.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 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 OHOS_HPAE_LOG_H +#define OHOS_HPAE_LOG_H + +#include "audio_log.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN 0xD002B88 +#endif // OHOS_HPAE_LOG_H diff --git a/services/audio_service/server/include/audio_server_hpae_dump.h b/services/audio_service/server/include/audio_server_hpae_dump.h new file mode 100644 index 0000000000..63d2854f72 --- /dev/null +++ b/services/audio_service/server/include/audio_server_hpae_dump.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 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 AUDIO_SERVER_HPAE_DUMP_H +#define AUDIO_SERVER_HPAE_DUMP_H + +#include +#include +#include +#include +#include +#include "securec.h" +#include "nocopyable.h" +#include "audio_service_hpae_dump_callback.h" +#include "audio_service_log.h" +#include "audio_timer.h" +#include "audio_errors.h" + +namespace OHOS { +namespace AudioStandard { + +class AudioServerHpaeDump : public AudioTimer, public AudioServiceHpaeDumpCallback { +public: + DISALLOW_COPY_AND_MOVE(AudioServerHpaeDump); + + AudioServerHpaeDump(); + ~AudioServerHpaeDump(); + int32_t Initialize(); + void AudioDataDump(std::string &dumpString, std::queue &argQue); + void OnDumpSinkInfoCb(std::string &dumpStr, int32_t result) override; + void OnDumpSourceInfoCb(std::string &dumpStr, int32_t result) override; +private: + void InitDumpFuncMap(); + void HelpInfoDump(std::string &dumpString); + void ArgDataDump(std::string &dumpString, std::queue &argQue); + void ServerDataDump(std::string &dumpString); + void PlaybackSinkDump(std::string &dumpString); + void GetDeviceSinkInfo(std::string &dumpString, std::string deviceName); + void RecordSourceDump(std::string &dumpString); + void GetDeviceSourceInfo(std::string &dumpString, std::string deviceName); + + using DumpFunc = void(AudioServerHpaeDump::*)(std::string &dumpString); + std::map dumpFuncMap; + std::string dumpHpaeSinkInfo_; + std::string dumpHpaeSourceInfo_; + std::mutex lock_; + // for status operation wait and notify + std::mutex callbackMutex_; + std::condition_variable callbackCV_; + bool isFinishGetSinkInfo_ = false; + bool isFinishGetSourceInfo_ = false; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_SERVER_DUMP_H diff --git a/services/audio_service/server/include/hpae_capturer_stream_impl.h b/services/audio_service/server/include/hpae_capturer_stream_impl.h new file mode 100644 index 0000000000..1bc9145093 --- /dev/null +++ b/services/audio_service/server/include/hpae_capturer_stream_impl.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef hpae_capturer_stream_impl_H +#define hpae_capturer_stream_impl_H + +#include "i_capturer_stream.h" + +namespace OHOS { +namespace AudioStandard { +class HpaeCapturerStreamImpl : public std::enable_shared_from_this, public ICapturerStream { +public: + HpaeCapturerStreamImpl(AudioProcessConfig processConfig); + ~HpaeCapturerStreamImpl(); + int32_t InitParams(const std::string &deviceName = ""); + int32_t Start() override; + int32_t Pause(bool isStandby = false) override; + int32_t Flush() override; + int32_t Drain(bool stopFlag = false) override { return 0; }; + int32_t Stop() override; + int32_t Release() override; + int32_t GetStreamFramesRead(uint64_t &framesRead) override; + int32_t GetCurrentTimeStamp(uint64_t ×tamp) override; + int32_t GetLatency(uint64_t &latency) override; + + void RegisterStatusCallback(const std::weak_ptr &callback) override; + void RegisterReadCallback(const std::weak_ptr &callback) override; + BufferDesc DequeueBuffer(size_t length) override; + int32_t EnqueueBuffer(const BufferDesc &bufferDesc) override; + int32_t GetMinimumBufferSize(size_t &minBufferSize) const override; + void GetByteSizePerFrame(size_t &byteSizePerFrame) const override; + void GetSpanSizePerFrame(size_t &spanSizeInFrame) const override; + void SetStreamIndex(uint32_t index) override; + uint32_t GetStreamIndex() override; + int32_t DropBuffer() override; + void AbortCallback(int32_t abortTimes) override; + +private: + + uint32_t streamIndex_ = static_cast(-1); // invalid index + + AudioProcessConfig processConfig_ = {}; + std::weak_ptr statusCallback_; + std::weak_ptr readCallback_; + State state_ = INVALID; + + size_t byteSizePerFrame_ = 0; + size_t spanSizeInFrame_ = 0; + size_t minBufferSize_ = 0; + + size_t totalBytesRead_ = 0; + + FILE *capturerServerDumpFile_ = nullptr; + + // Only for debug + int32_t abortFlag_ = 0; + + uint32_t capturerId_ = 0; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // hpae_capturer_stream_impl_H diff --git a/services/audio_service/server/include/hpae_renderer_stream_impl.h b/services/audio_service/server/include/hpae_renderer_stream_impl.h new file mode 100644 index 0000000000..f585a8c6fe --- /dev/null +++ b/services/audio_service/server/include/hpae_renderer_stream_impl.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef pro_renderer_stream_impl_H +#define pro_renderer_stream_impl_H + +#include +#include +#include "i_renderer_stream.h" + +namespace OHOS { +namespace AudioStandard { + +class HpaeRendererStreamImpl : public std::enable_shared_from_this, public IStreamCallback, public IRendererStream { +public: + HpaeRendererStreamImpl(AudioProcessConfig processConfig); + ~HpaeRendererStreamImpl(); + int32_t InitParams(const std::string &deviceName = ""); + int32_t Start() override; + int32_t Pause(bool isStandby = false) override; + int32_t Flush() override; + int32_t Drain(bool stopFlag = false) override; + int32_t Stop() override; + int32_t Release() override; + int32_t GetStreamFramesWritten(uint64_t &framesWritten) override; + int32_t GetCurrentTimeStamp(uint64_t ×tamp) override; + int32_t GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp, uint64_t &latency) override; + int32_t GetLatency(uint64_t &latency) override; + int32_t SetRate(int32_t rate) override; + int32_t SetAudioEffectMode(int32_t effectMode) override; + int32_t GetAudioEffectMode(int32_t &effectMode) override; + int32_t SetPrivacyType(int32_t privacyType) override; + int32_t GetPrivacyType(int32_t &privacyType) override; + + void RegisterStatusCallback(const std::weak_ptr &callback) override; + void RegisterWriteCallback(const std::weak_ptr &callback) override; + BufferDesc DequeueBuffer(size_t length) override; + int32_t EnqueueBuffer(const BufferDesc &bufferDesc) override; + int32_t GetMinimumBufferSize(size_t &minBufferSize) const override; + void GetByteSizePerFrame(size_t &byteSizePerFrame) const override; + void GetSpanSizePerFrame(size_t &spanSizeInFrame) const override; + void SetStreamIndex(uint32_t index) override; + uint32_t GetStreamIndex() override; + void AbortCallback(int32_t abortTimes) override; + // offload + int32_t SetOffloadMode(int32_t state, bool isAppBack) override; + int32_t UnsetOffloadMode() override; + int32_t GetOffloadApproximatelyCacheTime(uint64_t ×tamp, uint64_t &paWriteIndex, + uint64_t &cacheTimeDsp, uint64_t &cacheTimePa) override; + int32_t OffloadSetVolume(float volume) override; + size_t GetWritableSize() override; + int32_t UpdateMaxLength(uint32_t maxLength) override; + // offload end + + int32_t UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled) override; + int32_t Peek(std::vector *audioBuffer, int32_t &index) override; + int32_t ReturnIndex(int32_t index) override; + AudioProcessConfig GetAudioProcessConfig() const noexcept override; + int32_t SetClientVolume(float clientVolume) override; + void BlockStream() noexcept override; + int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) override; +private: + void SyncOffloadMode(); + + uint32_t streamIndex_ = static_cast(-1); // invalid index + AudioProcessConfig processConfig_; + std::weak_ptr statusCallback_; + std::weak_ptr writeCallback_; + State state_ = INVALID; + + size_t byteSizePerFrame_ = 0; + size_t spanSizeInFrame_ = 0; + size_t minBufferSize_ = 0; + + int32_t renderRate_ = 0; + int32_t effectMode_ = -1; + int32_t privacyType_ = 0; + + float powerVolumeFactor_ = 1.0f; + // Only for debug + int32_t abortFlag_ = 0; + // offload + bool offloadEnable_ = false; + std::atomic offloadStatePolicy_ = OFFLOAD_DEFAULT; + // offload end + float clientVolume_ = 1.0f; + // latency position timeStamp + std::shared_mutex latencyMutex_; + uint64_t framePosition_ = 0; + uint64_t timestamp_ = 0; + uint64_t latency_ = 0; + uint64_t framesWritten_ = 0; + std::string deviceClass_; + std::string deviceNetId_; + // record latency +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // pro_renderer_stream_impl_H diff --git a/services/audio_service/server/include/pro_adapter_manager.h b/services/audio_service/server/include/pro_adapter_manager.h new file mode 100644 index 0000000000..c9572f2021 --- /dev/null +++ b/services/audio_service/server/include/pro_adapter_manager.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PRO_ADAPTER_MANAGER_H +#define PRO_ADAPTER_MANAGER_H + +#include +#include + +#include "audio_timer.h" +#include "i_stream_manager.h" +#include "audio_effect.h" + +namespace OHOS { +namespace AudioStandard { + +class ProAdapterManager : public IStreamManager { +public: + ProAdapterManager(ManagerType type); + + int32_t CreateRender(AudioProcessConfig processConfig, std::shared_ptr &stream) override; + int32_t ReleaseRender(uint32_t streamIndex_) override; + int32_t StartRender(uint32_t streamIndex) override; + int32_t StopRender(uint32_t streamIndex) override; + int32_t PauseRender(uint32_t streamIndex) override; + int32_t GetStreamCount() const noexcept override; + int32_t TriggerStartIfNecessary() override; + int32_t CreateCapturer(AudioProcessConfig processConfig, std::shared_ptr &stream) override; + int32_t ReleaseCapturer(uint32_t streamIndex_) override; + int32_t AddUnprocessStream(int32_t appUid) override; + uint64_t GetLatency() noexcept override; + void GetAllSinkInputs(std::vector &sinkInputs) override; +private: + int32_t GetDeviceNameForConnect(AudioProcessConfig processConfig, uint32_t sessionId, std::string &deviceName); + // audio channel index + std::shared_ptr CreateRendererStream(AudioProcessConfig processConfig, + const std::string &deviceName = ""); + std::shared_ptr CreateCapturerStream(AudioProcessConfig processConfig, + const std::string &deviceName = ""); + + ManagerType managerType_ = PLAYBACK; + std::mutex streamMapMutex_; + std::mutex paElementsMutex_; + std::map> rendererStreamMap_; + std::map> capturerStreamMap_; + std::mutex sinkInputsMutex_; + std::vector sinkInputs_; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // pro_adapter_manager_H diff --git a/services/audio_service/server/src/audio_server_hpae_dump.cpp b/services/audio_service/server/src/audio_server_hpae_dump.cpp new file mode 100644 index 0000000000..3ada17b7e6 --- /dev/null +++ b/services/audio_service/server/src/audio_server_hpae_dump.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2025 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 "AudioServerHpaeDump" +#endif + +#include "audio_server_hpae_dump.h" +#include "audio_utils.h" +#include "audio_errors.h" +#include "i_hpae_manager.h" + +using namespace std; +using namespace OHOS::AudioStandard::HPAE; +namespace OHOS { +namespace AudioStandard { +static const int32_t OPERATION_TIMEOUT_IN_MS = 1000; // 1000ms +static const std::string BT_SINK_NAME = "Bt_Speaker"; +static const std::string MCH_SINK_NAME = "MCH_Speaker"; +static const std::string OFFLOAD_SINK_NAME = "Offload_Speaker"; +static const std::string DP_SINK_NAME = "DP_speaker"; +static const std::string DEFAULT_SINK_NAME = "Speaker"; +static const std::string PRIMARY_SOURCE_NAME = "Built_in_mic"; +static const std::string BT_SOURCE_NAME = "Bt_Mic"; +static const std::string USB_SOURCE_NAME = "Usb_arm_mic"; +static const std::string PRIMARY_WAKEUP_SOURCE_NAME = "Built_in_wakeup"; + +AudioServerHpaeDump::AudioServerHpaeDump() +{ + AUDIO_DEBUG_LOG("AudioServerHpaeDump construct"); + InitDumpFuncMap(); +} + +AudioServerHpaeDump::~AudioServerHpaeDump() +{} + +void AudioServerHpaeDump::InitDumpFuncMap() +{ + dumpFuncMap[u"-h"] = &AudioServerHpaeDump::HelpInfoDump; + dumpFuncMap[u"-p"] = &AudioServerHpaeDump::PlaybackSinkDump; +} + +void AudioServerHpaeDump::AudioDataDump(std::string &dumpString, std::queue &argQue) +{ + ArgDataDump(dumpString, argQue); +} + +void AudioServerHpaeDump::ServerDataDump(string &dumpString) +{ + PlaybackSinkDump(dumpString); + RecordSourceDump(dumpString); +} + +void AudioServerHpaeDump::GetDeviceSinkInfo(std::string &dumpString, std::string deviceName) +{ + lock_guard lock(lock_); + AUDIO_INFO_LOG("GetDeviceSinkInfo %{public}s start", deviceName.c_str()); + isFinishGetSinkInfo_ = false; + IHpaeManager::GetHpaeManager()->DumpSinkInfo(deviceName); + std::unique_lock waitLock(callbackMutex_); + dumpHpaeSinkInfo_.clear(); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetSinkInfo_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("GetDeviceSinkInfo timeout"); + return; + } + AUDIO_INFO_LOG("GetDeviceSinkInfo %{public}s end", deviceName.c_str()); + dumpString += dumpHpaeSinkInfo_; +} + +void AudioServerHpaeDump::PlaybackSinkDump(std::string &dumpString) +{ + dumpString += "Hpae AudioServer Playback sink Dump:\n\n"; + dumpString += DEFAULT_SINK_NAME + ":\n"; + GetDeviceSinkInfo(dumpString, DEFAULT_SINK_NAME); + dumpString += OFFLOAD_SINK_NAME + ":\n"; + GetDeviceSinkInfo(dumpString, OFFLOAD_SINK_NAME); + dumpString += MCH_SINK_NAME + ":\n"; + GetDeviceSinkInfo(dumpString, MCH_SINK_NAME); + dumpString += BT_SINK_NAME + ":\n"; + GetDeviceSinkInfo(dumpString, BT_SINK_NAME); + dumpString += DP_SINK_NAME + ":\n"; + GetDeviceSinkInfo(dumpString, DP_SINK_NAME); +} + +void AudioServerHpaeDump::OnDumpSinkInfoCb(std::string &dumpStr, int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + dumpHpaeSinkInfo_ = dumpStr; + isFinishGetSinkInfo_ = true; + AUDIO_INFO_LOG( + "AudioServerHpaeDump OnDumpSinkInfoCb %{public}s, result %{public}d", dumpHpaeSinkInfo_.c_str(), result); + callbackCV_.notify_all(); +} + +void AudioServerHpaeDump::GetDeviceSourceInfo(std::string &dumpString, std::string deviceName) +{ + lock_guard lock(lock_); + AUDIO_INFO_LOG("GetDeviceSourceInfo %{public}s start", deviceName.c_str()); + isFinishGetSourceInfo_ = false; + IHpaeManager::GetHpaeManager()->DumpSourceInfo(deviceName); + std::unique_lock waitLock(callbackMutex_); + dumpHpaeSourceInfo_.clear(); + bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return isFinishGetSourceInfo_; // will be true when got notified. + }); + if (!stopWaiting) { + AUDIO_ERR_LOG("GetDeviceSourceInfo timeout"); + return; + } + AUDIO_INFO_LOG("GetDeviceSourceInfo %{public}s end", deviceName.c_str()); + dumpString += dumpHpaeSourceInfo_; +} + +void AudioServerHpaeDump::RecordSourceDump(std::string &dumpString) +{ + dumpString += "\nHpae AudioServer Record source Dump:\n\n"; + dumpString += PRIMARY_SOURCE_NAME + ":\n"; + GetDeviceSourceInfo(dumpString, PRIMARY_SOURCE_NAME); + dumpString += BT_SOURCE_NAME + ":\n"; + GetDeviceSourceInfo(dumpString, BT_SOURCE_NAME); + dumpString += USB_SOURCE_NAME + ":\n"; + GetDeviceSourceInfo(dumpString, USB_SOURCE_NAME); + dumpString += PRIMARY_WAKEUP_SOURCE_NAME + ":\n"; + GetDeviceSourceInfo(dumpString, PRIMARY_WAKEUP_SOURCE_NAME); +} + +void AudioServerHpaeDump::OnDumpSourceInfoCb(std::string &dumpStr, int32_t result) +{ + std::unique_lock waitLock(callbackMutex_); + dumpHpaeSourceInfo_ = dumpStr; + isFinishGetSourceInfo_ = true; + AUDIO_INFO_LOG( + "AudioServerHpaeDump OnDumpSourceInfoCb %{public}s, result %{public}d", dumpHpaeSourceInfo_.c_str(), result); + callbackCV_.notify_all(); +} + +void AudioServerHpaeDump::ArgDataDump(std::string &dumpString, std::queue &argQue) +{ + dumpString += "Hpae AudioServer Data Dump:\n\n"; + if (argQue.empty()) { + ServerDataDump(dumpString); + return; + } + while (!argQue.empty()) { + std::u16string para = argQue.front(); + if (para == u"-h") { + dumpString.clear(); + (this->*dumpFuncMap[para])(dumpString); + return; + } else if (para == u"-p") { + dumpString.clear(); + (this->*dumpFuncMap[para])(dumpString); + return; + } else if (dumpFuncMap.count(para) == 0) { + dumpString.clear(); + AppendFormat(dumpString, "Please input correct param:\n"); + HelpInfoDump(dumpString); + return; + } else { + (this->*dumpFuncMap[para])(dumpString); + } + argQue.pop(); + } +} + +void AudioServerHpaeDump::HelpInfoDump(string &dumpString) +{ + AppendFormat(dumpString, "usage:\n"); + AppendFormat(dumpString, " -h\t\t\t|help text for hidumper audio\n"); + AppendFormat(dumpString, " -p\t\t\t|dump hpae playback streams\n"); + AppendFormat(dumpString, " -r\t\t\t|dump hpae record streams\n"); +} + +int32_t AudioServerHpaeDump::Initialize() +{ + AUDIO_INFO_LOG("AudioServerHpaeDump Initialize"); + IHpaeManager::GetHpaeManager()->RegisterHpaeDumpCallback(this); + return SUCCESS; +} + +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp new file mode 100644 index 0000000000..cf5504dd9b --- /dev/null +++ b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LOG_TAG +#define LOG_TAG "HpaeCapturerStreamImpl" +#endif + +#include "safe_map.h" +#include "hpae_capturer_stream_impl.h" +#include "audio_errors.h" +#include "audio_capturer_log.h" +#include "audio_utils.h" +#include "policy_handler.h" +#include +#include +#include "i_hpae_manager.h" +using namespace OHOS::AudioStandard::HPAE; +namespace OHOS { +namespace AudioStandard { +static SafeMap> paCapturerMap_; +const int32_t MIN_BUFFER_SIZE = 2; +const int32_t FRAME_LEN_10MS = 2; + +HpaeCapturerStreamImpl::HpaeCapturerStreamImpl(AudioProcessConfig processConfig) +{ + processConfig_ = processConfig; + spanSizeInFrame_ = FRAME_LEN_10MS * (processConfig.streamInfo.samplingRate / 100); + byteSizePerFrame_ = (processConfig.streamInfo.channels * GET_SIZE_FROM_FORMAT(processConfig.streamInfo.format)); + minBufferSize_ = MIN_BUFFER_SIZE * byteSizePerFrame_ * spanSizeInFrame_; +} + +HpaeCapturerStreamImpl::~HpaeCapturerStreamImpl() +{ + AUDIO_DEBUG_LOG("~HpaeCapturerStreamImpl"); + if (capturerServerDumpFile_) { + fclose(capturerServerDumpFile_); + capturerServerDumpFile_ = nullptr; + } + paCapturerMap_.Erase(this); +} + +int32_t HpaeCapturerStreamImpl::InitParams(const std::string &deviceName) +{ + paCapturerMap_.Insert(this, weak_from_this()); + + HpaeStreamInfo streamInfo; + streamInfo.channels = processConfig_.streamInfo.channels; + streamInfo.samplingRate = processConfig_.streamInfo.samplingRate; + streamInfo.format = processConfig_.streamInfo.format; + streamInfo.frameLen = spanSizeInFrame_; + streamInfo.sessionId = processConfig_.originalSessionId; + streamInfo.streamType = processConfig_.streamType; + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; + streamInfo.sourceType = processConfig_.capturerInfo.sourceType; + streamInfo.uid = processConfig_.appInfo.appUid; + streamInfo.pid = processConfig_.appInfo.appPid; + streamInfo.deviceName = deviceName; + int32_t ret = IHpaeManager::GetHpaeManager()->CreateStream(streamInfo); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR_INVALID_PARAM, "CreateStream is error"); + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::Start() +{ + AUDIO_INFO_LOG("Start"); + int32_t ret = IHpaeManager::GetHpaeManager()->Start(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_INVALID_PARAM, "Start failed"); + state_ = RUNNING; + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::Pause(bool isStandby) +{ + AUDIO_INFO_LOG("Pause"); + int32_t ret = IHpaeManager::GetHpaeManager()->Pause(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "Pause error"); + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::GetStreamFramesRead(uint64_t &framesRead) +{ + // to do callback data report + framesRead = 0; + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::GetCurrentTimeStamp(uint64_t ×tamp) +{ + timestamp = 0; + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::GetLatency(uint64_t &latency) +{ + latency = 0; + AUDIO_DEBUG_LOG("total latency: %{public}" PRIu64 "ms", latency); + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::Flush() +{ + AUDIO_INFO_LOG("Flush"); + int32_t ret = IHpaeManager::GetHpaeManager()->Flush(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "Flush error"); + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::Stop() +{ + AUDIO_INFO_LOG("Stop"); + int32_t ret = IHpaeManager::GetHpaeManager()->Stop(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "Stop failed"); + state_ = STOPPING; + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::Release() +{ + if (state_ == RUNNING) { + AUDIO_ERR_LOG("%{public}u Release state_ is RUNNING", processConfig_.originalSessionId); + IHpaeManager::GetHpaeManager()->Stop(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); + } + AUDIO_INFO_LOG("Release Enter"); + int32_t ret = IHpaeManager::GetHpaeManager()->Release(HPAE_STREAM_CLASS_TYPE_RECORD, + processConfig_.originalSessionId); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "Release is error"); + state_ = RELEASED; + // to do check closeaudioport + if (processConfig_.capturerInfo.sourceType == SOURCE_TYPE_WAKEUP) { + PolicyHandler::GetInstance().NotifyWakeUpCapturerRemoved(); + } + return SUCCESS; +} + +// to do callback data report +void HpaeCapturerStreamImpl::RegisterStatusCallback(const std::weak_ptr &callback) +{ + IHpaeManager::GetHpaeManager()->RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_RECORD, + processConfig_.originalSessionId, callback); + statusCallback_ = callback; +} + +void HpaeCapturerStreamImpl::RegisterReadCallback(const std::weak_ptr &callback) +{ + AUDIO_INFO_LOG("RegisterReadCallback start"); + IHpaeManager::GetHpaeManager()->RegisterReadCallback(processConfig_.originalSessionId, callback); + readCallback_ = callback; +} + +BufferDesc HpaeCapturerStreamImpl::DequeueBuffer(size_t length) +{ + BufferDesc bufferDesc; + return bufferDesc; +} + +int32_t HpaeCapturerStreamImpl::EnqueueBuffer(const BufferDesc &bufferDesc) +{ + AUDIO_DEBUG_LOG("After capturere EnqueueBuffer"); + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::DropBuffer() +{ + AUDIO_DEBUG_LOG("After capturere DropBuffer"); + return SUCCESS; +} + +int32_t HpaeCapturerStreamImpl::GetMinimumBufferSize(size_t &minBufferSize) const +{ + minBufferSize = minBufferSize_; + return SUCCESS; +} + +void HpaeCapturerStreamImpl::GetByteSizePerFrame(size_t &byteSizePerFrame) const +{ + byteSizePerFrame = byteSizePerFrame_; +} + +void HpaeCapturerStreamImpl::GetSpanSizePerFrame(size_t &spanSizeInFrame) const +{ + spanSizeInFrame = spanSizeInFrame_; +} + +void HpaeCapturerStreamImpl::SetStreamIndex(uint32_t index) +{ + AUDIO_INFO_LOG("Using index/sessionId %{public}u", index); + streamIndex_ = index; +} + +uint32_t HpaeCapturerStreamImpl::GetStreamIndex() +{ + return streamIndex_; +} + +void HpaeCapturerStreamImpl::AbortCallback(int32_t abortTimes) +{ + abortFlag_ += abortTimes; +} + +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp new file mode 100644 index 0000000000..7fbfb6830c --- /dev/null +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2025 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 "HpaeRendererStreamImpl" +#endif + +#ifdef FEATURE_POWER_MANAGER +#include "power_mgr_client.h" +#endif + +#include "hpae_renderer_stream_impl.h" +#include "i_audio_renderer_sink.h" +#include +#include "safe_map.h" +#include "audio_errors.h" +#include "audio_service_log.h" +#include "audio_utils.h" +#include "i_hpae_manager.h" +#include "audio_stream_info.h" +#include "audio_effect_map.h" + +using namespace OHOS::AudioStandard::HPAE; +namespace OHOS { +namespace AudioStandard { + +const int32_t MIN_BUFFER_SIZE = 2; +const int32_t FRAME_LEN_10MS = 2; +static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels); +HpaeRendererStreamImpl::HpaeRendererStreamImpl(AudioProcessConfig processConfig) +{ + processConfig_ = processConfig; + spanSizeInFrame_ = FRAME_LEN_10MS * (processConfig.streamInfo.samplingRate / 100); + byteSizePerFrame_ = (processConfig.streamInfo.channels * GET_SIZE_FROM_FORMAT(processConfig.streamInfo.format)); + minBufferSize_ = MIN_BUFFER_SIZE * byteSizePerFrame_ * spanSizeInFrame_; +} +HpaeRendererStreamImpl::~HpaeRendererStreamImpl() +{ + AUDIO_DEBUG_LOG("~HpaeRendererStreamImpl"); +} + +int32_t HpaeRendererStreamImpl::InitParams(const std::string &deviceName) +{ + HpaeStreamInfo streamInfo; + 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.frameLen = spanSizeInFrame_; + streamInfo.sessionId = processConfig_.originalSessionId; + streamInfo.streamType = processConfig_.streamType; + streamInfo.fadeType = FadeType::DEFAULT_FADE; // to be passed from processConfig + streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; + streamInfo.uid = processConfig_.appInfo.appUid; + streamInfo.pid = processConfig_.appInfo.appPid; + streamInfo.effectInfo.effectMode = (effectMode_ != EFFECT_DEFAULT && effectMode_ != EFFECT_NONE) ? EFFECT_DEFAULT : + static_cast(effectMode_); + const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); + streamInfo.effectInfo.effectScene = static_cast(GetKeyFromValue( + audioSupportedSceneTypes, processConfig_.rendererInfo.sceneType)); + streamInfo.effectInfo.volumeType = STREAM_MUSIC; + streamInfo.effectInfo.streamUsage = processConfig_.rendererInfo.streamUsage; + streamInfo.sourceType = processConfig_.isInnerCapturer == true ? SOURCE_TYPE_PLAYBACK_CAPTURE : SOURCE_TYPE_INVALID; + streamInfo.deviceName = deviceName; + AUDIO_INFO_LOG("InitParams channels %{public}u end", streamInfo.channels); + AUDIO_INFO_LOG("InitParams channelLayout %{public}lu end", streamInfo.channelLayout); + AUDIO_INFO_LOG("InitParams samplingRate %{public}u end", streamInfo.samplingRate); + AUDIO_INFO_LOG("InitParams format %{public}u end", streamInfo.format); + AUDIO_INFO_LOG("InitParams frameLen %{public}zu end", streamInfo.frameLen); + AUDIO_INFO_LOG("InitParams streamType %{public}u end", streamInfo.streamType); + AUDIO_INFO_LOG("InitParams sessionId %{public}u end", streamInfo.sessionId); + AUDIO_INFO_LOG("InitParams streamClassType %{public}u end", streamInfo.streamClassType); + AUDIO_INFO_LOG("InitParams sourceType %{public}d end", streamInfo.sourceType); + int32_t ret = IHpaeManager::GetHpaeManager()->CreateStream(streamInfo); + if (ret != 0) { + AUDIO_ERR_LOG("CreateStream is error"); + return ERR_INVALID_PARAM; + } + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::Start() +{ + AUDIO_INFO_LOG("Start"); + int32_t ret = IHpaeManager::GetHpaeManager()->Start(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); + if (ret != 0) { + AUDIO_ERR_LOG("Start is error"); + return ERR_INVALID_PARAM; + } + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::Pause(bool isStandby) +{ + AUDIO_INFO_LOG("Pause"); + int32_t ret = IHpaeManager::GetHpaeManager()->Pause(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); + if (ret != 0) { + AUDIO_ERR_LOG("Pause is error"); + return ERR_INVALID_PARAM; + } + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::Flush() +{ + AUDIO_PRERELEASE_LOGI("Flush Enter"); + int32_t ret = IHpaeManager::GetHpaeManager()->Flush(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); + if (ret != 0) { + AUDIO_ERR_LOG("Flush is error"); + return ERR_INVALID_PARAM; + } + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::Drain(bool stopFlag) +{ + AUDIO_INFO_LOG("Drain Enter %{public}d", stopFlag); + int32_t ret = IHpaeManager::GetHpaeManager()->Drain(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); + if (ret != 0) { + AUDIO_ERR_LOG("Drain is error"); + return ERR_INVALID_PARAM; + } + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::Stop() +{ + AUDIO_INFO_LOG("Stop Enter"); + int32_t ret = IHpaeManager::GetHpaeManager()->Stop(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); + if (ret != 0) { + AUDIO_ERR_LOG("Stop is error"); + return ERR_INVALID_PARAM; + } + state_ = STOPPING; + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::Release() +{ + if (state_ == RUNNING) { + AUDIO_ERR_LOG("%{public}u Release state_ is RUNNING", processConfig_.originalSessionId); + IHpaeManager::GetHpaeManager()->Stop(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); + } + AUDIO_INFO_LOG("Release Enter"); + int32_t ret = IHpaeManager::GetHpaeManager()->DestroyStream(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); + if (ret != 0) { + AUDIO_ERR_LOG("Release is error"); + return ERR_INVALID_PARAM; + } + state_ = RELEASED; + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::GetStreamFramesWritten(uint64_t &framesWritten) +{ + framesWritten = framesWritten_; + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::GetCurrentTimeStamp(uint64_t ×tamp) +{ + std::shared_lock lock(latencyMutex_); + timestamp = timestamp_; + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp, uint64_t &latency) +{ + std::shared_lock lock(latencyMutex_); + framePosition = framePosition_; + timestamp = timestamp_; + latency = latency_; + return SUCCESS; +} + + +int32_t HpaeRendererStreamImpl::GetLatency(uint64_t &latency) +{ + std::shared_lock lock(latencyMutex_); + if (deviceClass_ != "offload") { + uint32_t SinkLatency = 0; + IAudioRendererSink* audioRendererSink = IAudioRendererSink::GetInstance(deviceClass_.c_str(), deviceNetId_.c_str()); + if (audioRendererSink) { + audioRendererSink->GetLatency(&SinkLatency); + } + latency = SinkLatency + latency_; + return SUCCESS; + } + timespec tm {}; + clock_gettime(CLOCK_MONOTONIC, &tm); + auto timestamp = static_cast(tm.tv_sec) * 1000000000ll + static_cast(tm.tv_nsec); + auto interval = (timestamp - timestamp_) / 1000; + latency = latency_ > interval ? latency_ - interval : 0; + AUDIO_DEBUG_LOG("HpaeRendererStreamImpl::GetLatency latency_ %{public}lu, interval %{public}llu latency %{public}lu", latency_, interval, latency); + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::SetRate(int32_t rate) +{ + AUDIO_INFO_LOG("SetRate in"); + renderRate_ = rate; + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::SetAudioEffectMode(int32_t effectMode) +{ + AUDIO_INFO_LOG("SetAudioEffectMode: %d", effectMode); + + effectMode_ = effectMode; + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::GetAudioEffectMode(int32_t &effectMode) +{ + effectMode = effectMode_; + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::SetPrivacyType(int32_t privacyType) +{ + AUDIO_DEBUG_LOG("SetInnerCapturerState: %d", privacyType); + privacyType_ = privacyType; + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::GetPrivacyType(int32_t &privacyType) +{ + privacyType_ = privacyType; + return SUCCESS; +} + + +void HpaeRendererStreamImpl::RegisterStatusCallback(const std::weak_ptr &callback) +{ + AUDIO_DEBUG_LOG("RegisterStatusCallback in"); + int32_t ret = IHpaeManager::GetHpaeManager()->RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId, callback); + if (ret != 0) { + AUDIO_ERR_LOG("RegisterStatusCallback is error"); + return; + } + statusCallback_ = callback; +} + +void HpaeRendererStreamImpl::RegisterWriteCallback(const std::weak_ptr &callback) +{ + AUDIO_DEBUG_LOG("RegisterWriteCallback in"); + int32_t ret = IHpaeManager::GetHpaeManager()->RegisterWriteCallback(processConfig_.originalSessionId, shared_from_this()); + if (ret != 0) { + AUDIO_ERR_LOG("RegisterStatusCallback is error"); + return; + } + writeCallback_ = callback; +} + +int32_t HpaeRendererStreamImpl::OnStreamData(AudioCallBackStreamInfo& callBackStreamInfo) +{ + { + std::unique_lock lock(latencyMutex_); + framePosition_ = callBackStreamInfo.framePosition; + timestamp_ = callBackStreamInfo.timestamp; + latency_ = callBackStreamInfo.latency; + framesWritten_ = callBackStreamInfo.framesWritten; + deviceClass_ = callBackStreamInfo.deviceClass; + deviceNetId_ = callBackStreamInfo.deviceNetId; + } + if (callBackStreamInfo.needData && writeCallback_.lock()) { + return writeCallback_.lock()->OnWriteData(callBackStreamInfo.inputData, callBackStreamInfo.requestDataLen); + } + return SUCCESS; +} + +BufferDesc HpaeRendererStreamImpl::DequeueBuffer(size_t length) +{ + BufferDesc bufferDesc; + return bufferDesc; +} + +int32_t HpaeRendererStreamImpl::EnqueueBuffer(const BufferDesc &bufferDesc) +{ + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::GetMinimumBufferSize(size_t &minBufferSize) const +{ + minBufferSize = minBufferSize_; + return SUCCESS; +} + +void HpaeRendererStreamImpl::GetByteSizePerFrame(size_t &byteSizePerFrame) const +{ + byteSizePerFrame = byteSizePerFrame_; +} + +void HpaeRendererStreamImpl::GetSpanSizePerFrame(size_t &spanSizeInFrame) const +{ + spanSizeInFrame = spanSizeInFrame_; +} + +void HpaeRendererStreamImpl::SetStreamIndex(uint32_t index) +{ + AUDIO_INFO_LOG("Using index/sessionId %d", index); + streamIndex_ = index; +} + +uint32_t HpaeRendererStreamImpl::GetStreamIndex() +{ + return streamIndex_; +} + +void HpaeRendererStreamImpl::AbortCallback(int32_t abortTimes) +{ + abortFlag_ += abortTimes; +} + +// offload + +size_t HpaeRendererStreamImpl::GetWritableSize() +{ + return 0; +} + +int32_t HpaeRendererStreamImpl::OffloadSetVolume(float volume) +{ + IAudioRendererSink *audioRendererSinkInstance = IAudioRendererSink::GetInstance("offload", ""); + if (audioRendererSinkInstance == nullptr) { + AUDIO_ERR_LOG("Renderer is null."); + return ERROR; + } + return audioRendererSinkInstance->SetVolume(volume, volume); +} + +int32_t HpaeRendererStreamImpl::UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled) +{ + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::GetOffloadApproximatelyCacheTime(uint64_t ×tamp, uint64_t &paWriteIndex, + uint64_t &cacheTimeDsp, uint64_t &cacheTimePa) +{ + return SUCCESS; +} + +void HpaeRendererStreamImpl::SyncOffloadMode() +{ + std::shared_ptr statusCallback = statusCallback_.lock(); + if (statusCallback != nullptr) { + if (offloadEnable_) { + statusCallback->OnStatusUpdate(OPERATION_SET_OFFLOAD_ENABLE); + } else { + statusCallback->OnStatusUpdate(OPERATION_UNSET_OFFLOAD_ENABLE); + } + } +} + +int32_t HpaeRendererStreamImpl::SetOffloadMode(int32_t state, bool isAppBack) +{ +#ifdef FEATURE_POWER_MANAGER + static const std::set screenOffTable = { + PowerMgr::PowerState::INACTIVE, PowerMgr::PowerState::STAND_BY, + PowerMgr::PowerState::DOZE, PowerMgr::PowerState::SLEEP, + PowerMgr::PowerState::HIBERNATE, + }; + AudioOffloadType statePolicy = OFFLOAD_DEFAULT; + statePolicy = screenOffTable.count(static_cast(state)) ? + OFFLOAD_INACTIVE_BACKGROUND : OFFLOAD_ACTIVE_FOREGROUND; + + AUDIO_INFO_LOG("calling set stream offloadMode PowerState: %{public}d, isAppBack: %{public}d", state, isAppBack); + + if (offloadStatePolicy_.load() == statePolicy) { + return SUCCESS; + } + + offloadEnable_ = true; + SyncOffloadMode(); + auto ret = IHpaeManager::GetHpaeManager()->SetOffloadPolicy(processConfig_.originalSessionId, statePolicy); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, + "SetOffloadPolicy failed, errcode is %{public}d", ret); + offloadStatePolicy_.store(statePolicy); +#else + AUDIO_INFO_LOG("SetStreamOffloadMode not available, FEATURE_POWER_MANAGER no define"); +#endif + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::UnsetOffloadMode() +{ + offloadEnable_ = false; + SyncOffloadMode(); + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::UpdateMaxLength(uint32_t maxLength) +{ + return SUCCESS; +} + +AudioProcessConfig HpaeRendererStreamImpl::GetAudioProcessConfig() const noexcept +{ + return processConfig_; +} + +int32_t HpaeRendererStreamImpl::Peek(std::vector *audioBuffer, int32_t &index) +{ + return SUCCESS; +} + +int32_t HpaeRendererStreamImpl::ReturnIndex(int32_t index) +{ + return SUCCESS; +} + +void HpaeRendererStreamImpl::BlockStream() noexcept +{ + return; +} +// offload end + +int32_t HpaeRendererStreamImpl::SetClientVolume(float clientVolume) +{ + + AUDIO_PRERELEASE_LOGI("set client volume success"); + int32_t ret = IHpaeManager::GetHpaeManager()->SetClientVolume(processConfig_.originalSessionId, clientVolume); + if (ret != 0) { + AUDIO_ERR_LOG("SetClientVolume is error"); + return ERR_INVALID_PARAM; + } + clientVolume_ = 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; + } +} + +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_service/server/src/pro_adapter_manager.cpp b/services/audio_service/server/src/pro_adapter_manager.cpp new file mode 100644 index 0000000000..56338294f7 --- /dev/null +++ b/services/audio_service/server/src/pro_adapter_manager.cpp @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LOG_TAG +#define LOG_TAG "ProAdapterManager" +#endif + +#include "pro_adapter_manager.h" +#include +#include +#include "audio_common_log.h" +#include "audio_errors.h" +#include "hpae_renderer_stream_impl.h" +#include "hpae_capturer_stream_impl.h" +#include "audio_utils.h" +#include "audio_info.h" +#include "policy_handler.h" +namespace OHOS { +namespace AudioStandard { + +const char* PRO_INNER_CAPTURER_SOURCE = "Speaker.monitor"; +const char* PRO_NEW_INNER_CAPTURER_SOURCE = "InnerCapturerSink.monitor"; +const char* PRO_MONITOR_SOURCE_SUFFIX = ".monitor"; + +ProAdapterManager::ProAdapterManager(ManagerType type) +{ + AUDIO_INFO_LOG("Constructor with type:%{public}d", type); + managerType_ = type; +} + +int32_t ProAdapterManager::CreateRender(AudioProcessConfig processConfig, std::shared_ptr &stream) +{ + AUDIO_DEBUG_LOG("Create renderer start"); + uint32_t sessionId = 0; + sessionId = processConfig.originalSessionId; + if (managerType_ == DUP_PLAYBACK || + processConfig.originalSessionId < MIN_SESSIONID || processConfig.originalSessionId > MAX_SESSIONID) { + sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid); + AUDIO_ERR_LOG("Create [%{public}d] type renderer:[%{public}u] error", managerType_, processConfig.originalSessionId); + + } + AUDIO_INFO_LOG("Create [%{public}d] type renderer:[%{public}u]", managerType_, sessionId); + std::string deviceName; + int32_t ret = GetDeviceNameForConnect(processConfig, processConfig.originalSessionId, deviceName); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR_INVALID_PARAM, "getdevicename err: %{public}d", ret); + + processConfig.originalSessionId = sessionId; + // ProAdapterManager is solely responsible for creating paStream objects + std::shared_ptr rendererStream = CreateRendererStream(processConfig, deviceName); + CHECK_AND_RETURN_RET_LOG(rendererStream != nullptr, ERR_DEVICE_INIT, "Failed to init pa stream"); + rendererStream->SetStreamIndex(sessionId); + std::lock_guard lock(streamMapMutex_); + rendererStreamMap_[sessionId] = rendererStream; + stream = rendererStream; + + std::lock_guard mutex(sinkInputsMutex_); + SinkInput sinkInput; + sinkInput.streamId = sessionId; + sinkInput.streamType = processConfig.streamType; + sinkInput.uid = processConfig.appInfo.appUid; + sinkInput.pid = processConfig.appInfo.appPid; + sinkInput.paStreamId = sessionId; + sinkInputs_.push_back(sinkInput); + return SUCCESS; +} + +int32_t ProAdapterManager::ReleaseRender(uint32_t streamIndex) +{ + AUDIO_DEBUG_LOG("Release [%{public}d] type render:[%{public}u]", managerType_, streamIndex); + std::unique_lock lock(streamMapMutex_); + auto it = rendererStreamMap_.find(streamIndex); + if (it == rendererStreamMap_.end()) { + AUDIO_WARNING_LOG("No matching stream"); + return SUCCESS; + } + std::shared_ptr currentRender = rendererStreamMap_[streamIndex]; + rendererStreamMap_[streamIndex] = nullptr; + rendererStreamMap_.erase(streamIndex); + lock.unlock(); + + if (currentRender->Release() < 0) { + AUDIO_WARNING_LOG("Release stream %{public}d failed", streamIndex); + return ERR_OPERATION_FAILED; + } + + AUDIO_INFO_LOG("rendererStreamMap_.size() : %{public}zu", rendererStreamMap_.size()); + if (rendererStreamMap_.size() == 0) { + AUDIO_INFO_LOG("Release the last stream"); + } + + std::lock_guard mutex(sinkInputsMutex_); + sinkInputs_.erase( + std::remove_if(sinkInputs_.begin(), + sinkInputs_.end(), + [&](const SinkInput &sinkInput) { return static_cast(sinkInput.streamId) == streamIndex; }), + sinkInputs_.end()); + return SUCCESS; +} + +int32_t ProAdapterManager::StartRender(uint32_t streamIndex) +{ + AUDIO_DEBUG_LOG("Enter StartRender"); + std::lock_guard lock(streamMapMutex_); + auto it = rendererStreamMap_.find(streamIndex); + if (it == rendererStreamMap_.end()) { + AUDIO_WARNING_LOG("No matching stream"); + return SUCCESS; + } + return rendererStreamMap_[streamIndex]->Start(); +} + +int32_t ProAdapterManager::StopRender(uint32_t streamIndex) +{ + AUDIO_DEBUG_LOG("Enter StopRender"); + std::lock_guard lock(streamMapMutex_); + auto it = rendererStreamMap_.find(streamIndex); + if (it == rendererStreamMap_.end()) { + AUDIO_WARNING_LOG("No matching stream"); + return SUCCESS; + } + return rendererStreamMap_[streamIndex]->Stop(); +} + +int32_t ProAdapterManager::PauseRender(uint32_t streamIndex) +{ + AUDIO_DEBUG_LOG("Enter PauseRender"); + std::lock_guard lock(streamMapMutex_); + auto it = rendererStreamMap_.find(streamIndex); + if (it == rendererStreamMap_.end()) { + AUDIO_WARNING_LOG("No matching stream"); + return SUCCESS; + } + rendererStreamMap_[streamIndex]->Pause(); + return SUCCESS; +} + +int32_t ProAdapterManager::TriggerStartIfNecessary() +{ + return SUCCESS; +} + +int32_t ProAdapterManager::GetStreamCount() const noexcept +{ + if (managerType_ == RECORDER) { + return capturerStreamMap_.size(); + } else { + return rendererStreamMap_.size(); + } +} + +int32_t ProAdapterManager::GetDeviceNameForConnect(AudioProcessConfig processConfig, uint32_t sessionId, + std::string &deviceName) +{ + deviceName = ""; + if (processConfig.audioMode == AUDIO_MODE_RECORD) { + if (processConfig.isWakeupCapturer) { + int32_t ret = PolicyHandler::GetInstance().SetWakeUpAudioCapturerFromAudioServer(processConfig); + if (ret < 0) { + AUDIO_ERR_LOG("ErrorCode: %{public}d", ret); + return ERROR; + } + deviceName = PRIMARY_WAKEUP; + } + if (processConfig.isInnerCapturer) { + if (processConfig.innerCapMode == MODERN_INNER_CAP) { + deviceName = std::string(INNER_CAPTURER_SINK) + std::to_string(processConfig.innerCapId); + } else { + deviceName = PRO_INNER_CAPTURER_SOURCE; + } + } else if (processConfig.capturerInfo.sourceType == SOURCE_TYPE_REMOTE_CAST) { + deviceName = std::string(REMOTE_CAST_INNER_CAPTURER_SINK_NAME) + std::string(PRO_MONITOR_SOURCE_SUFFIX); + } + return PolicyHandler::GetInstance().NotifyCapturerAdded(processConfig.capturerInfo, + processConfig.streamInfo, sessionId); + } else if (managerType_ == DUP_PLAYBACK) { + deviceName = std::string(INNER_CAPTURER_SINK) + std::to_string(processConfig.innerCapId); + } + return SUCCESS; +} + +int32_t ProAdapterManager::CreateCapturer(AudioProcessConfig processConfig, std::shared_ptr &stream) +{ + AUDIO_DEBUG_LOG("Create capturer start"); + CHECK_AND_RETURN_RET_LOG(managerType_ == RECORDER, ERROR, "Invalid managerType:%{public}d", managerType_); + uint32_t sessionId = 0; + if (processConfig.originalSessionId < MIN_SESSIONID || processConfig.originalSessionId > MAX_SESSIONID) { + sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid); + AUDIO_ERR_LOG("Create capturer originalSessionId is error %{public}d", processConfig.originalSessionId); + } else { + sessionId = processConfig.originalSessionId; + } + processConfig.originalSessionId = sessionId; + std::string deviceName; + int32_t ret = GetDeviceNameForConnect(processConfig, processConfig.originalSessionId, deviceName); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR_INVALID_PARAM, "getdevicename err: %{public}d", ret); + + // ProAdapterManager is solely responsible for creating paStream objects + std::shared_ptr capturerStream = CreateCapturerStream(processConfig, deviceName); + CHECK_AND_RETURN_RET_LOG(capturerStream != nullptr, ERR_DEVICE_INIT, "Failed to init pa stream"); + capturerStream->SetStreamIndex(sessionId); + std::lock_guard lock(streamMapMutex_); + capturerStreamMap_[sessionId] = capturerStream; + stream = capturerStream; + return SUCCESS; +} + +int32_t ProAdapterManager::AddUnprocessStream(int32_t appUid) +{ + return SUCCESS; +} + +int32_t ProAdapterManager::ReleaseCapturer(uint32_t streamIndex) +{ + AUDIO_DEBUG_LOG("Enter ReleaseCapturer"); + std::lock_guard lock(streamMapMutex_); + auto it = capturerStreamMap_.find(streamIndex); + if (it == capturerStreamMap_.end()) { + AUDIO_WARNING_LOG("No matching stream"); + return SUCCESS; + } + + if (capturerStreamMap_[streamIndex]->Release() < 0) { + AUDIO_WARNING_LOG("Release stream %{public}d failed", streamIndex); + return ERR_OPERATION_FAILED; + } + + capturerStreamMap_[streamIndex] = nullptr; + capturerStreamMap_.erase(streamIndex); + if (capturerStreamMap_.size() == 0) { + AUDIO_INFO_LOG("Release the last stream"); + } + return SUCCESS; +} + +std::shared_ptr ProAdapterManager::CreateRendererStream(AudioProcessConfig processConfig, + const std::string &deviceName) +{ + std::lock_guard lock(paElementsMutex_); + if (managerType_ == DUP_PLAYBACK) { + // todo check + processConfig.isInnerCapturer = true; + AUDIO_INFO_LOG("Create dup playback renderer stream"); + } + std::shared_ptr rendererStream = + std::make_shared(processConfig); + if (rendererStream->InitParams(deviceName) != SUCCESS) { + AUDIO_ERR_LOG("Create rendererStream Failed"); + return nullptr; + } + return rendererStream; +} + +std::shared_ptr ProAdapterManager::CreateCapturerStream(AudioProcessConfig processConfig, + const std::string &deviceName) +{ + std::lock_guard lock(paElementsMutex_); + std::shared_ptr capturerStream = + std::make_shared(processConfig); + if (capturerStream->InitParams(deviceName) != SUCCESS) { + AUDIO_ERR_LOG("Create capturerStream Failed, error"); + return nullptr; + } + return capturerStream; +} + +uint64_t ProAdapterManager::GetLatency() noexcept +{ + return 0; +} + +void ProAdapterManager::GetAllSinkInputs(std::vector &sinkInputs) +{ + std::lock_guard lock(paElementsMutex_); + sinkInputs = sinkInputs_; + return; +} +} // namespace AudioStandard +} // namespace OHOS -- Gitee From 7ac45ed3de3a1af226e88f5ff821f89636bcad13 Mon Sep 17 00:00:00 2001 From: trytocalm Date: Sat, 12 Apr 2025 16:46:19 +0800 Subject: [PATCH 03/40] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: trytocalm --- services/audio_engine/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/services/audio_engine/BUILD.gn b/services/audio_engine/BUILD.gn index 5c6bc4256a..5bb937bb2c 100644 --- a/services/audio_engine/BUILD.gn +++ b/services/audio_engine/BUILD.gn @@ -13,7 +13,6 @@ import("//build/ohos.gni") - ohos_shared_library("audio_engine_utils") { stack_protector_ret = true sanitize = { -- Gitee From 20d1281766f9061c5c618fe9b17117fcca81f959 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Sat, 12 Apr 2025 18:38:34 +0800 Subject: [PATCH 04/40] sync change in frameworks folder Signed-off-by: c00657214 --- frameworks/native/audioadapter/BUILD.gn | 19 ++++- .../include/audio_service_adapter.h | 34 +++++++- .../pulse_audio_service_adapter_impl.h | 7 ++ .../src/pulse_audio_service_adapter_impl.cpp | 13 ++-- .../audioadapter/test/unittest/BUILD.gn | 78 +++++++++---------- .../audioeffect/include/audio_effect_chain.h | 2 - .../include/audio_effect_chain_manager.h | 25 ++++-- .../include/audio_effect_hdi_param.h | 3 +- .../include/audio_enhance_chain_manager.h | 8 +- .../audioeffect/libaudio_effect.versionscript | 29 ++++++- .../audioeffect/src/audio_effect_chain.cpp | 1 + .../src/audio_effect_chain_adapter.cpp | 9 +-- .../src/audio_effect_chain_manager.cpp | 74 ++++++++++++++++-- .../src/audio_effect_hdi_param.cpp | 1 - .../src/audio_enhance_chain_manager.cpp | 10 ++- .../audio_effect_chain_manager_unit_test.h | 1 + .../audio_effect_chain_manager_unit_test.cpp | 9 +-- .../native/audioutils/include/audio_utils.h | 2 + .../native/audioutils/src/audio_utils.cpp | 12 +++ .../sink/common/i_audio_renderer_sink.h | 25 +++--- .../sink/file/audio_renderer_file_sink.cpp | 5 ++ .../offload/offload_audio_renderer_sink.cpp | 4 +- .../sink/primary/audio_renderer_sink.cpp | 19 +++-- .../bluetooth/bluetooth_capturer_source.cpp | 9 ++- .../file/audio_capturer_file_source.cpp | 3 + .../source/primary/audio_capturer_source.cpp | 15 ++-- .../sink/file_audio_render_sink.cpp | 3 + .../source/file_audio_capture_source.cpp | 3 + .../native/audiocommon/include/audio_effect.h | 8 +- .../audiocommon/include/audio_stream_info.h | 19 +++++ 30 files changed, 324 insertions(+), 126 deletions(-) diff --git a/frameworks/native/audioadapter/BUILD.gn b/frameworks/native/audioadapter/BUILD.gn index f26ec5147a..eeb477f9d2 100644 --- a/frameworks/native/audioadapter/BUILD.gn +++ b/frameworks/native/audioadapter/BUILD.gn @@ -24,7 +24,13 @@ ohos_shared_library("pulse_audio_service_adapter") { boundary_sanitize = true } install_enable = true - sources = [ "src/pulse_audio_service_adapter_impl.cpp" ] + + sources = [ + "src/audio_service_adapter.cpp", + "src/pro_audio_service_adapter_impl.cpp", + "src/pulse_audio_service_adapter_impl.cpp", + ] + cflags = [ "-fPIC" ] cflags += [ "-Wall" ] cflags += [ "-Os" ] @@ -35,9 +41,18 @@ ohos_shared_library("pulse_audio_service_adapter") { "../audioutils/include", "../../../interfaces/inner_api/native/audiocommon/include", "../../../services/audio_service/server/include", + "../hdiadapter/common/include", + "../hdiadapter/sink/common", + "../hdiadapter/source/common", + "../../../services/audio_policy/server/include/service/common", + "../../../services/audio_engine/manager/include", + "../../../services/audio_service/common/include", ] - deps = [ "../audioutils:audio_utils" ] + deps = [ "../audioutils:audio_utils", + "../../../services/audio_engine:audio_engine_manager", + "../../../services/audio_service:audio_common", + ] external_deps = [ "c_utils:utils", diff --git a/frameworks/native/audioadapter/include/audio_service_adapter.h b/frameworks/native/audioadapter/include/audio_service_adapter.h index 4271182060..e4ad87f33b 100644 --- a/frameworks/native/audioadapter/include/audio_service_adapter.h +++ b/frameworks/native/audioadapter/include/audio_service_adapter.h @@ -22,6 +22,7 @@ #include #include "audio_effect.h" +#include "audio_module_info.h" namespace OHOS { namespace AudioStandard { @@ -42,7 +43,7 @@ public: * @param cb callback reference for AudioServiceAdapterCallback class * @return Returns instance of class that extends AudioServiceAdapter */ - static std::unique_ptr CreateAudioAdapter(std::unique_ptr cb); + static std::shared_ptrudioServiceAdapter> CreateAudioAdapter(std::unique_ptr cb); /** * @brief Connect to underlining audio server @@ -62,6 +63,7 @@ public: * defined in {@link audio_errors.h} otherwise. */ virtual uint32_t OpenAudioPort(std::string audioPortName, std::string moduleArgs) = 0; + virtual int32_t OpenAudioPort(std::string audioPortName, const AudioModuleInfo& audioModuleInfo) = 0; /** * @brief closes/unloads the audio modules loaded. @@ -177,6 +179,36 @@ public: */ virtual int32_t MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) = 0; + /** + * @brief Get current effect property. + * + * @return int32_t the result. + */ + virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) = 0; + + /** + * @brief Get current effect property. + * + * @return int32_t the result. + */ + virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) = 0; + + /** + * @brief Get current enhance property. + * + * @return int32_t the result. + */ + virtual int32_t GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) = 0; + + /** + * @brief Get current enhance property. + * + * @return int32_t the result. + */ + virtual int32_t GetAudioEnhanceProperty(AudioEffectPropertyArray &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) = 0; + virtual ~AudioServiceAdapter(); }; } // namespace AudioStandard diff --git a/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h index 604bbbf534..0d5f0778b0 100644 --- a/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h +++ b/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h @@ -32,6 +32,7 @@ public: bool Connect() override; uint32_t OpenAudioPort(std::string audioPortName, std::string moduleArgs) override; + int32_t OpenAudioPort(std::string audioPortName, const AudioModuleInfo& audioModuleInfo) override; int32_t CloseAudioPort(int32_t audioHandleIndex, bool isSync = false) override; int32_t SetDefaultSink(std::string name) override; int32_t SetDefaultSource(std::string name) override; @@ -48,6 +49,12 @@ public: int32_t MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) override; int32_t MoveSourceOutputByIndexOrName(uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) override; + int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) override { return 0; } + int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) override { return 0; } + int32_t GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) override { return 0; } + int32_t GetAudioEnhanceProperty(AudioEffectPropertyArray &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) override { return 0; } // Static Member functions static void PaGetSinksCb(pa_context *c, const pa_sink_info *i, int eol, void *userdata); diff --git a/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp index b067333e48..3f0f4f194f 100644 --- a/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp +++ b/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp @@ -72,15 +72,8 @@ static const unordered_map STREAM_TYPE_STRING_ENUM {"camcorder", STREAM_CAMCORDER} }; -AudioServiceAdapter::~AudioServiceAdapter() = default; PulseAudioServiceAdapterImpl::~PulseAudioServiceAdapterImpl() = default; -unique_ptr AudioServiceAdapter::CreateAudioAdapter(unique_ptr cb) -{ - CHECK_AND_RETURN_RET_LOG(cb != nullptr, nullptr, "CreateAudioAdapter cb is nullptr!"); - return make_unique(cb); -} - PulseAudioServiceAdapterImpl::PulseAudioServiceAdapterImpl(unique_ptr &cb) { g_audioServiceAdapterCallback = move(cb); @@ -172,6 +165,12 @@ Fail: return false; } +int32_t PulseAudioServiceAdapterImpl::OpenAudioPort(std::string audioPortName, const AudioModuleInfo& audioModuleInfo) +{ + AUDIO_PRERELEASE_LOGE("OpenAudioPort enter the INCORRECT func."); + return 0; +} + uint32_t PulseAudioServiceAdapterImpl::OpenAudioPort(string audioPortName, string moduleArgs) { AUDIO_PRERELEASE_LOGI("Enter, port name: %{public}s", audioPortName.c_str()); diff --git a/frameworks/native/audioadapter/test/unittest/BUILD.gn b/frameworks/native/audioadapter/test/unittest/BUILD.gn index d61e4a17cb..1ff921a681 100644 --- a/frameworks/native/audioadapter/test/unittest/BUILD.gn +++ b/frameworks/native/audioadapter/test/unittest/BUILD.gn @@ -18,52 +18,52 @@ import("../../../../../config.gni") module_output_path = "multimedia_audio_framework/audio_engine" config("audio_engine_private_config") { - visibility = [ ":*" ] + visibility = [ ":*" ] - include_dirs = [ - "../../../audioutils/include", - "../../../../../interfaces/inner_api/native/audiocommon/include", - "../../../../../services/audio_service/server/include", - "../../../hdiadapter/common/include", - "../../../hdiadapter/sink/common", - "../../../hdiadapter/source/common", - "../../../../../services/audio_policy/server/include/service/common", - "../../../../../services/audio_engine/manager/include", - "../../../../../services/audio_service/common/include", - "./include", - "../../include" - ] + include_dirs = [ + "../../../audioutils/include", + "../../../../../interfaces/inner_api/native/audiocommon/include", + "../../../../../services/audio_service/server/include", + "../../../hdiadapter/common/include", + "../../../hdiadapter/sink/common", + "../../../hdiadapter/source/common", + "../../../../../services/audio_policy/server/include/service/common", + "../../../../../services/audio_engine/manager/include", + "../../../../../services/audio_service/common/include", + "./include", + "../../include" + ] } ############################################################################################# ohos_unittest("pro_audio_service_adapter_unit_test") { - module_out_path = module_output_path - testonly = true - cflags = [ - "-Wall", - "-Werror", - "-fno-access-control", - ] - sources = [ - "src/pro_audio_service_adapter_unit_test.cpp", - ] + module_out_path = module_output_path + testonly = true + cflags = [ + "-Wall", + "-Werror", + "-fno-access-control", + ] + sources = [ + "src/pro_audio_service_adapter_unit_test.cpp", + ] - configs = [ ":audio_engine_private_config" ] + configs = [ ":audio_engine_private_config" ] - deps = [ - "../../../audioutils:audio_utils", - "../../../../../services/audio_engine:audio_engine_manager", - "../../:pulse_audio_service_adapter", - ] + deps = [ + "../../../audioutils:audio_utils", + "../../../../../services/audio_engine:audio_engine_manager", + "../../:pulse_audio_service_adapter", + ] - external_deps = [ - "c_utils:utils", - "googletest:gtest", - "hilog:libhilog", - "hisysevent:libhisysevent", - "ipc:ipc_single", - "safwk:system_ability_fwk", - "samgr:samgr_proxy", - ] + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] } diff --git a/frameworks/native/audioeffect/include/audio_effect_chain.h b/frameworks/native/audioeffect/include/audio_effect_chain.h index 989ba33279..5fb3a3ce7d 100644 --- a/frameworks/native/audioeffect/include/audio_effect_chain.h +++ b/frameworks/native/audioeffect/include/audio_effect_chain.h @@ -19,12 +19,10 @@ #include #include "audio_effect.h" -#include "audio_utils.h" #ifdef SENSOR_ENABLE #include "audio_head_tracker.h" #endif -#include "audio_effect_hdi_param.h" #ifdef WINDOW_MANAGER_ENABLE #include "audio_effect_rotation.h" #endif diff --git a/frameworks/native/audioeffect/include/audio_effect_chain_manager.h b/frameworks/native/audioeffect/include/audio_effect_chain_manager.h index 42bad17b97..1d06066793 100644 --- a/frameworks/native/audioeffect/include/audio_effect_chain_manager.h +++ b/frameworks/native/audioeffect/include/audio_effect_chain_manager.h @@ -35,7 +35,7 @@ #ifdef SENSOR_ENABLE #include "audio_head_tracker.h" #endif -#include "audio_effect_hdi_param.h" + #ifdef WINDOW_MANAGER_ENABLE #include "audio_effect_rotation.h" #endif @@ -44,6 +44,8 @@ namespace OHOS { namespace AudioStandard { +class AudioEffectHdiParam; + const uint32_t DEFAULT_FRAMELEN = 1440; const uint32_t DEFAULT_NUM_CHANNEL = STEREO; const uint32_t DEFAULT_MCH_NUM_CHANNEL = CHANNEL_6; @@ -64,7 +66,6 @@ struct SessionEffectInfo { std::string sceneType; uint32_t channels; uint64_t channelLayout; - std::string spatializationEnabled; int32_t streamUsage; int32_t systemVolumeType; }; @@ -104,17 +105,26 @@ enum SceneTypeOperation { REMOVE_SCENE_TYPE = 1, }; +enum ProcessClusterOperation { + NO_NEED_TO_CREATE_PROCESSCLUSTER, + CREATE_NEW_PROCESSCLUSTER, + CREATE_DEFAULT_PROCESSCLUSTER, + USE_DEFAULT_PROCESSCLUSTER, + USE_NONE_PROCESSCLUSTER, + CREATE_EXTRA_PROCESSCLUSTER +}; + class AudioEffectChainManager { public: AudioEffectChainManager(); ~AudioEffectChainManager(); static AudioEffectChainManager *GetInstance(); - void InitAudioEffectChainManager(std::vector &effectChains, + void InitAudioEffectChainManager(const std::vector &effectChains, const EffectChainManagerParam &effectChainManagerParam, - std::vector> &effectLibraryList); - void ConstructEffectChainMgrMaps(std::vector &effectChains, + const std::vector> &effectLibraryList); + void ConstructEffectChainMgrMaps(const std::vector &effectChains, const EffectChainManagerParam &effectChainManagerParam, - std::vector> &effectLibraryList); + const std::vector> &effectLibraryList); bool CheckAndAddSessionID(const std::string &sessionID); int32_t CreateAudioEffectChainDynamic(const std::string &sceneType); bool CheckAndRemoveSessionID(const std::string &sessionID); @@ -132,6 +142,7 @@ public: int32_t ReturnEffectChannelInfo(const std::string &sceneType, uint32_t &channels, uint64_t &channelLayout); int32_t ReturnMultiChannelInfo(uint32_t *channels, uint64_t *channelLayout); int32_t EffectRotationUpdate(const uint32_t rotationState); + int32_t EffectVolumeUpdate(); int32_t EffectVolumeUpdate(std::shared_ptr audioEffectVolume); int32_t StreamVolumeUpdate(const std::string sessionIDString, const float streamVolume); uint32_t GetLatency(const std::string &sessionId); @@ -154,6 +165,8 @@ public: int32_t QueryEffectChannelInfo(const std::string &sceneType, uint32_t &channels, uint64_t &channelLayout); int32_t QueryHdiSupportedChannelInfo(uint32_t &channels, uint64_t &channelLayout); void LoadEffectProperties(); + ProcessClusterOperation CheckProcessClusterInstances(const std::string &sceneType); + int32_t GetOutputChannelInfo(const std::string &sceneType, uint32_t &channels, uint64_t &channelLayout); private: int32_t SetAudioEffectChainDynamic(std::string &sceneType, const std::string &effectMode); void UpdateSensorState(); diff --git a/frameworks/native/audioeffect/include/audio_effect_hdi_param.h b/frameworks/native/audioeffect/include/audio_effect_hdi_param.h index 61f7bc1ac8..37312ff2ae 100644 --- a/frameworks/native/audioeffect/include/audio_effect_hdi_param.h +++ b/frameworks/native/audioeffect/include/audio_effect_hdi_param.h @@ -18,8 +18,7 @@ #include #include "v1_0/ieffect_model.h" - -const uint32_t SEND_HDI_COMMAND_LEN = 20; +#include "audio_effect.h" namespace OHOS { namespace AudioStandard { diff --git a/frameworks/native/audioeffect/include/audio_enhance_chain_manager.h b/frameworks/native/audioeffect/include/audio_enhance_chain_manager.h index 348efdce24..bd59dabd34 100644 --- a/frameworks/native/audioeffect/include/audio_enhance_chain_manager.h +++ b/frameworks/native/audioeffect/include/audio_enhance_chain_manager.h @@ -34,9 +34,9 @@ public: AudioEnhanceChainManager(); ~AudioEnhanceChainManager(); static AudioEnhanceChainManager* GetInstance(); - void InitAudioEnhanceChainManager(std::vector &enhanceChains, + void InitAudioEnhanceChainManager(const std::vector &enhanceChains, const EffectChainManagerParam &managerParam, - std::vector> &enhanceLibraryList); + const std::vector> &enhanceLibraryList); int32_t CreateAudioEnhanceChainDynamic(const uint64_t sceneKeyCode, const AudioEnhanceDeviceAttr &deviceAttr); int32_t ReleaseAudioEnhanceChainDynamic(const uint64_t sceneKeyCode); bool ExistAudioEnhanceChain(const uint64_t sceneKeyCode); @@ -89,9 +89,9 @@ private: void GetDeviceTypeName(DeviceType deviceType, std::string &deviceName); void GetDeviceNameByCaptureId(const uint32_t captureId, std::string &deviceName); // construct when init - void ConstructEnhanceChainMgrMaps(std::vector &enhanceChains, + void ConstructEnhanceChainMgrMaps(const std::vector &enhanceChains, const EffectChainManagerParam &managerParam, - std::vector> &enhanceLibraryList); + const std::vector> &enhanceLibraryList); void ConstructDeviceEnhances(); std::map> sceneTypeToEnhanceChainMap_; diff --git a/frameworks/native/audioeffect/libaudio_effect.versionscript b/frameworks/native/audioeffect/libaudio_effect.versionscript index 1f74ea8f0d..fd74047e50 100644 --- a/frameworks/native/audioeffect/libaudio_effect.versionscript +++ b/frameworks/native/audioeffect/libaudio_effect.versionscript @@ -77,6 +77,33 @@ *InitEffectBuffer*; *EffectChainManagerQueryHdiSupportedChannelLayout*; *LoadEffectProperties*; + *ApplyAudioEffectChain*; + *CheckAndAddSessionID*; + *UpdateSceneTypeList*; + *CreateAudioEffectChainDynamic*; + *SessionInfoMapAdd*; + *SessionInfoMapDelete*; + *UpdateMultichannelConfig*; + *UpdateDefaultAudioEffect*; + *UpdateStreamUsage*; + *CheckAndRemoveSessionID*; + *ReleaseAudioEffectChainDynamic*; + *CreateAudioEnhanceChainDynamic*; + *ReleaseAudioEnhanceChainDynamic*; + *GetOutputChannelInfo*; + *ReturnEffectChannelInfo*; + *ExistAudioEnhanceChain*; + *AudioEnhanceChainGetAlgoConfig*; + *IsEmptyEnhanceChain*; + *InitEnhanceBuffer*; + *CopyToEnhanceBuffer*; + *CopyEcToEnhanceBuffer*; + *CopyMicRefToEnhanceBuffer*; + *CopyFromEnhanceBuffer*; + *ApplyAudioEnhanceChain*; + *ApplyAudioEnhanceChainDefault*; + *SendInitCommand*; + *CheckProcessClusterInstances*; local: *; -}; +}; \ No newline at end of file diff --git a/frameworks/native/audioeffect/src/audio_effect_chain.cpp b/frameworks/native/audioeffect/src/audio_effect_chain.cpp index 1307c77936..97527a71f1 100644 --- a/frameworks/native/audioeffect/src/audio_effect_chain.cpp +++ b/frameworks/native/audioeffect/src/audio_effect_chain.cpp @@ -25,6 +25,7 @@ #include "securec.h" #include "media_monitor_manager.h" #include "audio_effect_map.h" +#include "audio_utils.h" namespace OHOS { namespace AudioStandard { diff --git a/frameworks/native/audioeffect/src/audio_effect_chain_adapter.cpp b/frameworks/native/audioeffect/src/audio_effect_chain_adapter.cpp index cd9e71e66a..a7da688cc5 100644 --- a/frameworks/native/audioeffect/src/audio_effect_chain_adapter.cpp +++ b/frameworks/native/audioeffect/src/audio_effect_chain_adapter.cpp @@ -168,9 +168,8 @@ int32_t EffectChainManagerMultichannelUpdate(const char *sceneType) int32_t EffectChainManagerVolumeUpdate(const char *sessionID) { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - std::shared_ptr audioEffectVolume = AudioEffectVolume::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager"); - if (audioEffectChainManager->EffectVolumeUpdate(audioEffectVolume) != SUCCESS) { + if (audioEffectChainManager->EffectVolumeUpdate() != SUCCESS) { return ERROR; } return SUCCESS; @@ -240,15 +239,12 @@ int32_t EffectChainManagerAddSessionInfo(const char *sceneType, const char *sess std::string sceneTypeString = ""; std::string sessionIDString = ""; std::string sceneModeString = ""; - std::string spatializationEnabledString = ""; - if (sceneType && pack.channelLayout && sessionID && pack.sceneMode && - pack.spatializationEnabled && pack.streamUsage && pack.systemVolumeType) { + if (sceneType && pack.channelLayout && sessionID && pack.sceneMode && pack.streamUsage) { sceneTypeString = sceneType; channelLayoutNum = std::strtoull(pack.channelLayout, nullptr, BASE_TEN); sessionIDString = sessionID; sceneModeString = pack.sceneMode; - spatializationEnabledString = pack.spatializationEnabled; streamUsage = static_cast(std::strtol(pack.streamUsage, nullptr, BASE_TEN)); systemVolumeType = static_cast(std::strtol(pack.systemVolumeType, nullptr, BASE_TEN)); } else { @@ -261,7 +257,6 @@ int32_t EffectChainManagerAddSessionInfo(const char *sceneType, const char *sess info.sceneType = sceneTypeString; info.channels = pack.channels; info.channelLayout = channelLayoutNum; - info.spatializationEnabled = spatializationEnabledString; info.streamUsage = streamUsage; info.systemVolumeType = systemVolumeType; return audioEffectChainManager->SessionInfoMapAdd(sessionIDString, info); diff --git a/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp b/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp index 9cad4c8488..01b841f392 100644 --- a/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp +++ b/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp @@ -20,11 +20,13 @@ #include "audio_effect.h" #include "audio_errors.h" #include "audio_effect_log.h" +#include "audio_utils.h" #include "securec.h" #include "system_ability_definition.h" #include "audio_setting_provider.h" #include "audio_device_type.h" #include "audio_effect_map.h" +#include "audio_effect_hdi_param.h" namespace OHOS { namespace AudioStandard { @@ -236,9 +238,9 @@ void AudioEffectChainManager::InitHdiStateInner() } // Boot initialize -void AudioEffectChainManager::InitAudioEffectChainManager(std::vector &effectChains, +void AudioEffectChainManager::InitAudioEffectChainManager(const std::vector &effectChains, const EffectChainManagerParam &effectChainManagerParam, - std::vector> &effectLibraryList) + const std::vector> &effectLibraryList) { std::lock_guard lock(dynamicMutex_); maxEffectChainCount_ = effectChainManagerParam.maxExtraNum + 1; @@ -252,9 +254,9 @@ void AudioEffectChainManager::InitAudioEffectChainManager(std::vector &effectChains, +void AudioEffectChainManager::ConstructEffectChainMgrMaps(const std::vector &effectChains, const EffectChainManagerParam &effectChainManagerParam, - std::vector> &effectLibraryList) + const std::vector> &effectLibraryList) { const std::unordered_map &map = effectChainManagerParam.sceneTypeToChainNameMap; std::set effectSet; @@ -413,6 +415,21 @@ bool AudioEffectChainManager::ExistAudioEffectChain(const std::string &sceneType return ExistAudioEffectChainInner(sceneType, effectMode); } +int32_t AudioEffectChainManager::GetOutputChannelInfo(const std::string &sceneType, + uint32_t &channels, uint64_t &channelLayout) +{ + std::lock_guard lock(dynamicMutex_); + std::string sceneTypeAndDeviceKey = sceneType + "_&_" + GetDeviceTypeName(); + + auto it = sceneTypeToEffectChainMap_.find(sceneTypeAndDeviceKey); + CHECK_AND_RETURN_RET_LOG(it != sceneTypeToEffectChainMap_.end() && it->second != nullptr, + ERROR, "effect chain not found for scene type: %{public}s", sceneTypeAndDeviceKey.c_str()); + + auto audioEffectChain = it->second; + audioEffectChain->UpdateBufferConfig(channels, channelLayout); + return SUCCESS; +} + int32_t AudioEffectChainManager::ApplyAudioEffectChain(const std::string &sceneType, std::unique_ptr &bufferAttr) { @@ -534,9 +551,10 @@ int32_t AudioEffectChainManager::SendEffectApVolume(std::shared_ptr audioEffectVolume) +int32_t AudioEffectChainManager::EffectVolumeUpdate() { std::lock_guard lock(dynamicMutex_); + std::shared_ptr audioEffectVolume = AudioEffectVolume::GetInstance(); return EffectVolumeUpdateInner(audioEffectVolume); } @@ -563,7 +581,7 @@ int32_t AudioEffectChainManager::SetEffectSystemVolume(const int32_t systemVolum AUDIO_INFO_LOG("systemVolumeType: %{public}d, systemVolume: %{public}f", systemVolumeType, audioEffectVolume->GetSystemVolume(systemVolumeType)); - return SUCCESS; + return EffectVolumeUpdateInner(audioEffectVolume); } #ifdef WINDOW_MANAGER_ENABLE @@ -730,8 +748,7 @@ int32_t AudioEffectChainManager::SessionInfoMapAdd(const std::string &sessionID, if (!sessionIDToEffectInfoMap_.count(sessionID)) { sceneTypeToSessionIDMap_[info.sceneType].insert(sessionID); sessionIDToEffectInfoMap_[sessionID] = info; - } else if (sessionIDToEffectInfoMap_[sessionID].sceneMode != info.sceneMode || - sessionIDToEffectInfoMap_[sessionID].spatializationEnabled != info.spatializationEnabled) { + } else if (sessionIDToEffectInfoMap_[sessionID].sceneMode != info.sceneMode) { sessionIDToEffectInfoMap_[sessionID] = info; } else { return ERROR; @@ -1738,6 +1755,47 @@ bool AudioEffectChainManager::IsEffectChainStop(const std::string &sceneType, co return true; } +ProcessClusterOperation AudioEffectChainManager::CheckProcessClusterInstances(const std::string &sceneType) +{ + std::lock_guard lock(dynamicMutex_); + CHECK_AND_RETURN_RET_LOG(sceneType != "SCENE_EXTRA", CREATE_EXTRA_PROCESSCLUSTER, "scene type is extra"); + CHECK_AND_RETURN_RET_LOG(!GetOffloadEnabled(), USE_NONE_PROCESSCLUSTER, "offload, use none processCluster"); + std::string sceneTypeAndDeviceKey = sceneType + "_&_" + GetDeviceTypeName(); + std::string defaultSceneTypeAndDeviceKey = DEFAULT_SCENE_TYPE + "_&_" + GetDeviceTypeName(); + + if (sceneTypeToEffectChainMap_.count(sceneTypeAndDeviceKey)) { + if (sceneTypeToEffectChainMap_[sceneTypeAndDeviceKey] == nullptr) { + AUDIO_WARNING_LOG("scene type %{public}s has null process cluster", sceneTypeAndDeviceKey.c_str()); + } else { + AUDIO_INFO_LOG("process cluster already exist, current count: %{public}d, default count: %{public}d", + sceneTypeToEffectChainCountMap_[sceneTypeAndDeviceKey], defaultEffectChainCount_); + if (isDefaultEffectChainExisted_ && sceneTypeToEffectChainMap_[sceneTypeAndDeviceKey] == + sceneTypeToEffectChainMap_[defaultSceneTypeAndDeviceKey]) { + return USE_DEFAULT_PROCESSCLUSTER; + } + return NO_NEED_TO_CREATE_PROCESSCLUSTER; + } + } + + bool isPriorScene = std::find(priorSceneList_.begin(), priorSceneList_.end(), sceneType) != priorSceneList_.end(); + if (isPriorScene) { + AUDIO_INFO_LOG("create prior process cluster: %{public}s", sceneType.c_str()); + return CREATE_NEW_PROCESSCLUSTER; + } + if ((maxEffectChainCount_ - static_cast(sceneTypeToSpecialEffectSet_.size())) > 1) { + AUDIO_INFO_LOG("max audio process cluster count not reached, create special process cluster: %{public}s", + sceneType.c_str()); + return CREATE_NEW_PROCESSCLUSTER; + } else if (!isDefaultEffectChainExisted_) { + AUDIO_INFO_LOG("max audio process cluster count reached, create current and default process cluster"); + return CREATE_DEFAULT_PROCESSCLUSTER; + } else { + AUDIO_INFO_LOG("max audio process cluster count reached and default already exist: %{public}d", + defaultEffectChainCount_); + return USE_DEFAULT_PROCESSCLUSTER; + } +} + int32_t AudioEffectChainManager::QueryEffectChannelInfo(const std::string &sceneType, uint32_t &channels, uint64_t &channelLayout) { diff --git a/frameworks/native/audioeffect/src/audio_effect_hdi_param.cpp b/frameworks/native/audioeffect/src/audio_effect_hdi_param.cpp index 517216da06..c21cded71b 100644 --- a/frameworks/native/audioeffect/src/audio_effect_hdi_param.cpp +++ b/frameworks/native/audioeffect/src/audio_effect_hdi_param.cpp @@ -16,7 +16,6 @@ #define LOG_TAG "AudioEffectHdiParam" #endif -#include "audio_effect.h" #include "audio_effect_hdi_param.h" #include "audio_errors.h" #include "audio_effect_log.h" diff --git a/frameworks/native/audioeffect/src/audio_enhance_chain_manager.cpp b/frameworks/native/audioeffect/src/audio_enhance_chain_manager.cpp index ed19b9991f..b7f990e201 100644 --- a/frameworks/native/audioeffect/src/audio_enhance_chain_manager.cpp +++ b/frameworks/native/audioeffect/src/audio_enhance_chain_manager.cpp @@ -137,8 +137,9 @@ void AudioEnhanceChainManager::ResetInfo() isMute_ = false; } -void AudioEnhanceChainManager::ConstructEnhanceChainMgrMaps(std::vector &enhanceChains, - const EffectChainManagerParam &managerParam, std::vector> &enhanceLibraryList) +void AudioEnhanceChainManager::ConstructEnhanceChainMgrMaps(const std::vector &enhanceChains, + const EffectChainManagerParam &managerParam, + const std::vector> &enhanceLibraryList) { std::set enhanceSet; for (EffectChain enhanceChain : enhanceChains) { @@ -240,8 +241,9 @@ void AudioEnhanceChainManager::UpdateEnhancePropertyMapFromDb(DeviceType deviceT } } -void AudioEnhanceChainManager::InitAudioEnhanceChainManager(std::vector &enhanceChains, - const EffectChainManagerParam &managerParam, std::vector> &enhanceLibraryList) +void AudioEnhanceChainManager::InitAudioEnhanceChainManager(const std::vector &enhanceChains, + const EffectChainManagerParam &managerParam, + const std::vector> &enhanceLibraryList) { std::lock_guard lock(chainManagerMutex_); normalSceneLimit_ = managerParam.maxExtraNum; diff --git a/frameworks/native/audioeffect/test/unittest/effect_unit_test/include/audio_effect_chain_manager_unit_test.h b/frameworks/native/audioeffect/test/unittest/effect_unit_test/include/audio_effect_chain_manager_unit_test.h index 2849371e57..6c00fee033 100644 --- a/frameworks/native/audioeffect/test/unittest/effect_unit_test/include/audio_effect_chain_manager_unit_test.h +++ b/frameworks/native/audioeffect/test/unittest/effect_unit_test/include/audio_effect_chain_manager_unit_test.h @@ -18,6 +18,7 @@ #include "gtest/gtest.h" #include "audio_effect_chain_manager.h" +#include "audio_effect_hdi_param.h" namespace OHOS { namespace AudioStandard { diff --git a/frameworks/native/audioeffect/test/unittest/effect_unit_test/src/audio_effect_chain_manager_unit_test.cpp b/frameworks/native/audioeffect/test/unittest/effect_unit_test/src/audio_effect_chain_manager_unit_test.cpp index 73a4ed77d7..7f1984c0d9 100644 --- a/frameworks/native/audioeffect/test/unittest/effect_unit_test/src/audio_effect_chain_manager_unit_test.cpp +++ b/frameworks/native/audioeffect/test/unittest/effect_unit_test/src/audio_effect_chain_manager_unit_test.cpp @@ -64,7 +64,6 @@ SessionEffectInfo DEFAULT_INFO = { "SCENE_MOVIE", INFOCHANNELS, INFOCHANNELLAYOUT, - "0", }; } @@ -1365,7 +1364,7 @@ HWTEST(AudioEffectChainManagerUnitTest, EffectVolumeUpdate_001, TestSize.Level1) const std::string sessionIDString = "12345"; const float streamVolume = 0.5; audioEffectVolume->SetStreamVolume(sessionIDString, streamVolume); - int32_t ret = AudioEffectChainManager::GetInstance()->EffectVolumeUpdate(audioEffectVolume); + int32_t ret = AudioEffectChainManager::GetInstance()->EffectVolumeUpdate(); EXPECT_EQ(ret, SUCCESS); } @@ -1480,7 +1479,6 @@ HWTEST(AudioEffectChainManagerUnitTest, GetLatency_007, TestSize.Level1) AudioEffectChainManager::GetInstance()->deviceType_ = DEVICE_TYPE_BLUETOOTH_A2DP; AudioEffectChainManager::GetInstance()->spkOffloadEnabled_ = false; AudioEffectChainManager::GetInstance()->btOffloadEnabled_ = false; - AudioEffectChainManager::GetInstance()->sessionIDToEffectInfoMap_[sessionID].spatializationEnabled = "0"; uint32_t result = AudioEffectChainManager::GetInstance()->GetLatency(sessionID); EXPECT_EQ(0, result); AudioEffectChainManager::GetInstance()->ResetInfo(); @@ -1499,7 +1497,6 @@ HWTEST(AudioEffectChainManagerUnitTest, GetLatency_008, TestSize.Level1) AudioEffectChainManager::GetInstance()->deviceType_ = DEVICE_TYPE_SPEAKER; AudioEffectChainManager::GetInstance()->spkOffloadEnabled_ = false; AudioEffectChainManager::GetInstance()->btOffloadEnabled_ = false; - AudioEffectChainManager::GetInstance()->sessionIDToEffectInfoMap_[sessionID].spatializationEnabled = "0"; uint32_t result = AudioEffectChainManager::GetInstance()->GetLatency(sessionID); EXPECT_EQ(0, result); AudioEffectChainManager::GetInstance()->ResetInfo(); @@ -2149,7 +2146,6 @@ HWTEST(AudioEffectChainManagerUnitTest, SessionInfoMapAdd_003, TestSize.Level1) "SCENE_MOVIE", INFOCHANNELS, INFOCHANNELLAYOUT, - "0", }; ret = AudioEffectChainManager::GetInstance()->SessionInfoMapAdd(sessionID, info); EXPECT_EQ(ret, SUCCESS); @@ -2158,7 +2154,6 @@ HWTEST(AudioEffectChainManagerUnitTest, SessionInfoMapAdd_003, TestSize.Level1) "SCENE_MOVIE", INFOCHANNELS, INFOCHANNELLAYOUT, - "1", }; ret = AudioEffectChainManager::GetInstance()->SessionInfoMapAdd(sessionID, info2); EXPECT_EQ(ret, SUCCESS); @@ -2256,7 +2251,6 @@ HWTEST(AudioEffectChainManagerUnitTest, FindMaxSessionID_001, TestSize.Level1) "SCENE_MOVIE", INFOCHANNELS, INFOCHANNELLAYOUT, - "0", }; EXPECT_NE(AudioEffectChainManager::GetInstance(), nullptr); AudioEffectChainManager::GetInstance()->sessionIDToEffectInfoMap_[sessionID] = sessionEffectInfo; @@ -2282,7 +2276,6 @@ HWTEST(AudioEffectChainManagerUnitTest, FindMaxSessionID_002, TestSize.Level1) "SCENE_MOVIE", INFOCHANNELS, INFOCHANNELLAYOUT, - "0", }; EXPECT_NE(AudioEffectChainManager::GetInstance(), nullptr); diff --git a/frameworks/native/audioutils/include/audio_utils.h b/frameworks/native/audioutils/include/audio_utils.h index af3561cb4d..4717a75cf7 100644 --- a/frameworks/native/audioutils/include/audio_utils.h +++ b/frameworks/native/audioutils/include/audio_utils.h @@ -218,6 +218,8 @@ bool SetSysPara(const std::string& key, int32_t value); template bool GetSysPara(const char *key, T &value); +int32_t GetEngineFlag(); + enum AudioDumpFileType { AUDIO_APP = 0, OTHER_NATIVE_SERVICE = 1, diff --git a/frameworks/native/audioutils/src/audio_utils.cpp b/frameworks/native/audioutils/src/audio_utils.cpp index 0a0b2ff46d..a397bc517c 100644 --- a/frameworks/native/audioutils/src/audio_utils.cpp +++ b/frameworks/native/audioutils/src/audio_utils.cpp @@ -1097,6 +1097,18 @@ template bool GetSysPara(const char *key, uint32_t &value); template bool GetSysPara(const char *key, int64_t &value); template bool GetSysPara(const char *key, std::string &value); +int32_t GetEngineFlag() +{ + std::string para = "sys.audio.engine.proaudio.enable"; + int32_t engineFlag = -1; + bool res = GetSysPara(para.c_str(), engineFlag); + AUDIO_DEBUG_LOG("get %{public}s = %{public}d", para.c_str(), engineFlag); + if (!res || engineFlag == -1) { + AUDIO_ERR_LOG("get %{public}s fail", para.c_str()); + } + return engineFlag; +} + std::map DumpFileUtil::g_lastPara = {}; FILE *DumpFileUtil::OpenDumpFileInner(std::string para, std::string fileName, AudioDumpFileType fileType) diff --git a/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h b/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h index abb26d0af8..6071ce7a1e 100644 --- a/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h +++ b/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h @@ -39,6 +39,11 @@ typedef struct IAudioSinkAttr { const char *aux = nullptr; } IAudioSinkAttr; +enum AudioDrainType { + AUDIO_DRAIN_EARLY_NOTIFY, + AUDIO_DRAIN_ALL +}; + class IAudioSinkCallback { public: virtual void OnAudioSinkParamChange(const std::string &netWorkId, const AudioParamKey key, @@ -121,6 +126,14 @@ public: { return; } + + virtual int32_t RegisterRenderCallback(OnRenderCallback (*callback), int8_t *userdata) { return 0; } + virtual int32_t Drain(AudioDrainType type) { return 0; } + virtual int32_t SetBufferSize(uint32_t sizeMs) { return 0; } + + virtual int32_t OffloadRunningLockInit(void) { return 0; } + virtual int32_t OffloadRunningLockLock(void) { return 0; } + virtual int32_t OffloadRunningLockUnlock(void) { return 0; } }; class IMmapAudioRendererSink : public IAudioRendererSink { @@ -132,22 +145,10 @@ public: virtual int32_t GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) = 0; }; -enum AudioDrainType { - AUDIO_DRAIN_EARLY_NOTIFY, - AUDIO_DRAIN_ALL -}; - class IOffloadAudioRendererSink : public IAudioRendererSink { public: IOffloadAudioRendererSink() = default; virtual ~IOffloadAudioRendererSink() = default; - virtual int32_t RegisterRenderCallback(OnRenderCallback (*callback), int8_t *userdata) = 0; - virtual int32_t Drain(AudioDrainType type) = 0; - virtual int32_t SetBufferSize(uint32_t sizeMs) = 0; - - virtual int32_t OffloadRunningLockInit(void) = 0; - virtual int32_t OffloadRunningLockLock(void) = 0; - virtual int32_t OffloadRunningLockUnlock(void) = 0; }; class IRemoteAudioRendererSink : public IAudioRendererSink { public: diff --git a/frameworks/native/hdiadapter/sink/file/audio_renderer_file_sink.cpp b/frameworks/native/hdiadapter/sink/file/audio_renderer_file_sink.cpp index 4e6cdad8e0..327147b16d 100644 --- a/frameworks/native/hdiadapter/sink/file/audio_renderer_file_sink.cpp +++ b/frameworks/native/hdiadapter/sink/file/audio_renderer_file_sink.cpp @@ -124,6 +124,9 @@ void AudioRendererFileSink::DeInit() int32_t AudioRendererFileSink::Init(const IAudioSinkAttr &attr) { + if (attr.filePath == nullptr) { + return ERROR; + } filePath_.assign(attr.filePath); return SUCCESS; @@ -172,6 +175,8 @@ int32_t AudioRendererFileSink::Stop(void) if (filePtr_ != nullptr) { fclose(filePtr_); filePtr_ = nullptr; + } else { + return ERROR; } return SUCCESS; diff --git a/frameworks/native/hdiadapter/sink/offload/offload_audio_renderer_sink.cpp b/frameworks/native/hdiadapter/sink/offload/offload_audio_renderer_sink.cpp index 873d98726b..7a4d53a5eb 100644 --- a/frameworks/native/hdiadapter/sink/offload/offload_audio_renderer_sink.cpp +++ b/frameworks/native/hdiadapter/sink/offload/offload_audio_renderer_sink.cpp @@ -1044,6 +1044,7 @@ int32_t OffloadAudioRendererSinkInner::OffloadRunningLockInit(void) int32_t OffloadAudioRendererSinkInner::OffloadRunningLockLock(void) { #ifdef FEATURE_POWER_MANAGER + CHECK_AND_RETURN_RET(!runninglocked, SUCCESS); AUDIO_INFO_LOG("keepRunningLock Lock"); std::shared_ptr keepRunningLock; if (offloadRunningLockManager_ == nullptr) { @@ -1058,7 +1059,6 @@ int32_t OffloadAudioRendererSinkInner::OffloadRunningLockLock(void) } CHECK_AND_RETURN_RET_LOG(offloadRunningLockManager_ != nullptr, ERR_OPERATION_FAILED, "offloadRunningLockManager_ is null, playback can not work well!"); - CHECK_AND_RETURN_RET(!runninglocked, SUCCESS); runninglocked = true; offloadRunningLockManager_->Lock(RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING); // -1 for lasting. #endif @@ -1069,10 +1069,10 @@ int32_t OffloadAudioRendererSinkInner::OffloadRunningLockLock(void) int32_t OffloadAudioRendererSinkInner::OffloadRunningLockUnlock(void) { #ifdef FEATURE_POWER_MANAGER + CHECK_AND_RETURN_RET(runninglocked, SUCCESS); AUDIO_INFO_LOG("keepRunningLock UnLock"); CHECK_AND_RETURN_RET_LOG(offloadRunningLockManager_ != nullptr, ERR_OPERATION_FAILED, "OffloadKeepRunningLock is null, playback can not work well!"); - CHECK_AND_RETURN_RET(runninglocked, SUCCESS); runninglocked = false; offloadRunningLockManager_->UnLock(); #endif diff --git a/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp b/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp index 813cef18b4..592ca335cb 100644 --- a/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp +++ b/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp @@ -1827,19 +1827,22 @@ void AudioRendererSinkInner::SetAddress(const std::string &address) int32_t AudioRendererSinkInner::SetAudioRouteInfoForEnhanceChain(const DeviceType &outputDevice) { - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); uint32_t renderId = 0; int32_t ret = GetRenderId(renderId); if (ret != SUCCESS) { AUDIO_WARNING_LOG("GetRenderId failed"); } - if (halName_ == "usb") { - audioEnhanceChainManager->SetOutputDevice(renderId, DEVICE_TYPE_USB_ARM_HEADSET); - } else if (halName_ == "dp") { - audioEnhanceChainManager->SetOutputDevice(renderId, DEVICE_TYPE_DP); - } else { - audioEnhanceChainManager->SetOutputDevice(renderId, outputDevice); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 0) { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); + if (halName_ == "usb") { + audioEnhanceChainManager->SetOutputDevice(renderId, DEVICE_TYPE_USB_ARM_HEADSET); + } else if (halName_ == "dp") { + audioEnhanceChainManager->SetOutputDevice(renderId, DEVICE_TYPE_DP); + } else { + audioEnhanceChainManager->SetOutputDevice(renderId, outputDevice); + } } return SUCCESS; } diff --git a/frameworks/native/hdiadapter/source/bluetooth/bluetooth_capturer_source.cpp b/frameworks/native/hdiadapter/source/bluetooth/bluetooth_capturer_source.cpp index 7381bf41db..1e260d43f8 100644 --- a/frameworks/native/hdiadapter/source/bluetooth/bluetooth_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/bluetooth/bluetooth_capturer_source.cpp @@ -583,15 +583,18 @@ int32_t BluetoothCapturerSourceInner::SetInputRoute(DeviceType inputDevice, cons int32_t BluetoothCapturerSourceInner::SetAudioRouteInfoForEnhanceChain(const DeviceType &inputDevice, const std::string &deviceName) { - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); uint32_t captureId = 0; int32_t ret = GetCaptureId(captureId); if (ret != SUCCESS) { AUDIO_WARNING_LOG("GetCaptureId failed"); } - audioEnhanceChainManager->SetInputDevice(captureId, inputDevice, deviceName); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 0) { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); + audioEnhanceChainManager->SetInputDevice(captureId, inputDevice, deviceName); + } return SUCCESS; } 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 aa40d129ae..d44ca4695c 100644 --- a/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.cpp +++ b/frameworks/native/hdiadapter/source/file/audio_capturer_file_source.cpp @@ -132,6 +132,9 @@ void AudioCapturerFileSource::DeInit() int32_t AudioCapturerFileSource::Init(const IAudioSourceAttr &attr) { + if (attr.filePath == nullptr) { + return ERROR; + } const char *filePath = attr.filePath; char realPath[PATH_MAX + 1] = {0x00}; std::string sourceFilePath(filePath); diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 2c8a186833..2f9bb95065 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -1765,17 +1765,20 @@ int32_t AudioCapturerSourceInner::SetAudioRouteInfoForEnhanceChain(const DeviceT AUDIO_ERR_LOG("non blocking source not support SetAudioRouteInfoForEnhanceChain"); return SUCCESS; } - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); uint32_t captureId = 0; int32_t ret = GetCaptureId(captureId); if (ret != SUCCESS) { AUDIO_WARNING_LOG("GetCaptureId failed"); } - if (halName_ == "usb") { - audioEnhanceChainManager->SetInputDevice(captureId, DEVICE_TYPE_USB_ARM_HEADSET, deviceName); - } else { - audioEnhanceChainManager->SetInputDevice(captureId, inputDevice, deviceName); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 0) { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); + if (halName_ == "usb") { + audioEnhanceChainManager->SetInputDevice(captureId, DEVICE_TYPE_USB_ARM_HEADSET, deviceName); + } else { + audioEnhanceChainManager->SetInputDevice(captureId, inputDevice, deviceName); + } } return SUCCESS; } diff --git a/frameworks/native/hdiadapter_new/sink/file_audio_render_sink.cpp b/frameworks/native/hdiadapter_new/sink/file_audio_render_sink.cpp index bf0dbd7c42..6db8d51369 100644 --- a/frameworks/native/hdiadapter_new/sink/file_audio_render_sink.cpp +++ b/frameworks/native/hdiadapter_new/sink/file_audio_render_sink.cpp @@ -30,6 +30,9 @@ FileAudioRenderSink::~FileAudioRenderSink() int32_t FileAudioRenderSink::Init(const IAudioSinkAttr &attr) { + if (attr.filePath == nullptr) { + return ERROR; + } filePath_.assign(attr.filePath); return SUCCESS; } diff --git a/frameworks/native/hdiadapter_new/source/file_audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/file_audio_capture_source.cpp index dcc31f8d7c..467f887c31 100644 --- a/frameworks/native/hdiadapter_new/source/file_audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/file_audio_capture_source.cpp @@ -30,6 +30,9 @@ FileAudioCaptureSource::~FileAudioCaptureSource() int32_t FileAudioCaptureSource::Init(const IAudioSourceAttr &attr) { + if (attr.filePath == nullptr) { + return ERROR; + } std::string filePath(attr.filePath); std::string dirPath; std::string fileName; diff --git a/interfaces/inner_api/native/audiocommon/include/audio_effect.h b/interfaces/inner_api/native/audiocommon/include/audio_effect.h index 0dcca3852f..8dcd7b8b33 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_effect.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_effect.h @@ -32,6 +32,7 @@ namespace OHOS { namespace AudioStandard { // audio effect manager info constexpr int32_t AUDIO_EFFECT_COUNT_UPPER_LIMIT = 20; +constexpr uint32_t SEND_HDI_COMMAND_LEN = 20; enum HdiSetParamCommandCode { HDI_INIT = 0, @@ -190,9 +191,10 @@ enum AudioEffectScene { * Enumerates the audio enhance scene effect type. */ enum AudioEnhanceScene { - SCENE_VOIP_UP = 0, - SCENE_RECORD = 1, - SCENE_PRE_ENHANCE = 2, + SCENE_NONE = 0, + SCENE_VOIP_UP = 1, + SCENE_RECORD = 2, + SCENE_PRE_ENHANCE = 3, SCENE_ASR = 4, SCENE_VOICE_MESSAGE = 5, }; diff --git a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h index 640a4e4e53..9b0d48def9 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -584,6 +585,24 @@ struct AudioStreamData { int32_t volumeEnd; std::unordered_map isInnerCapeds; }; + +struct AudioCallBackStreamInfo { + uint64_t framePosition; + uint64_t framesWritten; + uint64_t timestamp; + uint64_t latency = 0; + int8_t *inputData; + size_t requestDataLen; + std::string deviceClass; + std::string deviceNetId; + bool needData; +}; + +struct AudioChannelInfo { + AudioChannelLayOut channelLayout; + uint32_t numChannels; +}; + } // namespace AudioStandard } // namespace OHOS #endif // AUDIO_STREAM_INFO_H -- Gitee From 9d93de4b6bd33508481e155d309994b83a0d2216 Mon Sep 17 00:00:00 2001 From: trytocalm Date: Sat, 12 Apr 2025 18:41:41 +0800 Subject: [PATCH 05/40] =?UTF-8?q?audio=20framework=E9=80=82=E9=85=8DProAud?= =?UTF-8?q?io?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: trytocalm --- .../manager/src/hpae_capturer_manager.cpp | 2 +- .../src/hpae_audio_format_converter_node.cpp | 7 +- .../audio_engine/node/src/hpae_mixer_node.cpp | 3 +- .../node/src/hpae_offload_sinkoutput_node.cpp | 16 ++-- .../node/src/hpae_sinkInput_node.cpp | 4 +- .../node/src/hpae_sink_output_node.cpp | 14 ++-- .../channel_converter/src/down_mixer.cpp | 3 +- .../proresampler/audio_proresampler.cpp | 1 + services/audio_policy/etc/audio_config.para | 1 + .../interface/iaudio_policy_interface.h | 6 ++ .../service/manager/audio_adapter_manager.h | 8 +- .../src/service/audio_policy_service.cpp | 28 ++++++- .../service/manager/audio_adapter_manager.cpp | 83 ++++++++++++++----- services/audio_service/BUILD.gn | 6 ++ .../common/include/audio_volume_c.h | 2 + .../audio_service/common/src/audio_volume.cpp | 10 ++- .../server/include/audio_endpoint_private.h | 1 + .../server/include/audio_server.h | 2 + .../server/include/capturer_in_server.h | 1 + .../server/include/i_capturer_stream.h | 1 + .../server/include/i_renderer_stream.h | 5 ++ .../server/src/audio_endpoint.cpp | 6 ++ .../audio_service/server/src/audio_server.cpp | 38 ++++++--- .../server/src/hpae_renderer_stream_impl.cpp | 4 +- .../server/src/pro_adapter_manager.cpp | 4 +- test/BUILD.gn | 2 + 26 files changed, 192 insertions(+), 66 deletions(-) diff --git a/services/audio_engine/manager/src/hpae_capturer_manager.cpp b/services/audio_engine/manager/src/hpae_capturer_manager.cpp index 4322ccd654..e95d05cbf9 100644 --- a/services/audio_engine/manager/src/hpae_capturer_manager.cpp +++ b/services/audio_engine/manager/src/hpae_capturer_manager.cpp @@ -65,7 +65,7 @@ int32_t HpaeCapturerManager::CaptureEffectCreate(const HpaeProcessorType &proces uint64_t sceneCode = static_cast(sceneType); uint64_t sceneKeyCode = 0; sceneKeyCode = (sceneCode << SCENE_TYPE_OFFSET) + (captureId_ << CAPTURER_ID_OFFSET) + renderId_; - AUDIO_INFO_LOG("sceneCode:%{public}lu sceneKeyCode:%{public}lu", sceneCode, sceneKeyCode); + AUDIO_INFO_LOG("sceneCode:%{public}" PRIu64 "sceneKeyCode:%{public}" PRIu64, sceneCode, sceneKeyCode); CaptureEffectAttr attr = {}; attr.micChannels = static_cast(sourceInfo_.channels); attr.ecChannels = static_cast(sourceInfo_.ecChannels); diff --git a/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp b/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp index 254457b871..86ecff9c0a 100644 --- a/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp +++ b/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp @@ -18,6 +18,7 @@ #include "hpae_audio_format_converter_node.h" #include "audio_engine_log.h" #include "audio_utils.h" +#include "cinttypes" static constexpr uint32_t DEFAULT_EFFECT_RATE = 48000; @@ -47,8 +48,8 @@ HpaeAudioFormatConverterNode::HpaeAudioFormatConverterNode(HpaeNodeInfo preNodeI // for now, work at float32le by default channelConverter_.SetParam(inChannelInfo, outChannelInfo, SAMPLE_F32LE, true); AUDIO_INFO_LOG("node id %{public}d, sessionid %{public}d, " - "input: bitformat %{public}d, sample rate %{public}d, channels %{public}d, channelLayout %{public}lu" - ", output: bitformat %{public}d, sample rate %{public}d, channels %{public}d, channelLayout %{public}lu", + "input: bitformat %{public}d, sample rate %{public}d, channels %{public}d, channelLayout %{public}" PRIu64 "" + ", output: bitformat %{public}d, sample rate %{public}d, channels %{public}d, channelLayout %{public}" PRIu64 "", GetNodeId(), GetSessionId(), preNodeInfo.format, preNodeInfo.samplingRate, inChannelInfo.numChannels, inChannelInfo.channelLayout, nodeInfo.format, nodeInfo.samplingRate, outChannelInfo.numChannels, outChannelInfo.channelLayout); @@ -220,7 +221,7 @@ bool HpaeAudioFormatConverterNode::CheckUpdateInInfo(HpaePcmBuffer *input) // update channels and channelLayout if ((curInChannelInfo.numChannels != numChannels) || (curInChannelInfo.channelLayout != channelLayout)) { AUDIO_INFO_LOG("NodeId %{public}d: Update innput channel info from pcmBufferInfo, " - "channels: %{public}d -> %{public}d, channellayout: %{public}lu -> %{public}lu.", + "channels: %{public}d -> %{public}d, channellayout: %{public}" PRIu64 " -> %{public}" PRIu64 ".", GetNodeId(), curInChannelInfo.numChannels, numChannels, curInChannelInfo.channelLayout, channelLayout); AudioChannelInfo newInChannelInfo = { diff --git a/services/audio_engine/node/src/hpae_mixer_node.cpp b/services/audio_engine/node/src/hpae_mixer_node.cpp index 47bdd549b1..67ae097cc4 100644 --- a/services/audio_engine/node/src/hpae_mixer_node.cpp +++ b/services/audio_engine/node/src/hpae_mixer_node.cpp @@ -19,6 +19,7 @@ #include "hpae_mixer_node.h" #include "hpae_pcm_buffer.h" #include "audio_utils.h" +#include "cinttypes" namespace OHOS { namespace AudioStandard { namespace HPAE { @@ -67,7 +68,7 @@ HpaePcmBuffer *HpaeMixerNode::SignalProcess(const std::vector & isPCMBufferInfoUpdated = true; } if (pcmBufferInfo_.channelLayout != inputs[0]->GetChannelLayout()) { - AUDIO_INFO_LOG("Update channel layout %{public}lu -> %{public}lu", + AUDIO_INFO_LOG("Update channel layout %{public}" PRIu64 " -> %{public}" PRIu64 "", pcmBufferInfo_.channelLayout, inputs[0]->GetChannelLayout()); pcmBufferInfo_.channelLayout = inputs[0]->GetChannelLayout(); isPCMBufferInfoUpdated = true; diff --git a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp index d6f8a869eb..b872e9d952 100644 --- a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp +++ b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp @@ -193,7 +193,7 @@ int32_t HpaeOffloadSinkOutputNode::RenderSinkInit(IAudioSinkAttr &attr) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkInit Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, interval); + sinkOutAttr_.adapterName.c_str(), interval); #endif return ret; } @@ -214,7 +214,7 @@ int32_t HpaeOffloadSinkOutputNode::RenderSinkDeInit(void) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkDeInit Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, interval); + sinkOutAttr_.adapterName.c_str(), interval); #endif return SUCCESS; } @@ -235,7 +235,7 @@ int32_t HpaeOffloadSinkOutputNode::RenderSinkFlush(void) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkFlush Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, interval); + sinkOutAttr_.adapterName.c_str(), interval); #endif return ret; } @@ -261,7 +261,7 @@ int32_t HpaeOffloadSinkOutputNode::RenderSinkStart(void) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkStart Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, interval); + sinkOutAttr_.adapterName.c_str(), interval); #endif state_ = RENDERER_RUNNING; return SUCCESS; @@ -285,7 +285,7 @@ int32_t HpaeOffloadSinkOutputNode::RenderSinkStop(void) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkStop Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, interval); + sinkOutAttr_.adapterName.c_str(), interval); #endif state_ = RENDERER_STOPPED; return SUCCESS; @@ -412,7 +412,7 @@ int32_t HpaeOffloadSinkOutputNode::ProcessRenderFrame() intervalTimer_.Stop(); uint64_t interval = intervalTimer_.Elapsed(); AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, interval); + sinkOutAttr_.adapterName.c_str(), interval); #endif auto now = std::chrono::high_resolution_clock::now(); auto ret = audioRendererSink_->RenderFrame(*renderFrameData, renderFrameData_.size(), writeLen); @@ -441,14 +441,14 @@ int32_t HpaeOffloadSinkOutputNode::ProcessRenderFrame() SetBufferSizeWhileRenderFrame(); #ifdef ENABLE_HOOK_PCM AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, interval); + sinkOutAttr_.adapterName.c_str(), interval); if (outputPcmDumper_) { outputPcmDumper_->Dump((int8_t *)renderFrameData, renderFrameData_.size()); } timer.Stop(); uint64_t elapsed = timer.Elapsed(); AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode :name %{public}s, RenderFrame elapsed time: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, elapsed); + sinkOutAttr_.adapterName.c_str(), elapsed); intervalTimer_.Start(); #endif renderFrameData_.clear(); diff --git a/services/audio_engine/node/src/hpae_sinkInput_node.cpp b/services/audio_engine/node/src/hpae_sinkInput_node.cpp index e1755d28c9..53a14724c8 100644 --- a/services/audio_engine/node/src/hpae_sinkInput_node.cpp +++ b/services/audio_engine/node/src/hpae_sinkInput_node.cpp @@ -22,7 +22,7 @@ #include "hpae_node_common.h" #include "audio_engine_log.h" #include "audio_errors.h" - +#include "cinttypes" namespace OHOS { namespace AudioStandard { namespace HPAE { @@ -36,7 +36,7 @@ HpaeSinkInputNode::HpaeSinkInputNode(HpaeNodeInfo &nodeInfo) interleveData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), framesWritten_(0), totalFrames_(0) { - AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}lu, " + AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}" PRIu64", " "frameLen %{public}d", nodeInfo.sessionId, inputAudioBuffer_.GetChannelCount(), inputAudioBuffer_.GetChannelLayout(), inputAudioBuffer_.GetFrameLen()); diff --git a/services/audio_engine/node/src/hpae_sink_output_node.cpp b/services/audio_engine/node/src/hpae_sink_output_node.cpp index 6d11aefbc2..f26561dc39 100644 --- a/services/audio_engine/node/src/hpae_sink_output_node.cpp +++ b/services/audio_engine/node/src/hpae_sink_output_node.cpp @@ -40,7 +40,7 @@ HpaeSinkOutputNode::HpaeSinkOutputNode(HpaeNodeInfo &nodeInfo) outputPcmDumper_ = std::make_unique("HpaeSinkOutputNode_Out_bit_" + std::to_string(GetBitWidth()) + "_ch_" + std::to_string(GetChannelCount()) + "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); - AUDIO_INFO_LOG("HpaeSinkOutputNode name is %{public}s", sinkOutAttr_.adapterName); + AUDIO_INFO_LOG("HpaeSinkOutputNode name is %{public}s", sinkOutAttr_.adapterName.c_str()); #endif } @@ -87,7 +87,7 @@ void HpaeSinkOutputNode::DoProcess() intervalTimer_.Stop(); uint64_t interval = intervalTimer_.Elapsed(); AUDIO_DEBUG_LOG("HpaeSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, + sinkOutAttr_.adapterName.c_str(), interval); outputPcmDumper_->CheckAndReopenHandlde(); if (outputPcmDumper_) { @@ -107,7 +107,7 @@ void HpaeSinkOutputNode::DoProcess() timer.Stop(); uint64_t elapsed = timer.Elapsed(); AUDIO_DEBUG_LOG("HpaeSinkOutputNode :name %{public}s, RenderFrame elapsed time: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, + sinkOutAttr_.adapterName.c_str(), elapsed); intervalTimer_.Start(); #endif @@ -189,7 +189,7 @@ int32_t HpaeSinkOutputNode::RenderSinkInit(IAudioSinkAttr &attr) uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkInit Elapsed: %{public}" PRIu64 " ms ret: %{public}d", - sinkOutAttr_.adapterName, + sinkOutAttr_.adapterName.c_str(), interval, ret); std::string adapterName = sinkOutAttr_.adapterName; @@ -217,7 +217,7 @@ int32_t HpaeSinkOutputNode::RenderSinkDeInit(void) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkDeInit Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, + sinkOutAttr_.adapterName.c_str(), interval); #endif return SUCCESS; @@ -281,7 +281,7 @@ int32_t HpaeSinkOutputNode::RenderSinkStart(void) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkStart Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, + sinkOutAttr_.adapterName.c_str(), interval); #endif state_ = RENDERER_RUNNING; @@ -309,7 +309,7 @@ int32_t HpaeSinkOutputNode::RenderSinkStop(void) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkStop Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName, + sinkOutAttr_.adapterName.c_str(), interval); #endif state_ = RENDERER_STOPPED; 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 b49c882ade..828f654a24 100644 --- a/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp +++ b/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp @@ -17,6 +17,7 @@ #endif #include #include "securec.h" +#include "inttypes.h" #include "audio_engine_log.h" #include "down_mixer.h" namespace OHOS { @@ -143,7 +144,7 @@ int32_t DownMixer::SetupDownMixTable() if ((!isValidChLayout(inLayout_, inChannels_)) || (!isValidChLayout(outLayout_, outChannels_)) || inLayout_ == outLayout_ || inChannels_ <= outChannels_) { AUDIO_ERR_LOG("invalid input or output channellayout: input channel count %{public}d, " - "inLayout_ %{public}lu. output channel count %{public}d, outLayout_ %{public}lu", + "inLayout_ %{public}" PRIu64 ". output channel count %{public}d, outLayout_ %{public}" PRIu64 "", inChannels_, inLayout_, outChannels_, outLayout_); return DMIX_ERR_INVALID_ARG; } diff --git a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp index 0bd3810102..3672f16d98 100644 --- a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp +++ b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp @@ -14,6 +14,7 @@ */ #include "audio_proresampler.h" #include "audio_policy_log.h" +#include "securec.h" namespace OHOS { namespace AudioStandard { namespace HPAE { diff --git a/services/audio_policy/etc/audio_config.para b/services/audio_policy/etc/audio_config.para index 2d29a0d929..6a2342883c 100644 --- a/services/audio_policy/etc/audio_config.para +++ b/services/audio_policy/etc/audio_config.para @@ -16,3 +16,4 @@ const.multimedia.audio.volumestep = 1 persist.multimedia.audio.safevolume = 15 persist.multimedia.audio.safevolume.timeout = 1140 persist.multimedia.audio.firstboot = 1 +sys.audio.engine.proaudio.enable = 1 diff --git a/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h b/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h index ee2daa8c12..08e80b5421 100644 --- a/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h +++ b/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h @@ -188,6 +188,12 @@ public: virtual int32_t SetDoubleRingVolumeDb(const AudioStreamType &streamType, const int32_t &volumeLevel) = 0; + virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 & propertyArray) const = 0; + + virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArray& propertyArray) const = 0; + + virtual int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray& propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) const = 0; + virtual void SetDeviceSafeVolume(const AudioStreamType streamType, const int32_t volumeLevel) = 0; virtual void SetRestoreVolumeFlag(const bool safeVolumeCall) = 0; diff --git a/services/audio_policy/server/include/service/manager/audio_adapter_manager.h b/services/audio_policy/server/include/service/manager/audio_adapter_manager.h index c05b0e1ac1..e3f4f94897 100644 --- a/services/audio_policy/server/include/service/manager/audio_adapter_manager.h +++ b/services/audio_policy/server/include/service/manager/audio_adapter_manager.h @@ -250,6 +250,12 @@ public: std::shared_ptr GetAllDeviceVolumeInfo(DeviceType deviceType, AudioStreamType streamType); std::vector GetStreamVolumeInfo(AdjustStreamVolume volumeType); + + int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 & propertyArray) const; + + int32_t GetAudioEffectProperty(AudioEffectPropertyArray& propertyArray) const; + + int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray& propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) const; void SetDeviceSafeVolume(const AudioStreamType streamType, const int32_t volumeLevel); @@ -361,7 +367,7 @@ private: return *reinterpret_cast(const_cast(&data[0])); } - std::unique_ptr audioServiceAdapter_; + std::shared_ptr audioServiceAdapter_; std::unordered_map minVolumeIndexMap_; std::unordered_map maxVolumeIndexMap_; std::mutex systemSoundMutex_; 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 2766fff277..2878ccc48f 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -1807,7 +1807,12 @@ int32_t AudioPolicyService::SetAudioEffectProperty(const AudioEffectPropertyArra int32_t AudioPolicyService::GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray) { int32_t ret = AUDIO_OK; - ret = AudioServerProxy::GetInstance().GetAudioEffectPropertyProxy(propertyArray); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return audioPolicyManager_.GetAudioEffectProperty(propertyArray); + } else { + ret = AudioServerProxy::GetInstance().GetAudioEffectPropertyProxy(propertyArray); + } CHECK_AND_RETURN_RET_LOG(ret == AUDIO_OK, ret, "get audio enhance property fail"); auto oIter = propertyArray.property.begin(); while (oIter != propertyArray.property.end()) { @@ -1822,7 +1827,12 @@ int32_t AudioPolicyService::GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 & int32_t AudioPolicyService::GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) { - return AudioServerProxy::GetInstance().GetAudioEffectPropertyProxy(propertyArray); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return audioPolicyManager_.GetAudioEffectProperty(propertyArray); + } else { + return AudioServerProxy::GetInstance().GetAudioEffectPropertyProxy(propertyArray); + } } int32_t AudioPolicyService::GetSupportedAudioEffectProperty(AudioEffectPropertyArray &propertyArray) @@ -1873,7 +1883,12 @@ int32_t AudioPolicyService::SetAudioEffectProperty(const AudioEffectPropertyArra int32_t AudioPolicyService::GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) { - return AudioServerProxy::GetInstance().GetAudioEffectPropertyProxy(propertyArray); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return audioPolicyManager_->GetAudioEffectProperty(propertyArray); + else { + return AudioServerProxy::GetInstance().GetAudioEffectPropertyProxy(propertyArray); + } } int32_t AudioPolicyService::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &propertyArray) @@ -1907,7 +1922,12 @@ int32_t AudioPolicyService::GetAudioEnhanceProperty(AudioEnhancePropertyArray &p int32_t AudioPolicyService::GetAudioEnhancePropertyByDevice(DeviceType deviceType, AudioEnhancePropertyArray &propertyArray) { - return AudioServerProxy::GetInstance().GetAudioEnhancePropertyProxy(propertyArray, deviceType); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return audioPolicyManager_->GetAudioEffectProperty(propertyArray, deviceType); + else { + return AudioServerProxy::GetInstance().GetAudioEnhancePropertyProxy(propertyArray, deviceType); + } } void AudioPolicyService::UpdateEffectBtOffloadSupported(const bool &isSupported) diff --git a/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp b/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp index 4f5cfab0fd..3e4c1aea30 100644 --- a/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp +++ b/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp @@ -1060,13 +1060,20 @@ AudioIOHandle AudioAdapterManager::OpenAudioPort(std::shared_ptr AUDIO_INFO_LOG("Adapter load-module %{public}s, route flag: %{public}u", moduleArgs.c_str(), pipeInfo->routeFlag_); curActiveCount_++; AudioIOHandle ioHandle = HDI_INVALID_ID; - if (IsPaRoute(pipeInfo->routeFlag_)) { - AUDIO_INFO_LOG("Is pa route"); - return OpenPaAudioPort(pipeInfo, paIndex, moduleArgs); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + ioHandle = audioServiceAdapter_->OpenAudioPort(pipeInfo->moduleInfo_.lib, pipeInfo->moduleInfo_); + paIndex = ioHandle; + return ioHandle; + } else { + if (IsPaRoute(pipeInfo->routeFlag_)) { + AUDIO_INFO_LOG("Is pa route"); + return OpenPaAudioPort(pipeInfo, paIndex, moduleArgs); + } + + AUDIO_INFO_LOG("Not pa route"); + return OpenNotPaAudioPort(pipeInfo, paIndex); } - - AUDIO_INFO_LOG("Not pa route"); - return OpenNotPaAudioPort(pipeInfo, paIndex); } AudioIOHandle AudioAdapterManager::OpenPaAudioPort(std::shared_ptr pipeInfo, uint32_t &paIndex, @@ -1188,25 +1195,31 @@ AudioIOHandle AudioAdapterManager::OpenAudioPort(const AudioModuleInfo &audioMod curActiveCount_++; AudioIOHandle ioHandle = HDI_INVALID_ID; CHECK_AND_RETURN_RET_LOG(audioServerProxy_ != nullptr, ioHandle, "audioServerProxy_ null"); - std::string identity = IPCSkeleton::ResetCallingIdentity(); - if (audioModuleInfo.lib == "libmodule-inner-capturer-sink.z.so") { - std::string idInfo = audioModuleInfo.name; - IAudioSinkAttr attr = GetAudioSinkAttr(audioModuleInfo); - ioHandle = audioServerProxy_->CreateSinkPort(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, idInfo, attr); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + ioHandle = audioServiceAdapter_->OpenAudioPort(audioModuleInfo.lib, audioModuleInfo); + paIndex = ioHandle; } else { - if (audioModuleInfo.role == HDI_AUDIO_PORT_SINK_ROLE) { - std::string idInfo = GetHdiSinkIdInfo(audioModuleInfo); + std::string identity = IPCSkeleton::ResetCallingIdentity(); + if (audioModuleInfo.lib == "libmodule-inner-capturer-sink.z.so") { + std::string idInfo = audioModuleInfo.name; IAudioSinkAttr attr = GetAudioSinkAttr(audioModuleInfo); - ioHandle = audioServerProxy_->CreateHdiSinkPort(audioModuleInfo.className, idInfo, attr); - } else if (audioModuleInfo.role == HDI_AUDIO_PORT_SOURCE_ROLE) { - std::string idInfo = GetHdiSourceIdInfo(audioModuleInfo); - IAudioSourceAttr attr = GetAudioSourceAttr(audioModuleInfo); - ioHandle = audioServerProxy_->CreateHdiSourcePort(audioModuleInfo.className, idInfo, attr); + ioHandle = audioServerProxy_->CreateSinkPort(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, idInfo, attr); + } else { + if (audioModuleInfo.role == HDI_AUDIO_PORT_SINK_ROLE) { + std::string idInfo = GetHdiSinkIdInfo(audioModuleInfo); + IAudioSinkAttr attr = GetAudioSinkAttr(audioModuleInfo); + ioHandle = audioServerProxy_->CreateHdiSinkPort(audioModuleInfo.className, idInfo, attr); + } else if (audioModuleInfo.role == HDI_AUDIO_PORT_SOURCE_ROLE) { + std::string idInfo = GetHdiSourceIdInfo(audioModuleInfo); + IAudioSourceAttr attr = GetAudioSourceAttr(audioModuleInfo); + ioHandle = audioServerProxy_->CreateHdiSourcePort(audioModuleInfo.className, idInfo, attr); + } } + IPCSkeleton::SetCallingIdentity(identity); + + paIndex = audioServiceAdapter_->OpenAudioPort(audioModuleInfo.lib, moduleArgs.c_str()); } - IPCSkeleton::SetCallingIdentity(identity); - - paIndex = audioServiceAdapter_->OpenAudioPort(audioModuleInfo.lib, moduleArgs.c_str()); AUDIO_INFO_LOG("Open %{public}u port, paIndex: %{public}u end.", ioHandle, paIndex); return ioHandle; } @@ -1232,6 +1245,34 @@ int32_t AudioAdapterManager::GetCurActivateCount() const return curActiveCount_ > 0 ? curActiveCount_ : 0; } +int32_t AudioAdapterManager::GetAudioEffectProperty(AudioEffectPropertyArrayV3 & propertyArray) const +{ + CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); + int32_t ret = 0; + AudioEffectPropertyArrayV3 effectPropertyArray = {}; + ret = audioServiceAdapter_->GetAudioEffectProperty(effectPropertyArray); + CHECK_AND_RETURN_RET_LOG(ret != nullptr, ERR_OPERATION_FAILED, "GetAudioEffectProperty failed"); + propertyArray.property.insert(propertyArray.property.end(), effectPropertyArray.property.begin(), effectPropertyArray.property.end()); + AudioEffectPropertyArrayV3 enhancePropertyArray = {}; + ret = audioServiceAdapter_->GetAudioEnhanceProperty(enhancePropertyArray); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "GetAudioEnhanceProperty failed"); + propertyArray.property.insert(propertyArray.property.end(), enhancePropertyArray.property.begin(), enhancePropertyArray.property.end()); + return ret; + +} + +int32_t AudioAdapterManager::GetAudioEffectProperty(AudioEffectPropertyArray& propertyArray) const +{ + CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); + return audioServiceAdapter_->GetAudioEffectProperty(propertyArray); +} + +int32_t AudioAdapterManager::GetAudioEnhanceProperty(AudioEnhancePropertyArray& propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) const +{ + CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); + return audioServiceAdapter_->GetAudioEffectProperty(propertyArray, deviceType); +} + void UpdateSinkArgs(const AudioModuleInfo &audioModuleInfo, std::string &args) { if (!audioModuleInfo.name.empty()) { diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index 7ad31c3e4d..b3237807ac 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -372,6 +372,9 @@ audio_ohos_library("audio_process_service") { "server/src/pa_adapter_manager.cpp", "server/src/pa_capturer_stream_impl.cpp", "server/src/pa_renderer_stream_impl.cpp", + "server/src/pro_adapter_manager.cpp", + "server/src/hpae_capturer_stream_impl.cpp", + "server/src/hpae_renderer_stream_impl.cpp", "server/src/policy_handler.cpp", "server/src/policy_provider_proxy.cpp", "server/src/pro_audio_stream_manager.cpp", @@ -392,6 +395,7 @@ audio_ohos_library("audio_process_service") { deps = [ ":audio_common", + "../audio_engine:audio_engine_manager", "../../frameworks/native/audioeffect:audio_effect", "../../frameworks/native/audioqosmanager:audio_qosmanager", "../../frameworks/native/audioschedule:audio_schedule", @@ -471,6 +475,7 @@ audio_ohos_library("audio_service") { "server/src/audio_server.cpp", "server/src/audio_server_asr.cpp", "server/src/audio_server_dump.cpp", + "server/src/audio_server_hpae_dump.cpp", "server/src/audio_server_effect.cpp", "server/src/config/audio_param_parser.cpp", ] @@ -480,6 +485,7 @@ audio_ohos_library("audio_service") { deps = [ ":audio_common", ":audio_process_service", + "../auido_engine:audio_engine_manager", "../../frameworks/native/audioeffect:audio_effect", "../../frameworks/native/audioinnercall:audio_inner_call", "../../frameworks/native/audioschedule:audio_schedule", diff --git a/services/audio_service/common/include/audio_volume_c.h b/services/audio_service/common/include/audio_volume_c.h index c498bbb720..8b6715c498 100644 --- a/services/audio_service/common/include/audio_volume_c.h +++ b/services/audio_service/common/include/audio_volume_c.h @@ -51,6 +51,8 @@ float GetStreamVolume(uint32_t sessionId); float GetPreVolume(uint32_t sessionId); +float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char* deviceClass); + void SetPreVolume(uint32_t sessionId, float volume); void GetStreamVolumeFade(uint32_t sessionId, float *fadeBegin, float *fadeEnd); diff --git a/services/audio_service/common/src/audio_volume.cpp b/services/audio_service/common/src/audio_volume.cpp index 375f3f1788..31486458d0 100644 --- a/services/audio_service/common/src/audio_volume.cpp +++ b/services/audio_service/common/src/audio_volume.cpp @@ -202,7 +202,7 @@ float AudioVolume::GetHistoryVolume(uint32_t sessionId) void AudioVolume::SetHistoryVolume(uint32_t sessionId, float volume) { - AUDIO_INFO_LOG("history volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume); + AUDIO_DEBUG_LOG("history volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume); Trace trace("AudioVolume::SetHistoryVolume sessionId:" + std::to_string(sessionId)); std::shared_lock lock(volumeMutex_); auto it = historyVolume_.find(sessionId); @@ -662,6 +662,14 @@ float GetCurVolume(uint32_t sessionId, const char *streamType, const char *devic return AudioVolume::GetInstance()->GetVolume(sessionId, stream, deviceClass, volumes); } +float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char* deviceClass) +{ + struct VolumeValues volumes; + CHECK_AND_RETURN_RET_LOG(deviceClass != nullptr, 1.0f, "deviceClass is nullptr"); + AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(staitc_cast(streamType)); + return AudioVolume::GetInstance()->GetVolume(sessionId, volumeType, deviceClass, &volumes); +} + float GetStreamVolume(uint32_t sessionId) { return AudioVolume::GetInstance()->GetStreamVolume(sessionId); diff --git a/services/audio_service/server/include/audio_endpoint_private.h b/services/audio_service/server/include/audio_endpoint_private.h index d3300373eb..b0704abd6b 100644 --- a/services/audio_service/server/include/audio_endpoint_private.h +++ b/services/audio_service/server/include/audio_endpoint_private.h @@ -39,6 +39,7 @@ public: virtual ~MockCallbacks() = default; void OnStatusUpdate(IOperation operation) override; int32_t OnWriteData(size_t length) override; + int32_t OnWriteData(int8_t* inputData, size_t requestDataLen) override; private: uint32_t streamIndex_ = 0; }; diff --git a/services/audio_service/server/include/audio_server.h b/services/audio_service/server/include/audio_server.h index 3c12e7d72e..7070b01be3 100644 --- a/services/audio_service/server/include/audio_server.h +++ b/services/audio_service/server/include/audio_server.h @@ -29,6 +29,7 @@ #include "audio_manager_base.h" #include "audio_server_death_recipient.h" #include "audio_server_dump.h" +#include "audio_server_hpae_dump.h" #include "audio_system_manager.h" #include "audio_inner_call.h" #include "common/hdi_adapter_info.h" @@ -327,6 +328,7 @@ private: std::condition_variable isAudioPolicyReadyCv_; int32_t waitCreateStreamInServerCount_ = 0; + AudioServerHpaeDump hpaeDumpObj_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/include/capturer_in_server.h b/services/audio_service/server/include/capturer_in_server.h index fbc24d913b..572ebc9e7d 100644 --- a/services/audio_service/server/include/capturer_in_server.h +++ b/services/audio_service/server/include/capturer_in_server.h @@ -32,6 +32,7 @@ public: virtual ~CapturerInServer(); void OnStatusUpdate(IOperation operation) override; int32_t OnReadData(size_t length) override; + int32_t OnReadData(std::vector& outputData, size_t requestDataLen) override; int32_t ResolveBuffer(std::shared_ptr &buffer); int32_t GetSessionId(uint32_t &sessionId); diff --git a/services/audio_service/server/include/i_capturer_stream.h b/services/audio_service/server/include/i_capturer_stream.h index 94a5683873..67f964f2e0 100644 --- a/services/audio_service/server/include/i_capturer_stream.h +++ b/services/audio_service/server/include/i_capturer_stream.h @@ -24,6 +24,7 @@ namespace AudioStandard { class IReadCallback { public: virtual int32_t OnReadData(size_t length) = 0; + virtual int32_t OnReadData(std::vector& outputData, size_t requestDataLen) = 0; }; class ICapturerStream : public IStream { diff --git a/services/audio_service/server/include/i_renderer_stream.h b/services/audio_service/server/include/i_renderer_stream.h index 6277db77c2..86c069c238 100644 --- a/services/audio_service/server/include/i_renderer_stream.h +++ b/services/audio_service/server/include/i_renderer_stream.h @@ -24,6 +24,11 @@ namespace AudioStandard { class IWriteCallback { public: virtual int32_t OnWriteData(size_t length) = 0; + virtual int32_t OnwriteData(int8_t *inputData, size_t requestDataLen); +}; + +class IStreamCallback { + virtual int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) = 0; }; class IRendererStream : public IStream { diff --git a/services/audio_service/server/src/audio_endpoint.cpp b/services/audio_service/server/src/audio_endpoint.cpp index ef9d9b0453..5923f7a0f8 100644 --- a/services/audio_service/server/src/audio_endpoint.cpp +++ b/services/audio_service/server/src/audio_endpoint.cpp @@ -178,6 +178,12 @@ int32_t MockCallbacks::OnWriteData(size_t length) return SUCCESS; } +int32_t MockCallbacks::OnWriteData(int8_t *inputData, size_t requestDataLen) +{ + Trace trace("DupStream::OnWriteData length " + std::to_string(requestDataLen)); + return SUCCESS; +} + bool AudioEndpointInner::ShouldInnerCap(int32_t innerCapId) { bool shouldBecapped = false; diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index 9b83868535..bb7e8d6fb7 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -57,6 +57,7 @@ #include "offline_stream_in_server.h" #include "audio_dump_pcm.h" #include "audio_info.h" +#include "i_hpae_manager.h" #define PA #ifdef PA @@ -304,11 +305,18 @@ int32_t AudioServer::Dump(int32_t fd, const std::vector &args) } std::string dumpString; - AudioServerDump dumpObj; - int32_t res = dumpObj.Initialize(); - CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR, - "Audio Service Dump Not initialised\n"); - dumpObj.AudioDataDump(dumpString, argQue); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + int32_t res = hpaeDumpObj_.Initialize(); + CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR, "Audio Service Hpae Dump not Initialed"); + hpaeDUmperObj_.AudioDataDUmp(dumpString, argQue); + } else { + AudioServerDump dumpObj; + int32_t res = dumpObj.Initialize(); + CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR, + "Audio Service Dump Not initialised\n"); + dumpObj.AudioDataDump(dumpString, argQue); + } return write(fd, dumpString.c_str(), dumpString.size()); } @@ -343,15 +351,21 @@ void AudioServer::OnStart() } AddSystemAbilityListener(AUDIO_POLICY_SERVICE_ID); AddSystemAbilityListener(RES_SCHED_SYS_ABILITY_ID); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + HPAE::IHpaeManager::GetHpaeManager()->Init(); + AUDIO_INFO_LOG("IHpaeManager Init\n"); + } else { #ifdef PA - int32_t ret = pthread_create(&m_paDaemonThread, nullptr, AudioServer::paDaemonThread, nullptr); - pthread_setname_np(m_paDaemonThread, "OS_PaDaemon"); - if (ret != 0) { - AUDIO_ERR_LOG("pthread_create failed %d", ret); - WriteServiceStartupError(); - } - AUDIO_DEBUG_LOG("Created paDaemonThread\n"); + int32_t ret = pthread_create(&m_paDaemonThread, nullptr, AudioServer::paDaemonThread, nullptr); + pthread_setname_np(m_paDaemonThread, "OS_PaDaemon"); + if (ret != 0) { + AUDIO_ERR_LOG("pthread_create failed %d", ret); + WriteServiceStartupError(); + } + AUDIO_DEBUG_LOG("Created paDaemonThread\n"); #endif + } RegisterAudioCapturerSourceCallback(); RegisterAudioRendererSinkCallback(); 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 7fbfb6830c..53a0835aa3 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -76,7 +76,7 @@ int32_t HpaeRendererStreamImpl::InitParams(const std::string &deviceName) streamInfo.sourceType = processConfig_.isInnerCapturer == true ? SOURCE_TYPE_PLAYBACK_CAPTURE : SOURCE_TYPE_INVALID; streamInfo.deviceName = deviceName; AUDIO_INFO_LOG("InitParams channels %{public}u end", streamInfo.channels); - AUDIO_INFO_LOG("InitParams channelLayout %{public}lu end", streamInfo.channelLayout); + AUDIO_INFO_LOG("InitParams channelLayout %{public}" PRIu64 " end", streamInfo.channelLayout); AUDIO_INFO_LOG("InitParams samplingRate %{public}u end", streamInfo.samplingRate); AUDIO_INFO_LOG("InitParams format %{public}u end", streamInfo.format); AUDIO_INFO_LOG("InitParams frameLen %{public}zu end", streamInfo.frameLen); @@ -204,7 +204,7 @@ int32_t HpaeRendererStreamImpl::GetLatency(uint64_t &latency) auto timestamp = static_cast(tm.tv_sec) * 1000000000ll + static_cast(tm.tv_nsec); auto interval = (timestamp - timestamp_) / 1000; latency = latency_ > interval ? latency_ - interval : 0; - AUDIO_DEBUG_LOG("HpaeRendererStreamImpl::GetLatency latency_ %{public}lu, interval %{public}llu latency %{public}lu", latency_, interval, latency); + AUDIO_DEBUG_LOG("HpaeRendererStreamImpl::GetLatency latency_ %{public}" PRIu64 ", interval %{public}llu latency %{public}" PRIu64, latency_, interval, latency); return SUCCESS; } diff --git a/services/audio_service/server/src/pro_adapter_manager.cpp b/services/audio_service/server/src/pro_adapter_manager.cpp index 56338294f7..b4a505199a 100644 --- a/services/audio_service/server/src/pro_adapter_manager.cpp +++ b/services/audio_service/server/src/pro_adapter_manager.cpp @@ -45,7 +45,7 @@ int32_t ProAdapterManager::CreateRender(AudioProcessConfig processConfig, std::s uint32_t sessionId = 0; sessionId = processConfig.originalSessionId; if (managerType_ == DUP_PLAYBACK || - processConfig.originalSessionId < MIN_SESSIONID || processConfig.originalSessionId > MAX_SESSIONID) { + processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_STREAMID) { sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid); AUDIO_ERR_LOG("Create [%{public}d] type renderer:[%{public}u] error", managerType_, processConfig.originalSessionId); @@ -194,7 +194,7 @@ int32_t ProAdapterManager::CreateCapturer(AudioProcessConfig processConfig, std: AUDIO_DEBUG_LOG("Create capturer start"); CHECK_AND_RETURN_RET_LOG(managerType_ == RECORDER, ERROR, "Invalid managerType:%{public}d", managerType_); uint32_t sessionId = 0; - if (processConfig.originalSessionId < MIN_SESSIONID || processConfig.originalSessionId > MAX_SESSIONID) { + if (processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_SSTREAMID) { sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid); AUDIO_ERR_LOG("Create capturer originalSessionId is error %{public}d", processConfig.originalSessionId); } else { diff --git a/test/BUILD.gn b/test/BUILD.gn index c6f234560c..112da9db70 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -71,6 +71,8 @@ group("audio_unit_test") { "../frameworks/native/ohaudio/test/unittest/oh_audio_routing_manager_test:audio_oh_routing_manager_unit_test", "../frameworks/native/ohaudio/test/unittest/oh_audio_stream_builder_test:audio_oh_builder_unit_test", "../frameworks/native/toneplayer/test/unittest:audio_toneplayer_unit_test", + "../frameworks/native/audioadapter/test/unittest::pro_auido_service_adapter_unit_test", + "../services/audio_engine/test/unittest::audio_engine_unit_test", "../services/audio_policy/test:audio_policy_unittest_packages", "../services/audio_service/test/unittest:audio_balance_unit_test", "../services/audio_service/test/unittest:audio_dump_pcm_unit_test", -- Gitee From 359d6c265a359463dd98803653366a5598eb4e3d Mon Sep 17 00:00:00 2001 From: c00657214 Date: Sat, 12 Apr 2025 18:44:23 +0800 Subject: [PATCH 06/40] sync change in frameworks folder, bugfix Signed-off-by: c00657214 --- .../native/audioadapter/include/audio_service_adapter.h | 4 ++-- .../audioadapter/src/pulse_audio_service_adapter_impl.cpp | 2 +- .../native/audioeffect/include/audio_effect_chain_manager.h | 1 - .../native/hdiadapter/sink/common/i_audio_renderer_sink.h | 2 +- .../inner_api/native/audiocommon/include/audio_stream_info.h | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/frameworks/native/audioadapter/include/audio_service_adapter.h b/frameworks/native/audioadapter/include/audio_service_adapter.h index e4ad87f33b..124ba367a1 100644 --- a/frameworks/native/audioadapter/include/audio_service_adapter.h +++ b/frameworks/native/audioadapter/include/audio_service_adapter.h @@ -43,7 +43,7 @@ public: * @param cb callback reference for AudioServiceAdapterCallback class * @return Returns instance of class that extends AudioServiceAdapter */ - static std::shared_ptrudioServiceAdapter> CreateAudioAdapter(std::unique_ptr cb); + static std::shared_ptr CreateAudioAdapter(std::unique_ptr cb); /** * @brief Connect to underlining audio server @@ -206,7 +206,7 @@ public: * * @return int32_t the result. */ - virtual int32_t GetAudioEnhanceProperty(AudioEffectPropertyArray &propertyArray, + virtual int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; virtual ~AudioServiceAdapter(); diff --git a/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp index 3f0f4f194f..811addef60 100644 --- a/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp +++ b/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp @@ -165,7 +165,7 @@ Fail: return false; } -int32_t PulseAudioServiceAdapterImpl::OpenAudioPort(std::string audioPortName, const AudioModuleInfo& audioModuleInfo) +int32_t PulseAudioServiceAdapterImpl::OpenAudioPort(string audioPortName, const AudioModuleInfo& audioModuleInfo) { AUDIO_PRERELEASE_LOGE("OpenAudioPort enter the INCORRECT func."); return 0; diff --git a/frameworks/native/audioeffect/include/audio_effect_chain_manager.h b/frameworks/native/audioeffect/include/audio_effect_chain_manager.h index 1d06066793..96d3358a96 100644 --- a/frameworks/native/audioeffect/include/audio_effect_chain_manager.h +++ b/frameworks/native/audioeffect/include/audio_effect_chain_manager.h @@ -143,7 +143,6 @@ public: int32_t ReturnMultiChannelInfo(uint32_t *channels, uint64_t *channelLayout); int32_t EffectRotationUpdate(const uint32_t rotationState); int32_t EffectVolumeUpdate(); - int32_t EffectVolumeUpdate(std::shared_ptr audioEffectVolume); int32_t StreamVolumeUpdate(const std::string sessionIDString, const float streamVolume); uint32_t GetLatency(const std::string &sessionId); int32_t SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType); diff --git a/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h b/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h index 6071ce7a1e..c7da697da7 100644 --- a/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h +++ b/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h @@ -130,7 +130,7 @@ public: virtual int32_t RegisterRenderCallback(OnRenderCallback (*callback), int8_t *userdata) { return 0; } virtual int32_t Drain(AudioDrainType type) { return 0; } virtual int32_t SetBufferSize(uint32_t sizeMs) { return 0; } - + virtual int32_t OffloadRunningLockInit(void) { return 0; } virtual int32_t OffloadRunningLockLock(void) { return 0; } virtual int32_t OffloadRunningLockUnlock(void) { return 0; } diff --git a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h index 9b0d48def9..db72d5394a 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h @@ -599,7 +599,7 @@ struct AudioCallBackStreamInfo { }; struct AudioChannelInfo { - AudioChannelLayOut channelLayout; + AudioChannelLayout channelLayout; uint32_t numChannels; }; -- Gitee From c724c2336455ed71d7f076a53ad4a9d1c8ec056c Mon Sep 17 00:00:00 2001 From: c00657214 Date: Sat, 12 Apr 2025 18:48:34 +0800 Subject: [PATCH 07/40] sync change in frameworks folder, bugfix2 Signed-off-by: c00657214 --- .../pulse_audio_service_adapter_impl.h | 2 +- .../audioadapter/test/unittest/BUILD.gn | 50 +++++++++---------- .../src/audio_effect_chain_manager.cpp | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h index 0d5f0778b0..681cf6de10 100644 --- a/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h +++ b/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h @@ -53,7 +53,7 @@ public: int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) override { return 0; } int32_t GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override { return 0; } - int32_t GetAudioEnhanceProperty(AudioEffectPropertyArray &propertyArray, + int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override { return 0; } // Static Member functions diff --git a/frameworks/native/audioadapter/test/unittest/BUILD.gn b/frameworks/native/audioadapter/test/unittest/BUILD.gn index 1ff921a681..d4fa5f20a4 100644 --- a/frameworks/native/audioadapter/test/unittest/BUILD.gn +++ b/frameworks/native/audioadapter/test/unittest/BUILD.gn @@ -21,17 +21,17 @@ config("audio_engine_private_config") { visibility = [ ":*" ] include_dirs = [ - "../../../audioutils/include", - "../../../../../interfaces/inner_api/native/audiocommon/include", - "../../../../../services/audio_service/server/include", - "../../../hdiadapter/common/include", - "../../../hdiadapter/sink/common", - "../../../hdiadapter/source/common", - "../../../../../services/audio_policy/server/include/service/common", - "../../../../../services/audio_engine/manager/include", - "../../../../../services/audio_service/common/include", - "./include", - "../../include" + "../../../audioutils/include", + "../../../../../interfaces/inner_api/native/audiocommon/include", + "../../../../../services/audio_service/server/include", + "../../../hdiadapter/common/include", + "../../../hdiadapter/sink/common", + "../../../hdiadapter/source/common", + "../../../../../services/audio_policy/server/include/service/common", + "../../../../../services/audio_engine/manager/include", + "../../../../../services/audio_service/common/include", + "./include", + "../../include" ] } @@ -40,30 +40,30 @@ ohos_unittest("pro_audio_service_adapter_unit_test") { module_out_path = module_output_path testonly = true cflags = [ - "-Wall", - "-Werror", - "-fno-access-control", + "-Wall", + "-Werror", + "-fno-access-control", ] sources = [ - "src/pro_audio_service_adapter_unit_test.cpp", + "src/pro_audio_service_adapter_unit_test.cpp", ] configs = [ ":audio_engine_private_config" ] deps = [ - "../../../audioutils:audio_utils", - "../../../../../services/audio_engine:audio_engine_manager", - "../../:pulse_audio_service_adapter", + "../../../audioutils:audio_utils", + "../../../../../services/audio_engine:audio_engine_manager", + "../../:pulse_audio_service_adapter", ] external_deps = [ - "c_utils:utils", - "googletest:gtest", - "hilog:libhilog", - "hisysevent:libhisysevent", - "ipc:ipc_single", - "safwk:system_ability_fwk", - "samgr:samgr_proxy", + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", ] } diff --git a/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp b/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp index 01b841f392..4aab832921 100644 --- a/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp +++ b/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp @@ -1771,7 +1771,7 @@ ProcessClusterOperation AudioEffectChainManager::CheckProcessClusterInstances(co sceneTypeToEffectChainCountMap_[sceneTypeAndDeviceKey], defaultEffectChainCount_); if (isDefaultEffectChainExisted_ && sceneTypeToEffectChainMap_[sceneTypeAndDeviceKey] == sceneTypeToEffectChainMap_[defaultSceneTypeAndDeviceKey]) { - return USE_DEFAULT_PROCESSCLUSTER; + return USE_DEFAULT_PROCESSCLUSTER; } return NO_NEED_TO_CREATE_PROCESSCLUSTER; } -- Gitee From 727fff49355c926dc42efa6f9f2e4280a0215c97 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Sat, 12 Apr 2025 18:49:42 +0800 Subject: [PATCH 08/40] sync change in frameworks folder, bugfix3 Signed-off-by: c00657214 --- frameworks/native/audioadapter/test/unittest/BUILD.gn | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frameworks/native/audioadapter/test/unittest/BUILD.gn b/frameworks/native/audioadapter/test/unittest/BUILD.gn index d4fa5f20a4..1052901e77 100644 --- a/frameworks/native/audioadapter/test/unittest/BUILD.gn +++ b/frameworks/native/audioadapter/test/unittest/BUILD.gn @@ -48,7 +48,7 @@ ohos_unittest("pro_audio_service_adapter_unit_test") { "src/pro_audio_service_adapter_unit_test.cpp", ] - configs = [ ":audio_engine_private_config" ] + configs = [ ":audio_engine_private_config" ] deps = [ "../../../audioutils:audio_utils", @@ -65,5 +65,4 @@ ohos_unittest("pro_audio_service_adapter_unit_test") { "safwk:system_ability_fwk", "samgr:samgr_proxy", ] -} - +} \ No newline at end of file -- Gitee From 24a9de768aba19f93f1dd83865c7b7f2473ba25e Mon Sep 17 00:00:00 2001 From: c00657214 Date: Mon, 14 Apr 2025 22:12:33 +0800 Subject: [PATCH 09/40] sync change in test folder Signed-off-by: c00657214 --- test/BUILD.gn | 2 +- test/fuzztest/audioeffect_fuzzer/audio_effect_fuzzer.cpp | 1 - .../audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp | 1 - test/fuzztest/audiopolicy_fuzzer/audio_policy_fuzzer.cpp | 1 + 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/BUILD.gn b/test/BUILD.gn index 112da9db70..970f17d525 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -71,7 +71,7 @@ group("audio_unit_test") { "../frameworks/native/ohaudio/test/unittest/oh_audio_routing_manager_test:audio_oh_routing_manager_unit_test", "../frameworks/native/ohaudio/test/unittest/oh_audio_stream_builder_test:audio_oh_builder_unit_test", "../frameworks/native/toneplayer/test/unittest:audio_toneplayer_unit_test", - "../frameworks/native/audioadapter/test/unittest::pro_auido_service_adapter_unit_test", + "../frameworks/native/audioadapter/test/unittest::pro_audio_service_adapter_unit_test", "../services/audio_engine/test/unittest::audio_engine_unit_test", "../services/audio_policy/test:audio_policy_unittest_packages", "../services/audio_service/test/unittest:audio_balance_unit_test", diff --git a/test/fuzztest/audioeffect_fuzzer/audio_effect_fuzzer.cpp b/test/fuzztest/audioeffect_fuzzer/audio_effect_fuzzer.cpp index bd99431241..0acb03dce9 100644 --- a/test/fuzztest/audioeffect_fuzzer/audio_effect_fuzzer.cpp +++ b/test/fuzztest/audioeffect_fuzzer/audio_effect_fuzzer.cpp @@ -50,7 +50,6 @@ SessionEffectInfo DEFAULT_INFO = { SCENETYPEDEFAULT, INFOCHANNELS, INFOCHANNELLAYOUT, - "0", }; /* diff --git a/test/fuzztest/audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp b/test/fuzztest/audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp index 77cf8b095c..3985a5d9de 100644 --- a/test/fuzztest/audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp +++ b/test/fuzztest/audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp @@ -141,7 +141,6 @@ void AudioEffectChainManagerEnhanceFuzzTest() "SCENE_MOVIE", INFOCHANNELS, INFOCHANNELLAYOUT, - "0", }; AudioEffectChainManager::GetInstance()->sessionIDToEffectInfoMap_[sessionID] = sessionEffectInfo; diff --git a/test/fuzztest/audiopolicy_fuzzer/audio_policy_fuzzer.cpp b/test/fuzztest/audiopolicy_fuzzer/audio_policy_fuzzer.cpp index 75f4509334..009a1aaf2f 100644 --- a/test/fuzztest/audiopolicy_fuzzer/audio_policy_fuzzer.cpp +++ b/test/fuzztest/audiopolicy_fuzzer/audio_policy_fuzzer.cpp @@ -48,6 +48,7 @@ typedef void (*TestPtr)(const uint8_t *, size_t); sptr GetServerPtr() { static sptr server = sptr::MakeSptr(SYSTEM_ABILITY_ID, RUN_ON_CREATE); + server->ConnectServiceAdapter(); if (!g_hasServerInit) { server->OnStart(); server->OnAddSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID, ""); -- Gitee From 33497aa6ae53e10d9e84811464a0bcb9ffb77ca8 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 08:34:26 +0800 Subject: [PATCH 10/40] sync change in node folder Signed-off-by: c00657214 --- services/audio_engine/node/src/hpae_mixer_node.cpp | 1 + .../audio_engine/node/src/hpae_offload_sinkoutput_node.cpp | 3 ++- services/audio_engine/node/src/hpae_sink_input_node.cpp | 3 ++- services/audio_engine/node/src/hpae_sink_output_node.cpp | 3 +-- test/BUILD.gn | 4 ++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/services/audio_engine/node/src/hpae_mixer_node.cpp b/services/audio_engine/node/src/hpae_mixer_node.cpp index 67ae097cc4..41c2f5d6dc 100644 --- a/services/audio_engine/node/src/hpae_mixer_node.cpp +++ b/services/audio_engine/node/src/hpae_mixer_node.cpp @@ -20,6 +20,7 @@ #include "hpae_pcm_buffer.h" #include "audio_utils.h" #include "cinttypes" + namespace OHOS { namespace AudioStandard { namespace HPAE { diff --git a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp index b872e9d952..374499e47c 100644 --- a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp +++ b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp @@ -484,8 +484,9 @@ uint64_t HpaeOffloadSinkOutputNode::CalcOffloadCacheLenInHdi() void HpaeOffloadSinkOutputNode::OffloadSetHdiVolume() { + struct VolumeValues volumes; AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(GetStreamType()); - float volumeEnd = AudioVolume::GetInstance()->GetVolume(GetSessionId(), volumeType, DEVICE_CLASS_OFFLOAD); + float volumeEnd = AudioVolume::GetInstance()->GetVolume(GetSessionId(), volumeType, DEVICE_CLASS_OFFLOAD, &volumes); float volumeBeg = AudioVolume::GetInstance()->GetHistoryVolume(GetSessionId()); if (volumeBeg != volumeEnd) { AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode::sessionID:%{public}u, volumeBeg:%{public}f, volumeEnd:%{public}f", diff --git a/services/audio_engine/node/src/hpae_sink_input_node.cpp b/services/audio_engine/node/src/hpae_sink_input_node.cpp index 5eefc757f7..0ca1b86b62 100644 --- a/services/audio_engine/node/src/hpae_sink_input_node.cpp +++ b/services/audio_engine/node/src/hpae_sink_input_node.cpp @@ -24,6 +24,7 @@ #include "audio_engine_log.h" #include "audio_errors.h" #include "audio_utils.h" +#include "cinttypes" namespace OHOS { namespace AudioStandard { @@ -38,7 +39,7 @@ HpaeSinkInputNode::HpaeSinkInputNode(HpaeNodeInfo &nodeInfo) interleveData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), framesWritten_(0), totalFrames_(0) { - AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}lu, " + AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}" PRIu64 ", " "frameLen %{public}d", nodeInfo.sessionId, inputAudioBuffer_.GetChannelCount(), inputAudioBuffer_.GetChannelLayout(), inputAudioBuffer_.GetFrameLen()); diff --git a/services/audio_engine/node/src/hpae_sink_output_node.cpp b/services/audio_engine/node/src/hpae_sink_output_node.cpp index f26561dc39..2343ed6ba8 100644 --- a/services/audio_engine/node/src/hpae_sink_output_node.cpp +++ b/services/audio_engine/node/src/hpae_sink_output_node.cpp @@ -309,8 +309,7 @@ int32_t HpaeSinkOutputNode::RenderSinkStop(void) timer.Stop(); uint64_t interval = timer.Elapsed(); AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkStop Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), - interval); + sinkOutAttr_.adapterName.c_str(), interval); #endif state_ = RENDERER_STOPPED; return SUCCESS; diff --git a/test/BUILD.gn b/test/BUILD.gn index 970f17d525..8a5fcb82af 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -71,8 +71,8 @@ group("audio_unit_test") { "../frameworks/native/ohaudio/test/unittest/oh_audio_routing_manager_test:audio_oh_routing_manager_unit_test", "../frameworks/native/ohaudio/test/unittest/oh_audio_stream_builder_test:audio_oh_builder_unit_test", "../frameworks/native/toneplayer/test/unittest:audio_toneplayer_unit_test", - "../frameworks/native/audioadapter/test/unittest::pro_audio_service_adapter_unit_test", - "../services/audio_engine/test/unittest::audio_engine_unit_test", + "../frameworks/native/audioadapter/test/unittest:pro_audio_service_adapter_unit_test", + "../services/audio_engine/test/unittest:audio_engine_unit_test", "../services/audio_policy/test:audio_policy_unittest_packages", "../services/audio_service/test/unittest:audio_balance_unit_test", "../services/audio_service/test/unittest:audio_dump_pcm_unit_test", -- Gitee From b9fd17a5a40f2708a173117ba88a5161f2b73ffa Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 08:53:53 +0800 Subject: [PATCH 11/40] sync change in audio_service folder Signed-off-by: c00657214 --- .../node/src/hpae_sinkInput_node.cpp | 4 +-- .../channel_converter/src/down_mixer.cpp | 2 +- .../proresampler/audio_proresampler.cpp | 1 + .../interface/iaudio_policy_interface.h | 7 +++--- .../service/manager/audio_adapter_manager.h | 7 +++--- .../src/service/audio_policy_service.cpp | 6 ++--- .../service/manager/audio_adapter_manager.cpp | 25 +++++++++++-------- .../common/include/audio_volume_c.h | 4 +-- .../audio_service/common/src/audio_volume.cpp | 4 +-- .../server/include/audio_endpoint_private.h | 2 +- .../include/hpae_capturer_stream_impl.h | 2 +- .../include/hpae_renderer_stream_impl.h | 2 +- .../server/include/i_renderer_stream.h | 3 ++- .../audio_service/server/src/audio_server.cpp | 6 ++--- .../server/src/pro_adapter_manager.cpp | 2 +- 15 files changed, 43 insertions(+), 34 deletions(-) diff --git a/services/audio_engine/node/src/hpae_sinkInput_node.cpp b/services/audio_engine/node/src/hpae_sinkInput_node.cpp index 53a14724c8..d12359ca29 100644 --- a/services/audio_engine/node/src/hpae_sinkInput_node.cpp +++ b/services/audio_engine/node/src/hpae_sinkInput_node.cpp @@ -22,7 +22,7 @@ #include "hpae_node_common.h" #include "audio_engine_log.h" #include "audio_errors.h" -#include "cinttypes" + namespace OHOS { namespace AudioStandard { namespace HPAE { @@ -36,7 +36,7 @@ HpaeSinkInputNode::HpaeSinkInputNode(HpaeNodeInfo &nodeInfo) interleveData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), framesWritten_(0), totalFrames_(0) { - AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}" PRIu64", " + AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}" PRIu64 ", " "frameLen %{public}d", nodeInfo.sessionId, inputAudioBuffer_.GetChannelCount(), inputAudioBuffer_.GetChannelLayout(), inputAudioBuffer_.GetFrameLen()); 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 828f654a24..bff518c98c 100644 --- a/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp +++ b/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp @@ -144,7 +144,7 @@ int32_t DownMixer::SetupDownMixTable() if ((!isValidChLayout(inLayout_, inChannels_)) || (!isValidChLayout(outLayout_, outChannels_)) || inLayout_ == outLayout_ || inChannels_ <= outChannels_) { AUDIO_ERR_LOG("invalid input or output channellayout: input channel count %{public}d, " - "inLayout_ %{public}" PRIu64 ". output channel count %{public}d, outLayout_ %{public}" PRIu64 "", + "inLayout_ %{public}" PRIu64 "output channel count %{public}d, outLayout_ %{public}" PRIu64 "", inChannels_, inLayout_, outChannels_, outLayout_); return DMIX_ERR_INVALID_ARG; } diff --git a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp index 3672f16d98..8d0ad5773a 100644 --- a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp +++ b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp @@ -15,6 +15,7 @@ #include "audio_proresampler.h" #include "audio_policy_log.h" #include "securec.h" + namespace OHOS { namespace AudioStandard { namespace HPAE { diff --git a/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h b/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h index 08e80b5421..f2ef23aa64 100644 --- a/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h +++ b/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h @@ -188,11 +188,12 @@ public: virtual int32_t SetDoubleRingVolumeDb(const AudioStreamType &streamType, const int32_t &volumeLevel) = 0; - virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 & propertyArray) const = 0; + virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) const = 0; - virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArray& propertyArray) const = 0; + virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) const = 0; - virtual int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray& propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) const = 0; + virtual int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) const = 0; virtual void SetDeviceSafeVolume(const AudioStreamType streamType, const int32_t volumeLevel) = 0; diff --git a/services/audio_policy/server/include/service/manager/audio_adapter_manager.h b/services/audio_policy/server/include/service/manager/audio_adapter_manager.h index e3f4f94897..3266fda1e6 100644 --- a/services/audio_policy/server/include/service/manager/audio_adapter_manager.h +++ b/services/audio_policy/server/include/service/manager/audio_adapter_manager.h @@ -251,11 +251,12 @@ public: std::vector GetStreamVolumeInfo(AdjustStreamVolume volumeType); - int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 & propertyArray) const; + int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) const; - int32_t GetAudioEffectProperty(AudioEffectPropertyArray& propertyArray) const; + int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) const; - int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray& propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) const; + int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) const; void SetDeviceSafeVolume(const AudioStreamType streamType, const int32_t volumeLevel); 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 2878ccc48f..01545f1820 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -1886,7 +1886,7 @@ int32_t AudioPolicyService::GetAudioEffectProperty(AudioEffectPropertyArray &pro int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { return audioPolicyManager_->GetAudioEffectProperty(propertyArray); - else { + } else { return AudioServerProxy::GetInstance().GetAudioEffectPropertyProxy(propertyArray); } } @@ -1924,8 +1924,8 @@ int32_t AudioPolicyService::GetAudioEnhancePropertyByDevice(DeviceType deviceTyp { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return audioPolicyManager_->GetAudioEffectProperty(propertyArray, deviceType); - else { + return audioPolicyManager_->GetAudioEnhanceProperty(propertyArray, deviceType); + } else { return AudioServerProxy::GetInstance().GetAudioEnhancePropertyProxy(propertyArray, deviceType); } } diff --git a/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp b/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp index 3e4c1aea30..90e6f23715 100644 --- a/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp +++ b/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp @@ -1060,6 +1060,7 @@ AudioIOHandle AudioAdapterManager::OpenAudioPort(std::shared_ptr AUDIO_INFO_LOG("Adapter load-module %{public}s, route flag: %{public}u", moduleArgs.c_str(), pipeInfo->routeFlag_); curActiveCount_++; AudioIOHandle ioHandle = HDI_INVALID_ID; + int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { ioHandle = audioServiceAdapter_->OpenAudioPort(pipeInfo->moduleInfo_.lib, pipeInfo->moduleInfo_); @@ -1070,7 +1071,7 @@ AudioIOHandle AudioAdapterManager::OpenAudioPort(std::shared_ptr AUDIO_INFO_LOG("Is pa route"); return OpenPaAudioPort(pipeInfo, paIndex, moduleArgs); } - + AUDIO_INFO_LOG("Not pa route"); return OpenNotPaAudioPort(pipeInfo, paIndex); } @@ -1195,6 +1196,7 @@ AudioIOHandle AudioAdapterManager::OpenAudioPort(const AudioModuleInfo &audioMod curActiveCount_++; AudioIOHandle ioHandle = HDI_INVALID_ID; CHECK_AND_RETURN_RET_LOG(audioServerProxy_ != nullptr, ioHandle, "audioServerProxy_ null"); + int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { ioHandle = audioServiceAdapter_->OpenAudioPort(audioModuleInfo.lib, audioModuleInfo); @@ -1217,9 +1219,10 @@ AudioIOHandle AudioAdapterManager::OpenAudioPort(const AudioModuleInfo &audioMod } } IPCSkeleton::SetCallingIdentity(identity); - + paIndex = audioServiceAdapter_->OpenAudioPort(audioModuleInfo.lib, moduleArgs.c_str()); } + AUDIO_INFO_LOG("Open %{public}u port, paIndex: %{public}u end.", ioHandle, paIndex); return ioHandle; } @@ -1245,32 +1248,34 @@ int32_t AudioAdapterManager::GetCurActivateCount() const return curActiveCount_ > 0 ? curActiveCount_ : 0; } -int32_t AudioAdapterManager::GetAudioEffectProperty(AudioEffectPropertyArrayV3 & propertyArray) const +int32_t AudioAdapterManager::GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) const { CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); int32_t ret = 0; AudioEffectPropertyArrayV3 effectPropertyArray = {}; ret = audioServiceAdapter_->GetAudioEffectProperty(effectPropertyArray); - CHECK_AND_RETURN_RET_LOG(ret != nullptr, ERR_OPERATION_FAILED, "GetAudioEffectProperty failed"); - propertyArray.property.insert(propertyArray.property.end(), effectPropertyArray.property.begin(), effectPropertyArray.property.end()); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "GetAudioEffectProperty failed"); + propertyArray.property.insert(propertyArray.property.end(), + effectPropertyArray.property.begin(), effectPropertyArray.property.end()); AudioEffectPropertyArrayV3 enhancePropertyArray = {}; ret = audioServiceAdapter_->GetAudioEnhanceProperty(enhancePropertyArray); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "GetAudioEnhanceProperty failed"); - propertyArray.property.insert(propertyArray.property.end(), enhancePropertyArray.property.begin(), enhancePropertyArray.property.end()); + propertyArray.property.insert(propertyArray.property.end(), + enhancePropertyArray.property.begin(), enhancePropertyArray.property.end()); return ret; - } -int32_t AudioAdapterManager::GetAudioEffectProperty(AudioEffectPropertyArray& propertyArray) const +int32_t AudioAdapterManager::GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) const { CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); return audioServiceAdapter_->GetAudioEffectProperty(propertyArray); } -int32_t AudioAdapterManager::GetAudioEnhanceProperty(AudioEnhancePropertyArray& propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) const +int32_t AudioAdapterManager::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, + DeviceType deviceType = DEVICE_TYPE_NONE) const { CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); - return audioServiceAdapter_->GetAudioEffectProperty(propertyArray, deviceType); + return audioServiceAdapter_->GetAudioEnhanceProperty(propertyArray, deviceType); } void UpdateSinkArgs(const AudioModuleInfo &audioModuleInfo, std::string &args) diff --git a/services/audio_service/common/include/audio_volume_c.h b/services/audio_service/common/include/audio_volume_c.h index 8b6715c498..dd68ea4cae 100644 --- a/services/audio_service/common/include/audio_volume_c.h +++ b/services/audio_service/common/include/audio_volume_c.h @@ -49,10 +49,10 @@ float GetCurVolume(uint32_t sessionId, const char *streamType, const char *devic float GetStreamVolume(uint32_t sessionId); -float GetPreVolume(uint32_t sessionId); - float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char* deviceClass); +float GetPreVolume(uint32_t sessionId); + void SetPreVolume(uint32_t sessionId, float volume); void GetStreamVolumeFade(uint32_t sessionId, float *fadeBegin, float *fadeEnd); diff --git a/services/audio_service/common/src/audio_volume.cpp b/services/audio_service/common/src/audio_volume.cpp index 31486458d0..bfa855a445 100644 --- a/services/audio_service/common/src/audio_volume.cpp +++ b/services/audio_service/common/src/audio_volume.cpp @@ -662,11 +662,11 @@ float GetCurVolume(uint32_t sessionId, const char *streamType, const char *devic return AudioVolume::GetInstance()->GetVolume(sessionId, stream, deviceClass, volumes); } -float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char* deviceClass) +float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char *deviceClass) { struct VolumeValues volumes; CHECK_AND_RETURN_RET_LOG(deviceClass != nullptr, 1.0f, "deviceClass is nullptr"); - AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(staitc_cast(streamType)); + AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(static_cast(streamType)); return AudioVolume::GetInstance()->GetVolume(sessionId, volumeType, deviceClass, &volumes); } diff --git a/services/audio_service/server/include/audio_endpoint_private.h b/services/audio_service/server/include/audio_endpoint_private.h index b0704abd6b..bd8071dda7 100644 --- a/services/audio_service/server/include/audio_endpoint_private.h +++ b/services/audio_service/server/include/audio_endpoint_private.h @@ -39,7 +39,7 @@ public: virtual ~MockCallbacks() = default; void OnStatusUpdate(IOperation operation) override; int32_t OnWriteData(size_t length) override; - int32_t OnWriteData(int8_t* inputData, size_t requestDataLen) override; + int32_t OnWriteData(int8_t *inputData, size_t requestDataLen) override; private: uint32_t streamIndex_ = 0; }; diff --git a/services/audio_service/server/include/hpae_capturer_stream_impl.h b/services/audio_service/server/include/hpae_capturer_stream_impl.h index 1bc9145093..1fb97b5e56 100644 --- a/services/audio_service/server/include/hpae_capturer_stream_impl.h +++ b/services/audio_service/server/include/hpae_capturer_stream_impl.h @@ -45,7 +45,7 @@ public: void SetStreamIndex(uint32_t index) override; uint32_t GetStreamIndex() override; int32_t DropBuffer() override; - void AbortCallback(int32_t abortTimes) override; + void AbortCallback(int32_t abortTimes); private: diff --git a/services/audio_service/server/include/hpae_renderer_stream_impl.h b/services/audio_service/server/include/hpae_renderer_stream_impl.h index f585a8c6fe..6166ce23dc 100644 --- a/services/audio_service/server/include/hpae_renderer_stream_impl.h +++ b/services/audio_service/server/include/hpae_renderer_stream_impl.h @@ -53,7 +53,7 @@ public: void GetSpanSizePerFrame(size_t &spanSizeInFrame) const override; void SetStreamIndex(uint32_t index) override; uint32_t GetStreamIndex() override; - void AbortCallback(int32_t abortTimes) override; + void AbortCallback(int32_t abortTimes); // offload int32_t SetOffloadMode(int32_t state, bool isAppBack) override; int32_t UnsetOffloadMode() override; diff --git a/services/audio_service/server/include/i_renderer_stream.h b/services/audio_service/server/include/i_renderer_stream.h index 86c069c238..f5f882dfc2 100644 --- a/services/audio_service/server/include/i_renderer_stream.h +++ b/services/audio_service/server/include/i_renderer_stream.h @@ -24,10 +24,11 @@ namespace AudioStandard { class IWriteCallback { public: virtual int32_t OnWriteData(size_t length) = 0; - virtual int32_t OnwriteData(int8_t *inputData, size_t requestDataLen); + virtual int32_t OnWriteData(int8_t *inputData, size_t requestDataLen) = 0; }; class IStreamCallback { +public: virtual int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) = 0; }; diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index bb7e8d6fb7..9867ced13c 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -304,12 +304,12 @@ int32_t AudioServer::Dump(int32_t fd, const std::vector &args) argQue.push(args[index]); } std::string dumpString; - int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { int32_t res = hpaeDumpObj_.Initialize(); - CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR, "Audio Service Hpae Dump not Initialed"); - hpaeDUmperObj_.AudioDataDUmp(dumpString, argQue); + CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR, + "Audio Service Hpae Dump not Initialed"); + hpaeDumpObj_.AudioDataDump(dumpString, argQue); } else { AudioServerDump dumpObj; int32_t res = dumpObj.Initialize(); diff --git a/services/audio_service/server/src/pro_adapter_manager.cpp b/services/audio_service/server/src/pro_adapter_manager.cpp index b4a505199a..20b9938224 100644 --- a/services/audio_service/server/src/pro_adapter_manager.cpp +++ b/services/audio_service/server/src/pro_adapter_manager.cpp @@ -194,7 +194,7 @@ int32_t ProAdapterManager::CreateCapturer(AudioProcessConfig processConfig, std: AUDIO_DEBUG_LOG("Create capturer start"); CHECK_AND_RETURN_RET_LOG(managerType_ == RECORDER, ERROR, "Invalid managerType:%{public}d", managerType_); uint32_t sessionId = 0; - if (processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_SSTREAMID) { + if (processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_STREAMID) { sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid); AUDIO_ERR_LOG("Create capturer originalSessionId is error %{public}d", processConfig.originalSessionId); } else { -- Gitee From ff0aa3931d4a299590d29439078075f302f90a4d Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 11:54:28 +0800 Subject: [PATCH 12/40] sync change in audio_service folder, patchset2 Signed-off-by: c00657214 --- .../interface/iaudio_policy_interface.h | 2 +- .../service/manager/audio_adapter_manager.h | 2 +- .../src/service/audio_policy_service.cpp | 4 ++-- .../service/manager/audio_adapter_manager.cpp | 2 +- .../common/include/audio_volume_c.h | 2 +- .../server/include/renderer_in_server.h | 21 ++++++++++++++++++- .../audio_service/server/src/audio_server.cpp | 2 +- 7 files changed, 27 insertions(+), 8 deletions(-) diff --git a/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h b/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h index f2ef23aa64..43331fff40 100644 --- a/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h +++ b/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h @@ -193,7 +193,7 @@ public: virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) const = 0; virtual int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, - DeviceType deviceType = DEVICE_TYPE_NONE) const = 0; + DeviceType deviceType = DEVICE_TYPE_NONE) const = 0; virtual void SetDeviceSafeVolume(const AudioStreamType streamType, const int32_t volumeLevel) = 0; diff --git a/services/audio_policy/server/include/service/manager/audio_adapter_manager.h b/services/audio_policy/server/include/service/manager/audio_adapter_manager.h index 3266fda1e6..e7b46b1dfc 100644 --- a/services/audio_policy/server/include/service/manager/audio_adapter_manager.h +++ b/services/audio_policy/server/include/service/manager/audio_adapter_manager.h @@ -250,7 +250,7 @@ public: std::shared_ptr GetAllDeviceVolumeInfo(DeviceType deviceType, AudioStreamType streamType); std::vector GetStreamVolumeInfo(AdjustStreamVolume volumeType); - + int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) const; int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) const; 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 01545f1820..94b3724e52 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -1885,7 +1885,7 @@ int32_t AudioPolicyService::GetAudioEffectProperty(AudioEffectPropertyArray &pro { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return audioPolicyManager_->GetAudioEffectProperty(propertyArray); + return audioPolicyManager_.GetAudioEffectProperty(propertyArray); } else { return AudioServerProxy::GetInstance().GetAudioEffectPropertyProxy(propertyArray); } @@ -1924,7 +1924,7 @@ int32_t AudioPolicyService::GetAudioEnhancePropertyByDevice(DeviceType deviceTyp { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return audioPolicyManager_->GetAudioEnhanceProperty(propertyArray, deviceType); + return audioPolicyManager_.GetAudioEnhanceProperty(propertyArray, deviceType); } else { return AudioServerProxy::GetInstance().GetAudioEnhancePropertyProxy(propertyArray, deviceType); } diff --git a/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp b/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp index 90e6f23715..f12b0a240f 100644 --- a/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp +++ b/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp @@ -1272,7 +1272,7 @@ int32_t AudioAdapterManager::GetAudioEffectProperty(AudioEffectPropertyArray &pr } int32_t AudioAdapterManager::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, - DeviceType deviceType = DEVICE_TYPE_NONE) const + DeviceType deviceType) const { CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); return audioServiceAdapter_->GetAudioEnhanceProperty(propertyArray, deviceType); diff --git a/services/audio_service/common/include/audio_volume_c.h b/services/audio_service/common/include/audio_volume_c.h index dd68ea4cae..014db3ea69 100644 --- a/services/audio_service/common/include/audio_volume_c.h +++ b/services/audio_service/common/include/audio_volume_c.h @@ -49,7 +49,7 @@ float GetCurVolume(uint32_t sessionId, const char *streamType, const char *devic float GetStreamVolume(uint32_t sessionId); -float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char* deviceClass); +float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char *deviceClass); float GetPreVolume(uint32_t sessionId); diff --git a/services/audio_service/server/include/renderer_in_server.h b/services/audio_service/server/include/renderer_in_server.h index 7302d6bbb4..4bdc9957cc 100644 --- a/services/audio_service/server/include/renderer_in_server.h +++ b/services/audio_service/server/include/renderer_in_server.h @@ -22,6 +22,7 @@ #include "oh_audio_buffer.h" #include "i_stream_manager.h" #include "audio_effect.h" +#include "audio_ring_cache.h" #include "player_dfx_writer.h" @@ -30,11 +31,14 @@ namespace AudioStandard { class StreamCallbacks : public IStatusCallback, public IWriteCallback { public: explicit StreamCallbacks(uint32_t streamIndex); - virtual ~StreamCallbacks() = default; + virtual ~StreamCallbacks(); void OnStatusUpdate(IOperation operation) override; int32_t OnWriteData(size_t length) override; + int32_t OnWriteData(int8_t *inputData, size_t requestDataLen) override; private: uint32_t streamIndex_ = 0; + FILE *dumpDupOut_ = nullptr; + std::string dumpDupOutFileName_ = ""; }; class RendererInServer : public IStatusCallback, public IWriteCallback, @@ -47,6 +51,7 @@ public: void HandleOperationFlushed(); void HandleOperationStarted(); int32_t OnWriteData(size_t length) override; + int32_t OnWriteData(int8_t *inputData, size_t requestDataLen) override; int32_t ResolveBuffer(std::shared_ptr &buffer); int32_t GetSessionId(uint32_t &sessionId); @@ -91,6 +96,7 @@ public: int32_t EnableInnerCap(int32_t innerCapId); int32_t DisableInnerCap(int32_t innerCapId); int32_t InitDupStream(int32_t innerCapId); + std::unique_ptr& GetDupRingBuffer(); // for dual tone int32_t EnableDualTone(); @@ -130,6 +136,8 @@ private: void InnerCaptureOtherStream(const BufferDesc &bufferDesc, CaptureInfo &captureInfo); int32_t StartInner(); int64_t GetLastAudioDuration(); + int32_t CreateDupBufferInner(int32_t innerCapId); + int32_t WriteDupBufferInner(const BufferDesc &bufferDesc); private: std::mutex statusLock_; @@ -145,8 +153,15 @@ private: // for inner-cap std::mutex dupMutex_; + size_t dupTotalSizeInFrame_ = 0; + size_t dupSpanSizeInFrame_ = 0; + size_t dupSpanSizeInByte_ = 0; + size_t dupByteSizePerFrame_ = 0; + FILE *dumpDupIn_ = nullptr; + std::string dumpDupInFileName_ = ""; std::shared_ptr dupStreamCallback_ = nullptr; std::unordered_map captureInfos_; + std::unique_ptr dupRingBuffer_ = nullptr; // for dual sink tone std::mutex dualToneMutex_; @@ -170,6 +185,10 @@ private: float oldAppliedVolume_ = MAX_FLOAT_VOLUME; std::mutex updateIndexLock_; int64_t startedTime_ = 0; + int64_t pausedTime_ = 0; + int64_t stopedTime_ = 0; + int64_t flushedTime_ = 0; + int64_t drainedTime_ = 0; uint32_t underrunCount_ = 0; std::atomic standByCounter_ = 0; int64_t enterStandbyTime_ = 0; diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index 9867ced13c..f74feca92a 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -308,7 +308,7 @@ int32_t AudioServer::Dump(int32_t fd, const std::vector &args) if (engineFlag == 1) { int32_t res = hpaeDumpObj_.Initialize(); CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR, - "Audio Service Hpae Dump not Initialed"); + "Audio Service Hpae Dump Not Initialed"); hpaeDumpObj_.AudioDataDump(dumpString, argQue); } else { AudioServerDump dumpObj; -- Gitee From bf16b3272e7d071c46d3973e12e7d32c99fbd2f5 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 15:46:16 +0800 Subject: [PATCH 13/40] sync change in render_in_server_cpp Signed-off-by: c00657214 --- .../server/src/renderer_in_server.cpp | 200 ++++++++++++++++-- 1 file changed, 188 insertions(+), 12 deletions(-) diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index cc00cbc94c..235311fe81 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -39,6 +39,7 @@ #include "audio_volume_c.h" #include "core_service_handler.h" #include "audio_service_enum.h" +#include "i_hpae_manager.h" namespace OHOS { namespace AudioStandard { @@ -58,6 +59,9 @@ namespace { constexpr int32_t RELEASE_TIMEOUT_IN_SEC = 10; // 10S constexpr int32_t DEFAULT_SPAN_SIZE = 1; constexpr size_t MSEC_PER_SEC = 1000; + const int32_t DUP_OFFLOAD_LEN = 7000; + const int32_t DUP_COMMON_LEN = 40; + const int32_t DUP_DEFAULT_LEN = 20; } RendererInServer::RendererInServer(AudioProcessConfig processConfig, std::weak_ptr streamListener) @@ -86,7 +90,7 @@ int32_t RendererInServer::ConfigServerBuffer() return SUCCESS; } stream_->GetSpanSizePerFrame(spanSizeInFrame_); - totalSizeInFrame_ = spanSizeInFrame_ * DEFAULT_SPAN_SIZE; + totalSizeInFrame_ = spanSizeInFrame_ * 2; // 4 frames stream_->GetByteSizePerFrame(byteSizePerFrame_); if (totalSizeInFrame_ == 0 || spanSizeInFrame_ == 0 || totalSizeInFrame_ % spanSizeInFrame_ != 0) { AUDIO_ERR_LOG("ConfigProcessBuffer: ERR_INVALID_PARAM"); @@ -331,6 +335,10 @@ void RendererInServer::OnStatusUpdateSub(IOperation operation) case OPERATION_SET_OFFLOAD_ENABLE: case OPERATION_UNSET_OFFLOAD_ENABLE: offloadEnable_ = operation == OPERATION_SET_OFFLOAD_ENABLE ? true : false; + if (offloadEnable_ == true && dupRingBuffer_ != nullptr) { + dupTotalSizeInFrame_ = dupSpanSizeInFrame_ * (DUP_OFFLOAD_LEN / DUP_DEFAULT_LEN); + dupRingBuffer_->ReConfig(dupTotalSizeInFrame_ * dupByteSizePerFrame_, false); + } stateListener->OnOperationHandled(SET_OFFLOAD_ENABLE, operation == OPERATION_SET_OFFLOAD_ENABLE ? 1 : 0); break; default: @@ -613,6 +621,59 @@ int32_t RendererInServer::WriteData() return SUCCESS; } +int32_t RendererInServer::OnWriteData(int8_t *inputData, size_t requestDataLen) +{ + uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame(); + uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame(); + Trace trace1(traceTag_ + " WriteData"); // RendererInServer::sessionid:100001 WriteData + if (currentReadFrame + spanSizeInFrame_ > currentWriteFrame) { + Trace trace2(traceTag_ + " near underrun"); // RendererInServer::sessionid:100001 near underrun + FutexTool::FutexWake(audioServerBuffer_->GetFutex()); + if (!offloadEnable_) { + CHECK_AND_RETURN_RET_LOG(currentWriteFrame >= currentReadFrame, ERR_OPERATION_FAILED, + "invalid write and read position."); + uint64_t dataSize = currentWriteFrame - currentReadFrame; + AUDIO_INFO_LOG("sessionId: %{public}u OHAudioBuffer %{public}" PRIu64 "size is not enough", + streamIndex_, dataSize); + } + return ERR_OPERATION_FAILED; + } + + BufferDesc bufferDesc = {nullptr, 0, 0}; // will be changed in GetReadbuffer + if (audioServerBuffer_->GetReadbuffer(currentReadFrame, bufferDesc) == SUCCESS) { + if (bufferDesc.buffer == nullptr) { + AUDIO_ERR_LOG("The buffer is null!"); + return ERR_INVALID_PARAM; + } + VolumeHandle(bufferDesc); + Trace::CountVolume(traceTag_, *bufferDesc.buffer); + if (processConfig_.streamType != STREAM_ULTRASONIC) { + if (currentReadFrame + spanSizeInFrame_ == currentWriteFrame) { + DoFadingOut(bufferDesc); + } + } + memcpy_s(inputData, requestDataLen, bufferDesc.buffer, bufferDesc.bufLength); + if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) { + DumpFileUtil::WriteDumpFile(dumpC2S_, static_cast(bufferDesc.buffer), bufferDesc.bufLength); + AudioCacheMgr::GetInstance().CacheData(dumpFileName_, + static_cast(bufferDesc.buffer), bufferDesc.bufLength); + } + + OtherStreamEnqueue(bufferDesc); + + WriteMuteDataSysEvent(bufferDesc); + memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength); // clear is needed for reuse. + uint64_t nextReadFrame = currentReadFrame + spanSizeInFrame_; + audioServerBuffer_->SetCurReadFrame(nextReadFrame); + } else { + Trace trace3("RendererInServer::WriteData GetReadbuffer failed"); + } + FutexTool::FutexWake(audioServerBuffer_->GetFutex()); + standByCounter_ = 0; + lastWriteTime_ = ClockTime::GetCurNano(); + return SUCCESS; +} + void RendererInServer::OtherStreamEnqueue(const BufferDesc &bufferDesc) { // for inner capture @@ -635,15 +696,25 @@ void RendererInServer::InnerCaptureOtherStream(const BufferDesc &bufferDesc, Cap Trace traceDup("RendererInServer::WriteData DupSteam write"); std::lock_guard lock(dupMutex_); if (captureInfo.dupStream != nullptr) { + int32_t engineFlag = GetEngineFlag(); if (renderEmptyCountForInnerCap_ > 0) { size_t emptyBufferSize = static_cast(renderEmptyCountForInnerCap_) * spanSizeInByte_; auto buffer = std::make_unique(emptyBufferSize); BufferDesc emptyBufferDesc = {buffer.get(), emptyBufferSize, emptyBufferSize}; memset_s(emptyBufferDesc.buffer, emptyBufferDesc.bufLength, 0, emptyBufferDesc.bufLength); - captureInfo.dupStream->EnqueueBuffer(emptyBufferDesc); + if (engineFlag == 1) { + WriteDupBufferInner(emptyBufferDesc); + } else { + captureInfo.dupStream->EnqueueBuffer(emptyBufferDesc); + } renderEmptyCountForInnerCap_ = 0; } - captureInfo.dupStream->EnqueueBuffer(bufferDesc); // what if enqueue fail? + if (engineFlag == 1) { + AUDIO_INFO_LOG("OtherStreamEnqueue running"); + WriteDupBufferInner(bufferDesc); + } else { + captureInfo.dupStream->EnqueueBuffer(bufferDesc); // what if enqueue fail? + } } } } @@ -848,6 +919,7 @@ int32_t RendererInServer::Pause() } } } + pausedTime_ = ClockTime::GetCurNano(); if (isDualToneEnabled_ && dualToneStream_ != nullptr) { //Joint judgment ensures that there is a double ring and there is a stream to enter. stream_->SetAudioEffectMode(effectModeWhenDual_); @@ -897,7 +969,7 @@ int32_t RendererInServer::Flush() "writeFrame: %{public}" PRIu64 "", readFrame, spanSizeInFrame_, writeFrame); audioServerBuffer_->SetCurReadFrame(readFrame); } - + flushedTime_ = ClockTime::GetCurNano(); int ret = stream_->Flush(); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Flush stream failed, reason: %{public}d", ret); { @@ -939,6 +1011,7 @@ int32_t RendererInServer::Drain(bool stopFlag) fadeoutFlag_ = DO_FADINGOUT; } DrainAudioBuffer(); + drainedTime_ = ClockTime::GetCurNano(); AudioPerformanceMonitor::GetInstance().ClearSilenceMonitor(streamIndex_); int ret = stream_->Drain(stopFlag); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Drain stream failed, reason: %{public}d", ret); @@ -987,8 +1060,10 @@ int32_t RendererInServer::Stop() AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING"); fadeoutFlag_ = NO_FADING; } - int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ? - IStreamManager::GetPlaybackManager(managerType_).StopRender(streamIndex_) : stream_->Stop(); + stopedTime_ = ClockTime::GetCurNano(); + int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) + ? IStreamManager::GetPlaybackManager(managerType_).StopRender(streamIndex_) + : stream_->Stop(); { std::lock_guard lock(dupMutex_); for (auto &capInfo : captureInfos_) { @@ -1185,6 +1260,10 @@ int32_t RendererInServer::DisableInnerCap(int32_t innerCapId) AudioVolume::GetInstance()->RemoveStreamVolume(dupStreamIndex); captureInfos_[innerCapId].dupStream = nullptr; } + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + DumpFileUtil::CloseDumpFile(&dumpDupIn_); + } return SUCCESS; } @@ -1203,7 +1282,15 @@ int32_t RendererInServer::InitDupStream(int32_t innerCapId) processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid, isSystemApp, processConfig_.rendererInfo.volumeMode); - dupStreamCallback_ = std::make_shared(dupStreamIndex); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + ret = CreateDupBufferInner(innerCapId); + dumpDupInFileName_ = std::to_string(streamIndex_) + "_dup_in_" + ".pcm"; + DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupInFileName_, &dumpDupIn_); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Config dup buffer failed"); + } + // todo check index + dupStreamCallback_ = std::make_shared(streamIndex_); capInfo.dupStream->RegisterStatusCallback(dupStreamCallback_); capInfo.dupStream->RegisterWriteCallback(dupStreamCallback_); @@ -1305,6 +1392,13 @@ int32_t RendererInServer::InitDualToneStream() StreamCallbacks::StreamCallbacks(uint32_t streamIndex) : streamIndex_(streamIndex) { AUDIO_INFO_LOG("DupStream %{public}u create StreamCallbacks", streamIndex_); + dumpDupOutFileName_ = std::to_string(streamIndex_) + "_dup_out_" + ".pcm"; + DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupOutFileName_, &dumpDupOut_); +} + +StreamCallbacks::~StreamCallbacks() +{ + DumpFileUtil::CloseDumpFile(&dumpDupOut_); } void StreamCallbacks::OnStatusUpdate(IOperation operation) @@ -1318,6 +1412,29 @@ int32_t StreamCallbacks::OnWriteData(size_t length) return SUCCESS; } +int32_t StreamCallbacks::OnWriteData(int8_t *inputData, size_t requestDataLen) +{ + Trace trace("DupStream::OnWriteData length " + std::to_string(requestDataLen)); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + std::unique_ptr &dupBuffer = + AudioService::GetInstance()->GetRendererBySessionID(streamIndex_)->GetDupRingBuffer(); + // no need mutex + // todo wait readable + AUDIO_INFO_LOG("StreamCallbacks::OnWriteData running"); + OptResult result = dupBuffer->GetReadableSize(); + CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, + "dupBuffer get readable size failed, size is:%{public}zu", result.size); + CHECK_AND_RETURN_RET_LOG((result.size != 0) && (result.size >= requestDataLen), ERROR, + "Readable size is invaild, result.size:%{public}zu, requstDataLen:%{public}zu", result.size, requestDataLen); + AUDIO_DEBUG_LOG("requstDataLen is:%{public}zu readSize is:%{public}zu", requestDataLen, result.size); + result = dupBuffer->Dequeue({reinterpret_cast(inputData), requestDataLen}); + CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "dupBuffer dequeue failed");\ + DumpFileUtil::WriteDumpFile(dumpDupOut_, static_cast(inputData), requestDataLen); + } + return SUCCESS; +} + int32_t RendererInServer::SetOffloadMode(int32_t state, bool isAppBack) { int32_t ret = stream_->SetOffloadMode(state, isAppBack); @@ -1521,11 +1638,16 @@ int32_t RendererInServer::SetStreamVolumeInfoForEnhanceChain() { uint32_t sessionId = streamIndex_; float streamVolume = audioServerBuffer_->GetStreamVolume(); - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); - int32_t ret = audioEnhanceChainManager->SetStreamVolumeInfo(sessionId, streamVolume); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "SetStreamVolumeInfo failed"); - return ret; + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HPAE::IHpaeManager::GetHpaeManager()->SetStreamVolumeInfo(sessionId, streamVolume); + } else { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); + int32_t ret = audioEnhanceChainManager->SetStreamVolumeInfo(sessionId, streamVolume); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "SetStreamVolumeInfo failed"); + return ret; + } } void RendererInServer::OnDataLinkConnectionUpdate(IOperation operation) @@ -1682,5 +1804,59 @@ int32_t RendererInServer::SetSourceDuration(int64_t duration) return SUCCESS; } +std::unique_ptr& RendererInServer::GetDupRingBuffer() { + return dupRingBuffer_; +} + +int32_t RendererInServer::CreateDupBufferInner(int32_t innerCapId) +{ + // todo dynamic + if (dupRingBuffer_ != nullptr) { + AUDIO_INFO_LOG("dup buffer already configed!"); + return SUCCESS; + } + + auto &capInfo = captureInfos_[innerCapId]; + capInfo.dupStream->GetSpanSizePerFrame(dupSpanSizeInFrame_); + // todo offload 350 frames primary 1 frame + dupTotalSizeInFrame_ = dupSpanSizeInFrame_ * (DUP_COMMON_LEN/DUP_DEFAULT_LEN); + capInfo.dupStream->GetByteSizePerFrame(dupByteSizePerFrame_); + if (dupSpanSizeInFrame_ == 0 || dupByteSizePerFrame_ == 0) { + AUDIO_ERR_LOG("ERR_INVALID_PARAM"); + return ERR_INVALID_PARAM; + } + dupSpanSizeInByte_ = dupSpanSizeInFrame_ * dupByteSizePerFrame_; + CHECK_AND_RETURN_RET_LOG(dupSpanSizeInByte_ != 0, ERR_OPERATION_FAILED, "Config dup buffer failed"); + AUDIO_INFO_LOG("dupTotalSizeInFrame_: %{public}zu, dupSpanSizeInFrame_: %{public}zu," + "dupByteSizePerFrame_:%{public}zu dupSpanSizeInByte_: %{public}zu,", + dupTotalSizeInFrame_, dupSpanSizeInFrame_, dupByteSizePerFrame_, dupSpanSizeInByte_); + + // create dupBuffer in server + dupRingBuffer_ = AudioRingCache::Create(dupTotalSizeInFrame_ * dupByteSizePerFrame_); + CHECK_AND_RETURN_RET_LOG(dupRingBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create dup buffer failed"); + return SUCCESS; +} + +int32_t RendererInServer::WriteDupBufferInner(const BufferDesc &bufferDesc) +{ + size_t targetSize = bufferDesc.bufLength; + OptResult result = dupRingBuffer_->GetWritableSize(); + // todo get writeable size failed + CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, + "DupRingBuffer write invalid size is:%{public}zu", result.size); + size_t writableSize = result.size; + AUDIO_DEBUG_LOG("targetSize: %{public}zu, writableSize: %{public}zu", targetSize, writableSize); + size_t writeSize = std::min(writableSize, targetSize); + BufferWrap bufferWrap = {bufferDesc.buffer, writeSize}; + if (writeSize > 0) { + result = dupRingBuffer_->Enqueue(bufferWrap); + if (result.ret != OPERATION_SUCCESS) { + AUDIO_ERR_LOG("RingCache Enqueue failed ret:%{public}d size:%{public}zu", result.ret, result.size); + } + DumpFileUtil::WriteDumpFile(dumpDupIn_, static_cast(bufferDesc.buffer), writeSize); + } + return SUCCESS; +} + } // namespace AudioStandard } // namespace OHOS -- Gitee From d781f7bf9c996f1e4ac319f40e891cba81db81d4 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 16:36:34 +0800 Subject: [PATCH 14/40] sync change in audio_server_effect_cpp Signed-off-by: c00657214 --- .../server/src/audio_server_effect.cpp | 225 +++++++++++++----- .../server/src/capturer_in_server.cpp | 51 ++++ .../server/src/i_stream_manager.cpp | 43 +++- .../server/src/pa_renderer_stream_impl.cpp | 4 - 4 files changed, 246 insertions(+), 77 deletions(-) diff --git a/services/audio_service/server/src/audio_server_effect.cpp b/services/audio_service/server/src/audio_server_effect.cpp index a6332800cb..755be23702 100644 --- a/services/audio_service/server/src/audio_server_effect.cpp +++ b/services/audio_service/server/src/audio_server_effect.cpp @@ -22,6 +22,8 @@ #include "audio_enhance_chain_manager.h" #include "common/hdi_adapter_info.h" #include "manager/hdi_adapter_manager.h" +#include "i_hpae_manager.h" +#include "audio_utils.h" namespace OHOS { namespace AudioStandard { @@ -30,19 +32,29 @@ using namespace std; void AudioServer::RecognizeAudioEffectType(const std::string &mainkey, const std::string &subkey, const std::string &extraSceneType) { - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - if (audioEffectChainManager == nullptr) { - AUDIO_ERR_LOG("audioEffectChainManager is nullptr"); - return; + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + HAPE::IHpaeManager::GetHpaeManager()->UpdateParamExtra(mainkey, subkey, extraSceneType); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + if (audioEffectChainManager == nullptr) { + AUDIO_ERR_LOG("audioEffectChainManager is nullptr"); + return; + } + audioEffectChainManager->UpdateParamExtra(mainkey, subkey, extraSceneType); } - audioEffectChainManager->UpdateParamExtra(mainkey, subkey, extraSceneType); - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - if (audioEnhanceChainManager == nullptr) { - AUDIO_ERR_LOG("audioEnhanceChainManager is nullptr"); - return; + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + HAPE::IHpaeManager::GetHpaeManager()->UpdateExtraSceneType(mainkey, subkey, extraSceneType); + } else { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + if (audioEnhanceChainManager == nullptr) { + AUDIO_ERR_LOG("audioEnhanceChainManager is nullptr"); + return; + } + audioEnhanceChainManager->UpdateExtraSceneType(mainkey, subkey, extraSceneType); } - audioEnhanceChainManager->UpdateExtraSceneType(mainkey, subkey, extraSceneType); } bool AudioServer::CreateEffectChainManager(std::vector &effectChains, @@ -52,12 +64,21 @@ bool AudioServer::CreateEffectChainManager(std::vector &effectChain AUDIO_ERR_LOG("not audio calling!"); return false; } - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - audioEffectChainManager->InitAudioEffectChainManager(effectChains, effectParam, - audioEffectServer_->GetEffectEntries()); - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - audioEnhanceChainManager->InitAudioEnhanceChainManager(effectChains, enhanceParam, - audioEffectServer_->GetEffectEntries()); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + HAPE::IHpaeManager::GetHpaeManager()->InitAudioEffectChainManager(effectChains, effectParam, + audioEffectServer_->GetEffectEntries()); + HAPE::IHpaeManager::GetHpaeManager()->InitAudioEnhanceChainManager(effectChains, effectParam, + audioEffectServer_->GetEffectEntries()); + AUDIO_INFO_LOG("AudioEffectChainManager Init"); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + audioEffectChainManager->InitAudioEffectChainManager(effectChains, effectParam, + audioEffectServer_->GetEffectEntries()); + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + audioEnhanceChainManager->InitAudioEnhanceChainManager(effectChains, enhanceParam, + audioEffectServer_->GetEffectEntries()); + } return true; } @@ -68,8 +89,14 @@ void AudioServer::SetOutputDeviceSink(int32_t deviceType, std::string &sinkName) AUDIO_ERR_LOG("not audio calling!"); return; } - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - audioEffectChainManager->SetOutputDeviceSink(deviceType, sinkName); + + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + HAPE::IHpaeManager::GetHpaeManager()->SetOutputDeviceSink(deviceType, sinkName); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + audioEffectChainManager->SetOutputDeviceSink(deviceType, sinkName); + } return; } @@ -77,12 +104,18 @@ int32_t AudioServer::UpdateSpatializationState(AudioSpatializationState spatiali { int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid); - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - if (audioEffectChainManager == nullptr) { - AUDIO_ERR_LOG("audioEffectChainManager is nullptr"); - return ERROR; + + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->UpdateSpatializationState(spatializationState); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + if (audioEffectChainManager == nullptr) { + AUDIO_ERR_LOG("audioEffectChainManager is nullptr"); + return ERROR; + } + return audioEffectChainManager->UpdateSpatializationState(spatializationState); } - return audioEffectChainManager->UpdateSpatializationState(spatializationState); } int32_t AudioServer::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) @@ -90,25 +123,34 @@ int32_t AudioServer::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDevic int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid); - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->UpdateSpatialDeviceType(spatialDeviceType); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); - return audioEffectChainManager->UpdateSpatialDeviceType(spatialDeviceType); + return audioEffectChainManager->UpdateSpatialDeviceType(spatialDeviceType); + } } int32_t AudioServer::SetSystemVolumeToEffect(const AudioStreamType streamType, float volume) { AudioVolumeType systemVolumeType = VolumeUtils::GetVolumeTypeFromStreamType(streamType); - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); - AUDIO_INFO_LOG("streamType: %{public}d, systemVolume: %{public}f", streamType, volume); - audioEffectChainManager->SetEffectSystemVolume(systemVolumeType, volume); - - std::shared_ptr audioEffectVolume = AudioEffectVolume::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectVolume != nullptr, ERROR, "null audioEffectVolume"); - audioEffectChainManager->EffectVolumeUpdate(audioEffectVolume); - + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + HAPE::IHpaeManager::GetHpaeManager()->SetEffectSystemVolume(systemVolumeType, volume); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); + AUDIO_INFO_LOG("streamType: %{public}d, systemVolume: %{public}f", streamType, volume); + audioEffectChainManager->SetEffectSystemVolume(systemVolumeType, volume); + + std::shared_ptr audioEffectVolume = AudioEffectVolume::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectVolume != nullptr, ERROR, "null audioEffectVolume"); + audioEffectChainManager->EffectVolumeUpdate(audioEffectVolume); + } return SUCCESS; } @@ -117,9 +159,14 @@ int32_t AudioServer::SetSpatializationSceneType(AudioSpatializationSceneType spa int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid); - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); - return audioEffectChainManager->SetSpatializationSceneType(spatializationSceneType); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->SetSpatializationSceneType(spatializationSceneType); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); + return audioEffectChainManager->SetSpatializationSceneType(spatializationSceneType); + } } uint32_t AudioServer::GetEffectLatency(const std::string &sessionId) @@ -144,9 +191,14 @@ void AudioServer::LoadHdiEffectModel() int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_LOG(PermissionUtil::VerifyIsAudio(), "load hdi effect model refused for %{public}d", callingUid); - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); - audioEffectChainManager->InitHdiState(); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + HAPE::IHpaeManager::GetHpaeManager()->InitHdiState(); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); + audioEffectChainManager->InitHdiState(); + } } int32_t AudioServer::SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray, @@ -197,9 +249,15 @@ int32_t AudioServer::SetAudioEffectProperty(const AudioEffectPropertyArray &prop int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED, "SetA udio Effect Property refused for %{public}d", callingUid); - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); - return audioEffectChainManager->SetAudioEffectProperty(propertyArray); + + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->SetAudioEffectProperty(propertyArray); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); + return audioEffectChainManager->SetAudioEffectProperty(propertyArray); + } } int32_t AudioServer::GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) @@ -218,9 +276,15 @@ int32_t AudioServer::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &pr int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED, "Set Audio Enhance Property refused for %{public}d", callingUid); - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); - return audioEnhanceChainManager->SetAudioEnhanceProperty(propertyArray, deviceType); + + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); + } else { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); + return audioEnhanceChainManager->SetAudioEnhanceProperty(propertyArray, deviceType); + } } int32_t AudioServer::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, @@ -236,17 +300,27 @@ int32_t AudioServer::GetAudioEnhanceProperty(AudioEnhancePropertyArray &property int32_t AudioServer::SetAudioEffectChainProperty(const AudioEffectPropertyArrayV3 &propertyArray) { - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); - return audioEffectChainManager->SetAudioEffectProperty(propertyArray); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->SetAudioEffectProperty(propertyArray); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); + return audioEffectChainManager->SetAudioEffectProperty(propertyArray); + } } int32_t AudioServer::SetAudioEnhanceChainProperty(const AudioEffectPropertyArrayV3 &propertyArray, const DeviceType& deviceType) { - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); - return audioEnhanceChainManager->SetAudioEnhanceProperty(propertyArray, deviceType); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); + } else { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); + return audioEnhanceChainManager->SetAudioEnhanceProperty(propertyArray, deviceType); + } } int32_t AudioServer::GetAudioEffectPropertyArray(AudioEffectPropertyArrayV3 &propertyArray) @@ -269,9 +343,14 @@ void AudioServer::UpdateEffectBtOffloadSupported(const bool &isSupported) int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_LOG(PermissionUtil::VerifyIsAudio(), "refused for %{public}d", callingUid); - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); - audioEffectChainManager->UpdateEffectBtOffloadSupported(isSupported); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->UpdateEffectBtOffloadSupported(isSupported); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); + audioEffectChainManager->UpdateEffectBtOffloadSupported(isSupported); + } } void AudioServer::SetRotationToEffect(const uint32_t rotate) @@ -279,9 +358,14 @@ void AudioServer::SetRotationToEffect(const uint32_t rotate) int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_LOG(PermissionUtil::VerifyIsAudio(), "set rotation to effect refused for %{public}d", callingUid); - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); - audioEffectChainManager->EffectRotationUpdate(rotate); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + HAPE::IHpaeManager::GetHpaeManager()->EffectRotationUpdate(rotate); + } else { + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); + audioEffectChainManager->EffectRotationUpdate(rotate); + } std::string value = "rotation=" + std::to_string(rotate); HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); @@ -292,8 +376,6 @@ void AudioServer::SetRotationToEffect(const uint32_t rotate) int32_t AudioServer::SetVolumeInfoForEnhanceChain(const AudioStreamType &streamType) { - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(streamType); DeviceType deviceType = PolicyHandler::GetInstance().GetActiveOutPutDevice(); Volume vol = {false, 0.0f, 0}; @@ -303,14 +385,27 @@ int32_t AudioServer::SetVolumeInfoForEnhanceChain(const AudioStreamType &streamT PolicyHandler::GetInstance().GetActiveOutPutDevice() == DEVICE_TYPE_BLUETOOTH_A2DP) { systemVol = 1.0f; // 1.0f for a2dp abs volume } - return audioEnhanceChainManager->SetVolumeInfo(volumeType, systemVol); + + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->SetVolumeInfo(volumeType, systemVol); + } else { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); + return audioEnhanceChainManager->SetVolumeInfo(volumeType, systemVol); + } } int32_t AudioServer::SetMicrophoneMuteForEnhanceChain(const bool &isMute) { - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); - return audioEnhanceChainManager->SetMicrophoneMuteInfo(isMute); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + return HAPE::IHpaeManager::GetHpaeManager()->SetMicrophoneMuteInfo(isMute); + } else { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); + return audioEnhanceChainManager->SetMicrophoneMuteInfo(isMute); + } } bool AudioServer::LoadAudioEffectLibraries(const std::vector libraries, const std::vector effects, diff --git a/services/audio_service/server/src/capturer_in_server.cpp b/services/audio_service/server/src/capturer_in_server.cpp index 52c2ec79db..5b399c069c 100644 --- a/services/audio_service/server/src/capturer_in_server.cpp +++ b/services/audio_service/server/src/capturer_in_server.cpp @@ -295,6 +295,57 @@ int32_t CapturerInServer::OnReadData(size_t length) return SUCCESS; } +int32_t CapturerInServer::OnReadData(std::vector& outputData, size_t requestDataLen) +{ + CHECK_AND_RETURN_RET_LOG(requestDataLen >= spanSizeInBytes_, ERR_READ_FAILED, + "Length %{public}zu is less than spanSizeInBytes %{public}zu", requestDataLen, spanSizeInBytes_); + std::shared_ptr stateListener = streamListener_.lock(); + CHECK_AND_RETURN_RET_LOG(stateListener != nullptr, ERR_READ_FAILED, "IStreamListener is nullptr"); + uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame(); + if (IsReadDataOverFlow(requestDataLen, currentWriteFrame, stateListener)) { + return ERR_READ_FAILED; + } + Trace trace("CapturerInServer::ReadData:" + std::to_string(currentWriteFrame)); + OptResult result = ringCache_->GetWritableSize(); + CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERR_READ_FAILED, + "RingCache write invalid size %{public}zu", result.size); + + BufferDesc srcBuffer = {nullptr, requestDataLen, 0}; + srcBuffer.buffer = reinterpret_cast(outputData.data()); + + ringCache_->Enqueue({srcBuffer.buffer, srcBuffer.bufLength}); + result = ringCache_->GetReadableSize(); + if (result.ret != OPERATION_SUCCESS || result.size < spanSizeInBytes_) { + return SUCCESS; + } + + BufferDesc dstBuffer = {nullptr, 0, 0}; + uint64_t curWritePos = audioServerBuffer_->GetCurWriteFrame(); + if (audioServerBuffer_->GetWriteBuffer(curWritePos, dstBuffer) < 0) { + return ERR_READ_FAILED; + } + if ((processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE && processConfig_.innerCapMode == + LEGACY_MUTE_CAP) || muteFlag_) { + dstBuffer.buffer = dischargeBuffer_.get(); // discharge valid data. + } + if (muteFlag_) { + memset_s(static_cast(dstBuffer.buffer), dstBuffer.bufLength, 0, dstBuffer.bufLength); + } + ringCache_->Dequeue({dstBuffer.buffer, dstBuffer.bufLength}); + if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) { + DumpFileUtil::WriteDumpFile(dumpS2C_, static_cast(dstBuffer.buffer), dstBuffer.bufLength); + AudioCacheMgr::GetInstance().CacheData(dumpFileName_, + static_cast(dstBuffer.buffer), dstBuffer.bufLength); + } + + uint64_t nextWriteFrame = currentWriteFrame + spanSizeInFrame_; + audioServerBuffer_->SetCurWriteFrame(nextWriteFrame); + audioServerBuffer_->SetHandleInfo(currentWriteFrame, ClockTime::GetCurNano()); + + stateListener->OnOperationHandled(UPDATE_STREAM, currentWriteFrame); + return SUCCESS; +} + int32_t CapturerInServer::UpdateReadIndex() { AUDIO_DEBUG_LOG("audioServerBuffer_->GetAvailableDataFrames(): %{public}d, needStart: %{public}d", diff --git a/services/audio_service/server/src/i_stream_manager.cpp b/services/audio_service/server/src/i_stream_manager.cpp index e8a844f2cd..c278f14a50 100644 --- a/services/audio_service/server/src/i_stream_manager.cpp +++ b/services/audio_service/server/src/i_stream_manager.cpp @@ -13,7 +13,10 @@ * limitations under the License. */ +#include "audio_utils.h" +#include "audio_engine_log.h" #include "pa_adapter_manager.h" +#include "pro_adapter_manager.h" #include "pro_audio_stream_manager.h" namespace OHOS { @@ -29,27 +32,51 @@ IStreamManager &IStreamManager::GetPlaybackManager(ManagerType managerType) return voipManager; case PLAYBACK: default: - static PaAdapterManager adapterManager(PLAYBACK); - return adapterManager; + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + static ProAdapterManager adapterManager(PLAYBACK); + return adapterManager; + } else { + static PaAdapterManager adapterManager(PLAYBACK); + return adapterManager; + } } } IStreamManager &IStreamManager::GetDupPlaybackManager() { - static PaAdapterManager adapterManager(DUP_PLAYBACK); - return adapterManager; + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + static ProAdapterManager adapterManager(DUP_PLAYBACK); + return adapterManager; + } else { + static PaAdapterManager adapterManager(DUP_PLAYBACK); + return adapterManager; + } } IStreamManager &IStreamManager::GetDualPlaybackManager() { - static PaAdapterManager adapterManager(DUAL_PLAYBACK); - return adapterManager; + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + static ProAdapterManager adapterManager(DUAL_PLAYBACK); + return adapterManager; + } else { + static PaAdapterManager adapterManager(DUAL_PLAYBACK); + return adapterManager; + } } IStreamManager &IStreamManager::GetRecorderManager() { - static PaAdapterManager adapterManager(RECORDER); - return adapterManager; + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + static ProAdapterManager adapterManager(RECORDER); + return adapterManager; + } else { + static PaAdapterManager adapterManager(RECORDER); + return adapterManager; + } } } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/pa_renderer_stream_impl.cpp b/services/audio_service/server/src/pa_renderer_stream_impl.cpp index 7757ca037b..ee389a7cc9 100644 --- a/services/audio_service/server/src/pa_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/pa_renderer_stream_impl.cpp @@ -1197,10 +1197,6 @@ int32_t PaRendererStreamImpl::SetOffloadMode(int32_t state, bool isAppBack) return SUCCESS; } - if ((offloadStatePolicy_ == offloadNextStateTargetPolicy_) && (offloadStatePolicy_ == statePolicy)) { - return SUCCESS; - } - offloadEnable_ = true; SyncOffloadMode(); if (OffloadUpdatePolicy(statePolicy, false) != SUCCESS) { -- Gitee From b1653a64869ee0f6dd2f8924bcc5eb5221fcb724 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 16:38:40 +0800 Subject: [PATCH 15/40] sync change in audio_server_effect_cpp, bugfix1 Signed-off-by: c00657214 --- .../server/src/audio_server_effect.cpp | 37 +++++++++---------- .../server/src/capturer_in_server.cpp | 4 +- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/services/audio_service/server/src/audio_server_effect.cpp b/services/audio_service/server/src/audio_server_effect.cpp index 755be23702..b271ddc059 100644 --- a/services/audio_service/server/src/audio_server_effect.cpp +++ b/services/audio_service/server/src/audio_server_effect.cpp @@ -34,7 +34,7 @@ void AudioServer::RecognizeAudioEffectType(const std::string &mainkey, const std { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HAPE::IHpaeManager::GetHpaeManager()->UpdateParamExtra(mainkey, subkey, extraSceneType); + HPAE::IHpaeManager::GetHpaeManager()->UpdateParamExtra(mainkey, subkey, extraSceneType); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); if (audioEffectChainManager == nullptr) { @@ -44,9 +44,8 @@ void AudioServer::RecognizeAudioEffectType(const std::string &mainkey, const std audioEffectChainManager->UpdateParamExtra(mainkey, subkey, extraSceneType); } - int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HAPE::IHpaeManager::GetHpaeManager()->UpdateExtraSceneType(mainkey, subkey, extraSceneType); + HPAE::IHpaeManager::GetHpaeManager()->UpdateExtraSceneType(mainkey, subkey, extraSceneType); } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); if (audioEnhanceChainManager == nullptr) { @@ -66,9 +65,9 @@ bool AudioServer::CreateEffectChainManager(std::vector &effectChain } int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HAPE::IHpaeManager::GetHpaeManager()->InitAudioEffectChainManager(effectChains, effectParam, + HPAE::IHpaeManager::GetHpaeManager()->InitAudioEffectChainManager(effectChains, effectParam, audioEffectServer_->GetEffectEntries()); - HAPE::IHpaeManager::GetHpaeManager()->InitAudioEnhanceChainManager(effectChains, effectParam, + HPAE::IHpaeManager::GetHpaeManager()->InitAudioEnhanceChainManager(effectChains, effectParam, audioEffectServer_->GetEffectEntries()); AUDIO_INFO_LOG("AudioEffectChainManager Init"); } else { @@ -92,7 +91,7 @@ void AudioServer::SetOutputDeviceSink(int32_t deviceType, std::string &sinkName) int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HAPE::IHpaeManager::GetHpaeManager()->SetOutputDeviceSink(deviceType, sinkName); + HPAE::IHpaeManager::GetHpaeManager()->SetOutputDeviceSink(deviceType, sinkName); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); audioEffectChainManager->SetOutputDeviceSink(deviceType, sinkName); @@ -107,7 +106,7 @@ int32_t AudioServer::UpdateSpatializationState(AudioSpatializationState spatiali int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->UpdateSpatializationState(spatializationState); + return HPAE::IHpaeManager::GetHpaeManager()->UpdateSpatializationState(spatializationState); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); if (audioEffectChainManager == nullptr) { @@ -125,7 +124,7 @@ int32_t AudioServer::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDevic int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->UpdateSpatialDeviceType(spatialDeviceType); + return HPAE::IHpaeManager::GetHpaeManager()->UpdateSpatialDeviceType(spatialDeviceType); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -140,7 +139,7 @@ int32_t AudioServer::SetSystemVolumeToEffect(const AudioStreamType streamType, f int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HAPE::IHpaeManager::GetHpaeManager()->SetEffectSystemVolume(systemVolumeType, volume); + HPAE::IHpaeManager::GetHpaeManager()->SetEffectSystemVolume(systemVolumeType, volume); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -161,7 +160,7 @@ int32_t AudioServer::SetSpatializationSceneType(AudioSpatializationSceneType spa int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->SetSpatializationSceneType(spatializationSceneType); + return HPAE::IHpaeManager::GetHpaeManager()->SetSpatializationSceneType(spatializationSceneType); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -193,7 +192,7 @@ void AudioServer::LoadHdiEffectModel() int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HAPE::IHpaeManager::GetHpaeManager()->InitHdiState(); + HPAE::IHpaeManager::GetHpaeManager()->InitHdiState(); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); @@ -252,7 +251,7 @@ int32_t AudioServer::SetAudioEffectProperty(const AudioEffectPropertyArray &prop int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->SetAudioEffectProperty(propertyArray); + return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEffectProperty(propertyArray); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -279,7 +278,7 @@ int32_t AudioServer::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &pr int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); + return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); @@ -302,7 +301,7 @@ int32_t AudioServer::SetAudioEffectChainProperty(const AudioEffectPropertyArrayV { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->SetAudioEffectProperty(propertyArray); + return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEffectProperty(propertyArray); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -315,7 +314,7 @@ int32_t AudioServer::SetAudioEnhanceChainProperty(const AudioEffectPropertyArray { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); + return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); @@ -345,7 +344,7 @@ void AudioServer::UpdateEffectBtOffloadSupported(const bool &isSupported) int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->UpdateEffectBtOffloadSupported(isSupported); + return HPAE::IHpaeManager::GetHpaeManager()->UpdateEffectBtOffloadSupported(isSupported); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); @@ -360,7 +359,7 @@ void AudioServer::SetRotationToEffect(const uint32_t rotate) int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HAPE::IHpaeManager::GetHpaeManager()->EffectRotationUpdate(rotate); + HPAE::IHpaeManager::GetHpaeManager()->EffectRotationUpdate(rotate); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); @@ -388,7 +387,7 @@ int32_t AudioServer::SetVolumeInfoForEnhanceChain(const AudioStreamType &streamT int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->SetVolumeInfo(volumeType, systemVol); + return HPAE::IHpaeManager::GetHpaeManager()->SetVolumeInfo(volumeType, systemVol); } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); @@ -400,7 +399,7 @@ int32_t AudioServer::SetMicrophoneMuteForEnhanceChain(const bool &isMute) { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HAPE::IHpaeManager::GetHpaeManager()->SetMicrophoneMuteInfo(isMute); + return HPAE::IHpaeManager::GetHpaeManager()->SetMicrophoneMuteInfo(isMute); } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); diff --git a/services/audio_service/server/src/capturer_in_server.cpp b/services/audio_service/server/src/capturer_in_server.cpp index 5b399c069c..1c7c9386d1 100644 --- a/services/audio_service/server/src/capturer_in_server.cpp +++ b/services/audio_service/server/src/capturer_in_server.cpp @@ -229,8 +229,6 @@ bool CapturerInServer::IsReadDataOverFlow(size_t length, uint64_t currentWriteFr overFlowLogFlag_ = 0; } overFlowLogFlag_++; - BufferDesc dstBuffer = stream_->DequeueBuffer(length); - stream_->EnqueueBuffer(dstBuffer); stateListener->OnOperationHandled(UPDATE_STREAM, currentWriteFrame); return true; } @@ -309,7 +307,7 @@ int32_t CapturerInServer::OnReadData(std::vector& outputData, size_t reque OptResult result = ringCache_->GetWritableSize(); CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERR_READ_FAILED, "RingCache write invalid size %{public}zu", result.size); - + BufferDesc srcBuffer = {nullptr, requestDataLen, 0}; srcBuffer.buffer = reinterpret_cast(outputData.data()); -- Gitee From 99bb0cf7c54c55657965603e316fc166ed14e43d Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 16:42:04 +0800 Subject: [PATCH 16/40] sync change in audio_server_effect_cpp, bugfix2 Signed-off-by: c00657214 --- .../audio_service/server/src/audio_server_effect.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/services/audio_service/server/src/audio_server_effect.cpp b/services/audio_service/server/src/audio_server_effect.cpp index b271ddc059..c621161734 100644 --- a/services/audio_service/server/src/audio_server_effect.cpp +++ b/services/audio_service/server/src/audio_server_effect.cpp @@ -48,11 +48,8 @@ void AudioServer::RecognizeAudioEffectType(const std::string &mainkey, const std HPAE::IHpaeManager::GetHpaeManager()->UpdateExtraSceneType(mainkey, subkey, extraSceneType); } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - if (audioEnhanceChainManager == nullptr) { - AUDIO_ERR_LOG("audioEnhanceChainManager is nullptr"); - return; - } - audioEnhanceChainManager->UpdateExtraSceneType(mainkey, subkey, extraSceneType); + CHECK_AND_RETURN_LOG(audioEnhanceChainManager != nullptr, "audioEnhanceChainManager is nullptr"); + return audioEnhanceChainManager->UpdateExtraSceneType(mainkey, subkey, extraSceneType); } } @@ -67,7 +64,7 @@ bool AudioServer::CreateEffectChainManager(std::vector &effectChain if (engineFlag == 1) { HPAE::IHpaeManager::GetHpaeManager()->InitAudioEffectChainManager(effectChains, effectParam, audioEffectServer_->GetEffectEntries()); - HPAE::IHpaeManager::GetHpaeManager()->InitAudioEnhanceChainManager(effectChains, effectParam, + HPAE::IHpaeManager::GetHpaeManager()->InitAudioEnhanceChainManager(effectChains, enhanceParam, audioEffectServer_->GetEffectEntries()); AUDIO_INFO_LOG("AudioEffectChainManager Init"); } else { @@ -275,7 +272,6 @@ int32_t AudioServer::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &pr int32_t callingUid = IPCSkeleton::GetCallingUid(); CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED, "Set Audio Enhance Property refused for %{public}d", callingUid); - int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); @@ -344,7 +340,7 @@ void AudioServer::UpdateEffectBtOffloadSupported(const bool &isSupported) int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->UpdateEffectBtOffloadSupported(isSupported); + HPAE::IHpaeManager::GetHpaeManager()->UpdateEffectBtOffloadSupported(isSupported); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); -- Gitee From c77aa6d312a4e9f14252ef37e1bfebef76ea20fb Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 16:49:16 +0800 Subject: [PATCH 17/40] sync change in gn Signed-off-by: c00657214 --- services/audio_service/BUILD.gn | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index b3237807ac..0111762319 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -308,6 +308,8 @@ config("audio_service_config") { "client/include", "server/include", "server/include/config", + "../audio_engine/manager/include", + "../audio_policy/server/include/service/common", "../audio_policy/common/definitions/include", "../audio_policy/server/include/service/common", "../audio_policy/server/include/service/effect", @@ -323,6 +325,21 @@ config("audio_service_config") { "../../frameworks/native/playbackcapturer/include", "../../frameworks/native/hdiadapter_new/include", "../../frameworks/native/hdiadapter_new/include/common", + "../../frameworks/native/hdiadapter/commom/include", + "../../frameworks/native/hdiadapter/sink/bluetooth", + "../../frameworks/native/hdiadapter/sink/commom", + "../../frameworks/native/hdiadapter/sink/file", + "../../frameworks/native/hdiadapter/sink/fast", + "../../frameworks/native/hdiadapter/sink/remote", + "../../frameworks/native/hdiadapter/sink/remote_fast", + "../../frameworks/native/hdiadapter/sink/primary", + "../../frameworks/native/hdiadapter/sink/offload", + "../../frameworks/native/hdiadapter/source/bluetooth", + "../../frameworks/native/hdiadapter/source/commom", + "../../frameworks/native/hdiadapter/source/fast", + "../../frameworks/native/hdiadapter/source/primary", + "../../frameworks/native/hdiadapter/source/remote", + "../../frameworks/native/hdiadapter/source/remote_fast", "../../interfaces/inner_api/native/audiocommon/include", "../../interfaces/inner_api/native/audiomanager/include", ] @@ -402,6 +419,13 @@ audio_ohos_library("audio_process_service") { "../../frameworks/native/audioutils:audio_utils", "../../frameworks/native/hdiadapter_new:hdiadapter_new", "../audio_policy:audio_foundation", + "../../frameworks/native/hdiadapter/sink:audio_renderer_sink", + "../../frameworks/native/hdiadapter/sink:bluetooth_renderer_sink", + "../../frameworks/native/hdiadapter/sink:fast_audio_renderer_sink", + "../../frameworks/native/hdiadapter/sink:renderer_sink_adapter", + "../../frameworks/native/hdiadapter/source:audio_capturer_source", + "../../frameworks/native/hdiadapter/source:capturer_source_adapter", + "../../frameworks/native/hdiadapter/source:fast_audio_capturer_source", ] external_deps = [ -- Gitee From 98bc33d88bb0b5a391c7d4b9f4c640ac969d5d8e Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 16:50:25 +0800 Subject: [PATCH 18/40] sync change, bugfix Signed-off-by: c00657214 --- services/audio_service/BUILD.gn | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index 0111762319..fdc17946c7 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -325,9 +325,9 @@ config("audio_service_config") { "../../frameworks/native/playbackcapturer/include", "../../frameworks/native/hdiadapter_new/include", "../../frameworks/native/hdiadapter_new/include/common", - "../../frameworks/native/hdiadapter/commom/include", + "../../frameworks/native/hdiadapter/common/include", "../../frameworks/native/hdiadapter/sink/bluetooth", - "../../frameworks/native/hdiadapter/sink/commom", + "../../frameworks/native/hdiadapter/sink/common", "../../frameworks/native/hdiadapter/sink/file", "../../frameworks/native/hdiadapter/sink/fast", "../../frameworks/native/hdiadapter/sink/remote", @@ -335,7 +335,7 @@ config("audio_service_config") { "../../frameworks/native/hdiadapter/sink/primary", "../../frameworks/native/hdiadapter/sink/offload", "../../frameworks/native/hdiadapter/source/bluetooth", - "../../frameworks/native/hdiadapter/source/commom", + "../../frameworks/native/hdiadapter/source/common", "../../frameworks/native/hdiadapter/source/fast", "../../frameworks/native/hdiadapter/source/primary", "../../frameworks/native/hdiadapter/source/remote", @@ -509,7 +509,7 @@ audio_ohos_library("audio_service") { deps = [ ":audio_common", ":audio_process_service", - "../auido_engine:audio_engine_manager", + "../audio_engine:audio_engine_manager", "../../frameworks/native/audioeffect:audio_effect", "../../frameworks/native/audioinnercall:audio_inner_call", "../../frameworks/native/audioschedule:audio_schedule", -- Gitee From e5425ed2ef87d9158098459628317db4b42d9703 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Tue, 15 Apr 2025 20:36:00 +0800 Subject: [PATCH 19/40] remove audio engine Signed-off-by: c00657214 --- services/audio_engine/BUILD.gn | 306 --- .../audio_engine/buffer/hpae_pcm_buffer.cpp | 266 --- .../audio_engine/buffer/hpae_pcm_buffer.h | 242 --- .../audio_engine/buffer/hpae_pcm_process.cpp | 74 - .../audio_engine/buffer/hpae_pcm_process.h | 89 - services/audio_engine/dfx/hpae_dfx_tree.cpp | 190 -- services/audio_engine/dfx/hpae_dfx_tree.h | 64 - .../include/audio_service_hpae_callback.h | 56 - .../audio_service_hpae_dump_callback.h | 31 - .../manager/include/hpae_capture_move_info.h | 32 - .../manager/include/hpae_capturer_manager.h | 114 - .../manager/include/hpae_define.h | 123 -- .../audio_engine/manager/include/hpae_info.h | 74 - .../include/hpae_inner_capturer_manager.h | 126 -- .../manager/include/hpae_manager.h | 236 -- .../manager/include/hpae_msg_channel.h | 146 -- .../include/hpae_offload_renderer_manager.h | 112 - .../manager/include/hpae_policy_manager.h | 73 - .../manager/include/hpae_renderer_manager.h | 126 -- .../include/hpae_signal_process_thread.h | 54 - .../manager/include/hpae_stream_manager.h | 55 - .../manager/include/i_hpae_capturer_manager.h | 101 - .../manager/include/i_hpae_manager.h | 129 -- .../manager/include/i_hpae_renderer_manager.h | 109 - .../manager/src/hpae_capturer_manager.cpp | 863 -------- .../src/hpae_inner_capturer_manager.cpp | 745 ------- .../audio_engine/manager/src/hpae_manager.cpp | 1910 ----------------- .../src/hpae_offload_renderer_manager.cpp | 607 ------ .../manager/src/hpae_policy_manager.cpp | 179 -- .../manager/src/hpae_renderer_manager.cpp | 951 -------- .../src/hpae_signal_process_thread.cpp | 74 - .../manager/src/i_hpae_manager.cpp | 29 - .../manager/src/i_hpae_renderer_manager.cpp | 76 - .../hpae_audio_format_converter_node.h | 59 - .../node/include/hpae_capture_effect_node.h | 73 - .../node/include/hpae_gain_node.h | 61 - .../node/include/hpae_inner_cap_sink_node.h | 67 - .../node/include/hpae_mixer_node.h | 47 - .../audio_engine/node/include/hpae_node.h | 298 --- .../node/include/hpae_node_common.h | 37 - .../include/hpae_offload_sinkoutput_node.h | 116 - .../node/include/hpae_output_cluster.h | 63 - .../node/include/hpae_plugin_node.h | 53 - .../node/include/hpae_process_cluster.h | 58 - .../node/include/hpae_render_effect_node.h | 62 - .../node/include/hpae_resample_node.h | 56 - .../node/include/hpae_sink_input_node.h | 78 - .../node/include/hpae_sink_output_node.h | 78 - .../node/include/hpae_source_input_cluster.h | 62 - .../node/include/hpae_source_input_node.h | 88 - .../node/include/hpae_source_output_node.h | 57 - .../include/hpae_source_process_cluster.h | 54 - .../src/hpae_audio_format_converter_node.cpp | 318 --- .../node/src/hpae_capture_effect_node.cpp | 214 -- .../audio_engine/node/src/hpae_gain_node.cpp | 233 -- .../node/src/hpae_inner_cap_sink_node.cpp | 178 -- .../audio_engine/node/src/hpae_mixer_node.cpp | 96 - .../node/src/hpae_node_common.cpp | 153 -- .../node/src/hpae_offload_sinkoutput_node.cpp | 528 ----- .../node/src/hpae_output_cluster.cpp | 241 --- .../node/src/hpae_plugin_node.cpp | 110 - .../node/src/hpae_process_cluster.cpp | 275 --- .../node/src/hpae_render_effect_node.cpp | 289 --- .../node/src/hpae_resample_node.cpp | 174 -- .../node/src/hpae_sinkInput_node.cpp | 240 --- .../node/src/hpae_sink_input_node.cpp | 249 --- .../node/src/hpae_sink_output_node.cpp | 330 --- .../node/src/hpae_source_input_cluster.cpp | 231 -- .../node/src/hpae_source_input_node.cpp | 362 ---- .../node/src/hpae_source_output_node.cpp | 136 -- .../node/src/hpae_source_process_cluster.cpp | 167 -- .../bitdepth_converter/bitdepth_converter.c | 329 --- .../bitdepth_converter/bitdepth_converter.h | 67 - .../include/channel_converter.h | 47 - .../channel_converter/include/down_mixer.h | 95 - .../src/channel_converter.cpp | 138 -- .../channel_converter/src/down_mixer.cpp | 1088 ---------- .../resample/include/audio_proresampler.h | 53 - .../include/audio_proresampler_process.h | 149 -- .../plugin/resample/include/resampler.h | 38 - .../proresampler/audio_proresampler.cpp | 176 -- .../proresampler/audio_proresampler_process.c | 1490 ------------- services/audio_engine/simd/SimdUtils.cpp | 117 - services/audio_engine/simd/SimdUtils.h | 40 - services/audio_engine/test/unittest/BUILD.gn | 90 - .../hpae_audio_service_callback_unit_test.h | 99 - .../unittest/common/hpae_manager_unit_test.h | 41 - .../test/unittest/common/test_case_common.cpp | 184 -- .../test/unittest/common/test_case_common.h | 99 - .../test/unittest/dfx/hpae_dfx_tree_test.cpp | 114 - .../hpae_audio_service_callback_unit_test.cpp | 163 -- .../manager/hpae_capturer_manager_test.cpp | 306 --- .../manager/hpae_inner_capturer_unit_test.cpp | 341 --- .../unittest/manager/hpae_manager_test.cpp | 377 ---- .../manager/hpae_render_manager_test.cpp | 260 --- .../unittest/node/hpae_gain_node_test.cpp | 135 -- .../unittest/node/hpae_mixer_node_test.cpp | 125 -- .../node/hpae_output_cluster_test.cpp | 177 -- .../unittest/node/hpae_pcm_buffer_test.cpp | 180 -- .../unittest/node/hpae_pcm_process_test.cpp | 125 -- .../node/hpae_process_cluster_test.cpp | 168 -- .../unittest/node/hpae_resample_node_test.cpp | 94 - .../node/hpae_sink_input_node_test.cpp | 154 -- .../node/hpae_sink_output_node_test.cpp | 123 -- .../node/hpae_source_input_cluster_test.cpp | 87 - .../node/hpae_source_input_node_test.cpp | 165 -- .../node/hpae_source_output_node_test.cpp | 148 -- .../test/unittest/resource/ohos_test.xml | 24 - .../utils/high_resolution_timer.h | 54 - .../utils/hpae_format_convert.cpp | 153 -- .../audio_engine/utils/hpae_format_convert.h | 28 - .../audio_engine/utils/hpae_no_lock_queue.cpp | 159 -- .../audio_engine/utils/hpae_no_lock_queue.h | 64 - .../audio_engine/utils/hpae_pcm_dumper.cpp | 57 - services/audio_engine/utils/hpae_pcm_dumper.h | 34 - 115 files changed, 22508 deletions(-) delete mode 100644 services/audio_engine/BUILD.gn delete mode 100644 services/audio_engine/buffer/hpae_pcm_buffer.cpp delete mode 100644 services/audio_engine/buffer/hpae_pcm_buffer.h delete mode 100644 services/audio_engine/buffer/hpae_pcm_process.cpp delete mode 100644 services/audio_engine/buffer/hpae_pcm_process.h delete mode 100644 services/audio_engine/dfx/hpae_dfx_tree.cpp delete mode 100644 services/audio_engine/dfx/hpae_dfx_tree.h delete mode 100644 services/audio_engine/manager/include/audio_service_hpae_callback.h delete mode 100644 services/audio_engine/manager/include/audio_service_hpae_dump_callback.h delete mode 100644 services/audio_engine/manager/include/hpae_capture_move_info.h delete mode 100644 services/audio_engine/manager/include/hpae_capturer_manager.h delete mode 100644 services/audio_engine/manager/include/hpae_define.h delete mode 100644 services/audio_engine/manager/include/hpae_info.h delete mode 100644 services/audio_engine/manager/include/hpae_inner_capturer_manager.h delete mode 100644 services/audio_engine/manager/include/hpae_manager.h delete mode 100644 services/audio_engine/manager/include/hpae_msg_channel.h delete mode 100644 services/audio_engine/manager/include/hpae_offload_renderer_manager.h delete mode 100644 services/audio_engine/manager/include/hpae_policy_manager.h delete mode 100644 services/audio_engine/manager/include/hpae_renderer_manager.h delete mode 100644 services/audio_engine/manager/include/hpae_signal_process_thread.h delete mode 100644 services/audio_engine/manager/include/hpae_stream_manager.h delete mode 100644 services/audio_engine/manager/include/i_hpae_capturer_manager.h delete mode 100644 services/audio_engine/manager/include/i_hpae_manager.h delete mode 100644 services/audio_engine/manager/include/i_hpae_renderer_manager.h delete mode 100644 services/audio_engine/manager/src/hpae_capturer_manager.cpp delete mode 100644 services/audio_engine/manager/src/hpae_inner_capturer_manager.cpp delete mode 100644 services/audio_engine/manager/src/hpae_manager.cpp delete mode 100644 services/audio_engine/manager/src/hpae_offload_renderer_manager.cpp delete mode 100644 services/audio_engine/manager/src/hpae_policy_manager.cpp delete mode 100644 services/audio_engine/manager/src/hpae_renderer_manager.cpp delete mode 100644 services/audio_engine/manager/src/hpae_signal_process_thread.cpp delete mode 100644 services/audio_engine/manager/src/i_hpae_manager.cpp delete mode 100644 services/audio_engine/manager/src/i_hpae_renderer_manager.cpp delete mode 100644 services/audio_engine/node/include/hpae_audio_format_converter_node.h delete mode 100644 services/audio_engine/node/include/hpae_capture_effect_node.h delete mode 100644 services/audio_engine/node/include/hpae_gain_node.h delete mode 100644 services/audio_engine/node/include/hpae_inner_cap_sink_node.h delete mode 100644 services/audio_engine/node/include/hpae_mixer_node.h delete mode 100644 services/audio_engine/node/include/hpae_node.h delete mode 100644 services/audio_engine/node/include/hpae_node_common.h delete mode 100644 services/audio_engine/node/include/hpae_offload_sinkoutput_node.h delete mode 100644 services/audio_engine/node/include/hpae_output_cluster.h delete mode 100644 services/audio_engine/node/include/hpae_plugin_node.h delete mode 100644 services/audio_engine/node/include/hpae_process_cluster.h delete mode 100644 services/audio_engine/node/include/hpae_render_effect_node.h delete mode 100644 services/audio_engine/node/include/hpae_resample_node.h delete mode 100644 services/audio_engine/node/include/hpae_sink_input_node.h delete mode 100644 services/audio_engine/node/include/hpae_sink_output_node.h delete mode 100644 services/audio_engine/node/include/hpae_source_input_cluster.h delete mode 100644 services/audio_engine/node/include/hpae_source_input_node.h delete mode 100644 services/audio_engine/node/include/hpae_source_output_node.h delete mode 100644 services/audio_engine/node/include/hpae_source_process_cluster.h delete mode 100644 services/audio_engine/node/src/hpae_audio_format_converter_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_capture_effect_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_gain_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_inner_cap_sink_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_mixer_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_node_common.cpp delete mode 100644 services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_output_cluster.cpp delete mode 100644 services/audio_engine/node/src/hpae_plugin_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_process_cluster.cpp delete mode 100644 services/audio_engine/node/src/hpae_render_effect_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_resample_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_sinkInput_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_sink_input_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_sink_output_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_source_input_cluster.cpp delete mode 100644 services/audio_engine/node/src/hpae_source_input_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_source_output_node.cpp delete mode 100644 services/audio_engine/node/src/hpae_source_process_cluster.cpp delete mode 100644 services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.c delete mode 100644 services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.h delete mode 100644 services/audio_engine/plugin/channel_converter/include/channel_converter.h delete mode 100644 services/audio_engine/plugin/channel_converter/include/down_mixer.h delete mode 100644 services/audio_engine/plugin/channel_converter/src/channel_converter.cpp delete mode 100644 services/audio_engine/plugin/channel_converter/src/down_mixer.cpp delete mode 100644 services/audio_engine/plugin/resample/include/audio_proresampler.h delete mode 100644 services/audio_engine/plugin/resample/include/audio_proresampler_process.h delete mode 100644 services/audio_engine/plugin/resample/include/resampler.h delete mode 100644 services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp delete mode 100644 services/audio_engine/plugin/resample/proresampler/audio_proresampler_process.c delete mode 100644 services/audio_engine/simd/SimdUtils.cpp delete mode 100644 services/audio_engine/simd/SimdUtils.h delete mode 100644 services/audio_engine/test/unittest/BUILD.gn delete mode 100644 services/audio_engine/test/unittest/common/hpae_audio_service_callback_unit_test.h delete mode 100644 services/audio_engine/test/unittest/common/hpae_manager_unit_test.h delete mode 100644 services/audio_engine/test/unittest/common/test_case_common.cpp delete mode 100644 services/audio_engine/test/unittest/common/test_case_common.h delete mode 100644 services/audio_engine/test/unittest/dfx/hpae_dfx_tree_test.cpp delete mode 100644 services/audio_engine/test/unittest/manager/hpae_audio_service_callback_unit_test.cpp delete mode 100644 services/audio_engine/test/unittest/manager/hpae_capturer_manager_test.cpp delete mode 100644 services/audio_engine/test/unittest/manager/hpae_inner_capturer_unit_test.cpp delete mode 100644 services/audio_engine/test/unittest/manager/hpae_manager_test.cpp delete mode 100644 services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_gain_node_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_mixer_node_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_output_cluster_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_pcm_buffer_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_pcm_process_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_process_cluster_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_resample_node_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_sink_input_node_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_sink_output_node_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_source_input_cluster_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_source_input_node_test.cpp delete mode 100644 services/audio_engine/test/unittest/node/hpae_source_output_node_test.cpp delete mode 100644 services/audio_engine/test/unittest/resource/ohos_test.xml delete mode 100644 services/audio_engine/utils/high_resolution_timer.h delete mode 100644 services/audio_engine/utils/hpae_format_convert.cpp delete mode 100644 services/audio_engine/utils/hpae_format_convert.h delete mode 100644 services/audio_engine/utils/hpae_no_lock_queue.cpp delete mode 100644 services/audio_engine/utils/hpae_no_lock_queue.h delete mode 100644 services/audio_engine/utils/hpae_pcm_dumper.cpp delete mode 100644 services/audio_engine/utils/hpae_pcm_dumper.h diff --git a/services/audio_engine/BUILD.gn b/services/audio_engine/BUILD.gn deleted file mode 100644 index 5bb937bb2c..0000000000 --- a/services/audio_engine/BUILD.gn +++ /dev/null @@ -1,306 +0,0 @@ -# Copyright (c) 2025 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") - -ohos_shared_library("audio_engine_utils") { - stack_protector_ret = true - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - install_enable = true - - sources = [ - "utils/hpae_format_convert.cpp", - "utils/hpae_no_lock_queue.cpp", - "utils/hpae_pcm_dumper.cpp", - "dfx/hpae_dfx_tree.cpp", - ] - - include_dirs = [ - "utils", - "dfx", - "buffer", - "manager/include", - "../audio_service/server/include", - "../../interfaces/inner_api/native/audiocommon/include", - "../../frameworks/native/audioutils/include", - ] - - cflags = [ - "-Wall", - "-Werror", - "-D_FORTIFY_SOURCE=2 -O2", - ] - - deps = [ - "../../frameworks/native/audioutils:audio_utils", - ] - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - ] - - subsystem_name = "multimedia" - part_name = "audio_framework" -} - -ohos_shared_library("audio_engine_resample") { - stack_protector_ret = true - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - install_enable = true - - sources = [ - "plugin/resample/proresampler/audio_proresampler.cpp", - "plugin/resample/proresampler/audio_proresampler_process.c", - "plugin/channel_converter/src/channel_converter.cpp", - "plugin/channel_converter/src/down_mixer.cpp", - "plugin/bitdepth_converter/bitdepth_converter.c" - ] - - include_dirs = [ - "plugin/resample/include", - "../../interfaces/inner_api/native/audiocommon/include", - "plugin/channel_converter/include", - "pulgin/bitdepth_converter" - ] - - cflags = [ - "-Wall", - "-Werror", - "-D_FORTIFY_SOURCE=2 -O2", - ] - - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - ] - - subsystem_name = "multimedia" - part_name = "audio_framework" -} - -ohos_shared_library("audio_engine_simd") { - stack_protector_ret = true - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - install_enable = true - - sources = [ - "simd/SimdUtils.cpp", - ] - - include_dirs = [ - "simd", - ] - - cflags = [ - "-Wall", - "-Werror", - "-D_FORTIFY_SOURCE=2 -O2", - ] - - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - ] - - subsystem_name = "multimedia" - part_name = "audio_framework" -} - -ohos_shared_library("audio_engine_buffer") { - stack_protector_ret = true - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - install_enable = true - - sources = [ - "buffer/hpae_pcm_buffer.cpp", - "buffer/hpae_pcm_process.cpp", - ] - - include_dirs = [ - "buffer", - "simd", - "../../interfaces/inner_api/native/audiocommon/include", - ] - - cflags = [ - "-Wall", - "-Werror", - "-D_FORTIFY_SOURCE=2 -O2", - ] - - deps = [ - ":audio_engine_simd", - ] - - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - ] - - subsystem_name = "multimedia" - part_name = "audio_framework" -} - -config("audio_engine_node_config") { - include_dirs = [ - "node/include", - "manager/include", - "buffer", - "simd", - "utils", - "dfx", - "plugin/resample/include", - "plugin/channel_converter/include", - "plugin/bitdepth_converter", - "../audio_service/common/include", - "../audio_service/server/include", - "../audio_policy/util/include", - "../../frameworks/native/audioeffect/include", - "../../interfaces/inner_api/native/audiocommon/include", - "../../frameworks/native/hdiadapter_new/include", - ] - - cflags = [ - "-Wall", - "-Werror", - "-D_FORTIFY_SOURCE=2 -O2", - ] - cflags += [ "-Os" ] - cflags += [ "-DENABLE_HOOK_PCM"] - cflags += [ "-DENABLE_HIDUMP_DFX"] - cflags_cc = cflags -} - -ohos_shared_library("audio_engine_node") { - stack_protector_ret = true - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - install_enable = true - - configs = [ ":audio_engine_node_config" ] - - sources = [ - "node/src/hpae_mixer_node.cpp", - "node/src/hpae_plugin_node.cpp", - "node/src/hpae_sink_input_node.cpp", - "node/src/hpae_sink_output_node.cpp", - "node/src/hpae_source_output_node.cpp", - "node/src/hpae_source_input_node.cpp", - "node/src/hpae_render_effect_node.cpp", - "node/src/hpae_resample_node.cpp", - "node/src/hpae_gain_node.cpp", - "node/src/hpae_node_common.cpp", - "node/src/hpae_process_cluster.cpp", - "node/src/hpae_output_cluster.cpp", - "node/src/hpae_source_input_cluster.cpp", - "node/src/hpae_source_process_cluster.cpp", - "node/src/hpae_capture_effect_node.cpp", - "node/src/hpae_audio_format_converter_node.cpp", - "node/src/hpae_inner_cap_sink_node.cpp", - "node/src/hpae_offload_sinkoutput_node.cpp", - ] - - deps = [ - ":audio_engine_simd", - ":audio_engine_buffer", - ":audio_engine_utils", - ":audio_engine_resample", - "../audio_service:audio_common", - "../audio_policy:audio_foundation", - "../../frameworks/native/audioeffect:audio_effect", - "../../frameworks/native/audioutils:audio_utils", - "../../frameworks/native/hdiadapter_new:hdiadapter_new", - "../../frameworks/native/audioutils:audio_utils", - ] - - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - ] - - subsystem_name = "multimedia" - part_name = "audio_framework" -} - -ohos_shared_library("audio_engine_manager") { - stack_protector_ret = true - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - install_enable = true - - configs = [ ":audio_engine_node_config" ] - - include_dirs = [ - "manager/include", - "../audio_policy/server/include/service/common", - "../../frameworks/native/audioeffect/include", - "../../frameworks/native/audioschedule/include", - ] - - sources = [ - "manager/src/hpae_manager.cpp", - "manager/src/hpae_capturer_manager.cpp", - "manager/src/hpae_policy_manager.cpp", - "manager/src/hpae_renderer_manager.cpp", - "manager/src/hpae_signal_process_thread.cpp", - "manager/src/i_hpae_manager.cpp", - "manager/src/hpae_inner_capturer_manager.cpp", - "manager/src/hpae_offload_renderer_manager.cpp", - "manager/src/i_hpae_renderer_manager.cpp", - ] - - deps = [ - ":audio_engine_utils", - ":audio_engine_node", - "../audio_policy:audio_foundation", - "../../frameworks/native/audioeffect:audio_effect", - "../../frameworks/native/audioschedule:audio_schedule", - "../../frameworks/native/audioutils:audio_utils", - ] - - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - ] - - subsystem_name = "multimedia" - part_name = "audio_framework" -} \ No newline at end of file diff --git a/services/audio_engine/buffer/hpae_pcm_buffer.cpp b/services/audio_engine/buffer/hpae_pcm_buffer.cpp deleted file mode 100644 index b454a9c695..0000000000 --- a/services/audio_engine/buffer/hpae_pcm_buffer.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaePcmBuffer" -#endif - -#include "securec.h" -#include "SimdUtils.h" -#include "hpae_pcm_buffer.h" -#include "audio_engine_log.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaePcmBuffer::HpaePcmBuffer(PcmBufferInfo &pcmBufferInfo) : pcmBufferInfo_(pcmBufferInfo) -{ - InitPcmProcess(); -} - -HpaePcmBuffer &HpaePcmBuffer::operator=(HpaePcmBuffer &other) -{ - if (this != &other) { - pcmBufferInfo_ = other.pcmBufferInfo_; - InitPcmProcess(); - memcpy_s(GetPcmDataBuffer(), bufferByteSize_, other.GetPcmDataBuffer(), bufferByteSize_); - } - return *this; -} - -HpaePcmBuffer::HpaePcmBuffer(HpaePcmBuffer &&other) -{ - pcmBufferInfo_ = other.pcmBufferInfo_; - bufferByteSize_ = other.bufferByteSize_; - bufferFloatSize_ = other.bufferFloatSize_; - pcmDataBuffer_ = std::move(other.pcmDataBuffer_); - pcmProcessVec_ = std::move(other.pcmProcessVec_); - other.pcmBufferInfo_.frames = 0; - other.bufferByteSize_ = 0; - other.bufferFloatSize_ = 0; -} - -void HpaePcmBuffer::InitPcmProcess() -{ - size_t ch = GetChannelCount(); - size_t frameLen = GetFrameLen(); - size_t frames = GetFrames(); - size_t addBytes = MEMORY_ALIGN_BYTE_NUM - (frameLen * sizeof(float) * ch) % MEMORY_ALIGN_BYTE_NUM; - frameByteSize_ = frameLen * sizeof(float) * ch + addBytes; - frameFloatSize_ = frameByteSize_ / sizeof(float); - bufferByteSize_ = frameByteSize_ * frames; - bufferFloatSize_ = frameFloatSize_ * frames; - frameSample_ = frameLen * ch; - pcmDataBuffer_.resize(bufferFloatSize_); - readPos_.store(0); - writePos_.store(0); - curFrames_.store(0); - pcmProcessVec_.clear(); - pcmProcessVec_.reserve(frames); - float *itr = pcmDataBuffer_.data(); - for (size_t i = 0; i < frames; ++i) { - pcmProcessVec_.push_back(HpaePcmProcess(itr, frameSample_)); - itr += frameFloatSize_; - } -} - -HpaePcmBuffer &HpaePcmBuffer::operator+=(HpaePcmBuffer &other) -{ - for (size_t i = 0; i < pcmProcessVec_.size(); ++i) { - pcmProcessVec_[i] += other[i]; - } - return *this; -} - -HpaePcmBuffer &HpaePcmBuffer::operator-=(HpaePcmBuffer &other) -{ - for (size_t i = 0; i < pcmProcessVec_.size(); ++i) { - pcmProcessVec_[i] -= other[i]; - } - return *this; -} - -HpaePcmBuffer &HpaePcmBuffer::operator*=(HpaePcmBuffer &other) -{ - for (size_t i = 0; i < pcmProcessVec_.size(); ++i) { - pcmProcessVec_[i] *= other[i]; - } - return *this; -} - -HpaePcmBuffer &HpaePcmBuffer::operator=(const std::vector> &other) -{ - for (size_t i = 0; i < other.size() && i < pcmProcessVec_.size(); ++i) { - if (IsMultiFrames()) { - if (curFrames_.load() < GetFrames()) { - pcmProcessVec_[i + writePos_.load()] = other[i]; - writePos_.store((writePos_.load() + 1) % GetFrames()); - curFrames_.fetch_add(1); - } else { - AUDIO_WARNING_LOG("HpaePcmBuffer::operator=, frames is full index = %{public}zu", i); - } - } else { - pcmProcessVec_[i] = other[i]; - } - } - return *this; -} - -HpaePcmBuffer &HpaePcmBuffer::operator=(const std::vector &other) -{ - if (IsMultiFrames()) { - if (curFrames_.load() < GetFrames()) { - pcmProcessVec_[writePos_.load()] = other; - writePos_.store((writePos_.load() + 1) % GetFrames()); - curFrames_.fetch_add(1); - } else { - AUDIO_WARNING_LOG("HpaePcmBuffer::operator=, frames is full"); - } - } else { - pcmProcessVec_[0] = other; - } - return *this; -} - -void HpaePcmBuffer::Reset() -{ - for (HpaePcmProcess &pcmProc : pcmProcessVec_) { - pcmProc.Reset(); - } -} - -bool HpaePcmBuffer::GetFrameData(std::vector &frameData) -{ - if (!IsMultiFrames()) { - return false; - } - - if (curFrames_.load() <= 0) { - AUDIO_WARNING_LOG("GetFrameData vector frames is empty"); - return false; - } - int32_t ret = memcpy_s(frameData.data(), - sizeof(float) * frameData.size(), - pcmProcessVec_[readPos_.load()].begin(), - frameSample_ * sizeof(float)); - if (ret != 0) { - return false; - } - readPos_.store((readPos_.load() + 1) % GetFrames()); - curFrames_.fetch_sub(1); - return true; -} -// frameData is not MultiFrames -bool HpaePcmBuffer::GetFrameData(HpaePcmBuffer &frameData) -{ - if (!IsMultiFrames() || frameData.IsMultiFrames()) { - return false; - } - - if (curFrames_.load() <= 0) { - AUDIO_WARNING_LOG("GetFrameData HpaePcmBuffer frames is empty"); - return false; - } - memcpy_s(frameData.GetPcmDataBuffer(), - sizeof(float) * frameData.Size(), - pcmProcessVec_[readPos_.load()].begin(), - frameSample_ * sizeof(float)); - readPos_.store((readPos_.load() + 1) % GetFrames()); - curFrames_.fetch_sub(1); - return true; -} - -bool HpaePcmBuffer::PushFrameData(std::vector &frameData) -{ - if (!IsMultiFrames()) { - return false; - } - - if (curFrames_.load() >= GetFrames()) { - AUDIO_WARNING_LOG("PushFrameData vector frames is full"); - return false; - } - memcpy_s(pcmProcessVec_[writePos_.load()].begin(), frameByteSize_, - frameData.data(), sizeof(float) * frameData.size()); - writePos_.store((writePos_.load() + 1) % GetFrames()); - curFrames_.fetch_add(1); - return true; -} - -bool HpaePcmBuffer::PushFrameData(HpaePcmBuffer &frameData) -{ - if (!IsMultiFrames() || frameData.IsMultiFrames()) { - return false; - } - - if (curFrames_.load() >= GetFrames()) { - AUDIO_WARNING_LOG("PushFrameData HpaePcmBuffer frames is full"); - return false; - } - memcpy_s(pcmProcessVec_[writePos_.load()].begin(), frameByteSize_, - frameData.GetPcmDataBuffer(), frameData.Size()); - writePos_.store((writePos_.load() + 1) % GetFrames()); - curFrames_.fetch_add(1); - return true; -} - -bool HpaePcmBuffer::StoreFrameData(HpaePcmBuffer &frameData) -{ - if (!IsMultiFrames() || frameData.IsMultiFrames()) { - return false; - } - - memcpy_s(pcmProcessVec_[writePos_.load()].begin(), frameByteSize_, - frameData.GetPcmDataBuffer(), frameData.Size()); - writePos_.store((writePos_.load() + 1) % GetFrames()); - readPos_.store((readPos_.load() + 1) % GetFrames()); - return true; -} - -size_t HpaePcmBuffer::RewindBuffer(size_t frames) -{ - if (!IsMultiFrames()) { - return 0; - } - frames = curFrames_.load() + frames > GetFrames() ? GetFrames() - curFrames_.load() : frames; - readPos_.store((readPos_.load() - frames + GetFrames()) % GetFrames()); - curFrames_.fetch_add(frames); - return frames; -} - -bool HpaePcmBuffer::UpdateReadPos(size_t readPos) -{ - readPos_.store(readPos); - return true; -} - -bool HpaePcmBuffer::UpdateWritePos(size_t writePos) -{ - writePos_.store(writePos); - return true; -} - -void HpaePcmBuffer::SetBufferValid(bool valid) -{ - pcmBufferInfo_.isValid = valid; -} - -size_t HpaePcmBuffer::GetCurFrames() const -{ - return curFrames_.load(); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/buffer/hpae_pcm_buffer.h b/services/audio_engine/buffer/hpae_pcm_buffer.h deleted file mode 100644 index b2bd7ff9f7..0000000000 --- a/services/audio_engine/buffer/hpae_pcm_buffer.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_PCM_BUFFER_H -#define HPAE_PCM_BUFFER_H -#include -#include -#include -#include -#include "hpae_pcm_process.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr size_t MEMORY_ALIGN_BYTE_NUM = 64; - -enum HpaeSourceBufferType { - HPAE_SOURCE_BUFFER_TYPE_DEFAULT, - HPAE_SOURCE_BUFFER_TYPE_MIC, - HPAE_SOURCE_BUFFER_TYPE_EC, - HPAE_SOURCE_BUFFER_TYPE_MICREF, -}; - -// redefine allocator to ensure memory alignment -template -class AlignedAllocator : public std::allocator { -public: - using pointer = T *; - using size_type = size_t; - - pointer allocate(size_type n) - { - void *ptr = std::aligned_alloc(Alignment, n * sizeof(T)); - return static_cast(ptr); - } - - void deallocate(pointer p, size_type n) - { - std::free(p); - } -}; - -struct PcmBufferInfo { - PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1) - : ch(ch1), frameLen(frameLen1), rate(rate1) - {} - PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1, uint64_t channelLayout1) - : ch(ch1), frameLen(frameLen1), rate(rate1), channelLayout(channelLayout1) - {} - PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1, uint64_t channelLayout1, - uint32_t frames1, bool isMultiFrames) - : ch(ch1), frameLen(frameLen1), rate(rate1), channelLayout(channelLayout1), frames(frames1), - isMultiFrames(isMultiFrames) - {} - PcmBufferInfo() = default; - uint32_t ch; - uint32_t frameLen; - uint32_t rate; - uint64_t channelLayout = 0; - uint32_t frames = 1; - bool isMultiFrames = false; - bool isValid = true; -}; - -// todo: multithread access? -class HpaePcmBuffer { -public: - HpaePcmBuffer() = delete; - explicit HpaePcmBuffer(PcmBufferInfo &pcmBufferInfo); - HpaePcmBuffer(HpaePcmBuffer &&other); - HpaePcmBuffer(const HpaePcmBuffer &other) = delete; - ~HpaePcmBuffer() - { - } - HpaePcmBuffer &operator=(HpaePcmBuffer &other); - HpaePcmBuffer &operator=(HpaePcmBuffer &&other) = delete; - - PcmBufferInfo GetPcmBufferInfo() const - { - return pcmBufferInfo_; - } - - uint32_t GetChannelCount() const - { - return pcmBufferInfo_.ch; - } - - uint32_t GetFrameLen() const - { - return pcmBufferInfo_.frameLen; - } - - uint32_t GetSampleRate() const - { - return pcmBufferInfo_.rate; - } - - bool IsMultiFrames() const - { - return pcmBufferInfo_.isMultiFrames; - } - - bool IsValid() const - { - return pcmBufferInfo_.isValid; - } - - uint64_t GetChannelLayout() const - { - return pcmBufferInfo_.channelLayout; - } - - void ReConfig(const PcmBufferInfo &pcmBufferInfo) - { - pcmBufferInfo_ = pcmBufferInfo; - InitPcmProcess(); - } - - bool GetFrameData(std::vector &frameData); - bool GetFrameData(HpaePcmBuffer &frameData); - bool PushFrameData(std::vector &frameData); - bool PushFrameData(HpaePcmBuffer &frameData); - // store history frame for offload - bool StoreFrameData(HpaePcmBuffer &frameData); - // rewind history frame for offload, return frames that rewinded - size_t RewindBuffer(size_t frames); - - HpaePcmProcess &operator[](size_t index) - { - return pcmProcessVec_[index]; - } - - const HpaePcmProcess &operator[](size_t index) const - { - return pcmProcessVec_[index]; - } - - size_t Size() const - { - return bufferByteSize_; - } - - size_t GetFrames() const - { - return pcmBufferInfo_.frames; - } - - size_t GetReadPos() const - { - return readPos_.load(); - } - - size_t GetWritePos() const - { - return writePos_.load(); - } - - bool UpdateReadPos(size_t readPos); - bool UpdateWritePos(size_t writePos); - void SetBufferValid(bool valid); - size_t GetCurFrames() const; - - HpaePcmBuffer &operator=(const std::vector> &other); - HpaePcmBuffer &operator=(const std::vector &other); - - HpaePcmBuffer &operator+=(HpaePcmBuffer &other); - HpaePcmBuffer &operator-=(HpaePcmBuffer &other); - HpaePcmBuffer &operator*=(HpaePcmBuffer &other); - void Reset(); - - std::vector::iterator begin() - { - return pcmProcessVec_.begin(); - } - - std::vector::iterator end() - { - return pcmProcessVec_.end(); - } - - std::vector::const_iterator begin() const - { - return pcmProcessVec_.begin(); - } - - std::vector::const_iterator end() const - { - return pcmProcessVec_.end(); - } - - float *GetPcmDataBuffer() - { - return pcmDataBuffer_.data(); - } - - size_t GetFrameSample() - { - return frameSample_; - } - - HpaeSourceBufferType GetSourceBufferType() - { - return sourceBufferType_; - } - - void SetSourceBufferType(HpaeSourceBufferType type) - { - sourceBufferType_ = type; - } - -private: - void InitPcmProcess(); - - // todo: add err to deal with operator override - std::vector> pcmDataBuffer_; - size_t bufferFloatSize_; - size_t bufferByteSize_; - size_t frameFloatSize_; - size_t frameByteSize_; - size_t frameSample_; - std::atomic readPos_; - std::atomic writePos_; - std::atomic curFrames_; - std::vector pcmProcessVec_; - PcmBufferInfo pcmBufferInfo_; - HpaeSourceBufferType sourceBufferType_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/buffer/hpae_pcm_process.cpp b/services/audio_engine/buffer/hpae_pcm_process.cpp deleted file mode 100644 index 10df391479..0000000000 --- a/services/audio_engine/buffer/hpae_pcm_process.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaePcmProcess" -#endif - -#include "hpae_pcm_process.h" -#include "SimdUtils.h" -#include "audio_engine_log.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaePcmProcess &HpaePcmProcess::operator = (const std::vector& other) -{ - errNo_ = memcpy_s(pcmDataPtr_, sizeof(float) * size_, other.data(), sizeof(float) * other.size()); - CHECK_AND_RETURN_RET_LOG(errNo_ == 0, *this, "memcpy_s failed, errNo: %{public}d", errNo_); - return *this; -} - -HpaePcmProcess &HpaePcmProcess::operator = (const HpaePcmProcess& other) -{ - if (this != &other) { - errNo_ = memcpy_s(pcmDataPtr_, sizeof(float) * size_, other.begin(), sizeof(float) * other.Size()); - CHECK_AND_RETURN_RET_LOG(errNo_ == 0, *this, "memcpy_s failed, errNo: %{public}d", errNo_); - } - return *this; -} - -HpaePcmProcess &HpaePcmProcess::operator+=(const HpaePcmProcess &other) -{ - float *curData = begin(); - const float *otherData = other.begin(); - SimdPointByPointAdd(size_, otherData, curData, curData); - return *this; -} - -HpaePcmProcess &HpaePcmProcess::operator-=(const HpaePcmProcess &other) -{ - float *curData = begin(); - const float *otherData = other.begin(); - SimdPointByPointSub(size_, curData, otherData, curData); - return *this; -} - -HpaePcmProcess &HpaePcmProcess::operator*=(const HpaePcmProcess &other) -{ - float *curData = begin(); - const float *otherData = other.begin(); - SimdPointByPointMul(size_, otherData, curData, curData); - return *this; -} - -void HpaePcmProcess::Reset() -{ - errNo_ = memset_s(begin(), sizeof(float) * size_, 0, sizeof(float) * size_); - CHECK_AND_RETURN_LOG(errNo_ == 0, "memcpy_s failed, errNo: %{public}d", errNo_); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/buffer/hpae_pcm_process.h b/services/audio_engine/buffer/hpae_pcm_process.h deleted file mode 100644 index 6f4cc4ec82..0000000000 --- a/services/audio_engine/buffer/hpae_pcm_process.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_PCM_PROCESS_H -#define HPAE_PCM_PROCESS_H -#include -#include "securec.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaePcmProcess { -public: - HpaePcmProcess(float *begin, size_t size) : pcmDataPtr_(begin), size_(size) {} - - float &operator[](size_t index) - { - return *(pcmDataPtr_ + index); - } - - const float &operator[](size_t index) const - { - return *(pcmDataPtr_ + index); - } - - size_t Size() const - { - return size_; - } - - float *begin() - { - return pcmDataPtr_; - } - - float *end() - { - return pcmDataPtr_ + size_; - } - - const float *begin() const - { - return pcmDataPtr_; - } - - const float *end() const - { - return pcmDataPtr_ + size_; - } - - HpaePcmProcess(const HpaePcmProcess &other) = default; - - HpaePcmProcess &operator = (const HpaePcmProcess &other); - - HpaePcmProcess &operator = (const std::vector& other); - - HpaePcmProcess &operator += (const HpaePcmProcess &other); - - HpaePcmProcess &operator -= (const HpaePcmProcess &other); - - HpaePcmProcess &operator *= (const HpaePcmProcess &other); - - void Reset() ; - - int32_t GetErrNo() - { - int32_t tmpErrNo = errNo_; - errNo_ = 0; - return tmpErrNo; - } - -private: - int32_t errNo_; - float* const pcmDataPtr_; - const size_t size_; -}; -}}} -#endif // HPAE_PCM_PROCESS_H \ No newline at end of file diff --git a/services/audio_engine/dfx/hpae_dfx_tree.cpp b/services/audio_engine/dfx/hpae_dfx_tree.cpp deleted file mode 100644 index 0e3a9f63b2..0000000000 --- a/services/audio_engine/dfx/hpae_dfx_tree.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeDfxTree" -#endif -#include "hpae_dfx_tree.h" -#include -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -DfxTreeNode *HpaeDfxTree::FindDfxNode(DfxTreeNode *currentNode, const uint32_t nodeId) -{ - if (!currentNode) { - return nullptr; - } - std::queue q; - q.push(currentNode); - while (!q.empty()) { - DfxTreeNode *node = q.front(); - q.pop(); - if (node->nodeInfo_.nodeId == nodeId) { - return node; - } - for (auto &child : node->children_) { - q.push(child); - } - } - return nullptr; -} - -DfxTreeNode *HpaeDfxTree::FindDfxParent(DfxTreeNode *target) -{ - if (!root_ || target == root_) { - return nullptr; - } - std::queue q; - q.push(root_); - while (!q.empty()) { - DfxTreeNode *node = q.front(); - q.pop(); - for (auto &child : node->children_) { - if (child->nodeInfo_.nodeId == target->nodeInfo_.nodeId) { - return node; - } - q.push(child); - } - } - return nullptr; -} - -bool HpaeDfxTree::Insert(const uint32_t parentNodeId, const HpaeDfxNodeInfo &info) -{ - if (!root_) { - AUDIO_INFO_LOG("Insert Root is null"); - root_ = new DfxTreeNode(info); - return true; - } - DfxTreeNode *parent = FindDfxNode(root_, parentNodeId); - if (!parent) { - AUDIO_INFO_LOG("Insert can not find correct parent"); - return false; - } - parent->children_.push_back(new DfxTreeNode(info)); - return true; -} - -bool HpaeDfxTree::Remove(const uint32_t nodeId) -{ - if (!root_) { - AUDIO_INFO_LOG("Remove Root is null"); - return false; - } - DfxTreeNode *nodeToRemove = FindDfxNode(root_, nodeId); - if (!nodeToRemove) { - return false; - } - - if (nodeToRemove == root_) { - delete root_; - root_ = nullptr; - return true; - } - - DfxTreeNode *parent = FindDfxParent(nodeToRemove); - if (!parent) { - return false; - } - // Remove from parent's children - auto &children = parent->children_; - auto it = find(children.begin(), children.end(), nodeToRemove); - if (it != children.end()) { - children.erase(it); - delete nodeToRemove; - return true; - } - return false; -} - -std::vector> HpaeDfxTree::LevelOrderTraversal() -{ - std::vector> result; - if (!root_) { - return result; - } - std::queue q; - q.push(root_); - while (!q.empty()) { - int32_t levelSize = q.size(); - std::vector curLevelResult; - for (int32_t i = 0; i < levelSize; ++i) { - DfxTreeNode *node = q.front(); - q.pop(); - curLevelResult.push_back(node->nodeInfo_); - for (auto &child : node->children_) { - q.push(child); - } - } - result.push_back(curLevelResult); - } - return result; -} - -void HpaeDfxTree::PrintNodeInfo(std::string &outStr, HpaeDfxNodeInfo &nodeInfo) -{ - outStr = outStr + nodeInfo.nodeName + ": " + "id[" + std::to_string(nodeInfo.sessionId) + "],"; - outStr = outStr + "rate[" + std::to_string(nodeInfo.samplingRate) + "],"; - outStr = outStr + "ch[" + std::to_string(nodeInfo.channels) + "],"; - outStr = outStr + "bw[" + std::to_string(nodeInfo.format) + "],"; - outStr = outStr + "len[" + std::to_string(nodeInfo.frameLen) + "],"; - outStr = outStr + "scene[" + std::to_string(nodeInfo.sceneType) + "] \n"; -} - -void HpaeDfxTree::PrintSubTree(DfxTreeNode *node, const std::string &prefix, bool isLastChild, std::string &outStr) -{ - if (!node) - return; - - outStr = outStr + prefix; - outStr = outStr + (isLastChild ? "|___ " : "|--- "); - PrintNodeInfo(outStr, node->nodeInfo_); - std::string newPrefix = prefix + (isLastChild ? " " : "| "); - for (size_t i = 0; i < node->children_.size(); ++i) { - bool childIsLast = (i == node->children_.size() - 1); - PrintSubTree(node->children_[i], newPrefix, childIsLast, outStr); - } -} - -void HpaeDfxTree::PrintTree(std::string &outStr) -{ - if (!root_) { - return; - } - PrintNodeInfo(outStr, root_->nodeInfo_); - for (size_t i = 0; i < root_->children_.size(); ++i) { - bool isLast = (i == root_->children_.size() - 1); - PrintSubTree(root_->children_[i], "", isLast, outStr); - } -} - -void HpaeDfxTree::UpdateNodeInfo(uint32_t NodeId, const HpaeDfxNodeInfo &nodeInfo) -{ - if (root_ == nullptr) { - AUDIO_WARNING_LOG("Hidumper dfx tree is empty!"); - return; - } - DfxTreeNode *target = FindDfxNode(root_, NodeId); - if (target == nullptr) { - AUDIO_WARNING_LOG("Cannot find Node Id: %{public}d", NodeId); - return; - } - target->nodeInfo_ = nodeInfo; -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/dfx/hpae_dfx_tree.h b/services/audio_engine/dfx/hpae_dfx_tree.h deleted file mode 100644 index 94cf975042..0000000000 --- a/services/audio_engine/dfx/hpae_dfx_tree.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_DFX_TREE_H -#define HPAE_DFX_TREE_H -#include "hpae_define.h" -#include -#include -#include -#include - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr uint32_t MIN_START_NODE_ID = 100; -class DfxTreeNode { -public: - DfxTreeNode(HpaeDfxNodeInfo val) : nodeInfo_(val) - {} - ~DfxTreeNode() - { - for (auto child : children_) { - delete child; - } - } - HpaeDfxNodeInfo nodeInfo_; - std::vector children_; -}; - -class HpaeDfxTree { -public: - HpaeDfxTree() : root_(nullptr) - {} - ~HpaeDfxTree() - { - delete root_; - } - std::vector> LevelOrderTraversal(); - bool Insert(const uint32_t parentNodeId, const HpaeDfxNodeInfo &info); - bool Remove(const uint32_t nodeId); - void PrintTree(std::string &outStr); - void UpdateNodeInfo(uint32_t NodeId, const HpaeDfxNodeInfo &nodeInfo); -private: - DfxTreeNode *FindDfxNode(DfxTreeNode *currentNode, const uint32_t nodeId); - DfxTreeNode *FindDfxParent(DfxTreeNode *target); - void PrintSubTree(DfxTreeNode *node, const std::string &prefix, bool isLastChild, std::string &outStr); - void PrintNodeInfo(std::string &outStr, HpaeDfxNodeInfo &nodeInfo); - DfxTreeNode *root_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/audio_service_hpae_callback.h b/services/audio_engine/manager/include/audio_service_hpae_callback.h deleted file mode 100644 index 137aeb090b..0000000000 --- a/services/audio_engine/manager/include/audio_service_hpae_callback.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2025 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 AUDIO_SERVICE_HAPE_CALLBACK_H -#define AUDIO_SERVICE_HAPE_CALLBACK_H -#include "audio_effect.h" -namespace OHOS { -namespace AudioStandard { -class AudioServiceHpaeCallback { -public: - virtual void OnOpenAudioPortCb(int32_t portId) = 0; - - virtual void OnCloseAudioPortCb(int32_t result) = 0; - - virtual void OnSetSinkMuteCb(int32_t result) = 0; - - virtual void OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) = 0; - - virtual void OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) = 0; - - virtual void OnGetAllSinksCb(int32_t result, std::vector &sinks) = 0; - - virtual void OnMoveSinkInputByIndexOrNameCb(int32_t result) = 0; - - virtual void OnMoveSourceOutputByIndexOrNameCb(int32_t result) = 0; - - virtual void OnSetSourceOutputMuteCb(int32_t result) = 0; - - virtual void OnGetAudioEffectPropertyCbV3(int32_t result) = 0; - - virtual void OnGetAudioEffectPropertyCb(int32_t result) = 0; - - virtual void OnGetAudioEnhancePropertyCbV3(int32_t result) = 0; - - virtual void OnGetAudioEnhancePropertyCb(int32_t result) = 0; - - virtual void HandleSourceAudioStreamRemoved(uint32_t sessionId) = 0; - - virtual ~AudioServiceHpaeCallback() - {} -}; -} // namespace AudioStandard -} // namespace OHOS -#endif // AUDIO_SERVICE_HAPE_CALLBACK_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/audio_service_hpae_dump_callback.h b/services/audio_engine/manager/include/audio_service_hpae_dump_callback.h deleted file mode 100644 index d39bcd2fda..0000000000 --- a/services/audio_engine/manager/include/audio_service_hpae_dump_callback.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2025 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 AUDIO_SERVICE_HAPE_DUMP_CALLBACK_H -#define AUDIO_SERVICE_HAPE_DUMP_CALLBACK_H -#include -namespace OHOS { -namespace AudioStandard { -class AudioServiceHpaeDumpCallback { -public: - virtual void OnDumpSinkInfoCb(std::string& dumpStr, int32_t result) = 0; - virtual void OnDumpSourceInfoCb(std::string &dumpStr, int32_t result) = 0; - - virtual ~AudioServiceHpaeDumpCallback() - {} -}; -} // namespace AudioStandard -} // namespace OHOS -#endif // AUDIO_SERVICE_HAPE_CALLBACK_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_capture_move_info.h b/services/audio_engine/manager/include/hpae_capture_move_info.h deleted file mode 100644 index f42cab99a9..0000000000 --- a/services/audio_engine/manager/include/hpae_capture_move_info.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_CAPTURE_MOVE_INFO_H -#define HPAE_CAPTURE_MOVE_INFO_H -#include "hpae_define.h" -#include "hpae_source_output_node.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -struct HpaeCaptureMoveInfo { - uint32_t sessionId; - std::shared_ptr sourceOutputNode; - HpaeCapturerSessionInfo sessionInfo; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif // HPAE_CAPTURE_MOVE_INFO_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_capturer_manager.h b/services/audio_engine/manager/include/hpae_capturer_manager.h deleted file mode 100644 index 6ca9a70206..0000000000 --- a/services/audio_engine/manager/include/hpae_capturer_manager.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_CAPTURER_MANAGER_H -#define HPAE_CAPTURER_MANAGER_H -#include -#include -#include -#include -#include -#include -#include "audio_effect.h" -#include "hpae_signal_process_thread.h" -#include "hpae_source_input_node.h" -#include "hpae_source_input_cluster.h" -#include "hpae_source_output_node.h" -#include "hpae_source_process_cluster.h" -#include "hpae_no_lock_queue.h" -#include "i_hpae_capturer_manager.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaeCapturerManager : public IHpaeCapturerManager { -public: - HpaeCapturerManager(HpaeSourceInfo &sourceInfo); - virtual ~HpaeCapturerManager(); - int32_t CreateStream(const HpaeStreamInfo& streamInfo) override; - int32_t DestroyStream(uint32_t sessionId) override; - - int32_t Start(uint32_t sessionId) override; - int32_t Pause(uint32_t sessionId) override; - int32_t Flush(uint32_t sessionId) override; - int32_t Drain(uint32_t sessionId) override; - int32_t Stop(uint32_t sessionId) override; - int32_t Release(uint32_t sessionId) override; - int32_t MoveStream(uint32_t sessionId, const std::string& sourceName) override; - int32_t MoveAllStream(const std::string& sourceName, const std::vector& sessionIds, - bool isMoveAll = true) override; - int32_t SetMute(bool isMute) override; - void Process() override; - void HandleMsg() override; - int32_t Init() override; - int32_t DeInit(bool isMoveDefault = false) override; - bool IsInit() override; - bool IsRunning(void) override; - bool IsMsgProcessing() override; - bool DeactivateThread() override; - - int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) override; - HpaeSourceInfo GetSourceInfo() override; - std::vector GetAllSourceOutputsInfo() override; - - void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) override; - void OnNotifyQueue() override; - - int32_t AddNodeToSource(const HpaeCaptureMoveInfo &moveInfo) override; - int32_t AddAllNodesToSource(const std::vector &moveInfos, bool isConnect) override; - std::string GetThreadName() override; - void SetCaptureId(uint32_t captureId); - int32_t ReloadCaptureManager(const HpaeSourceInfo &sourceInfo) override; - void DumpSourceInfo() override; -private: - int32_t CreateOutputSession(const HpaeStreamInfo &streamInfo); - int32_t DeleteOutputSession(uint32_t sessionId); - int32_t ConnectProcessClusterWithEc(HpaeProcessorType &sceneType); - int32_t ConnectProcessClusterWithMicRef(HpaeProcessorType &sceneType); - int32_t ConnectOutputSession(uint32_t sessionId); - int32_t DisConnectOutputSession(uint32_t sessionId); - void DisConnectSceneClusterFromSourceInputCluster(HpaeProcessorType &sceneType); - void SetSessionState(uint32_t sessionId, CapturerState capturerState); - int32_t PrepareCapturerEc(HpaeNodeInfo &ecNodeInfo); - int32_t PrepareCapturerMicRef(HpaeNodeInfo &micRefNodeInfo); - int32_t InitCapturer(); - void AddSingleNodeToSource(const HpaeCaptureMoveInfo &moveInfo, bool isConnect = true); - void MoveAllStreamToNewSource(const std::string &sourceName, - const std::vector& moveIds, bool isMoveAll); - int32_t CaptureEffectCreate(const HpaeProcessorType &sceneType, const AudioEnhanceScene &enhanceScene); - int32_t CaptureEffectRelease(const HpaeProcessorType &sceneType); - int32_t InitCapturerManager(); - -private: - void SendRequest(Request &&request, bool isInit = false); - HpaeNoLockQueue hpaeNoLockQueue_; - std::unique_ptr hpaeSignalProcessThread_ = nullptr; - std::unordered_map sessionNodeMap_; - std::unordered_map streamInfoMap_; - std::unordered_map> sceneClusterMap_; - std::unordered_map> sourceOutputNodeMap_; - std::unordered_map> sourceInputClusterMap_; - - HpaeSourceInputNodeType mainMicType_; - std::atomic isInit_ = false; - std::atomic isMute_ = false; - HpaeSourceInfo sourceInfo_; - uint32_t captureId_ = 0; - uint32_t renderId_ = 0; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_define.h b/services/audio_engine/manager/include/hpae_define.h deleted file mode 100644 index 786895e6df..0000000000 --- a/services/audio_engine/manager/include/hpae_define.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_DEFINE_H -#define HPAE_DEFINE_H -#include "hpae_msg_channel.h" -#include "i_stream.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr uint32_t MILLISECOND_PER_SECOND = 1000; - -struct HpaeSessionInfo { - HpaeStreamInfo streamInfo; - uint32_t state = I_STATUS_IDLE; - std::weak_ptr statusCallback; -}; - - -constexpr int32_t SCENE_TYPE_NUM = 9; - -struct HpaeRenderSessionInfo { - uint32_t sinkInputNodeId; - HpaeProcessorType sceneType = HPAE_SCENE_DEFAULT; - uint32_t state = I_STATUS_IDLE; -}; - -struct HpaeSinkInputInfo { - HpaeRenderSessionInfo rendererSessionInfo; - HpaeNodeInfo nodeInfo; -}; - -struct HpaeSinkInfo { - uint32_t sinkId; - std::string deviceNetId; - std::string deviceClass; - std::string adapterName; - std::string filePath; - std::string deviceName; - size_t frameLen; - AudioSamplingRate samplingRate; - AudioSampleFormat format; - AudioChannel channels; - uint32_t suspendTime = 0; // in ms - uint64_t channelLayout = 0ULL; - int32_t deviceType = 0; - float volume = 0.0f; - uint32_t openMicSpeaker = 0; - uint32_t renderInIdleState = 0; - uint32_t sourceType = 0; - uint32_t offloadEnable = 0; - uint32_t fixedLatency = 0; - uint32_t sinkLatency = 0; -}; - -struct HpaeCapturerSessionInfo { - HpaeProcessorType sceneType = HPAE_SCENE_DEFAULT; - uint32_t state = I_STATUS_IDLE; -}; - -struct HpaeSourceOutputInfo { - HpaeCapturerSessionInfo capturerSessionInfo; - HpaeNodeInfo nodeInfo; -}; - -enum HpaeEcType { - HPAE_EC_TYPE_NONE, - HPAE_EC_TYPE_SAME_ADAPTER, - HPAE_EC_TYPE_DIFF_ADAPTER -}; - -enum HpaeMicRefSwitch { - HPAE_REF_OFF = 0, - HPAE_REF_ON -}; - -struct HpaeSourceInfo { - uint32_t sourceId; - std::string deviceNetId; - std::string deviceClass; - std::string adapterName; - std::string sourceName; - SourceType sourceType; - std::string filePath; - std::string deviceName; - size_t frameLen; - AudioSamplingRate samplingRate; - AudioSampleFormat format; - AudioChannel channels; - uint64_t channelLayout = 0ULL; - int32_t deviceType = 0; - float volume = 0.0f; - HpaeEcType ecType; - size_t ecFrameLen; - std::string ecAdapterName; - AudioSamplingRate ecSamplingRate; - AudioSampleFormat ecFormat; - AudioChannel ecChannels; - HpaeMicRefSwitch micRef; - size_t micRefFrameLen; - AudioSamplingRate micRefSamplingRate; - AudioSampleFormat micRefFormat; - AudioChannel micRefChannels; - uint32_t openMicSpeaker; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS - -#endif // HPAE_DEFINE_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_info.h b/services/audio_engine/manager/include/hpae_info.h deleted file mode 100644 index 53606ea837..0000000000 --- a/services/audio_engine/manager/include/hpae_info.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_INFO_H -#define HPAE_INFO_H -#include "audio_effect.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -enum HpaeStreamClassType { - HPAE_STREAM_CLASS_TYPE_INVALID = -1, - HPAE_STREAM_CLASS_TYPE_PLAY, - HPAE_STREAM_CLASS_TYPE_RECORD, -}; - -enum HpaeNodeType { - HPAE_NODE_TYPE_INVALID = -1, - HPAE_NODE_TYPE_SOURCE_INPUT, - HPAE_NODE_TYPE_SOURCE_OUTPUT, - HPAE_NODE_TYPE_SINK_INPUT, - HPAE_NODE_TYPE_SINK_OUTPUT, - HPAE_NODE_TYPE_PLUGIN, -}; - -struct HpaeEffectInfo { - StreamUsage streamUsage; - AudioVolumeType volumeType; - AudioEffectScene effectScene; - AudioEffectMode effectMode; - AudioEnhanceScene enhanceScene; - AudioEnhanceMode enhanceMode; -}; - -enum FadeType { - DEFAULT_FADE = 0, // default one frame fade - SHORT_FADE, // short 5ms fade - NONE_FADE // do not fade -}; -struct HpaeStreamInfo { - uint32_t sessionId; - size_t frameLen; - HpaeNodeType nodeType; - AudioStreamType streamType; - FadeType fadeType = NONE_FADE; - AudioPipeType pipeType; - AudioSamplingRate samplingRate; - AudioSampleFormat format; - AudioChannel channels; - uint64_t channelLayout = 0ULL; - HpaeStreamClassType streamClassType; - SourceType sourceType; - int32_t uid = -1; - int32_t pid = 0; - HpaeEffectInfo effectInfo; - std::string deviceName; -}; - -#define GET_SIZE_FROM_FORMAT(format) ((format) != SAMPLE_F32LE ? ((format) + 1) : (4)) -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_inner_capturer_manager.h b/services/audio_engine/manager/include/hpae_inner_capturer_manager.h deleted file mode 100644 index 5148fc6729..0000000000 --- a/services/audio_engine/manager/include/hpae_inner_capturer_manager.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_INNER_CAPTURER_MANAGER_H -#define HPAE_INNER_CAPTURER_MANAGER_H -#include -#include -#include -#include -#include -#include -#include "i_renderer_stream.h" -#include "hpae_signal_process_thread.h" -#include "hpae_sink_input_node.h" -#include "hpae_resample_node.h" -#include "hpae_inner_cap_sink_node.h" -#include "hpae_source_output_node.h" -#include "hpae_source_process_cluster.h" -#include "hpae_msg_channel.h" -#include "hpae_no_lock_queue.h" -#include "i_hpae_renderer_manager.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaeInnerCapturerManager : public IHpaeRendererManager { -public: - HpaeInnerCapturerManager(HpaeSinkInfo &sinkInfo); - ~HpaeInnerCapturerManager(); - int32_t CreateStream(const HpaeStreamInfo &streamInfo) override; - int32_t DestroyStream(uint32_t sessionId) override; - - int32_t Start(uint32_t sessionId) override; - int32_t Pause(uint32_t sessionId) override; - int32_t Flush(uint32_t sessionId) override; - int32_t Drain(uint32_t sessionId) override; - int32_t Stop(uint32_t sessionId) override; - int32_t Release(uint32_t sessionId) override; - int32_t MoveStream(uint32_t sessionId, const std::string &sinkName) override; - int32_t MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, - bool isMoveAll = true) override; - int32_t SuspendStreamManager(bool isSuspend) override; - int32_t SetMute(bool isMute) override; - void Process() override; - void HandleMsg() override; - int32_t Init() override; - int32_t DeInit(bool isMoveDefault = false) override; - bool IsInit() override; - bool IsRunning(void) override; - bool IsMsgProcessing() override; - bool DeactivateThread() override; - int32_t SetClientVolume(uint32_t sessionId, float volume) override; - int32_t SetRate(uint32_t sessionId, int32_t rate) override; - int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) override; - int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) override; - int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) override; - int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) override; - int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - - size_t GetWritableSize(uint32_t sessionId) override; - int32_t UpdateSpatializationState( - uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) override; - int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) override; - std::vector GetAllSinkInputsInfo() override; - int32_t GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) override; - HpaeSinkInfo GetSinkInfo() override; - - void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) override; - void OnFadeDone(uint32_t sessionId, IOperation operation) override; - - int32_t AddNodeToSink(const std::shared_ptr &node) override; - int32_t AddAllNodesToSink( - const std::vector> &sinkInputs, bool isConnect) override; - - int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) override; - std::vector GetAllSourceOutputsInfo() override; - std::string GetThreadName() override; - -private: - void TransStreamInfoToNodeInfoInner(const HpaeStreamInfo &streamInfo, HpaeNodeInfo &nodeInfo); - int32_t CreateRendererInputSessionInner(const HpaeStreamInfo &streamInfo); - int32_t CreateCapturerInputSessionInner(const HpaeStreamInfo &streamInfo); - int32_t DeleteRendererInputSessionInner(uint32_t sessionId); - int32_t DeleteCapturerInputSessionInner(uint32_t sessionId); - int32_t ConnectRendererInputSessionInner(uint32_t sessionId); - int32_t ConnectCapturerOutputSessionInner(uint32_t sessionId); - int32_t DisConnectRendererInputSessionInner(uint32_t sessionId); - int32_t DisConnectCapturerInputSessionInner(uint32_t sessionId); - void SetSessionStateInner(uint32_t sessionId, RendererState renderState); - void SetSessionStateInner(uint32_t sessionId, CapturerState capturerState); - void SendRequestInner(Request &&request, bool isInit = false); - uint32_t GetSinkInputNodeIdInner(); - void AddSingleNodeToSinkInner(const std::shared_ptr &node, bool isConnect = true); - void MoveAllStreamToNewSinkInner(const std::string &sinkName, const std::vector &moveIds, bool isMoveAll); - uint32_t sinkInputNodeCounter_ = 0; - std::atomic isInit_ = false; - std::atomic isMute_ = false; - HpaeSinkInfo sinkInfo_; - HpaeNoLockQueue hpaeNoLockQueue_; - std::shared_ptr hpaeInnerCapSinkNode_ = nullptr; - std::unique_ptr hpaeSignalProcessThread_ = nullptr; - std::unordered_map> sinkInputNodeMap_; - std::unordered_map> sourceOutputNodeMap_; - std::unordered_map> capturerResampleNodeMap_; - std::unordered_map> capturerSceneClusterMap_; - std::unordered_map> rendererSceneClusterMap_; - std::unordered_map capturerSessionNodeMap_; - std::unordered_map rendererSessionNodeMap_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_manager.h b/services/audio_engine/manager/include/hpae_manager.h deleted file mode 100644 index 5dce47f5e7..0000000000 --- a/services/audio_engine/manager/include/hpae_manager.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_MANAGER_H -#define HPAE_MANAGER_H -#include -#include -#include "audio_module_info.h" -#include "hpae_capturer_manager.h" -#include "hpae_renderer_manager.h" -#include "hpae_inner_capturer_manager.h" -#include "hpae_msg_channel.h" -#include "i_hpae_manager.h" -#include "i_hpae_renderer_manager.h" -#include "hpae_policy_manager.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaeManager; - -class HpaeManagerThread { -public: - HpaeManagerThread() : running_(false) - {} - ~HpaeManagerThread(); - void ActivateThread(HpaeManager *hpaeManager); - void DeactivateThread(); - void Run(); - void Notify(); - bool IsRunning() const - { - return running_.load(); - } - bool IsMsgProcessing() const - { - return recvSignal_.load(); - } - -private: - std::atomic running_; - std::atomic recvSignal_; - HpaeManager *m_hpaeManager; - std::condition_variable condition_; - std::mutex mutex_; - std::thread thread_; -}; - -class HpaeManager : public IHpaeManager, public ISendMsgCallback, public std::enable_shared_from_this { -public: - static constexpr std::string_view SPLIT_STREAM_SINK = "libmodule-split-stream-sink.z.so"; - static constexpr std::string_view HDI_SINK = "libmodule-hdi-sink.z.so"; - static constexpr std::string_view HDI_SOURCE = "libmodule-hdi-source.z.so"; - static constexpr std::string_view INNER_CAPTURER_SINK = "libmodule-inner-capturer-sink.z.so"; - HpaeManager(); - ~HpaeManager(); - // sync interface - int32_t Init() override; - int32_t DeInit() override; - int32_t RegisterSerivceCallback(const std::weak_ptr &callback) override; - int32_t RegisterHpaeDumpCallback( AudioServiceHpaeDumpCallback *callback) override; - void DumpSinkInfo(std::string deviceName) override; - void DumpSourceInfo(std::string deviceName) override; - uint32_t OpenAudioPort(const AudioModuleInfo &audioModuleInfo) override; - int32_t CloseAudioPort(int32_t audioHandleIndex) override; - int32_t GetAllSinkInputs() override; - int32_t GetAllSourceOutputs() override; - int32_t MoveSourceOutputByIndexOrName( - uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) override; - int32_t MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) override; - void HandleMsg() override; - bool IsInit() override; - bool IsRunning() override; - bool IsMsgProcessing() override; - // async interface - int32_t SetDefaultSink(std::string name) override; - int32_t SetDefaultSource(std::string name) override; - int32_t SuspendAudioDevice(std::string &audioPortName, bool isSuspend) override; - bool SetSinkMute(const std::string &sinkName, bool isMute, bool isSync = false) override; - int32_t SetSourceOutputMute(int32_t uid, bool setMute) override; - int32_t GetAllSinks() override; - - int32_t GetMsgCount(); - - void Invoke(HpaeMsgCode cmdID, const std::any &args) override; - // play and record stream interface - int32_t CreateStream(const HpaeStreamInfo &streamInfo) override; - int32_t DestroyStream(HpaeStreamClassType streamClassType, uint32_t sessionId) override; - int32_t Start(HpaeStreamClassType streamClassType, uint32_t sessionId) override; - int32_t Pause(HpaeStreamClassType streamClassType, uint32_t sessionId) override; - int32_t Flush(HpaeStreamClassType streamClassType, uint32_t sessionId) override; - int32_t Drain(HpaeStreamClassType streamClassType, uint32_t sessionId) override; - int32_t Stop(HpaeStreamClassType streamClassType, uint32_t sessionId) override; - int32_t Release(HpaeStreamClassType streamClassType, uint32_t sessionId) override; - int32_t RegisterStatusCallback(HpaeStreamClassType streamClassType, uint32_t sessionId, - const std::weak_ptr &callback) override; - // record stream interface - void RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeStreamInfo &streamInfo) override; - // play stream interface - int32_t SetClientVolume(uint32_t sessionId, float volume) override; - int32_t SetRate(uint32_t sessionId, int32_t rate) override; - int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) override; - int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) override; - int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) override; - int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) override; - int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - int32_t SetOffloadPolicy(uint32_t sessionId, int32_t state) override; - size_t GetWritableSize(uint32_t sessionId) override; - int32_t UpdateSpatializationState( - uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) override; - int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) override; - // only interface for unit test - int32_t GetSessionInfo(HpaeStreamClassType streamClassType, uint32_t sessionId, HpaeSessionInfo &sessionInfo); - - // interfaces for render effect - void InitAudioEffectChainManager(const std::vector &effectChains, - const EffectChainManagerParam &effectChainManagerParam, - const std::vector> &effectLibraryList) override; - void SetOutputDeviceSink(int32_t device, const std::string &sinkName) override; - int32_t UpdateSpatializationState(AudioSpatializationState spatializationState) override; - int32_t UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) override; - int32_t SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType) override; - int32_t EffectRotationUpdate(const uint32_t rotationState) override; - int32_t SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume) override; - int32_t SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray) override; - int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) override; - int32_t SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray) override; - int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) override; - void InitHdiState() override; - void UpdateEffectBtOffloadSupported(const bool &isSupported) override; - void UpdateParamExtra(const std::string &mainkey, const std::string &subkey, const std::string &value) override; - // interfaces for capture effect - void InitAudioEnhanceChainManager(const std::vector &enhanceChains, - const EffectChainManagerParam &managerParam, - const std::vector> &enhanceLibraryList) override; - int32_t SetInputDevice( - const uint32_t &captureId, const DeviceType &inputDevice, const std::string &deviceName = "") override; - int32_t SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice) override; - int32_t SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol) override; - int32_t SetMicrophoneMuteInfo(const bool &isMute) override; - int32_t SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol) override; - int32_t SetAudioEnhanceProperty( - const AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; - int32_t GetAudioEnhanceProperty( - AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; - int32_t SetAudioEnhanceProperty( - const AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; - int32_t GetAudioEnhanceProperty( - AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; - void UpdateExtraSceneType( - const std::string &mainkey, const std::string &subkey, const std::string &extraSceneType) override; - -private: - void TransModuleInfoToHpaeSinkInfo(const AudioModuleInfo &audioModuleInfo, HpaeSinkInfo &sinkInfo); - void TransModuleInfoToHpaeSourceInfo(const AudioModuleInfo &audioModuleInfo, HpaeSourceInfo &sourceInfo); - AudioSampleFormat TransFormatFromStringToEnum(std::string format); - int32_t CloseOutAudioPort(std::string &sinkName); - void PrintAudioModuleInfo(const AudioModuleInfo &audioModuleInfo); - int32_t CloseInAudioPort(std::string &sourceName); - void AdjustMchSinkInfo(const AudioModuleInfo &audioModuleInfo, HpaeSinkInfo &sinkInfo); - template - void RegisterHandler(HpaeMsgCode cmdID, void (HpaeManager::*func)(Args...)); - void HandleUpdateStatus( - HpaeStreamClassType streamClassType, uint32_t sessionId, uint32_t status, IOperation operation); - void HandleInitDeviceResult(std::string deviceName, int32_t result); - void HandleDeInitDeviceResult(std::string deviceName, int32_t result); - void HandleMoveSinkInput(const std::shared_ptr sinkInputNode, std::string sinkName); - void HandleMoveAllSinkInputs(const std::vector> sinkInputs, std::string sinkNam); - void HandleMoveSourceOutput(const HpaeCaptureMoveInfo moveInfo, std::string sourceName); - void HandleMoveAllSourceOutputs(const std::vector moveInfos, std::string sourceName); - void HandleDumpSinkInfo(std::string deviceName, std::string dumpStr); - void HandleDumpSourceInfo(std::string deviceName, std::string dumpStr); - - void SendRequest(Request &&request); - int32_t OpenAudioPortInner(const AudioModuleInfo &audioModuleInfo); - uint32_t OpenOutputAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex); - uint32_t OpenInputAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex); - uint32_t OpenVirtualAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex); - void HandleRendererManager(const std::string& sinkName, const HpaeStreamInfo &streamInfo); - void CreateStreamForCapInner(const HpaeStreamInfo &streamInfo); - - std::shared_ptr GetRendererManagerById(uint32_t sessionId); - std::shared_ptr GetCapturerManagerById(uint32_t sessionId); - std::shared_ptr GetRendererManagerByNmae(const std::string &sinkName); - std::shared_ptr GetCapturerManagerByName(const std::string &sourceName); - void AddStreamToCollection(const HpaeStreamInfo &streamInfo); - - void MoveToPreferSink(const std::string& name); - -private: - std::unique_ptr hpaeManagerThread_ = nullptr; - std::unique_ptr hpaePolicyManager_ = nullptr; - std::unordered_map> capturerManagerMap_; - std::unordered_map> rendererManagerMap_; - std::unordered_map capturerIdSourceNameMap_; - std::unordered_map rendererIdSinkNameMap_; - std::unordered_map idPreferSinkNameMap_; - std::unordered_map rendererIdStreamInfoMap_; - std::unordered_map capturerIdStreamInfoMap_; - std::unordered_map sinkInputs_; - std::unordered_map sourceOutputs_; - std::unordered_map sinkNameSinkIdMap_; // todo - std::unordered_map sinkIdSinkNameMap_; - std::string defaultSink_ = "Speaker"; - std::unordered_map sourceNameSourceIdMap_; - std::unordered_map sourceIdSourceNameMap_; - std::string defaultSource_ = "Built_in_mic"; - std::atomic sinkSourceIndex_ = 0; - std::atomic isInit_ = false; - - HpaeNoLockQueue hpaeNoLockQueue_; - - std::atomic receiveMsgCount_ = 0; - std::weak_ptr serviceCallback_; - AudioServiceHpaeDumpCallback *dumpCallback_ = nullptr; - std::unordered_map deviceDumpSinkInfoMap_; - std::unordered_map> handlers_; -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif // HPAE_HDI_MANAGER_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_msg_channel.h b/services/audio_engine/manager/include/hpae_msg_channel.h deleted file mode 100644 index 1b93cbe988..0000000000 --- a/services/audio_engine/manager/include/hpae_msg_channel.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_MSG_CHANNEL_H -#define HPAE_MSG_CHANNEL_H -#include -#include "i_stream.h" -#include "hpae_info.h" -#include "audio_engine_log.h" -#include "hpae_pcm_buffer.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -enum HpaeMsgCode { - UPDATE_STATUS, - INIT_DEVICE_RESULT, - DEINIT_DEVICE_RESULT, - MOVE_SINK_INPUT, - MOVE_ALL_SINK_INPUT, - MOVE_SOURCE_OUTPUT, - MOVE_ALL_SOURCE_OUTPUT, - DUMP_SINK_INFO, - DUMP_SOURCE_INFO, -}; - -enum NodeOperation { UNDERFLOW, FADED, DRAINED }; - -class ISendMsgCallback { -public: - virtual void Invoke(HpaeMsgCode cmdID, const std::any &args) = 0; -}; - -class CallbackSender { -protected: - std::weak_ptr weakCallback_; - -public: - void RegisterSendMsgCallback(std::weak_ptr cb) - { - weakCallback_ = cb; - } - - template - void TriggerCallback(HpaeMsgCode cmdID, Args &&...args) - { - if (auto callback = weakCallback_.lock()) { - // pack the arguments into a tuple - auto packed = std::make_tuple(std::forward(args)...); - callback->Invoke(cmdID, packed); - } else { - AUDIO_ERR_LOG("Hpae TriggerCallback callback is null"); - } - } -}; - -enum HpaeProcessorType { - HPAE_SCENE_DEFAULT = 0, - HPAE_SCENE_MUSIC = 1, - HPAE_SCENE_GAME = 2, - HPAE_SCENE_MOVIE = 3, - HPAE_SCENE_SPEECH = 4, - HPAE_SCENE_RING = 5, - HPAE_SCENE_VOIP_DOWN = 6, - HPAE_SCENE_OTHERS = 7, - HPAE_SCENE_EFFECT_NONE = 8, - HPAE_SCENE_EFFECT_OUT = 9, - - // up processor scene - HPAE_SCENE_VOIP_UP = 20, - HPAE_SCENE_RECORD = 21, - HPAE_SCENE_PRE_ENHANCE = 22, - HPAE_SCENE_ASR = 23, - HPAE_SCENE_VOICE_MESSAGE = 24, -}; - -// mark sourceInputNode(cluster) -enum HpaeSourceInputNodeType { - HPAE_SOURCE_DEFAULT, - HPAE_SOURCE_MIC, - HPAE_SOURCE_MIC_EC, - HPAE_SOURCE_EC, - HPAE_SOURCE_MICREF, -}; - -struct HpaeDfxNodeInfo { - uint32_t nodeId; - uint32_t sessionId; - uint32_t frameLen; - size_t historyFrameCount; - AudioSamplingRate samplingRate; - AudioSampleFormat format = AudioSampleFormat::SAMPLE_F32LE; - AudioChannel channels; - AudioChannelLayout channelLayout = AudioChannelLayout::CH_LAYOUT_UNKNOWN; - FadeType fadeType = NONE_FADE; - AudioStreamType streamType; - HpaeProcessorType sceneType; - std::string deviceClass; - std::string deviceNetId; - std::string nodeName; -}; - -class INodeCallback { -public: - virtual void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation){}; - virtual void OnFadeDone(uint32_t sessionId, IOperation operation){}; - virtual void OnRequestLatency(uint32_t sessionId, uint64_t &latency){}; - virtual void OnRewindAndFlush(uint64_t rewindTime){}; - virtual void OnNotifyQueue(){}; - // add callback - virtual uint32_t OnGetNodeId() - { - return 0; - }; - virtual void OnNotifyDfxNodeInfo(bool isConnect, uint32_t preNodeId, HpaeDfxNodeInfo &nodeInfo){}; - virtual void OnNotifyDfxNodeInfoChanged(uint32_t NodeId, const HpaeDfxNodeInfo &nodeInfo){}; -}; - -struct HpaeNodeInfo : HpaeDfxNodeInfo { - HpaeEffectInfo effectInfo; - std::weak_ptr statusCallback; - HpaeSourceBufferType sourceBufferType = HpaeSourceBufferType::HPAE_SOURCE_BUFFER_TYPE_DEFAULT; - HpaeSourceInputNodeType sourceInputNodeType = HpaeSourceInputNodeType::HPAE_SOURCE_DEFAULT; -}; - -class INodeFormatInfoCallback { -public: - virtual int32_t GetEffectNodeInputChannelInfo(uint32_t &channels, uint64_t &channelLayout) = 0; -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS - -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_offload_renderer_manager.h b/services/audio_engine/manager/include/hpae_offload_renderer_manager.h deleted file mode 100644 index a714257a4b..0000000000 --- a/services/audio_engine/manager/include/hpae_offload_renderer_manager.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_OFFLOAD_RENDER_MANAGER_H -#define HPAE_OFFLOAD_RENDER_MANAGER_H -#include -#include -#include -#include -#include -#include -#include "hpae_signal_process_thread.h" -#include "hpae_sink_input_node.h" -#include "hpae_process_cluster.h" -#include "hpae_offload_sinkoutput_node.h" -#include "hpae_msg_channel.h" -#include "hpae_no_lock_queue.h" -#include "i_hpae_renderer_manager.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaeOffloadRendererManager : public IHpaeRendererManager { -public: - HpaeOffloadRendererManager(HpaeSinkInfo& sinkInfo); - virtual ~HpaeOffloadRendererManager(); - int32_t CreateStream(const HpaeStreamInfo &streamInfo) override; - int32_t DestroyStream(uint32_t sessionId) override; - - int32_t Start(uint32_t sessionId) override; - int32_t Pause(uint32_t sessionId) override; - int32_t Flush(uint32_t sessionId) override; - int32_t Drain(uint32_t sessionId) override; - int32_t Stop(uint32_t sessionId) override; - int32_t Release(uint32_t sessionId) override; - int32_t MoveStream(uint32_t sessionId, const std::string& sinkName) override; - int32_t MoveAllStream(const std::string& sinkName, const std::vector& sessionIds, - bool isMoveAll = true) override; - int32_t SuspendStreamManager(bool isSuspend) override; - int32_t SetMute(bool isMute) override; - void Process() override; - void HandleMsg() override; - int32_t Init() override; - int32_t DeInit(bool isMoveDefault = false) override; - bool IsInit() override; - bool IsRunning(void) override; - bool IsMsgProcessing() override; - bool DeactivateThread() override; - int32_t SetClientVolume(uint32_t sessionId, float volume) override; - int32_t SetRate(uint32_t sessionId, int32_t rate) override; - int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) override; - int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) override; - int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) override; - int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) override; - int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - - int32_t SetOffloadPolicy(uint32_t sessionId, int32_t state) override; - size_t GetWritableSize(uint32_t sessionId) override; - int32_t UpdateSpatializationState(uint32_t sessionId, bool spatializationEnabled, - bool headTrackingEnabled) override; - int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) override; - std::vector GetAllSinkInputsInfo() override; - int32_t GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) override; - HpaeSinkInfo GetSinkInfo() override; - - int32_t AddNodeToSink(const std::shared_ptr &node) override; - int32_t AddAllNodesToSink( - const std::vector> &sinkInputs, bool isConnect) override; - - void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) override; - void OnRequestLatency(uint32_t sessionId, uint64_t &latency) override; - void OnRewindAndFlush(uint64_t rewindTime) override; - void OnNotifyQueue() override; - std::string GetThreadName() override; - void DumpSinkInfo() override; -private: - void SendRequest(Request &&request, bool isInit = false); - int32_t StartRenderSink(); - int32_t CreateInputSession(const HpaeStreamInfo &streamInfo); - int32_t ConnectInputSession(); - int32_t DisConnectInputSession(); - void AddSingleNodeToSink(const std::shared_ptr &node, bool isConnect = true); - void MoveAllStreamToNewSink(const std::string &sinkName, const std::vector &moveIds, bool isMoveAll); - - HpaeRenderSessionInfo sessionInfo_; - std::shared_ptr sinkInputNode_ = nullptr; - std::shared_ptr formatConverterNode_ = nullptr; - std::unique_ptr sinkOutputNode_ = nullptr; - HpaeNoLockQueue hpaeNoLockQueue_; - std::unique_ptr hpaeSignalProcessThread_ = nullptr; - std::atomic isInit_ = false; - HpaeSinkInfo sinkInfo_; - bool isMute_ = false; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif // HPAE_OFFLOAD_RENDER_MANAGER_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_policy_manager.h b/services/audio_engine/manager/include/hpae_policy_manager.h deleted file mode 100644 index cb8b3b685c..0000000000 --- a/services/audio_engine/manager/include/hpae_policy_manager.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_POLICY_MANAGER_H -#define HPAE_POLICY_MANAGER_H - -#include "audio_effect.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - - -class HpaePolicyManager { -public: - HpaePolicyManager(); - ~HpaePolicyManager(); - // interfaces for render effect - void InitAudioEffectChainManager(const std::vector &effectChains, - const EffectChainManagerParam &effectChainManagerParam, - const std::vector> &effectLibraryList); - void SetOutputDeviceSink(int32_t device, const std::string &sinkName); - int32_t UpdateSpatializationState(AudioSpatializationState spatializationState); - int32_t UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType); - int32_t SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType); - int32_t EffectRotationUpdate(const uint32_t rotationState); - int32_t SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume); - int32_t SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray); - int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray); - int32_t SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray); - int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray); - void InitHdiState(); - void UpdateEffectBtOffloadSupported(const bool &isSupported); - void UpdateParamExtra(const std::string &mainkey, const std::string &subkey, const std::string &value); - - // interfaces for capture effect - void InitAudioEnhanceChainManager(const std::vector &enhanceChains, - const EffectChainManagerParam &managerParam, - const std::vector> &enhanceLibraryList); - int32_t SetInputDevice(const uint32_t &captureId, const DeviceType &inputDevice, - const std::string &deviceName = ""); - int32_t SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice); - int32_t SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol); - int32_t SetMicrophoneMuteInfo(const bool &isMute); - int32_t SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol); - int32_t SetAudioEnhanceProperty(const AudioEffectPropertyArrayV3 &propertyArray, - DeviceType deviceType = DEVICE_TYPE_NONE); - int32_t GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, - DeviceType deviceType = DEVICE_TYPE_NONE); - int32_t SetAudioEnhanceProperty(const AudioEnhancePropertyArray &propertyArray, - DeviceType deviceType = DEVICE_TYPE_NONE); - int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, - DeviceType deviceType = DEVICE_TYPE_NONE); - void UpdateExtraSceneType(const std::string &mainkey, const std::string &subkey, - const std::string &extraSceneType); -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif // HPAE_POLICY_MANAGER_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_renderer_manager.h b/services/audio_engine/manager/include/hpae_renderer_manager.h deleted file mode 100644 index cc1bfe4c48..0000000000 --- a/services/audio_engine/manager/include/hpae_renderer_manager.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_RENDER_MANAGER_H -#define HPAE_RENDER_MANAGER_H -#include -#include -#include -#include -#include -#include -#include "hpae_signal_process_thread.h" -#include "hpae_sink_input_node.h" -#include "hpae_process_cluster.h" -#include "hpae_output_cluster.h" -#include "hpae_msg_channel.h" -#include "hpae_no_lock_queue.h" -#include "i_hpae_renderer_manager.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaeRendererManager : public IHpaeRendererManager { -public: - HpaeRendererManager(HpaeSinkInfo &sinkInfo); - virtual ~HpaeRendererManager(); - int32_t CreateStream(const HpaeStreamInfo &streamInfo) override; - int32_t DestroyStream(uint32_t sessionId) override; - - int32_t Start(uint32_t sessionId) override; - int32_t Pause(uint32_t sessionId) override; - int32_t Flush(uint32_t sessionId) override; - int32_t Drain(uint32_t sessionId) override; - int32_t Stop(uint32_t sessionId) override; - int32_t Release(uint32_t sessionId) override; - int32_t MoveStream(uint32_t sessionId, const std::string &sinkName) override; - int32_t MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, - bool isMoveAll = true) override; - int32_t SuspendStreamManager(bool isSuspend) override; - int32_t SetMute(bool isMute) override; - void Process() override; - void HandleMsg() override; - int32_t Init() override; - int32_t DeInit(bool isMoveDefault = false) override; - bool IsInit() override; - bool IsRunning(void) override; - bool IsMsgProcessing() override; - bool DeactivateThread() override; - int32_t SetClientVolume(uint32_t sessionId, float volume) override; - int32_t SetRate(uint32_t sessionId, int32_t rate) override; - int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) override; - int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) override; - int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) override; - int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) override; - int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - - size_t GetWritableSize(uint32_t sessionId) override; - int32_t UpdateSpatializationState( - uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) override; - int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) override; - std::vector GetAllSinkInputsInfo() override; - int32_t GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) override; - HpaeSinkInfo GetSinkInfo() override; - - int32_t AddNodeToSink(const std::shared_ptr &node) override; - int32_t AddAllNodesToSink( - const std::vector> &sinkInputs, bool isConnect) override; - - int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) override; - void OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) override; - void OnFadeDone(uint32_t sessionId, IOperation operation) override; - void OnRequestLatency(uint32_t sessionId, uint64_t &latency) override; - void OnNotifyQueue() override; - std::string GetThreadName() override; - void DumpSinkInfo() override; -private: - void SendRequest(Request &&request, bool isInit = false); - int32_t StartRenderSink(); - bool IsMchDevice(); - int32_t CreateInputSession(const HpaeStreamInfo &streamInfo); - int32_t DeleteInputSession(uint32_t sessionId); - int32_t ConnectInputSession(uint32_t sessionId); - int32_t DisConnectInputSession(uint32_t sessionId); - int32_t ConnectMchInputSession(uint32_t sessionId); - int32_t DisConnectMchInputSession(uint32_t sessionId); - int32_t DeleteMchInputSession(uint32_t sessionId); - void SetSessionState(uint32_t sessionId, RendererState renderState); - void AddSingleNodeToSink(const std::shared_ptr &node, bool isConnect = true); - void MoveAllStreamToNewSink(const std::string &sinkName, const std::vector& moveIds, bool isMoveAll); - void UpdateProcessClusterConnection(uint32_t sessionId, int32_t effectMode); - void ConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType); - void DisConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType); - void DeleteProcessCluster(const HpaeNodeInfo &nodeInfo, HpaeProcessorType sceneType, uint32_t sessionId); - std::shared_ptr CreateProcessCluster(HpaeNodeInfo &nodeInfo); - bool SetSessionFade(uint32_t sessionId, IOperation operation); - -private: - std::unordered_map sessionNodeMap_; - std::unordered_map> sceneClusterMap_; - std::unordered_map> sinkInputNodeMap_; - std::unordered_map> mchIdGainNodeMap_; - std::unique_ptr outputCluster_ = nullptr; - HpaeNoLockQueue hpaeNoLockQueue_; - std::unique_ptr hpaeSignalProcessThread_ = nullptr; - std::atomic isInit_ = false; - std::atomic isMute_ = false; - HpaeSinkInfo sinkInfo_; - std::unordered_map sceneTypeToProcessClusterCountMap_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_signal_process_thread.h b/services/audio_engine/manager/include/hpae_signal_process_thread.h deleted file mode 100644 index 719f420603..0000000000 --- a/services/audio_engine/manager/include/hpae_signal_process_thread.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_SIGNAL_PROCESS_THREAD_H -#define HPAE_SIGNAL_PROCESS_THREAD_H -#include -#include -#include -#include -#include "hpae_stream_manager.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaeSignalProcessThread { -public: - HpaeSignalProcessThread() : running_(false), recvSignal_(false) - {} - ~HpaeSignalProcessThread(); - void ActivateThread(const std::weak_ptr& streamManager); - void DeactivateThread(); - void Notify(); - void Run(); - bool IsRunning() const - { - return running_.load(); - } - bool IsMsgProcessing() const - { - return recvSignal_.load(); - } -private: - - std::atomic running_; - std::atomic recvSignal_; - std::weak_ptr streamManager_; - std::thread thread_; - std::condition_variable condition_; - std::mutex mutex_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/hpae_stream_manager.h b/services/audio_engine/manager/include/hpae_stream_manager.h deleted file mode 100644 index df67bd734b..0000000000 --- a/services/audio_engine/manager/include/hpae_stream_manager.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_STREAM_MANAGER_H -#define HPAE_STREAM_MANAGER_H -#include -#include "audio_stream_info.h" -#include "hpae_define.h" -#include "i_stream.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaeStreamManager : public CallbackSender, - public INodeCallback, - public std::enable_shared_from_this { -public: - virtual ~HpaeStreamManager() - {} - virtual int32_t CreateStream(const HpaeStreamInfo &streamInfo) = 0; - virtual int32_t DestroyStream(uint32_t sessionId) = 0; - virtual int32_t Start(uint32_t sessionId) = 0; - virtual int32_t Pause(uint32_t sessionId) = 0; - virtual int32_t Flush(uint32_t sessionId) = 0; - virtual int32_t Drain(uint32_t sessionId) = 0; - virtual int32_t Stop(uint32_t sessionId) = 0; - virtual int32_t Release(uint32_t sessionId) = 0; - virtual int32_t MoveStream(uint32_t sessionId, const std::string &sinkName) = 0; - virtual int32_t MoveAllStream(const std::string &name, const std::vector& sessionIds, - bool isMoveAll = true) = 0; - virtual int32_t SetMute(bool isMute) = 0; - virtual void Process() = 0; - virtual void HandleMsg() = 0; - virtual int32_t Init() = 0; - virtual int32_t DeInit(bool isMoveDefault = false) = 0; - virtual bool IsInit() = 0; - virtual bool IsRunning() = 0; - virtual bool IsMsgProcessing() = 0; - virtual bool DeactivateThread() = 0; - virtual std::string GetThreadName() = 0; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/i_hpae_capturer_manager.h b/services/audio_engine/manager/include/i_hpae_capturer_manager.h deleted file mode 100644 index d9b07373ab..0000000000 --- a/services/audio_engine/manager/include/i_hpae_capturer_manager.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_I_CAPTURER_MANAGER_H -#define HPAE_I_CAPTURER_MANAGER_H -#include "audio_info.h" -#include "i_capturer_stream.h" -#include "hpae_stream_manager.h" -#include "hpae_capture_move_info.h" -#include "audio_engine_log.h" -#include "hpae_dfx_tree.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class IHpaeCapturerManager : public HpaeStreamManager { -public: - virtual ~IHpaeCapturerManager() {} - virtual int32_t CreateStream(const HpaeStreamInfo& streamInfo) = 0; - virtual int32_t DestroyStream(uint32_t sessionId) = 0; - - virtual int32_t Start(uint32_t sessionId) = 0; - virtual int32_t Pause(uint32_t sessionId) = 0; - virtual int32_t Flush(uint32_t sessionId) = 0; - virtual int32_t Drain(uint32_t sessionId) = 0; - virtual int32_t Stop(uint32_t sessionId) = 0; - virtual int32_t Release(uint32_t sessionId) = 0; - virtual void Process() = 0; - virtual void HandleMsg() = 0; - virtual int32_t Init() = 0; - virtual int32_t DeInit(bool isMoveDefault = false) = 0; - virtual bool IsInit() = 0; - virtual bool IsRunning(void) = 0; - virtual bool IsMsgProcessing() = 0; - virtual bool DeactivateThread() = 0; - - virtual int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; - virtual int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) = 0; - virtual HpaeSourceInfo GetSourceInfo() = 0; - virtual std::vector GetAllSourceOutputsInfo() = 0; - virtual int32_t AddNodeToSource(const HpaeCaptureMoveInfo &moveInfo) = 0; - virtual int32_t AddAllNodesToSource(const std::vector &moveInfos, bool isConnect) = 0; - virtual std::string GetThreadName() = 0; - virtual int32_t ReloadCaptureManager(const HpaeSourceInfo &sourceInfo) = 0; - virtual void DumpSourceInfo() {}; - virtual void UploadDumpSourceInfo(std::string &deviceName) - { -#ifdef ENABLE_HIDUMP_DFX - std::string dumpStr; - dfxTree_.PrintTree(dumpStr); - TriggerCallback(DUMP_SOURCE_INFO, deviceName, dumpStr); -#endif - }; - virtual void OnNotifyDfxNodeInfo(bool isConnect, uint32_t preNodeId, HpaeDfxNodeInfo &nodeInfo) - { -#ifdef ENABLE_HIDUMP_DFX - AUDIO_INFO_LOG("%{public}s preNodeId %{public}u nodeName:%{public}s, NodeId: %{public}u", - isConnect ? "connect" : "disconnect", - preNodeId, - nodeInfo.nodeName.c_str(), - nodeInfo.nodeId); - if (isConnect) { - dfxTree_.Insert(preNodeId, nodeInfo); - } else { - dfxTree_.Remove(nodeInfo.nodeId); - } -#endif - }; - - virtual uint32_t OnGetNodeId() - { - if (nodeIdCounter_.load() == std::numeric_limits::max()) { - nodeIdCounter_.store(MIN_START_NODE_ID); - } else { - nodeIdCounter_.fetch_add(1); - } - return nodeIdCounter_.load(); - }; -private: - std::atomic nodeIdCounter_ = 0; -#ifdef ENABLE_HIDUMP_DFX - HpaeDfxTree dfxTree_; -#endif -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/include/i_hpae_manager.h b/services/audio_engine/manager/include/i_hpae_manager.h deleted file mode 100644 index 26d9475d4b..0000000000 --- a/services/audio_engine/manager/include/i_hpae_manager.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2025 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 IHPAE_MANAGER_H -#define IHPAE_MANAGER_H -#include "audio_module_info.h" -#include "hpae_info.h" -#include "i_capturer_stream.h" -#include "i_renderer_stream.h" -#include "audio_service_hpae_callback.h" -#include "audio_service_hpae_dump_callback.h" -#include "audio_effect.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class IHpaeManager { -public: - virtual ~IHpaeManager() = default; - - static std::shared_ptr GetHpaeManager(); - - virtual int32_t Init() = 0; - virtual int32_t DeInit() = 0; - virtual int32_t RegisterSerivceCallback(const std::weak_ptr &callback) = 0; - virtual int32_t RegisterHpaeDumpCallback( AudioServiceHpaeDumpCallback *callback) = 0; - virtual void DumpSinkInfo(std::string deviceName) = 0; - virtual void DumpSourceInfo(std::string deviceName) = 0; - virtual uint32_t OpenAudioPort(const AudioModuleInfo &audioModuleInfo) = 0; - virtual int32_t CloseAudioPort(int32_t audioHandleIndex) = 0; - - virtual int32_t SetDefaultSink(std::string name) = 0; - virtual int32_t SetDefaultSource(std::string name) = 0; - virtual int32_t GetAllSinkInputs() = 0; - virtual int32_t GetAllSourceOutputs() = 0; - virtual int32_t MoveSourceOutputByIndexOrName( - uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) = 0; - virtual int32_t MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) = 0; - virtual void HandleMsg() = 0; - virtual bool IsInit() = 0; - virtual bool IsRunning() = 0; - virtual bool IsMsgProcessing() = 0; - virtual int32_t SuspendAudioDevice(std::string &audioPortName, bool isSuspend) = 0; - virtual bool SetSinkMute(const std::string &sinkName, bool isMute, bool isSync = false) = 0; - virtual int32_t SetSourceOutputMute(int32_t uid, bool setMute) = 0; - virtual int32_t GetAllSinks() = 0; - - virtual int32_t CreateStream(const HpaeStreamInfo &streamInfo) = 0; - virtual int32_t DestroyStream(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; - virtual int32_t Start(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; - virtual int32_t Pause(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; - virtual int32_t Flush(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; - virtual int32_t Drain(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; - virtual int32_t Stop(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; - virtual int32_t Release(HpaeStreamClassType streamClassType, uint32_t sessionId) = 0; - virtual int32_t RegisterStatusCallback( - HpaeStreamClassType streamClassType, uint32_t sessionId, const std::weak_ptr &callback) = 0; - - virtual void RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; - virtual int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeStreamInfo &streamInfo) = 0; - - virtual int32_t SetClientVolume(uint32_t sessionId, float volume) = 0; - virtual int32_t SetRate(uint32_t sessionId, int32_t rate) = 0; - virtual int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) = 0; - virtual int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) = 0; - virtual int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) = 0; - virtual int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) = 0; - virtual int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; - - virtual int32_t SetOffloadPolicy(uint32_t sessionId, int32_t state) = 0; - virtual size_t GetWritableSize(uint32_t sessionId) = 0; - virtual int32_t UpdateSpatializationState( - uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) = 0; - virtual int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) = 0; - - // interfaces for render effect - virtual void InitAudioEffectChainManager(const std::vector &effectChains, - const EffectChainManagerParam &effectChainManagerParam, - const std::vector> &effectLibraryList) = 0; - virtual void SetOutputDeviceSink(int32_t device, const std::string &sinkName) = 0; - virtual int32_t UpdateSpatializationState(AudioSpatializationState spatializationState) = 0; - virtual int32_t UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) = 0; - virtual int32_t SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType) = 0; - virtual int32_t EffectRotationUpdate(const uint32_t rotationState) = 0; - virtual int32_t SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume) = 0; - virtual int32_t SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray) = 0; - virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) = 0; - virtual int32_t SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray) = 0; - virtual int32_t GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) = 0; - virtual void InitHdiState() = 0; - virtual void UpdateEffectBtOffloadSupported(const bool &isSupported) = 0; - virtual void UpdateParamExtra(const std::string &mainkey, const std::string &subkey, const std::string &value) = 0; - // interfaces for capture effect - virtual void InitAudioEnhanceChainManager(const std::vector &enhanceChains, - const EffectChainManagerParam &managerParam, - const std::vector> &enhanceLibraryList) = 0; - virtual int32_t SetInputDevice( - const uint32_t &captureId, const DeviceType &inputDevice, const std::string &deviceName = "") = 0; - virtual int32_t SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice) = 0; - virtual int32_t SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol) = 0; - virtual int32_t SetMicrophoneMuteInfo(const bool &isMute) = 0; - virtual int32_t SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol) = 0; - virtual int32_t SetAudioEnhanceProperty( - const AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; - virtual int32_t GetAudioEnhanceProperty( - AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; - virtual int32_t SetAudioEnhanceProperty( - const AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; - virtual int32_t GetAudioEnhanceProperty( - AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) = 0; - virtual void UpdateExtraSceneType( - const std::string &mainkey, const std::string &subkey, const std::string &extraSceneType) = 0; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif // IHPAE_MANAGER_H \ No newline at end of file diff --git a/services/audio_engine/manager/include/i_hpae_renderer_manager.h b/services/audio_engine/manager/include/i_hpae_renderer_manager.h deleted file mode 100644 index df1f169fd5..0000000000 --- a/services/audio_engine/manager/include/i_hpae_renderer_manager.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_I_RENDER_MANAGER_H -#define HPAE_I_RENDER_MANAGER_H -#include "audio_info.h" -#include "audio_errors.h" -#include "i_renderer_stream.h" -#include "i_capturer_stream.h" -#include "hpae_sink_input_node.h" -#include "hpae_stream_manager.h" -#include "audio_engine_log.h" -#include "hpae_dfx_tree.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class IHpaeRendererManager : public HpaeStreamManager { -public: - static std::shared_ptr CreateRendererManager(HpaeSinkInfo &sinkInfo); - - virtual ~IHpaeRendererManager() - {} - virtual int32_t CreateStream(const HpaeStreamInfo &streamInfo) = 0; - virtual int32_t DestroyStream(uint32_t sessionId) = 0; - virtual int32_t Start(uint32_t sessionId) = 0; - virtual int32_t Pause(uint32_t sessionId) = 0; - virtual int32_t Flush(uint32_t sessionId) = 0; - virtual int32_t Drain(uint32_t sessionId) = 0; - virtual int32_t Stop(uint32_t sessionId) = 0; - virtual int32_t Release(uint32_t sessionId) = 0; - virtual int32_t SuspendStreamManager(bool isSuspend) = 0; - virtual void Process() = 0; - virtual void HandleMsg() = 0; - virtual int32_t Init() = 0; - virtual int32_t DeInit(bool isMoveDefault = false) = 0; - virtual bool IsInit() = 0; - virtual bool IsRunning(void) = 0; - virtual bool IsMsgProcessing() = 0; - virtual bool DeactivateThread() = 0; - virtual int32_t SetClientVolume(uint32_t sessionId, float volume) = 0; - virtual int32_t SetRate(uint32_t sessionId, int32_t rate) = 0; - virtual int32_t SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) = 0; - virtual int32_t GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) = 0; - virtual int32_t SetPrivacyType(uint32_t sessionId, int32_t privacyType) = 0; - virtual int32_t GetPrivacyType(uint32_t sessionId, int32_t &privacyType) = 0; - virtual int32_t RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; - - virtual int32_t SetOffloadPolicy(uint32_t sessionId, int32_t state) - { - return ERR_NOT_SUPPORTED; - }; - virtual size_t GetWritableSize(uint32_t sessionId) = 0; - virtual int32_t UpdateSpatializationState( - uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) = 0; - virtual int32_t UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) = 0; - virtual std::vector GetAllSinkInputsInfo() = 0; - virtual int32_t GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) = 0; - virtual HpaeSinkInfo GetSinkInfo() = 0; - virtual int32_t AddNodeToSink(const std::shared_ptr &node) = 0; - virtual int32_t AddAllNodesToSink( - const std::vector> &sinkInputs, bool isConnect) = 0; - virtual int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) = 0; - virtual int32_t GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) - { - return 0; - }; - virtual std::vector GetAllSourceOutputsInfo() - { - return {}; - }; - virtual std::string GetThreadName() = 0; - - virtual void DumpSinkInfo() {}; - - virtual void UploadDumpSinkInfo(std::string& deviceName); - - virtual void OnNotifyDfxNodeInfo(bool isConnect, uint32_t preNodeId, HpaeDfxNodeInfo &nodeInfo); - - virtual uint32_t OnGetNodeId(); - - virtual void OnNotifyDfxNodeInfoChanged(uint32_t nodeId, const HpaeDfxNodeInfo &nodeInfo) - { -#ifdef ENABLE_HIDUMP_DFX - dfxTree_.UpdateNodeInfo(nodeId, nodeInfo); -#endif - } - -private: - std::atomic nodeIdCounter_ = 0; -#ifdef ENABLE_HIDUMP_DFX - HpaeDfxTree dfxTree_; -#endif -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_capturer_manager.cpp b/services/audio_engine/manager/src/hpae_capturer_manager.cpp deleted file mode 100644 index e95d05cbf9..0000000000 --- a/services/audio_engine/manager/src/hpae_capturer_manager.cpp +++ /dev/null @@ -1,863 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeCapturerManager" -#endif - -#include "hpae_capturer_manager.h" -#include "audio_info.h" -#include "audio_engine_log.h" -#include "audio_errors.h" -#include "hpae_node_common.h" -#include "audio_utils.h" -#include "audio_effect_map.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -const std::string DEFAULT_DEVICE_CLASS = "primary"; -const std::string DEFAULT_DEVICE_NETWORKID = "LocalDevice"; - -HpaeCapturerManager::HpaeCapturerManager(HpaeSourceInfo &sourceInfo) - : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sourceInfo_(sourceInfo) -{ - AUDIO_INFO_LOG("Source info: mic[%{public}d_%{public}d_%{public}d] "\ - "ec[%{public}d_%{public}d_%{public}d] "\ - "micref[%{public}d_%{public}d_%{public}d]", - sourceInfo.samplingRate, sourceInfo.channels, sourceInfo.format, - sourceInfo.ecSamplingRate, sourceInfo.ecChannels, sourceInfo.ecFormat, - sourceInfo.micRefSamplingRate, sourceInfo.micRefChannels, sourceInfo.micRefFormat); -} - -HpaeCapturerManager::~HpaeCapturerManager() -{ - if (isInit_.load()) { - DeInit(); - } -} - -void HpaeCapturerManager::SetCaptureId(uint32_t captureId) -{ - captureId_ = captureId; -} - -int32_t HpaeCapturerManager::CaptureEffectCreate(const HpaeProcessorType &processorType, - const AudioEnhanceScene &sceneType) -{ - const std::unordered_map &audioEnhanceSupportedSceneTypes = - GetEnhanceSupportedSceneType(); - auto item = audioEnhanceSupportedSceneTypes.find(sceneType); - CHECK_AND_RETURN_RET_LOG(item != audioEnhanceSupportedSceneTypes.end(), ERROR, - "sceneType %{public}d not supported", sceneType); - uint64_t sceneCode = static_cast(sceneType); - uint64_t sceneKeyCode = 0; - sceneKeyCode = (sceneCode << SCENE_TYPE_OFFSET) + (captureId_ << CAPTURER_ID_OFFSET) + renderId_; - AUDIO_INFO_LOG("sceneCode:%{public}" PRIu64 "sceneKeyCode:%{public}" PRIu64, sceneCode, sceneKeyCode); - CaptureEffectAttr attr = {}; - attr.micChannels = static_cast(sourceInfo_.channels); - attr.ecChannels = static_cast(sourceInfo_.ecChannels); - attr.micRefChannels = static_cast(sourceInfo_.micRefChannels); - - int32_t ret = sceneClusterMap_[processorType]->CaptureEffectCreate(sceneKeyCode, attr); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "sceneType[%{public}u] create failed", sceneType); - return SUCCESS; -} - -int32_t HpaeCapturerManager::CreateOutputSession(const HpaeStreamInfo &streamInfo) -{ - AUDIO_INFO_LOG("Create output node:%{public}d", streamInfo.sessionId); - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = OnGetNodeId(); - nodeInfo.nodeName = "HpaeSourceOutputNode"; - nodeInfo.channels = streamInfo.channels; - nodeInfo.format = streamInfo.format; - nodeInfo.frameLen = streamInfo.frameLen; - nodeInfo.streamType = streamInfo.streamType; - nodeInfo.sessionId = streamInfo.sessionId; - nodeInfo.samplingRate = (AudioSamplingRate)streamInfo.samplingRate; - HpaeProcessorType sceneType = TransSourceTypeToSceneType(streamInfo.sourceType); - nodeInfo.sceneType = sceneType; - nodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC; - nodeInfo.statusCallback = weak_from_this(); - - // todo: sourceType->processorType->sceneType => sourceType->sceneType - AudioEnhanceScene enhanceScene = TransProcessType2EnhanceScene(sceneType); - nodeInfo.effectInfo.enhanceScene = enhanceScene; - sourceOutputNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); - sessionNodeMap_[streamInfo.sessionId].sceneType = sceneType; - - if (sceneType != HPAE_SCENE_EFFECT_NONE && sceneClusterMap_.find(sceneType) == sceneClusterMap_.end()) { - // todo: algorithm instance count control - sceneClusterMap_[sceneType] = std::make_shared(nodeInfo); - if (CaptureEffectCreate(sceneType, enhanceScene) != SUCCESS) { - sceneClusterMap_.erase(sceneType); - } - } - - return SUCCESS; -} - -int32_t HpaeCapturerManager::CaptureEffectRelease(const HpaeProcessorType &sceneType) -{ - uint64_t sceneCode = static_cast(TransProcessType2EnhanceScene(sceneType)); - uint64_t sceneKeyCode = 0; - sceneKeyCode = (sceneCode << SCENE_TYPE_OFFSET) + (captureId_ << CAPTURER_ID_OFFSET) + renderId_; - int32_t ret = sceneClusterMap_[sceneType]->CaptureEffectRelease(sceneKeyCode); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "sceneType[%{public}u] release failed", sceneType); - return SUCCESS; -} - -void HpaeCapturerManager::DisConnectSceneClusterFromSourceInputCluster(HpaeProcessorType &sceneType) -{ - if (sceneClusterMap_[sceneType]->GetOutputPortNum() != 0) { - return; - } - // need to disconnect sceneCluster and sourceInputCluster - HpaeNodeInfo ecNodeInfo; - if (CheckSceneTypeNeedEc(sceneType) && - sceneClusterMap_[sceneType]->GetCapturerEffectConfig(ecNodeInfo, HPAE_SOURCE_BUFFER_TYPE_EC)) { - if (sourceInfo_.ecType == HPAE_EC_TYPE_SAME_ADAPTER) { - sceneClusterMap_[sceneType]->DisConnectWithInfo( - sourceInputClusterMap_[mainMicType_], ecNodeInfo); // ec from mic - } else if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { - sceneClusterMap_[sceneType]->DisConnectWithInfo( - sourceInputClusterMap_[HPAE_SOURCE_EC], ecNodeInfo); // ec - } - } - - HpaeNodeInfo micRefNodeInfo; - if (CheckSceneTypeNeedMicRef(sceneType) && - sceneClusterMap_[sceneType]->GetCapturerEffectConfig(micRefNodeInfo, HPAE_SOURCE_BUFFER_TYPE_MICREF) && - sourceInfo_.micRef == HPAE_REF_ON) { - sceneClusterMap_[sceneType]->DisConnectWithInfo( - sourceInputClusterMap_[HPAE_SOURCE_MICREF], micRefNodeInfo); // micref - } - - HpaeNodeInfo micNodeInfo; - if (sceneClusterMap_[sceneType]->GetCapturerEffectConfig(micNodeInfo, HPAE_SOURCE_BUFFER_TYPE_MIC)) { - sceneClusterMap_[sceneType]->DisConnectWithInfo( - sourceInputClusterMap_[mainMicType_], micNodeInfo); // mic - } - return; -} - -int32_t HpaeCapturerManager::DeleteOutputSession(uint32_t sessionId) -{ - AUDIO_INFO_LOG("delete output node:%{public}d, source name:%{public}s", sessionId, sourceInfo_.deviceClass.c_str()); - if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { - return SUCCESS; - } - - if (!sourceOutputNodeMap_[sessionId]) { - sourceOutputNodeMap_.erase(sessionId); - sessionNodeMap_.erase(sessionId); - return SUCCESS; - } - - HpaeProcessorType sceneType = sessionNodeMap_[sessionId].sceneType; - if (sceneType != HPAE_SCENE_EFFECT_NONE && sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - sourceOutputNodeMap_[sessionId]->DisConnectWithInfo( - sceneClusterMap_[sceneType], sourceOutputNodeMap_[sessionId]->GetNodeInfo()); - DisConnectSceneClusterFromSourceInputCluster(sceneType); - if (sceneClusterMap_[sceneType]->GetOutputPortNum() == 0) { - CaptureEffectRelease(sceneType); - sceneClusterMap_.erase(sceneType); - } - } else { - sourceOutputNodeMap_[sessionId]->DisConnect(sourceInputClusterMap_[mainMicType_]); - } - sourceOutputNodeMap_.erase(sessionId); - sessionNodeMap_.erase(sessionId); - return SUCCESS; -} - -void HpaeCapturerManager::SetSessionState(uint32_t sessionId, CapturerState capturerState) -{ - sessionNodeMap_[sessionId].state = capturerState; -} - -int32_t HpaeCapturerManager::CreateStream(const HpaeStreamInfo &streamInfo) -{ - if (!IsInit()) { - return ERR_INVALID_OPERATION; - } - auto request = [this, streamInfo]() { - AUDIO_INFO_LOG("CreateStream sessionId %{public}u deviceName %{public}s", - streamInfo.sessionId, - sourceInfo_.deviceName.c_str()); - CreateOutputSession(streamInfo); - SetSessionState(streamInfo.sessionId, CAPTURER_NEW); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeCapturerManager::DestroyStream(uint32_t sessionId) -{ - if (!IsInit()) { - return ERR_INVALID_OPERATION; - } - auto request = [this, sessionId]() { - DeleteOutputSession(sessionId); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeCapturerManager::ConnectProcessClusterWithEc(HpaeProcessorType &sceneType) -{ - HpaeNodeInfo ecNodeInfo; - if (CheckSceneTypeNeedEc(sceneType) && - sceneClusterMap_[sceneType]->GetCapturerEffectConfig(ecNodeInfo, HPAE_SOURCE_BUFFER_TYPE_EC)) { - ecNodeInfo.statusCallback = weak_from_this(); - if(sourceInfo_.ecType == HPAE_EC_TYPE_SAME_ADAPTER) { - sceneClusterMap_[sceneType]->ConnectWithInfo(sourceInputClusterMap_[mainMicType_], ecNodeInfo); // ec from mic - } else if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { - sceneClusterMap_[sceneType]->ConnectWithInfo(sourceInputClusterMap_[HPAE_SOURCE_EC], ecNodeInfo); // ec - } - } - return SUCCESS; -} - -int32_t HpaeCapturerManager::ConnectProcessClusterWithMicRef(HpaeProcessorType &sceneType) -{ - HpaeNodeInfo micRefNodeInfo; - if (CheckSceneTypeNeedMicRef(sceneType) && - sceneClusterMap_[sceneType]->GetCapturerEffectConfig(micRefNodeInfo, HPAE_SOURCE_BUFFER_TYPE_MICREF)&& - sourceInfo_.micRef == HPAE_REF_ON) { - micRefNodeInfo.statusCallback = weak_from_this(); - sceneClusterMap_[sceneType]->ConnectWithInfo( - sourceInputClusterMap_[HPAE_SOURCE_MICREF], micRefNodeInfo); // micref - } - return SUCCESS; -} - -int32_t HpaeCapturerManager::ConnectOutputSession(uint32_t sessionId) -{ - CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), ERR_INVALID_PARAM, - "ConnectOutputSession error, sessionId %{public}u can not find in sourceOutputNodeMap.\n", sessionId); - - HpaeProcessorType sceneType = sessionNodeMap_[sessionId].sceneType; - if (sceneType != HPAE_SCENE_EFFECT_NONE && sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - // 1. Determine if the ResampleNode needs to be created - // 2. If ResampleNode needs to be created, it should be connected to the UpEffectNode after creation - // 3. Connect the SourceOutputNode to the ResampleNode - sourceOutputNodeMap_[sessionId]->ConnectWithInfo(sceneClusterMap_[sceneType], - sourceOutputNodeMap_[sessionId]->GetNodeInfo()); - HpaeNodeInfo micNodeInfo; - micNodeInfo.statusCallback = weak_from_this(); - if (sceneClusterMap_[sceneType]->GetCapturerEffectConfig(micNodeInfo, HPAE_SOURCE_BUFFER_TYPE_MIC)) { - sceneClusterMap_[sceneType]->ConnectWithInfo(sourceInputClusterMap_[mainMicType_], micNodeInfo); // mic - } - ConnectProcessClusterWithEc(sceneType); - ConnectProcessClusterWithMicRef(sceneType); - } else { - sourceOutputNodeMap_[sessionId]->ConnectWithInfo(sourceInputClusterMap_[mainMicType_], - sourceOutputNodeMap_[sessionId]->GetNodeInfo()); - } - return SUCCESS; -} - -int32_t HpaeCapturerManager::Start(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeCapturerManager::Start"); - CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), - ERR_INVALID_PARAM, "sessionId %{public}u can not find in sourceOutputNodeMap.", sessionId); - auto request = [this, sessionId]() { - AUDIO_INFO_LOG("Start sessionId %{public}u", sessionId); - ConnectOutputSession(sessionId); - SetSessionState(sessionId, CAPTURER_RUNNING); - if (sourceInputClusterMap_[mainMicType_]->GetSourceState() != CAPTURER_RUNNING) { - int32_t ret = sourceInputClusterMap_[mainMicType_]->CapturerSourceStart(); - CHECK_AND_RETURN_LOG(ret == SUCCESS, "Capturer source start error, ret = %{public}d.\n", ret); - if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { - ret = sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceStart(); - CHECK_AND_RETURN_LOG(ret == SUCCESS, "Capturer ec source start error, ret = %{public}d.\n", ret); - } - if (sourceInfo_.micRef == HPAE_REF_ON) { - ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceStart(); - CHECK_AND_RETURN_LOG(ret == SUCCESS, "Capturer micref source start error, ret = %{public}d.\n", ret); - } - } - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - sessionNodeMap_[sessionId].state, OPERATION_STARTED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeCapturerManager::DisConnectOutputSession(uint32_t sessionId) -{ - if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { - return SUCCESS; - } - HpaeProcessorType sceneType = sessionNodeMap_[sessionId].sceneType; - if (sceneType != HPAE_SCENE_EFFECT_NONE && sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - // 1. Disconnect SourceOutputNode and ResampleNode - // 2. Disconnect the ResampleNode and UpEffectNode - // 3. If the ResampleNode has no output, it needs to be deleted - sourceOutputNodeMap_[sessionId]->DisConnectWithInfo( - sceneClusterMap_[sceneType], sourceOutputNodeMap_[sessionId]->GetNodeInfo()); - DisConnectSceneClusterFromSourceInputCluster(sceneType); - } else { - sourceOutputNodeMap_[sessionId]->DisConnectWithInfo(sourceInputClusterMap_[mainMicType_], - sourceOutputNodeMap_[sessionId]->GetNodeInfo()); - } - - if (sourceInputClusterMap_[mainMicType_]->GetOutputPortNum() == 0) { - sourceInputClusterMap_[mainMicType_]->CapturerSourceStop(); - if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { - sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceStop(); - } - if (sourceInfo_.micRef == HPAE_REF_ON) { - sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceStop(); - } - } - return SUCCESS; -} - -int32_t HpaeCapturerManager::Pause(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeCapturerManager::Pause"); - auto request = [this, sessionId]() { - AUDIO_INFO_LOG("Pause sessionId %{public}u", sessionId); - DisConnectOutputSession(sessionId); - SetSessionState(sessionId, CAPTURER_PAUSED); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - sessionNodeMap_[sessionId].state, OPERATION_PAUSED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeCapturerManager::Flush(uint32_t sessionId) -{ - if (sessionNodeMap_.find(sessionId) == sessionNodeMap_.end()) { - return ERR_INVALID_OPERATION; - } - // to do - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - sessionNodeMap_[sessionId].state, OPERATION_FLUSHED); - return SUCCESS; -} - -int32_t HpaeCapturerManager::Drain(uint32_t sessionId) -{ - if (sessionNodeMap_.find(sessionId) == sessionNodeMap_.end()) { - return ERR_INVALID_OPERATION; - } - // to do - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - sessionNodeMap_[sessionId].state, OPERATION_DRAINED); - return SUCCESS; -} - -int32_t HpaeCapturerManager::Stop(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeCapturerManager::Stop"); - auto request = [this, sessionId]() { - DisConnectOutputSession(sessionId); - SetSessionState(sessionId, CAPTURER_STOPPED); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - sessionNodeMap_[sessionId].state, OPERATION_STOPPED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeCapturerManager::Release(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeCapturerManager::Release"); - return DestroyStream(sessionId); -} - -int32_t HpaeCapturerManager::SetMute(bool isMute) -{ - // to do check pulseaudio - auto request = [this, isMute]() { - if (isMute_ != isMute) { - isMute_ = isMute; // todo: fadein and fadeout and mute feature - } - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeCapturerManager::Process() -{ - Trace trace("HpaeCapturerManager::Process"); - if (!sourceOutputNodeMap_.empty() && IsRunning()) { - for (const auto &sourceOutputNodePair : sourceOutputNodeMap_) { - sourceOutputNodePair.second->DoProcess(); - } - } -} - -void HpaeCapturerManager::HandleMsg() -{ - hpaeNoLockQueue_.HandleRequests(); -} - -int32_t HpaeCapturerManager::PrepareCapturerEc(HpaeNodeInfo &ecNodeInfo) -{ - if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { - ecNodeInfo.frameLen = sourceInfo_.ecFrameLen; - ecNodeInfo.channels = sourceInfo_.ecChannels; - ecNodeInfo.format = sourceInfo_.ecFormat; - ecNodeInfo.samplingRate = sourceInfo_.ecSamplingRate; - ecNodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_EC; - ecNodeInfo.sourceInputNodeType = HPAE_SOURCE_EC; - ecNodeInfo.statusCallback = weak_from_this(); - sourceInputClusterMap_[HPAE_SOURCE_EC] = std::make_shared(ecNodeInfo); - int32_t ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->GetCapturerSourceInstance( - DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_NETWORKID, SOURCE_TYPE_INVALID, HDI_ID_INFO_EC); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, - "get ec capturer soruce instance error, ret = %{public}d.\n", ret); - } - return SUCCESS; -} - -int32_t HpaeCapturerManager::PrepareCapturerMicRef(HpaeNodeInfo &micRefNodeInfo) -{ - if (sourceInfo_.micRef == HPAE_REF_ON) { - micRefNodeInfo.frameLen = sourceInfo_.micRefFrameLen; - micRefNodeInfo.channels = sourceInfo_.micRefChannels; - micRefNodeInfo.format = sourceInfo_.micRefFormat; - micRefNodeInfo.samplingRate = sourceInfo_.micRefSamplingRate; - micRefNodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MICREF; - micRefNodeInfo.sourceInputNodeType = HPAE_SOURCE_MICREF; - micRefNodeInfo.statusCallback = weak_from_this(); - sourceInputClusterMap_[HPAE_SOURCE_MICREF] = std::make_shared(micRefNodeInfo); - int32_t ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->GetCapturerSourceInstance( - DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_NETWORKID, SOURCE_TYPE_INVALID, HDI_ID_INFO_MIC_REF); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, - "get micRef capturer soruce instance error, ret = %{public}d.\n", ret); - } - return SUCCESS; -} - -int32_t HpaeCapturerManager::InitCapturer() -{ - IAudioSourceAttr attr; - attr.adapterName = sourceInfo_.adapterName.c_str(); - attr.sampleRate = sourceInfo_.samplingRate; - attr.channel = sourceInfo_.channels; - attr.format = sourceInfo_.format; - attr.channelLayout = sourceInfo_.channelLayout; - attr.deviceType = sourceInfo_.deviceType; - attr.volume = sourceInfo_.volume; - attr.deviceNetworkId = sourceInfo_.deviceNetId.c_str(); - attr.filePath = sourceInfo_.filePath.c_str(); - attr.isBigEndian = false; - attr.sourceType = static_cast(sourceInfo_.sourceType); - attr.openMicSpeaker = sourceInfo_.openMicSpeaker; - attr.hasEcConfig = mainMicType_ == HPAE_SOURCE_MIC_EC; - if (attr.hasEcConfig) { - attr.formatEc = sourceInfo_.ecFormat; - attr.sampleRateEc = sourceInfo_.ecSamplingRate; - attr.channelEc = sourceInfo_.ecChannels; - } - int32_t ret = sourceInputClusterMap_[mainMicType_]->CapturerSourceInit(attr); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, - "init mic source input node err, , ret = %{public}d.\n", ret); - if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER && - sourceInputClusterMap_.find(HPAE_SOURCE_EC) != sourceInputClusterMap_.end()) { - IAudioSourceAttr attrEc; - attrEc.sourceType = SOURCE_TYPE_EC; - attrEc.adapterName = sourceInfo_.ecAdapterName.c_str(); - attrEc.deviceType = DEVICE_TYPE_MIC; - attrEc.sampleRate = sourceInfo_.ecSamplingRate; - attrEc.channel = sourceInfo_.ecChannels; - attrEc.format = sourceInfo_.ecFormat; - attrEc.isBigEndian = false; - attrEc.openMicSpeaker = sourceInfo_.openMicSpeaker; - ret = sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceInit(attrEc); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, "init ec source input node err"); - } - if (sourceInfo_.micRef == HPAE_REF_ON && - sourceInputClusterMap_.find(HPAE_SOURCE_MICREF) != sourceInputClusterMap_.end()) { - IAudioSourceAttr attrMicRef; - attrMicRef.sourceType = SOURCE_TYPE_MIC_REF; - attrMicRef.adapterName = "primary"; - attrMicRef.deviceType = DEVICE_TYPE_MIC; - attrMicRef.sampleRate = sourceInfo_.micRefSamplingRate; - attrMicRef.channel = sourceInfo_.micRefChannels; - attrMicRef.format = sourceInfo_.micRefFormat; - attrMicRef.isBigEndian = false; - attrMicRef.openMicSpeaker = sourceInfo_.openMicSpeaker; - ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceInit(attrMicRef); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, "init micRef source input node err"); - } - return SUCCESS; -} - -int32_t HpaeCapturerManager::ReloadCaptureManager(const HpaeSourceInfo &sourceInfo) -{ - if (IsInit()) { - DeInit(); - } - hpaeSignalProcessThread_ = std::make_unique(); - auto request = [this, sourceInfo] { - // disconnect - std::vector moveInfos; - for (const auto &it : sourceOutputNodeMap_) { - HpaeCaptureMoveInfo moveInfo; - moveInfo.sessionId = it.first; - moveInfo.sourceOutputNode = it.second; - if (sessionNodeMap_.find(it.first) != sessionNodeMap_.end()) { - moveInfo.sessionInfo = sessionNodeMap_[it.first]; - moveInfos.emplace_back(moveInfo); - } - } - for (const auto &it : moveInfos) { - DeleteOutputSession(it.sessionId); - } - sourceInfo_ = sourceInfo; - int32_t ret = InitCapturerManager(); - if (ret != SUCCESS) { - AUDIO_INFO_LOG("re-Init HpaeCapturerManager failed"); - return; - } - AUDIO_INFO_LOG("re-Init HpaeCapturerManager success"); - // connect - for (const auto &moveInfo : moveInfos) { - AddSingleNodeToSource(moveInfo, true); - } - TriggerCallback(INIT_DEVICE_RESULT, sourceInfo_.deviceName, ret); - }; - SendRequest(request, true); - hpaeSignalProcessThread_->ActivateThread(shared_from_this()); - return SUCCESS; -} - -int32_t HpaeCapturerManager::InitCapturerManager() -{ - HpaeNodeInfo nodeInfo; - HpaeNodeInfo ecNodeInfo; - HpaeNodeInfo micRefNodeInfo; - nodeInfo.channels = sourceInfo_.channels; - nodeInfo.format = sourceInfo_.format; - nodeInfo.frameLen = sourceInfo_.frameLen; - nodeInfo.samplingRate = sourceInfo_.samplingRate; - nodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC; - nodeInfo.statusCallback = weak_from_this(); - mainMicType_ = sourceInfo_.ecType == HPAE_EC_TYPE_SAME_ADAPTER ? HPAE_SOURCE_MIC_EC : HPAE_SOURCE_MIC; - - if (mainMicType_ == HPAE_SOURCE_MIC_EC) { - ecNodeInfo.channels = sourceInfo_.ecChannels; - ecNodeInfo.format = sourceInfo_.ecFormat; - ecNodeInfo.samplingRate = sourceInfo_.ecSamplingRate; - ecNodeInfo.frameLen = sourceInfo_.ecFrameLen; - ecNodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_EC; - ecNodeInfo.statusCallback = weak_from_this(); - nodeInfo.sourceInputNodeType = HPAE_SOURCE_MIC_EC; - std::vector nodeInfos = {nodeInfo, ecNodeInfo}; - sourceInputClusterMap_[mainMicType_] = std::make_shared(nodeInfos); - } else { - nodeInfo.sourceInputNodeType = HPAE_SOURCE_MIC; - sourceInputClusterMap_[mainMicType_] = std::make_shared(nodeInfo); - } - - sourceInputClusterMap_[mainMicType_]->SetSourceInputNodeType(mainMicType_); // to do rewrite, optimise - int32_t ret = sourceInputClusterMap_[mainMicType_]->GetCapturerSourceInstance( - sourceInfo_.deviceClass, sourceInfo_.deviceNetId, sourceInfo_.sourceType, sourceInfo_.sourceName); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "get mic capturer soruce instance error, ret = %{public}d.\n", ret); - CHECK_AND_RETURN_RET_LOG(PrepareCapturerEc(ecNodeInfo) == SUCCESS, ret, "PrepareCapturerEc error"); - CHECK_AND_RETURN_RET_LOG(PrepareCapturerMicRef(micRefNodeInfo) == SUCCESS, ret, "PrepareCapturerMicRef error"); - CHECK_AND_RETURN_RET_LOG(InitCapturer() == SUCCESS, ret, "init main capturer error"); - isInit_.store(true); - return SUCCESS; -} - - -int32_t HpaeCapturerManager::Init() -{ - hpaeSignalProcessThread_ = std::make_unique(); - auto request = [this] { - int32_t ret = InitCapturerManager(); - if (ret == SUCCESS) { - AUDIO_INFO_LOG("Init HpaeCapturerManager success"); - TriggerCallback(INIT_DEVICE_RESULT, sourceInfo_.deviceName, ret); - } - }; - SendRequest(request, true); - hpaeSignalProcessThread_->ActivateThread(shared_from_this()); - return SUCCESS; -} - -int32_t HpaeCapturerManager::DeInit(bool isMoveDefault) -{ - AUDIO_INFO_LOG("DeInit device:%{public}s", sourceInfo_.deviceName.c_str()); - if (hpaeSignalProcessThread_ != nullptr) { - hpaeSignalProcessThread_->DeactivateThread(); - hpaeSignalProcessThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); - int32_t ret = sourceInputClusterMap_[mainMicType_]->CapturerSourceDeInit(); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_OPERATION, - "CapturerSourceDeInit error, ret = %{public}d.\n", ret); - if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { - ret = sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceDeInit(); - CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_INVALID_OPERATION, - "deinit ec source input node err.ret = %d.\n", ret); - } - if (sourceInfo_.micRef == HPAE_REF_ON) { - ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceDeInit(); - CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_INVALID_OPERATION, - "deinit micref source input node err.ret = %d.\n", ret); - } - isInit_.store(false); - - if (isMoveDefault) { - std::string name = ""; - std::vector ids; - AUDIO_INFO_LOG("move all source to default sink"); - MoveAllStreamToNewSource(name, ids, true); - } - return SUCCESS; -} - -bool HpaeCapturerManager::DeactivateThread() -{ - if (hpaeSignalProcessThread_ != nullptr) { - hpaeSignalProcessThread_->DeactivateThread(); - hpaeSignalProcessThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); - return true; -} - -int32_t HpaeCapturerManager::RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) -{ - auto request = [this, sessionId, callback]() { - sourceOutputNodeMap_[sessionId]->RegisterReadCallback(callback); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeCapturerManager::GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) -{ - if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { - return ERR_INVALID_OPERATION; - } - sourceOutputInfo.nodeInfo = sourceOutputNodeMap_[sessionId]->GetNodeInfo(); - sourceOutputInfo.capturerSessionInfo = sessionNodeMap_[sessionId]; - return SUCCESS; -} - -HpaeSourceInfo HpaeCapturerManager::GetSourceInfo() -{ - return sourceInfo_; -} - -std::vector HpaeCapturerManager::GetAllSourceOutputsInfo() -{ - return {}; -} - -bool HpaeCapturerManager::IsInit() -{ - return isInit_.load(); -} - -bool HpaeCapturerManager::IsMsgProcessing() -{ - return !hpaeNoLockQueue_.IsFinishProcess(); -} - -bool HpaeCapturerManager::IsRunning(void) -{ - if (sourceInputClusterMap_.find(mainMicType_) != sourceInputClusterMap_.end() && - hpaeSignalProcessThread_ != nullptr) { - return sourceInputClusterMap_[mainMicType_]->GetSourceState() == CAPTURER_RUNNING && - hpaeSignalProcessThread_->IsRunning(); - } else { - return false; - } -} - -void HpaeCapturerManager::SendRequest(Request &&request, bool isInit) -{ - if (!isInit && !IsInit()) { - AUDIO_INFO_LOG("HpaeCapturerManager not init"); - return; - } - hpaeNoLockQueue_.PushRequest(std::move(request)); - CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ capturer is nullptr"); - hpaeSignalProcessThread_->Notify(); -} - -void HpaeCapturerManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) -{ - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - sessionNodeMap_[sessionId].state, operation); -} - -int32_t HpaeCapturerManager::AddAllNodesToSource(const std::vector &moveInfos, bool isConnect) -{ - auto request = [this, moveInfos, isConnect]() { - for (const auto &moveInfo : moveInfos) { - AddSingleNodeToSource(moveInfo, isConnect); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeCapturerManager::AddNodeToSource(const HpaeCaptureMoveInfo &moveInfo) -{ - auto request = [this, moveInfo]() { AddSingleNodeToSource(moveInfo); }; - SendRequest(request); - return SUCCESS; -} - -void HpaeCapturerManager::AddSingleNodeToSource(const HpaeCaptureMoveInfo &moveInfo, bool isConnect) -{ - uint32_t sessionId = moveInfo.sessionId; - AUDIO_INFO_LOG("Add node to source:%{public}d", sessionId); - sourceOutputNodeMap_[sessionId] = moveInfo.sourceOutputNode; - sessionNodeMap_[sessionId] = moveInfo.sessionInfo; - HpaeProcessorType sceneType = sessionNodeMap_[sessionId].sceneType; - AudioEnhanceScene enhanceScene = TransProcessType2EnhanceScene(sceneType); - if (sceneType != HPAE_SCENE_EFFECT_NONE) { - // todo: algorithm instance count control - HpaeNodeInfo nodeInfo = moveInfo.sourceOutputNode->GetNodeInfo(); - if (sceneClusterMap_.find(sceneType) == sceneClusterMap_.end()) { - sceneClusterMap_[sceneType] = std::make_shared(nodeInfo); - } - } - if (CaptureEffectCreate(sceneType, enhanceScene) != SUCCESS) { - sceneClusterMap_.erase(sceneType); - } - if (!isConnect) { - AUDIO_INFO_LOG("not need connect session:%{public}d", sessionId); - } - AUDIO_INFO_LOG("connect node :%{public}d to sink:%{public}s", sessionId, sourceInfo_.deviceClass.c_str()); - ConnectOutputSession(sessionId); - if (moveInfo.sessionInfo.state == CAPTURER_RUNNING) { - if (sourceInputClusterMap_[mainMicType_]->GetSourceState() != CAPTURER_RUNNING) { - int32_t ret = sourceInputClusterMap_[mainMicType_]->CapturerSourceStart(); - CHECK_AND_RETURN_LOG(ret == SUCCESS, "capturer source start error, ret = %{public}d.\n", ret); - if (sourceInfo_.ecType == HPAE_EC_TYPE_DIFF_ADAPTER) { - ret = sourceInputClusterMap_[HPAE_SOURCE_EC]->CapturerSourceStart(); - CHECK_AND_RETURN_LOG(ret == SUCCESS, "ec capturer source start error, ret = %{public}d.\n", ret); - } - if (sourceInfo_.micRef == HPAE_REF_ON) { - ret = sourceInputClusterMap_[HPAE_SOURCE_MICREF]->CapturerSourceStart(); - CHECK_AND_RETURN_LOG(ret == SUCCESS, "micref capturer source start error, ret = %{public}d.\n", ret); - } - } - hpaeSignalProcessThread_->Notify(); - } -} - -int32_t HpaeCapturerManager::MoveAllStream(const std::string &sourceName, const std::vector& sessionIds, - bool isMoveAll) -{ - if (!IsInit()) { - AUDIO_INFO_LOG("source is not init ,use sync mode move to: %{public}s", sourceName.c_str()); - MoveAllStreamToNewSource(sourceName, sessionIds, isMoveAll); - } else { - AUDIO_INFO_LOG("source is init ,use async mode move to: %{public}s", sourceName.c_str()); - auto request = [this, sourceName, sessionIds, isMoveAll]() { - MoveAllStreamToNewSource(sourceName, sessionIds, isMoveAll); - }; - SendRequest(request); - } - return SUCCESS; -} - -void HpaeCapturerManager::MoveAllStreamToNewSource(const std::string &sourceName, - const std::vector& moveIds, bool isMoveAll = true) -{ - std::string name = sourceName; - std::vector moveInfos; - for (const auto &it : sourceOutputNodeMap_) { - if (isMoveAll || std::find(moveIds.begin(), moveIds.end(), it.first) != moveIds.end()) { - HpaeCaptureMoveInfo moveInfo; - moveInfo.sessionId = it.first; - moveInfo.sourceOutputNode = it.second; - if (sessionNodeMap_.find(it.first) != sessionNodeMap_.end()) { - moveInfo.sessionInfo = sessionNodeMap_[it.first]; - moveInfos.emplace_back(moveInfo); - } - } - } - - for (const auto &it : moveInfos) { - DeleteOutputSession(it.sessionId); - } - - AUDIO_INFO_LOG("move source count: %{public}zu,source name:%{public}s", moveInfos.size(), sourceName.c_str()); - TriggerCallback(MOVE_ALL_SOURCE_OUTPUT, moveInfos, name); -} - -int32_t HpaeCapturerManager::MoveStream(uint32_t sessionId, const std::string& sourceName) -{ - AUDIO_INFO_LOG("soft stop session:%{public}d,source name:%{public}s", sessionId, sourceName.c_str()); - auto request = [this, sessionId, sourceName]() { - AUDIO_ERR_LOG("trigger call back1, source name:%{public}s", sourceName.c_str()); - if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { - AUDIO_ERR_LOG("could not find session:%{public}d,source name:%{public}s", sessionId, sourceName.c_str()); - return; - } - AUDIO_ERR_LOG("trigger call back2, source name:%{public}s", sourceName.c_str()); - std::shared_ptr sourceNode = sourceOutputNodeMap_[sessionId]; - if (sessionNodeMap_.find(sessionId)==sessionNodeMap_.end()) { - AUDIO_ERR_LOG("can not find session node:%{public}d,source name:%{public}s", sessionId, sourceName.c_str()); - return; - } - HpaeCapturerSessionInfo sessionInfo = sessionNodeMap_[sessionId]; - if (sessionInfo.state == CAPTURER_RUNNING) { - // todo: do fade out - } - HpaeCaptureMoveInfo moveInfo; - moveInfo.sessionId = sessionId; - moveInfo.sourceOutputNode = sourceNode; - moveInfo.sessionInfo = sessionInfo; - DeleteOutputSession(sessionId); - if (!sourceName.empty()) { - std::string name = sourceName; - AUDIO_ERR_LOG("trigger call back, source name:%{public}s", sourceName.c_str()); - TriggerCallback(MOVE_SOURCE_OUTPUT, moveInfo, name); - } - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeCapturerManager::OnNotifyQueue() -{ - hpaeSignalProcessThread_->Notify(); -} - -std::string HpaeCapturerManager::GetThreadName() -{ - return sourceInfo_.deviceName; -} - -void HpaeCapturerManager::DumpSourceInfo() -{ - SendRequest([this](){ - AUDIO_INFO_LOG("DumpSourceInfo deviceName %{public}s", sourceInfo_.deviceName.c_str()); - UploadDumpSourceInfo(sourceInfo_.deviceName); - }); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_inner_capturer_manager.cpp b/services/audio_engine/manager/src/hpae_inner_capturer_manager.cpp deleted file mode 100644 index cc8355d154..0000000000 --- a/services/audio_engine/manager/src/hpae_inner_capturer_manager.cpp +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeInnerCapturerManager" -#endif -#include "audio_stream_info.h" -#include "audio_errors.h" -#include "audio_engine_log.h" -#include "hpae_node_common.h" -#include "hpae_inner_capturer_manager.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -// todo sinkInfo -HpaeInnerCapturerManager::HpaeInnerCapturerManager(HpaeSinkInfo &sinkInfo) - : sinkInfo_(sinkInfo), hpaeNoLockQueue_(CURRENT_REQUEST_COUNT) -{} - -HpaeInnerCapturerManager::~HpaeInnerCapturerManager() -{ - AUDIO_INFO_LOG("destructor inner capturer sink."); - if (isInit_.load()) { - DeInit(); - } -} - -int32_t HpaeInnerCapturerManager::AddNodeToSink(const std::shared_ptr &node) -{ - auto request = [this, node]() { - AddSingleNodeToSinkInner(node); - }; - SendRequestInner(request); - return SUCCESS; -} - -void HpaeInnerCapturerManager::AddSingleNodeToSinkInner(const std::shared_ptr &node, bool isConnect) -{ - HpaeNodeInfo nodeInfo = node->GetNodeInfo(); - uint32_t sessionId = nodeInfo.sessionId; - AUDIO_INFO_LOG("add node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); - sinkInputNodeMap_[sessionId] = node; - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - nodeInfo.statusCallback = weak_from_this(); - sinkInputNodeMap_[sessionId]->SetNodeInfo(nodeInfo); - SetSessionStateInner(sessionId, node->GetState()); - rendererSessionNodeMap_[sessionId].sinkInputNodeId = nodeInfo.nodeId; - rendererSessionNodeMap_[sessionId].sceneType = nodeInfo.sceneType; - - if (rendererSceneClusterMap_.find(nodeInfo.sceneType) == rendererSceneClusterMap_.end()) { - rendererSceneClusterMap_[nodeInfo.sceneType] = std::make_shared(nodeInfo, sinkInfo_); - } - - if (!isConnect) { - AUDIO_INFO_LOG("not need connect session:%{public}d", sessionId); - return; - } - if (node->GetState() == RENDERER_RUNNING) { - AUDIO_INFO_LOG("connect node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); - ConnectRendererInputSessionInner(sessionId); // todo: fadein - if (hpaeInnerCapSinkNode_->GetSinkState() != RENDERER_RUNNING) { - hpaeInnerCapSinkNode_->InnerCapturerSinkStart(); - } - } -} - -int32_t HpaeInnerCapturerManager::AddAllNodesToSink( - const std::vector> &sinkInputs, bool isConnect) -{ - auto request = [this, sinkInputs, isConnect]() { - for (const auto &it : sinkInputs) { - AddSingleNodeToSinkInner(it, isConnect); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -void HpaeInnerCapturerManager::MoveAllStreamToNewSinkInner(const std::string &sinkName, - const std::vector& moveIds, bool isMoveAll) -{ - std::string name = sinkName; - std::vector> sinkInputs; - std::vector sessionIds; - for (const auto &it : sinkInputNodeMap_) { - if (isMoveAll || std::find(moveIds.begin(), moveIds.end(), it.first) != moveIds.end()) { - sinkInputs.emplace_back(it.second); - sessionIds.emplace_back(it.first); - } - } - for (const auto &it : sessionIds) { - DisConnectRendererInputSessionInner(it); - } - AUDIO_INFO_LOG("sink input count:%{public}zu", sinkInputs.size()); - TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name); -} - -int32_t HpaeInnerCapturerManager::MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, - bool isMoveAll) -{ - if (!IsInit()) { - AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str()); - MoveAllStreamToNewSinkInner(sinkName, sessionIds, isMoveAll); - } else { - AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str()); - auto request = [this, sinkName, sessionIds, isMoveAll]() { - MoveAllStreamToNewSinkInner(sinkName, sessionIds, isMoveAll); - }; - SendRequestInner(request); - } - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::MoveStream(uint32_t sessionId, const std::string &sinkName) -{ - AUDIO_INFO_LOG("move session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); - auto request = [this, sessionId, sinkName]() { - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - AUDIO_ERR_LOG("could not find session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); - return; - } - std::shared_ptr inputNode = sinkInputNodeMap_[sessionId]; - if (inputNode->GetState() == RENDERER_RUNNING) { - // todo: do fade out - } - DisConnectRendererInputSessionInner(sessionId); - if (!sinkName.empty()) { - std::string name = sinkName; - AUDIO_ERR_LOG("trigger call back, sink name:%{public}s", sinkName.c_str()); - TriggerCallback(MOVE_SINK_INPUT, inputNode, name); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::CreateStream(const HpaeStreamInfo &streamInfo) -{ - if (!IsInit()) { - AUDIO_INFO_LOG("CreateStream not init"); - return ERR_INVALID_OPERATION; - } - auto request = [this, streamInfo]() { - if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { - AUDIO_INFO_LOG("CreateCapRendererStream sessionID: %{public}d", streamInfo.sessionId); - CreateRendererInputSessionInner(streamInfo); - SetSessionStateInner(streamInfo.sessionId, RENDERER_NEW); - sinkInputNodeMap_[streamInfo.sessionId]->SetState(RENDERER_NEW); - } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD) { - AUDIO_INFO_LOG("CreateCapCapturerStream sessionID: %{public}d", streamInfo.sessionId); - CreateCapturerInputSessionInner(streamInfo); - SetSessionStateInner(streamInfo.sessionId, CAPTURER_NEW); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::DestroyStream(uint32_t sessionId) -{ - if (!IsInit()) { - return ERR_INVALID_OPERATION; - } - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || - sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ - "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); - AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("DestroyCapRendererStream sessionID: %{public}d", sessionId); - DeleteRendererInputSessionInner(sessionId); - } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { - AUDIO_INFO_LOG("DestroyCapCapturerStream sessionID: %{public}d", sessionId); - DeleteCapturerInputSessionInner(sessionId); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::Init() -{ - hpaeSignalProcessThread_ = std::make_unique(); - auto request = [this] { - HpaeNodeInfo nodeInfo; - nodeInfo.channels = sinkInfo_.channels; - nodeInfo.format = sinkInfo_.format; - nodeInfo.frameLen = sinkInfo_.frameLen; - nodeInfo.nodeId = 0; - nodeInfo.samplingRate = sinkInfo_.samplingRate; - nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT; - hpaeInnerCapSinkNode_ = std::make_unique(nodeInfo); - AUDIO_INFO_LOG("Init innerCapSinkNode"); - hpaeInnerCapSinkNode_->InnerCapturerSinkInit(); - isInit_.store(true); - TriggerCallback(INIT_DEVICE_RESULT, sinkInfo_.deviceName, SUCCESS); - }; - SendRequestInner(request, true); - hpaeSignalProcessThread_->ActivateThread(shared_from_this()); - return SUCCESS; -} - -bool HpaeInnerCapturerManager::DeactivateThread() -{ - if (hpaeSignalProcessThread_ != nullptr) { - hpaeSignalProcessThread_->DeactivateThread(); - hpaeSignalProcessThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); - return true; -} - -int32_t HpaeInnerCapturerManager::DeInit(bool isMoveDefault) -{ - if (hpaeSignalProcessThread_ != nullptr) { - hpaeSignalProcessThread_->DeactivateThread(); - hpaeSignalProcessThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); - int32_t ret = hpaeInnerCapSinkNode_->InnerCapturerSinkDeInit(); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InnerCapManagerDeInit error, ret %{public}d.\n", ret); - hpaeInnerCapSinkNode_->ResetAll(); - isInit_.store(false); - TriggerCallback(DEINIT_DEVICE_RESULT, sinkInfo_.deviceName, ret); - if (isMoveDefault) { - std::string sinkName = ""; - std::vector ids; - AUDIO_INFO_LOG("move all sink to default sink"); - MoveAllStreamToNewSinkInner(sinkName, ids, true); - } - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::Start(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || - sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ - "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("StartCapRendererStream sessionId %{public}u", sessionId); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->SetState(RENDERER_RUNNING); - } - ConnectRendererInputSessionInner(sessionId); - SetSessionStateInner(sessionId, RENDERER_RUNNING); - if (hpaeInnerCapSinkNode_->GetSinkState() != RENDERER_RUNNING) { - hpaeInnerCapSinkNode_->InnerCapturerSinkStart(); - } - } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { - AUDIO_INFO_LOG("StartCapCapturerStream sessionId %{public}u", sessionId); - ConnectCapturerOutputSessionInner(sessionId); - SetSessionStateInner(sessionId, CAPTURER_RUNNING); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - capturerSessionNodeMap_[sessionId].state, OPERATION_STARTED); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::Pause(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || - sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ - "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("PauseCapRendererStream sessionId %{public}u", sessionId); - DisConnectRendererInputSessionInner(sessionId); - SetSessionStateInner(sessionId, RENDERER_PAUSED); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->SetState(RENDERER_PAUSED); - } - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, - rendererSessionNodeMap_[sessionId].state, OPERATION_PAUSED); - } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { - AUDIO_INFO_LOG("PauseCapCapturerStream sessionId %{public}u", sessionId); - DisConnectCapturerInputSessionInner(sessionId); - SetSessionStateInner(sessionId, CAPTURER_PAUSED); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - capturerSessionNodeMap_[sessionId].state, OPERATION_PAUSED); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::Flush(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || - sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ - "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("FlushCapRendererStream sessionId %{public}u", sessionId); - CHECK_AND_RETURN_LOG(rendererSessionNodeMap_.find(sessionId) != rendererSessionNodeMap_.end(), - "Flush not find sessionId %{public}u", sessionId); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, - rendererSessionNodeMap_[sessionId].state, OPERATION_FLUSHED); - } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { - AUDIO_INFO_LOG("FlushCapCapturerStream sessionId %{public}u", sessionId); - CHECK_AND_RETURN_LOG(capturerSessionNodeMap_.find(sessionId) != capturerSessionNodeMap_.end(), - "Flush not find sessionId %{public}u", sessionId); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - capturerSessionNodeMap_[sessionId].state, OPERATION_FLUSHED); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::Drain(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || - sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ - "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("DrainCapRendererStream sessionId %{public}u", sessionId); - CHECK_AND_RETURN_LOG(rendererSessionNodeMap_.find(sessionId) != rendererSessionNodeMap_.end(), - "Drain not find sessionId %{public}u", sessionId); - sinkInputNodeMap_[sessionId]->Drain(); - if (rendererSessionNodeMap_[sessionId].state != RENDERER_RUNNING) { - AUDIO_INFO_LOG("TriggerCallback Drain sessionId %{public}u", sessionId); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, - rendererSessionNodeMap_[sessionId].state, OPERATION_DRAINED); - } - } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { - AUDIO_INFO_LOG("DrainCapCapturerStream sessionId %{public}u", sessionId); - CHECK_AND_RETURN_LOG(capturerSessionNodeMap_.find(sessionId) != capturerSessionNodeMap_.end(), - "Drain not find sessionId %{public}u", sessionId); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - capturerSessionNodeMap_[sessionId].state, OPERATION_DRAINED); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::Stop(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || - sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ - "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("StopCapRendererStream sessionId %{public}u", sessionId); - DisConnectRendererInputSessionInner(sessionId); - SetSessionStateInner(sessionId, RENDERER_STOPPED); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->SetState(RENDERER_STOPPED); - } - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, - rendererSessionNodeMap_[sessionId].state, OPERATION_STOPPED); - } else if (sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end()) { - AUDIO_INFO_LOG("StopCapCapturerStream sessionId %{public}u", sessionId); - DisConnectCapturerInputSessionInner(sessionId); - SetSessionStateInner(sessionId, CAPTURER_STOPPED); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_RECORD, sessionId, - capturerSessionNodeMap_[sessionId].state, OPERATION_STOPPED); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::Release(uint32_t sessionId) -{ - return DestroyStream(sessionId); -} - -int32_t HpaeInnerCapturerManager::SuspendStreamManager(bool isSuspend) -{ - auto request = [this, isSuspend]() { - if (isSuspend) { - // todo fadout - hpaeInnerCapSinkNode_->InnerCapturerSinkStop(); - } else { - // todo fadout - hpaeInnerCapSinkNode_->InnerCapturerSinkStart(); - } - }; - SendRequestInner(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::SetMute(bool isMute) -{ - auto request = [this, isMute]() { - if (isMute_ != isMute) { - isMute_ = isMute; // todo: fadein and fadeout and mute feature - } - }; - SendRequestInner(request); - return SUCCESS; -} - -void HpaeInnerCapturerManager::Process() -{ - if (hpaeInnerCapSinkNode_ != nullptr && !sourceOutputNodeMap_.empty() && IsRunning()) { - for (const auto& sourceOutputNodePair : sourceOutputNodeMap_) { - if (capturerSessionNodeMap_[sourceOutputNodePair.first].state == CAPTURER_RUNNING) { - sourceOutputNodePair.second->DoProcess(); - } - } - } -} - -void HpaeInnerCapturerManager::HandleMsg() -{ - hpaeNoLockQueue_.HandleRequests(); -} - -bool HpaeInnerCapturerManager::IsInit() -{ - return isInit_.load(); -} - -bool HpaeInnerCapturerManager::IsRunning(void) -{ - if (hpaeInnerCapSinkNode_ != nullptr && hpaeSignalProcessThread_ != nullptr) { - return hpaeSignalProcessThread_->IsRunning(); - } else { - return false; - } -} - -bool HpaeInnerCapturerManager::IsMsgProcessing() -{ - return !hpaeNoLockQueue_.IsFinishProcess(); -} - -int32_t HpaeInnerCapturerManager::SetClientVolume(uint32_t sessionId, float volume) -{ - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::SetRate(uint32_t sessionId, int32_t rate) -{ - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) -{ - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) -{ - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType) -{ - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType) -{ - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::RegisterWriteCallback(uint32_t sessionId, - const std::weak_ptr &callback) -{ - auto request = [this, sessionId, callback]() { - AUDIO_INFO_LOG("RegisterWriteCallback sessionId %{public}u", sessionId); - CHECK_AND_RETURN_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end() || - sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(),\ - "no find sessionId in sinkInputNodeMap and sourceOutputNodeMap"); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->RegisterWriteCallback(callback); - } - }; - hpaeNoLockQueue_.PushRequest(request); - return SUCCESS; -} - -int32_t RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) -{ - return SUCCESS; -} - -size_t HpaeInnerCapturerManager::GetWritableSize(uint32_t sessionId) -{ - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::UpdateSpatializationState( - uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) -{ - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) -{ - return SUCCESS; -} - -std::vector HpaeInnerCapturerManager::GetAllSinkInputsInfo() -{ - std::vector sinkInputs; - return sinkInputs; -} - -int32_t HpaeInnerCapturerManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) -{ - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - return ERR_INVALID_OPERATION; - } - sinkInputInfo.nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); - sinkInputInfo.rendererSessionInfo = rendererSessionNodeMap_[sessionId]; - return SUCCESS; -} - -HpaeSinkInfo HpaeInnerCapturerManager::GetSinkInfo() -{ - return sinkInfo_; -} - -void HpaeInnerCapturerManager::OnFadeDone(uint32_t sessionId, IOperation operation) -{ - auto request = [this, sessionId, operation]() { - DisConnectRendererInputSessionInner(sessionId); - RendererState state = operation == OPERATION_STOPPED ? RENDERER_STOPPED : RENDERER_PAUSED; - SetSessionStateInner(sessionId, state); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->SetState(state); - } - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, - rendererSessionNodeMap_[sessionId].state, operation); - }; - SendRequestInner(request); -} - -void HpaeInnerCapturerManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) -{ - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, - rendererSessionNodeMap_[sessionId].state, operation); -} - -int32_t HpaeInnerCapturerManager::RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) -{ - auto request = [this, sessionId, callback]() { - AUDIO_INFO_LOG("RegisterReadCallback sessionId %{public}u", sessionId); - sourceOutputNodeMap_[sessionId]->RegisterReadCallback(callback); - }; - hpaeNoLockQueue_.PushRequest(request); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::GetSourceOutputInfo(uint32_t sessionId, HpaeSourceOutputInfo &sourceOutputInfo) -{ - if (sourceOutputNodeMap_.find(sessionId) == sourceOutputNodeMap_.end()) { - return ERR_INVALID_OPERATION; - } - sourceOutputInfo.nodeInfo = sourceOutputNodeMap_[sessionId]->GetNodeInfo(); - sourceOutputInfo.capturerSessionInfo = capturerSessionNodeMap_[sessionId]; - return SUCCESS; -} - -std::vector HpaeInnerCapturerManager::GetAllSourceOutputsInfo() -{ - // to do - std::vector sourceOutputs; - return sourceOutputs; -} - -int32_t HpaeInnerCapturerManager::CreateRendererInputSessionInner(const HpaeStreamInfo &streamInfo) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.channels = streamInfo.channels; - nodeInfo.format = streamInfo.format; - nodeInfo.frameLen = streamInfo.frameLen; - nodeInfo.nodeId = GetSinkInputNodeIdInner(); - nodeInfo.streamType = streamInfo.streamType; - nodeInfo.sessionId = streamInfo.sessionId; - nodeInfo.samplingRate = (AudioSamplingRate)streamInfo.samplingRate; - nodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE; - nodeInfo.statusCallback = weak_from_this(); - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - AUDIO_INFO_LOG("nodeInfo.channels %{public}d, nodeInfo.format %{public}hhu, nodeInfo.frameLen %{public}d", - nodeInfo.channels, nodeInfo.format, nodeInfo.frameLen); - sinkInputNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); - - if (rendererSceneClusterMap_.find(nodeInfo.sceneType) == rendererSceneClusterMap_.end()) { - rendererSceneClusterMap_[nodeInfo.sceneType] = std::make_shared(nodeInfo, sinkInfo_); - } - // todo change nodeInfo - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::CreateCapturerInputSessionInner(const HpaeStreamInfo &streamInfo) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.channels = streamInfo.channels; - nodeInfo.format = streamInfo.format; - nodeInfo.frameLen = streamInfo.frameLen; - nodeInfo.streamType = streamInfo.streamType; - nodeInfo.sessionId = streamInfo.sessionId; - nodeInfo.samplingRate = (AudioSamplingRate)streamInfo.samplingRate; - nodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE; - AUDIO_INFO_LOG("nodeInfo.channels %{public}d, nodeInfo.format %{public}hhu, nodeInfo.frameLen %{public}d", - nodeInfo.channels, nodeInfo.format, nodeInfo.frameLen); - sourceOutputNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); - HpaeNodeInfo outputNodeInfo = hpaeInnerCapSinkNode_->GetNodeInfo(); - // todo change nodeInfo - capturerResampleNodeMap_[streamInfo.sessionId] = std::make_shared(outputNodeInfo, nodeInfo); - capturerSessionNodeMap_[streamInfo.sessionId].sceneType = nodeInfo.sceneType; - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::DeleteRendererInputSessionInner(uint32_t sessionId) -{ - CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end(), SUCCESS, - "sessionId %{public}u can not find in sinkInputNodeMap_.", sessionId); - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - if (rendererSceneClusterMap_.find(sceneType) != rendererSceneClusterMap_.end()) { - rendererSceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]); - if (rendererSceneClusterMap_[sceneType]->GetPreOutNum() == 0) { - hpaeInnerCapSinkNode_->DisConnect(rendererSceneClusterMap_[sceneType]); - rendererSceneClusterMap_.erase(sceneType); - } - } - sinkInputNodeMap_.erase(sessionId); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::DeleteCapturerInputSessionInner(uint32_t sessionId) -{ - CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), SUCCESS, - "sessionId %{public}u can not find in sourceOutputNodeMap_.", sessionId); - CHECK_AND_RETURN_RET_LOG(capturerResampleNodeMap_.find(sessionId) != capturerResampleNodeMap_.end(), SUCCESS, - "sessionId %{public}u can not find in capturerResampleNodeMap_.", sessionId); - // no need process cluster - sourceOutputNodeMap_[sessionId]->DisConnect(capturerResampleNodeMap_[sessionId]); - capturerResampleNodeMap_[sessionId]->DisConnect(hpaeInnerCapSinkNode_); - // if need disconnect all? - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::ConnectRendererInputSessionInner(uint32_t sessionId) -{ - CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end(), ERR_INVALID_PARAM, - "sessionId %{public}u can not find in sinkInputNodeMap_.", sessionId); - CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_[sessionId]->GetState() == RENDERER_RUNNING, SUCCESS, - "sink input node is running"); - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - CHECK_AND_RETURN_RET_LOG(rendererSceneClusterMap_.find(sceneType) != rendererSceneClusterMap_.end(), SUCCESS, - "miss corresponding process cluster for scene type %{public}d", sceneType); - rendererSceneClusterMap_[sceneType]->Connect(sinkInputNodeMap_[sessionId]); - // todo check if connect process cluster - hpaeInnerCapSinkNode_->Connect(rendererSceneClusterMap_[sceneType]); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::ConnectCapturerOutputSessionInner(uint32_t sessionId) -{ - CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), ERR_INVALID_PARAM, - "sessionId %{public}u can not find in sourceOutputCLusterMap.", sessionId); - CHECK_AND_RETURN_RET_LOG(capturerResampleNodeMap_.find(sessionId) != capturerResampleNodeMap_.end(), - ERR_INVALID_PARAM, - "sessionId %{public}u can not find in capturerResampleNodeMap_.", sessionId); - // todo connect gain node - sourceOutputNodeMap_[sessionId]->Connect(capturerResampleNodeMap_[sessionId]); - capturerResampleNodeMap_[sessionId]->Connect(hpaeInnerCapSinkNode_); - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::DisConnectRendererInputSessionInner(uint32_t sessionId) -{ - CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end(), SUCCESS, - "sessionId %{public}u can not find in sinkInputNodeMap_.", sessionId); - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - if (rendererSceneClusterMap_.find(sceneType) != rendererSceneClusterMap_.end()) { - rendererSceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]); - if (rendererSceneClusterMap_[sceneType]->GetPreOutNum() == 0) { - hpaeInnerCapSinkNode_->DisConnect(rendererSceneClusterMap_[sceneType]); - } - } - return SUCCESS; -} - -int32_t HpaeInnerCapturerManager::DisConnectCapturerInputSessionInner(uint32_t sessionId) -{ - CHECK_AND_RETURN_RET_LOG(sourceOutputNodeMap_.find(sessionId) != sourceOutputNodeMap_.end(), SUCCESS, - "sessionId %{public}u can not find in sourceOutputNodeMap_.", sessionId); - CHECK_AND_RETURN_RET_LOG(capturerResampleNodeMap_.find(sessionId) != capturerResampleNodeMap_.end(), SUCCESS, - "sessionId %{public}u can not find in capturerResampleNodeMap_.", sessionId); - sourceOutputNodeMap_[sessionId]->DisConnect(capturerResampleNodeMap_[sessionId]); - capturerResampleNodeMap_[sessionId]->DisConnect(hpaeInnerCapSinkNode_); - // todo if need disconnect render - return SUCCESS; -} - -void HpaeInnerCapturerManager::SetSessionStateInner(uint32_t sessionId, RendererState renderState) -{ - rendererSessionNodeMap_[sessionId].state = renderState; -} - -void HpaeInnerCapturerManager::SetSessionStateInner(uint32_t sessionId, CapturerState capturerState) -{ - capturerSessionNodeMap_[sessionId].state = capturerState; -} - -void HpaeInnerCapturerManager::SendRequestInner(Request &&request, bool isInit) -{ - if (!isInit && !IsInit()) { - AUDIO_INFO_LOG("HpaeInnerCapturerManager not init"); - return; - } - hpaeNoLockQueue_.PushRequest(std::move(request)); - CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ inner capturer sink is nullptr"); - hpaeSignalProcessThread_->Notify(); -} - -uint32_t HpaeInnerCapturerManager::GetSinkInputNodeIdInner() -{ - return sinkInputNodeCounter_++; -} - -std::string HpaeInnerCapturerManager::GetThreadName() -{ - return sinkInfo_.deviceName; -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_manager.cpp b/services/audio_engine/manager/src/hpae_manager.cpp deleted file mode 100644 index ea55765d79..0000000000 --- a/services/audio_engine/manager/src/hpae_manager.cpp +++ /dev/null @@ -1,1910 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeManager" -#endif -#include "hpae_manager.h" -#include -#include -#include -#include "audio_errors.h" -#include "audio_schedule.h" -#include "audio_engine_log.h" -#include "audio_utils.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -namespace { -constexpr uint32_t DEFAULT_SUSPEND_TIME_IN_MS = 3000; // 3s to stop hdi -static inline const std::unordered_set INNER_SOURCE_TYPE_SET = { - SOURCE_TYPE_PLAYBACK_CAPTURE, SOURCE_TYPE_REMOTE_CAST}; -} // namespace -static constexpr uint32_t DEFAULT_MULTICHANNEL_NUM = 6; -static constexpr uint32_t DEFAULT_MULTICHANNEL_CHANNELLAYOUT = 1551; -static constexpr float MAX_SINK_VOLUME_LEVEL = 1.0; -static constexpr uint32_t DEFAULT_MULTICHANNEL_FRAME_LEN_MS = 20; -static constexpr uint32_t MS_PER_SECOND = 1000; -static std::map formatFromParserStrToEnum = { - {"s16le", SAMPLE_S16LE}, - {"s24le", SAMPLE_S24LE}, - {"s32le", SAMPLE_S32LE}, - {"f32le", SAMPLE_F32LE}, -}; - -// base + offset * 8 -static uint32_t GetRenderId(const std::string &deviceClass) -{ - uint32_t renderId = 0; - if (deviceClass == "usb") { - renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_USB); - } else if (deviceClass == "dp") { - renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DP); - } else if (deviceClass == "voip") { - renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP); - } else if (deviceClass == "direct") { - renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DIRECT); - } else { - renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_PRIMARY); - } - return renderId; -} - -static uint32_t GetCaptureId(const std::string &deviceClass) -{ - uint32_t captureId = 0; - if (deviceClass == "usb") { - captureId = GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_USB); - } else if (deviceClass == "a2dp") { - captureId = GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_BLUETOOTH); - } else { - captureId = GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_PRIMARY); - } - return captureId; -} - -HpaeManagerThread::~HpaeManagerThread() -{ - DeactivateThread(); -} - -void HpaeManagerThread::ActivateThread(HpaeManager *hpaeManager) -{ - m_hpaeManager = hpaeManager; - auto threadFunc = std::bind(&HpaeManagerThread::Run, this); - thread_ = std::thread(threadFunc); - pthread_setname_np(thread_.native_handle(), "HpaeManager"); -} - -void HpaeManagerThread::Run() -{ - running_.store(true); - ScheduleThreadInServer(getpid(), gettid()); - while (running_.load() && m_hpaeManager != nullptr) { - { - std::unique_lock lock(mutex_); - condition_.wait(lock, [this] { return recvSignal_.load() || m_hpaeManager->IsMsgProcessing(); }); - } - m_hpaeManager->HandleMsg(); - recvSignal_.store(false); - } - UnscheduleThreadInServer(getpid(), gettid()); -} - -void HpaeManagerThread::Notify() -{ - recvSignal_.store(true); - condition_.notify_all(); -} - -void HpaeManagerThread::DeactivateThread() -{ - Notify(); - running_.store(false); - if (thread_.joinable()) { - thread_.join(); - } -} - -HpaeManager::HpaeManager() : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT) // todo Message queue exceeds the upper limit -{ - RegisterHandler(UPDATE_STATUS, &HpaeManager::HandleUpdateStatus); - RegisterHandler(INIT_DEVICE_RESULT, &HpaeManager::HandleInitDeviceResult); - RegisterHandler(DEINIT_DEVICE_RESULT, &HpaeManager::HandleDeInitDeviceResult); - RegisterHandler(MOVE_SINK_INPUT, &HpaeManager::HandleMoveSinkInput); - RegisterHandler(MOVE_ALL_SINK_INPUT, &HpaeManager::HandleMoveAllSinkInputs); - RegisterHandler(MOVE_SOURCE_OUTPUT, &HpaeManager::HandleMoveSourceOutput); - RegisterHandler(MOVE_ALL_SOURCE_OUTPUT, &HpaeManager::HandleMoveAllSourceOutputs); - RegisterHandler(DUMP_SINK_INFO, &HpaeManager::HandleDumpSinkInfo); - RegisterHandler(DUMP_SOURCE_INFO, &HpaeManager::HandleDumpSourceInfo); -} - -HpaeManager::~HpaeManager() -{ - if (IsInit()) { - DeInit(); - } -} - -int32_t HpaeManager::Init() -{ - sinkSourceIndex_ = 0; - hpaeManagerThread_ = std::make_unique(); - hpaeManagerThread_->ActivateThread(this); - hpaePolicyManager_ = std::make_unique(); - isInit_.store(true); - return 0; -} - -int32_t HpaeManager::SuspendAudioDevice(std::string &audioPortName, bool isSuspend) -{ - AUDIO_INFO_LOG("suspend audio device: %{public}s, isSuspend: %{public}d", audioPortName.c_str(), isSuspend); - auto request = [this, audioPortName, isSuspend]() { - if (rendererManagerMap_.find(audioPortName) != rendererManagerMap_.end()) { - rendererManagerMap_[audioPortName]->SuspendStreamManager(isSuspend); - } else if (capturerManagerMap_.find(audioPortName) != capturerManagerMap_.end()) { - AUDIO_WARNING_LOG("capture not support suspend"); - return; - } else { - AUDIO_WARNING_LOG("can not find sink: %{public}s", audioPortName.c_str()); - return; - } - }; - SendRequest(request); - return SUCCESS; -} - -bool HpaeManager::SetSinkMute(const std::string &sinkName, bool isMute, bool isSync) -{ - auto request = [this, sinkName, isMute, isSync]() { - // todo for device change - AUDIO_INFO_LOG("HpaeManager::SetSinkMute sinkName: %{public}s isMute: %{public}d, isSync: %{public}d", - sinkName.c_str(), - isMute, - isSync); - if (rendererManagerMap_.find(sinkName) != rendererManagerMap_.end()) { - rendererManagerMap_[sinkName]->SetMute(isMute); - } else { - AUDIO_WARNING_LOG("can not find sink: %{public}s for mute:%{public}d", sinkName.c_str(), isMute); - } - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnSetSinkMuteCb(SUCCESS); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetSourceOutputMute(int32_t uid, bool setMute) -{ - auto request = [this, uid, setMute]() { - AUDIO_INFO_LOG("HpaeManager::SetSourceOutputMute uid: %{public}d setMute: %{public}d", uid, setMute); - if (capturerIdSourceNameMap_.find(uid) != capturerIdSourceNameMap_.end()) { - capturerManagerMap_[capturerIdSourceNameMap_[uid]]->SetMute(setMute); - } else { - AUDIO_WARNING_LOG("can not find sink: %{public}d for mute:%{public}d", uid, setMute); - } - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnSetSourceOutputMuteCb(SUCCESS); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::GetAllSinks() -{ - auto request = [this]() { - std::vector sinks; - // todo for device change - AUDIO_INFO_LOG("HpaeManager::GetAllSinks end"); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnGetAllSinksCb(SUCCESS, sinks); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::DeInit() -{ - if (hpaeManagerThread_ != nullptr) { - hpaeManagerThread_->DeactivateThread(); - hpaeManagerThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); // todo suspend - isInit_.store(false); - AUDIO_INFO_LOG("HpaeManager::DeInit end"); - return SUCCESS; -} - -int32_t HpaeManager::RegisterSerivceCallback(const std::weak_ptr &callback) -{ - auto request = [this, callback]() { - serviceCallback_ = callback; - AUDIO_INFO_LOG("HpaeManager::RegisterSerivceCallback end"); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::RegisterHpaeDumpCallback(AudioServiceHpaeDumpCallback *callback) -{ - auto request = [this, callback]() { - dumpCallback_ = callback; - AUDIO_INFO_LOG("HpaeManager::RegisterHpaeDumpCallback end"); - }; - SendRequest(request); - return SUCCESS; -} - -AudioSampleFormat HpaeManager::TransFormatFromStringToEnum(std::string format) -{ - return static_cast(formatFromParserStrToEnum[format]); -} - -void HpaeManager::AdjustMchSinkInfo(const AudioModuleInfo &audioModuleInfo, HpaeSinkInfo &sinkInfo) -{ - if (sinkInfo.deviceName != "MCH_Speaker") { - return; - } - sinkInfo.channels = static_cast(DEFAULT_MULTICHANNEL_NUM); - sinkInfo.channelLayout = DEFAULT_MULTICHANNEL_CHANNELLAYOUT; - sinkInfo.frameLen = DEFAULT_MULTICHANNEL_FRAME_LEN_MS * sinkInfo.samplingRate / MS_PER_SECOND; - sinkInfo.volume = MAX_SINK_VOLUME_LEVEL; - AUDIO_INFO_LOG("adjust MCH SINK info ch: %{public}u, channelLayout: %{public}" PRIu64 - " frameLen: %{public}zu volume %{public}f", - sinkInfo.channels, - sinkInfo.channelLayout, - sinkInfo.frameLen, - sinkInfo.volume); -} - -void HpaeManager::TransModuleInfoToHpaeSinkInfo(const AudioModuleInfo &audioModuleInfo, HpaeSinkInfo &sinkInfo) -{ - sinkInfo.deviceNetId = audioModuleInfo.networkId; - sinkInfo.deviceClass = audioModuleInfo.className; - AUDIO_INFO_LOG("HpaeManager::deviceNetId: %{public}s, deviceClass: %{public}s", - sinkInfo.deviceNetId.c_str(), - sinkInfo.deviceClass.c_str()); - sinkInfo.adapterName = audioModuleInfo.adapterName; - sinkInfo.filePath = audioModuleInfo.fileName; - - sinkInfo.samplingRate = static_cast(std::atol(audioModuleInfo.rate.c_str())); - sinkInfo.format = static_cast(TransFormatFromStringToEnum(audioModuleInfo.format)); - sinkInfo.channels = static_cast(std::atol(audioModuleInfo.channels.c_str())); - int32_t bufferSize = static_cast(std::atol(audioModuleInfo.bufferSize.c_str())); - sinkInfo.frameLen = bufferSize / (sinkInfo.channels * GET_SIZE_FROM_FORMAT(sinkInfo.format)); - sinkInfo.channelLayout = 0ULL; - sinkInfo.deviceType = static_cast(std::atol(audioModuleInfo.deviceType.c_str())); - sinkInfo.volume = static_cast(std::atol(audioModuleInfo.deviceType.c_str())); - sinkInfo.openMicSpeaker = static_cast(std::atol(audioModuleInfo.OpenMicSpeaker.c_str())); - sinkInfo.renderInIdleState = static_cast(std::atol(audioModuleInfo.renderInIdleState.c_str())); - sinkInfo.offloadEnable = static_cast(std::atol(audioModuleInfo.offloadEnable.c_str())); - sinkInfo.sinkLatency = static_cast(std::atol(audioModuleInfo.sinkLatency.c_str())); - sinkInfo.fixedLatency = static_cast(std::atol(audioModuleInfo.fixedLatency.c_str())); - sinkInfo.deviceName = audioModuleInfo.name; - AdjustMchSinkInfo(audioModuleInfo, sinkInfo); -} - -void HpaeManager::TransModuleInfoToHpaeSourceInfo(const AudioModuleInfo &audioModuleInfo, HpaeSourceInfo &sourceInfo) -{ - sourceInfo.deviceNetId = audioModuleInfo.networkId; - sourceInfo.deviceClass = audioModuleInfo.className; - sourceInfo.adapterName = audioModuleInfo.adapterName; - sourceInfo.sourceName = audioModuleInfo.name; // built_in_mic - sourceInfo.deviceName = audioModuleInfo.name; - sourceInfo.sourceType = static_cast(std::atol(audioModuleInfo.sourceType.c_str())); - sourceInfo.filePath = audioModuleInfo.fileName; - int32_t bufferSize = static_cast(std::atol(audioModuleInfo.bufferSize.c_str())); - sourceInfo.channels = static_cast(std::atol(audioModuleInfo.channels.c_str())); - sourceInfo.format = TransFormatFromStringToEnum(audioModuleInfo.format); - sourceInfo.frameLen = bufferSize / (sourceInfo.channels * GET_SIZE_FROM_FORMAT(sourceInfo.format)); - sourceInfo.samplingRate = static_cast(std::atol(audioModuleInfo.rate.c_str())); - sourceInfo.channelLayout = 0ULL; - sourceInfo.deviceType = static_cast(std::atol(audioModuleInfo.deviceType.c_str())); - sourceInfo.volume = static_cast(std::atol(audioModuleInfo.deviceType.c_str())); // 1.0f; - - sourceInfo.ecType = static_cast(std::atol(audioModuleInfo.ecType.c_str())); - sourceInfo.ecAdapterName = audioModuleInfo.ecAdapter; - sourceInfo.ecSamplingRate = static_cast(std::atol(audioModuleInfo.ecSamplingRate.c_str())); - sourceInfo.ecFormat = TransFormatFromStringToEnum(audioModuleInfo.ecFormat); - sourceInfo.ecChannels = static_cast(std::atol(audioModuleInfo.ecChannels.c_str())); - sourceInfo.ecFrameLen = DEFAULT_MULTICHANNEL_FRAME_LEN_MS * (sourceInfo.ecSamplingRate / MS_PER_SECOND); - - sourceInfo.micRef = static_cast(std::atol(audioModuleInfo.openMicRef.c_str())); - sourceInfo.micRefSamplingRate = static_cast(std::atol(audioModuleInfo.micRefRate.c_str())); - sourceInfo.micRefFormat = TransFormatFromStringToEnum(audioModuleInfo.micRefFormat); - sourceInfo.micRefChannels = static_cast(std::atol(audioModuleInfo.micRefChannels.c_str())); - sourceInfo.openMicSpeaker = static_cast(std::atol(audioModuleInfo.OpenMicSpeaker.c_str())); - sourceInfo.micRefFrameLen = DEFAULT_MULTICHANNEL_FRAME_LEN_MS * (sourceInfo.micRefSamplingRate / MS_PER_SECOND); -} - -void HpaeManager::PrintAudioModuleInfo(const AudioModuleInfo &audioModuleInfo) -{ - AUDIO_INFO_LOG("rate: %{public}s ch: %{public}s buffersize: %{public}s ", - audioModuleInfo.rate.c_str(), - audioModuleInfo.channels.c_str(), - audioModuleInfo.bufferSize.c_str()); - AUDIO_INFO_LOG("format: %{public}s name: %{public}s lib: %{public}s ", - audioModuleInfo.format.c_str(), - audioModuleInfo.name.c_str(), - audioModuleInfo.lib.c_str()); - AUDIO_INFO_LOG("deviceType: %{public}s className: %{public}s adapterName: %{public}s ", - audioModuleInfo.deviceType.c_str(), - audioModuleInfo.className.c_str(), - audioModuleInfo.adapterName.c_str()); - AUDIO_INFO_LOG("OpenMicSpeaker: %{public}s networkId: %{public}s fileName: %{public}s ", - audioModuleInfo.OpenMicSpeaker.c_str(), - audioModuleInfo.networkId.c_str(), - audioModuleInfo.fileName.c_str()); - AUDIO_INFO_LOG("fixedLatency: %{public}s sinkLatency: %{public}s renderInIdleState: %{public}s ", - audioModuleInfo.fixedLatency.c_str(), - audioModuleInfo.sinkLatency.c_str(), - audioModuleInfo.renderInIdleState.c_str()); - AUDIO_INFO_LOG("sceneName: %{public}s sourceType: %{public}s offloadEnable: %{public}s ", - audioModuleInfo.sceneName.c_str(), - audioModuleInfo.sourceType.c_str(), - audioModuleInfo.offloadEnable.c_str()); -} - -uint32_t HpaeManager::OpenOutputAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex) -{ - if (rendererManagerMap_.find(audioModuleInfo.name) != rendererManagerMap_.end()) { - AUDIO_INFO_LOG("sink name: %{public}s already open", audioModuleInfo.name.c_str()); - if (!rendererManagerMap_[audioModuleInfo.name]->IsInit()) { - rendererManagerMap_[audioModuleInfo.name]->Init(); - MoveToPreferSink(audioModuleInfo.name); - } else if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnOpenAudioPortCb(sinkNameSinkIdMap_[audioModuleInfo.name]); - } - return sinkNameSinkIdMap_[audioModuleInfo.name]; - } - sinkSourceIndex_.fetch_add(1); - HpaeSinkInfo sinkInfo; - sinkInfo.sinkId = sinkSourceIndex; - sinkInfo.suspendTime = DEFAULT_SUSPEND_TIME_IN_MS; - TransModuleInfoToHpaeSinkInfo(audioModuleInfo, sinkInfo); - auto rendererManager = IHpaeRendererManager::CreateRendererManager(sinkInfo); - rendererManagerMap_[audioModuleInfo.name] = rendererManager; - sinkNameSinkIdMap_[audioModuleInfo.name] = sinkSourceIndex; - sinkIdSinkNameMap_[sinkSourceIndex] = audioModuleInfo.name; - rendererManager->Init(); - rendererManager->RegisterSendMsgCallback(weak_from_this()); - MoveToPreferSink(audioModuleInfo.name); - AUDIO_INFO_LOG( - "open sink name: %{public}s end sinkIndex is %{public}u", audioModuleInfo.name.c_str(), sinkSourceIndex); - uint32_t renderId = GetRenderId(sinkInfo.deviceClass); - // todo: set renderId to CaptureManger - hpaePolicyManager_->SetOutputDevice(renderId, static_cast(sinkInfo.deviceType)); - return SUCCESS; -} - -uint32_t HpaeManager::OpenInputAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex) -{ - if (capturerManagerMap_.find(audioModuleInfo.name) != capturerManagerMap_.end()) { - HpaeEcType ecType = static_cast(std::atol(audioModuleInfo.ecType.c_str())); - HpaeMicRefSwitch micRef = static_cast(std::atol(audioModuleInfo.openMicRef.c_str())); - HpaeSourceInfo oldInfo = capturerManagerMap_[audioModuleInfo.name]->GetSourceInfo(); - if (oldInfo.ecType != ecType || oldInfo.micRef != micRef) { - AUDIO_INFO_LOG("source name: %{public}s need reload", audioModuleInfo.name.c_str()); - HpaeSourceInfo sourceInfo; - sourceInfo.sourceId = oldInfo.sourceId; - TransModuleInfoToHpaeSourceInfo(audioModuleInfo, sourceInfo); - capturerManagerMap_[audioModuleInfo.name]->ReloadCaptureManager(sourceInfo); - return sourceNameSourceIdMap_[audioModuleInfo.name]; - } - AUDIO_INFO_LOG("source name: %{public}s already open", audioModuleInfo.name.c_str()); - if (!capturerManagerMap_[audioModuleInfo.name]->IsInit()) { - capturerManagerMap_[audioModuleInfo.name]->Init(); - } else if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnOpenAudioPortCb(sourceNameSourceIdMap_[audioModuleInfo.name]); - } - return sourceNameSourceIdMap_[audioModuleInfo.name]; - } - sinkSourceIndex_.fetch_add(1); - HpaeSourceInfo sourceInfo; - sourceInfo.sourceId = sinkSourceIndex; - TransModuleInfoToHpaeSourceInfo(audioModuleInfo, sourceInfo); - auto capturerManager = std::make_shared(sourceInfo); - capturerManagerMap_[audioModuleInfo.name] = capturerManager; - sourceNameSourceIdMap_[audioModuleInfo.name] = sinkSourceIndex; - sourceIdSourceNameMap_[sinkSourceIndex] = audioModuleInfo.name; - capturerManagerMap_[audioModuleInfo.name]->Init(); - capturerManager->RegisterSendMsgCallback(weak_from_this()); - AUDIO_INFO_LOG( - "open source name: %{public}s end sourceIndex is %{public}u", audioModuleInfo.name.c_str(), sinkSourceIndex); - uint32_t captureId = GetCaptureId(sourceInfo.deviceClass); - capturerManager->SetCaptureId(captureId); - hpaePolicyManager_->SetInputDevice(captureId, static_cast(sourceInfo.deviceType)); - return SUCCESS; -} - -uint32_t HpaeManager::OpenVirtualAudioPort(const AudioModuleInfo &audioModuleInfo, int32_t sinkSourceIndex) -{ - if (rendererManagerMap_.find(audioModuleInfo.name) != rendererManagerMap_.end()) { - AUDIO_INFO_LOG("inner capture name: %{public}s already open", audioModuleInfo.name.c_str()); - if (!rendererManagerMap_[audioModuleInfo.name]->IsInit()) { - rendererManagerMap_[audioModuleInfo.name]->Init(); - } else if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnOpenAudioPortCb(sinkNameSinkIdMap_[audioModuleInfo.name]); - } - return sinkNameSinkIdMap_[audioModuleInfo.name]; - } - sinkSourceIndex_.fetch_add(1); - HpaeSinkInfo sinkInfo; - sinkInfo.sinkId = sinkSourceIndex; - TransModuleInfoToHpaeSinkInfo(audioModuleInfo, sinkInfo); - auto rendererManager = IHpaeRendererManager::CreateRendererManager(sinkInfo); - rendererManagerMap_[audioModuleInfo.name] = rendererManager; - sinkNameSinkIdMap_[audioModuleInfo.name] = sinkSourceIndex; - sinkIdSinkNameMap_[sinkSourceIndex] = audioModuleInfo.name; - rendererManagerMap_[audioModuleInfo.name]->Init(); - rendererManager->RegisterSendMsgCallback(weak_from_this()); - AUDIO_INFO_LOG("HpaeManager::OpenAudioPort name: %{public}s end sinkIndex is %{public}u", - audioModuleInfo.name.c_str(), - sinkSourceIndex); - return SUCCESS; -} - -int32_t HpaeManager::OpenAudioPortInner(const AudioModuleInfo &audioModuleInfo) -{ - int32_t sinkSourceIndex = sinkSourceIndex_.load(); - if ((audioModuleInfo.lib != "libmodule-hdi-source.z.so") && - (audioModuleInfo.lib != "libmodule-inner-capturer-sink.z.so")) { - OpenOutputAudioPort(audioModuleInfo, sinkSourceIndex); - } else if (audioModuleInfo.lib == "libmodule-hdi-source.z.so") { - OpenInputAudioPort(audioModuleInfo, sinkSourceIndex); - } else { - OpenVirtualAudioPort(audioModuleInfo, sinkSourceIndex); - } - return sinkSourceIndex; -} - -uint32_t HpaeManager::OpenAudioPort(const AudioModuleInfo &audioModuleInfo) -{ - auto request = [this, audioModuleInfo]() { - PrintAudioModuleInfo(audioModuleInfo); - OpenAudioPortInner(audioModuleInfo); - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeManager::DumpSinkInfo(std::string deviceName) -{ - auto request = [this, deviceName]() { - AUDIO_INFO_LOG("DumpSinkInfo %{public}s", deviceName.c_str()); - if (rendererManagerMap_.find(deviceName) == rendererManagerMap_.end()) { - AUDIO_WARNING_LOG("can not find sinkName: %{public}s in rendererManagerMap_", deviceName.c_str()); - if (dumpCallback_) { - std::string dumpStr; - dumpCallback_->OnDumpSinkInfoCb(dumpStr, ERROR); - } - return; - } - rendererManagerMap_[deviceName]->DumpSinkInfo(); - }; - SendRequest(request); -} - -void HpaeManager::DumpSourceInfo(std::string deviceName) -{ - auto request = [this, deviceName]() { - AUDIO_INFO_LOG("DumpSourceInfo %{public}s", deviceName.c_str()); - if (capturerManagerMap_.find(deviceName) == capturerManagerMap_.end()) { - AUDIO_WARNING_LOG("can not find sourceName: %{public}s in capturerManagerMap_", deviceName.c_str()); - if (dumpCallback_) { - std::string dumpStr; - dumpCallback_->OnDumpSourceInfoCb(dumpStr, ERROR); - } - return; - } - capturerManagerMap_[deviceName]->DumpSourceInfo(); - }; - SendRequest(request); -} - -int32_t HpaeManager::CloseOutAudioPort(std::string &sinkName) -{ - if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { - AUDIO_WARNING_LOG("can not find sinkName: %{public}s in rendererManagerMap_", sinkName.c_str()); - return SUCCESS; - } - rendererManagerMap_[sinkName]->DeInit(sinkName != defaultSink_); - if (sinkName != defaultSink_) { - rendererManagerMap_.erase(sinkName); - sinkIdSinkNameMap_.erase(sinkNameSinkIdMap_[sinkName]); - sinkNameSinkIdMap_.erase(sinkName); - } - return SUCCESS; -} - -int32_t HpaeManager::CloseInAudioPort(std::string &sourceName) -{ - if (capturerManagerMap_.find(sourceName) == capturerManagerMap_.end()) { - AUDIO_WARNING_LOG("can not find sourceName: %{public}s in capturerManagerMap_", sourceName.c_str()); - return SUCCESS; - } - capturerManagerMap_[sourceName]->DeInit(sourceName != defaultSource_); - if (sourceName != defaultSource_) { - capturerManagerMap_.erase(sourceName); - sourceIdSourceNameMap_.erase(sourceNameSourceIdMap_[sourceName]); - sourceNameSourceIdMap_.erase(sourceName); - } - return SUCCESS; -} - -int32_t HpaeManager::CloseAudioPort(int32_t audioHandleIndex) -{ - auto request = [this, audioHandleIndex]() { - int32_t ret = -1; - if (sinkIdSinkNameMap_.find(audioHandleIndex) != sinkIdSinkNameMap_.end()) { - AUDIO_INFO_LOG("close sink index: %{public}d name %{public}s", - audioHandleIndex, - sinkIdSinkNameMap_[audioHandleIndex].c_str()); - ret = CloseOutAudioPort(sinkIdSinkNameMap_[audioHandleIndex]); - } else { - AUDIO_INFO_LOG("close source index: %{public}d name %{public}s", - audioHandleIndex, - sourceIdSourceNameMap_[audioHandleIndex].c_str()); - ret = CloseInAudioPort(sourceIdSourceNameMap_[audioHandleIndex]); - } - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnCloseAudioPortCb(ret); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetDefaultSink(std::string name) -{ - auto request = [this, name]() { - AUDIO_INFO_LOG("SetDefaultSink name: %{public}s", name.c_str()); - if (name == defaultSink_) { - AUDIO_INFO_LOG("sink is same as default sink"); - return; - } - std::shared_ptr rendererManager = GetRendererManagerByNmae(defaultSink_); - if (rendererManager == nullptr) { - AUDIO_INFO_LOG("default sink not exist, set default sink direct"); - defaultSink_ = name; - return; - } - if (rendererManagerMap_.find(name) == rendererManagerMap_.end()) { - AUDIO_WARNING_LOG("sink: %{public}s not exist, do not change default sink", name.c_str()); - return; - } - std::vector sessionIds; - rendererManager->MoveAllStream(name, sessionIds, true); - std::string oldDefaultSink = defaultSink_; - defaultSink_ = name; - if (!rendererManager->IsInit()) { - rendererManagerMap_.erase(defaultSink_); - sinkIdSinkNameMap_.erase(sinkNameSinkIdMap_[defaultSink_]); - sinkNameSinkIdMap_.erase(defaultSink_); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetDefaultSource(std::string name) -{ - AUDIO_INFO_LOG("HpaeManager::SetDefaultSource name: %{public}s", name.c_str()); - auto request = [this, name]() { - if (name == defaultSource_) { - AUDIO_INFO_LOG("source is same as default source"); - return; - } - std::shared_ptr capturerManager = GetCapturerManagerByName(defaultSource_); - if (capturerManager == nullptr) { - AUDIO_INFO_LOG("default source not exist, set default source direct"); - defaultSource_ = name; - return; - } - if (capturerManagerMap_.find(name) == capturerManagerMap_.end()) { - AUDIO_WARNING_LOG("source: %{public}s not exist, do not change default source", name.c_str()); - return; - } - std::vector sessionIds; - capturerManager->MoveAllStream(name, sessionIds, true); - std::string oldDefaultSource_ = defaultSource_; - defaultSource_ = name; - if (!capturerManager->IsInit()) { - capturerManagerMap_.erase(oldDefaultSource_); - sourceIdSourceNameMap_.erase(sourceNameSourceIdMap_[oldDefaultSource_]); - sourceNameSourceIdMap_.erase(oldDefaultSource_); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::GetAllSinkInputs() -{ - AUDIO_INFO_LOG("GetAllSinkInputs"); - auto request = [this]() { - std::vector results; - std::transform(sinkInputs_.begin(), sinkInputs_.end(), std::back_inserter(results), [](const auto &pair) { - return pair.second; - }); - AUDIO_INFO_LOG("sink input number:%{public}zu", results.size()); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnGetAllSinkInputsCb(SUCCESS, results); - } - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeManager::MoveToPreferSink(const std::string &name) -{ - AUDIO_INFO_LOG("enter in"); - std::unordered_map> sinkIdMap; - for (const auto &id : idPreferSinkNameMap_) { - if (id.second == name && rendererIdSinkNameMap_[id.first] != id.second) { - if (sinkIdMap.find(id.second) == sinkIdMap.end()) { - sinkIdMap[id.second] = std::vector{}; - } - sinkIdMap[id.second].push_back(id.first); - } - } - for (const auto &sinkId : sinkIdMap) { - std::string sinkName = sinkId.first; - const std::vector ids = sinkId.second; - auto request = [this, sinkName, name, ids]() { - AUDIO_INFO_LOG("MoveToPreferSink name: %{public}s", name.c_str()); - if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { - AUDIO_ERR_LOG("can not find prefer sink: %{public}s", sinkName.c_str()); - return; - } - rendererManagerMap_[sinkName]->MoveAllStream(name, ids, false); - }; - SendRequest(request); - } -} - -int32_t HpaeManager::GetAllSourceOutputs() -{ - AUDIO_INFO_LOG("GetAllSourceOutputs"); - auto request = [this]() { - std::vector results; - std::transform(sourceOutputs_.begin(), sourceOutputs_.end(), std::back_inserter(results), [](const auto &pair) { - return pair.second; - }); - AUDIO_INFO_LOG("source output number:%{public}zu", results.size()); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnGetAllSourceOutputsCb(SUCCESS, results); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::MoveSourceOutputByIndexOrName( - uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName) -{ - auto request = [this, sourceOutputId, sourceName]() { - AUDIO_INFO_LOG("start to move id:%{public}d, source name:%{public}s", sourceOutputId, sourceName.c_str()); - if (sourceName.empty()) { - AUDIO_ERR_LOG("source name is empty."); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSourceOutputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - - std::shared_ptr oldCaptureManager = GetCapturerManagerById(sourceOutputId); - if (oldCaptureManager == nullptr) { - AUDIO_ERR_LOG("can not find source by id:%{public}d.", sourceOutputId); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSourceOutputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - if (capturerManagerMap_.find(sourceName) == capturerManagerMap_.end()) { - AUDIO_ERR_LOG("can not find source by name:%{public}s.", sourceName.c_str()); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSourceOutputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - if (sourceName == capturerIdSourceNameMap_[sourceOutputId]) { - AUDIO_INFO_LOG("source is the same, no need move,source name:%{public}s", sourceName.c_str()); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSourceOutputByIndexOrNameCb(SUCCESS); - } - return; - } - oldCaptureManager->MoveStream(sourceOutputId, sourceName); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) -{ - auto request = [this, sinkInputId, sinkName]() { - AUDIO_INFO_LOG("start to move id:%{public}d, sink name:%{public}s", sinkInputId, sinkName.c_str()); - if (sinkName.empty()) { - AUDIO_ERR_LOG("sink name is empty."); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - std::shared_ptr oldRendererManager = GetRendererManagerById(sinkInputId); - if (oldRendererManager == nullptr) { - AUDIO_ERR_LOG("can not find sink by id:%{public}d", sinkInputId); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - if (sinkName == rendererIdSinkNameMap_[sinkInputId]) { - AUDIO_INFO_LOG("sink is the same, no need move,sink:%{public}s", sinkName.c_str()); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSinkInputByIndexOrNameCb(SUCCESS); - } - return; - } - if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { - AUDIO_ERR_LOG("can not find sink:%{public}s.", sinkName.c_str()); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - if (rendererIdStreamInfoMap_.find(sinkInputId) == rendererIdStreamInfoMap_.end()) { - AUDIO_ERR_LOG("can not find session info:%{public}d", sinkInputId); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - oldRendererManager->MoveStream(sinkInputId, sinkName); - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeManager::HandleMsg() -{ - hpaeNoLockQueue_.HandleRequests(); -} - -bool HpaeManager::IsInit() -{ - return isInit_.load(); -} - -bool HpaeManager::IsRunning() -{ - if (hpaeManagerThread_ == nullptr) { - return false; - } - return hpaeManagerThread_->IsRunning(); -} - -bool HpaeManager::IsMsgProcessing() -{ - return !hpaeNoLockQueue_.IsFinishProcess(); -} - -int32_t HpaeManager::GetMsgCount() -{ - return receiveMsgCount_.load(); -} - -void HpaeManager::Invoke(HpaeMsgCode cmdID, const std::any &args) -{ - auto it = handlers_.find(cmdID); - if (it != handlers_.end()) { - auto request = [it, args]() { it->second(args); }; - SendRequest(request); - return; - }; - AUDIO_ERR_LOG("HpaeManager::Invoke cmdID %{public}d not found", (int32_t)cmdID); -} - -template -void HpaeManager::RegisterHandler(HpaeMsgCode cmdID, void (HpaeManager::*func)(Args...)) -{ - handlers_[cmdID] = [this, cmdID, func](const std::any &packedArgs) { - // unpack args - auto args = std::any_cast>(&packedArgs); - // print log if args parse error - CHECK_AND_RETURN_LOG(args != nullptr, "cmdId %{public}d type mismatched", cmdID); - std::apply( - [this, func]( - auto &&...unpackedArgs) { (this->*func)(std::forward(unpackedArgs)...); }, - *args); - }; -} - -void HpaeManager::HandleMoveSinkInput(const std::shared_ptr sinkInputNode, std::string sinkName) -{ - AUDIO_INFO_LOG("move to new sink:%{public}s", sinkName.c_str()); - std::shared_ptr rendererManager = GetRendererManagerByNmae(sinkName); - if (rendererManager == nullptr) { - AUDIO_ERR_LOG("can not find sink by new name:%{public}s", sinkName.c_str()); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSinkInputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - uint32_t sessionId = sinkInputNode->GetNodeInfo().sessionId; - rendererManager->AddNodeToSink(sinkInputNode); - rendererIdSinkNameMap_[sessionId] = sinkName; - idPreferSinkNameMap_[sessionId] = sinkName; - if (sinkInputs_.find(sessionId) != sinkInputs_.end()) { - sinkInputs_[sessionId].deviceSinkId = sinkNameSinkIdMap_[sinkName]; - sinkInputs_[sessionId].sinkName = sinkName; - } - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSinkInputByIndexOrNameCb(SUCCESS); - } -} - -void HpaeManager::HandleMoveSourceOutput(const HpaeCaptureMoveInfo moveInfo, std::string sourceName) -{ - AUDIO_INFO_LOG("move to new source:%{public}s", sourceName.c_str()); - std::shared_ptr catpureManager = GetCapturerManagerByName(sourceName); - if (catpureManager == nullptr) { - AUDIO_ERR_LOG("can not find source by name:%{public}s", sourceName.c_str()); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSourceOutputByIndexOrNameCb(ERROR_INVALID_PARAM); - } - return; - } - uint32_t sessionId = moveInfo.sessionId; - catpureManager->AddNodeToSource(moveInfo); - capturerIdSourceNameMap_[sessionId] = sourceName; - if (sourceOutputs_.find(sessionId) != sourceOutputs_.end()) { - sourceOutputs_[sessionId].deviceSourceId = sourceNameSourceIdMap_[sourceName]; - } - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnMoveSourceOutputByIndexOrNameCb(SUCCESS); - } -} - -void HpaeManager::HandleMoveAllSinkInputs( - const std::vector> sinkInputs, std::string sinkName) -{ - AUDIO_INFO_LOG("sink name is :%{public}s", sinkName.c_str()); - if (sinkName.empty()) { - AUDIO_INFO_LOG("sink name is empty, move to default sink:%{public}s", defaultSink_.c_str()); - sinkName = defaultSink_; - } - if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { - AUDIO_WARNING_LOG("can not find sink: %{public}s", sinkName.c_str()); - return; - } - AUDIO_INFO_LOG("sink input count:%{public}zu", sinkInputs.size()); - rendererManagerMap_[sinkName]->AddAllNodesToSink(sinkInputs, false); - for (const auto &sinkInput : sinkInputs) { - uint32_t sessionId = sinkInput->GetNodeInfo().sessionId; - rendererIdSinkNameMap_[sessionId] = sinkName; - if (sinkInputs_.find(sessionId) != sinkInputs_.end()) { - sinkInputs_[sessionId].deviceSinkId = sinkNameSinkIdMap_[sinkName]; - sinkInputs_[sessionId].sinkName = sinkName; - } - } -} - -void HpaeManager::HandleMoveAllSourceOutputs(const std::vector moveInfos, std::string sourceName) -{ - AUDIO_INFO_LOG("move all source to :%{public}s", sourceName.c_str()); - if (sourceName.empty()) { - AUDIO_INFO_LOG("source is empty, move to default source:%{public}s", defaultSource_.c_str()); - sourceName = defaultSource_; - } - if (capturerManagerMap_.find(sourceName) == capturerManagerMap_.end()) { - AUDIO_WARNING_LOG("can not find source: %{public}s", sourceName.c_str()); - return; - } - AUDIO_INFO_LOG("sink input count:%{public}zu", moveInfos.size()); - capturerManagerMap_[sourceName]->AddAllNodesToSource(moveInfos, false); - for (const auto &it : moveInfos) { - capturerIdSourceNameMap_[it.sessionId] = sourceName; - if (sourceOutputs_.find(it.sessionId) != sourceOutputs_.end()) { - sourceOutputs_[it.sessionId].deviceSourceId = sourceNameSourceIdMap_[sourceName]; - } - } -} - -void HpaeManager::HandleUpdateStatus( - HpaeStreamClassType streamClassType, uint32_t sessionId, uint32_t status, IOperation operation) -{ - AUDIO_INFO_LOG("HpaeManager::HandleUpdateStatus sessionid:%{public}u " - "status:%{public}d operation:%{public}d", - sessionId, - status, - operation); - if (operation == OPERATION_INVALID) { - // maybe dosomething while move sink inputs - return; - } - auto it = streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY ? rendererIdStreamInfoMap_.find(sessionId) - : capturerIdStreamInfoMap_.find(sessionId); - if (it != rendererIdStreamInfoMap_.end() && it != capturerIdStreamInfoMap_.end()) { - if (auto callback = it->second.statusCallback.lock()) { - callback->OnStatusUpdate(operation); - } - } -} - -void HpaeManager::HandleDumpSinkInfo(std::string deviceName, std::string dumpStr) -{ - AUDIO_INFO_LOG("HpaeManager::HandleDumpSinkInfo deviceName:%{public}s dumpStr:%{public}s", - deviceName.c_str(), - dumpStr.c_str()); - if (dumpCallback_) { - dumpCallback_->OnDumpSinkInfoCb(dumpStr, SUCCESS); - } -} - -void HpaeManager::HandleDumpSourceInfo(std::string deviceName, std::string dumpStr) -{ - AUDIO_INFO_LOG("HpaeManager::HandleDumpSourceInfo deviceName:%{public}s dumpStr:%{public}s", - deviceName.c_str(), - dumpStr.c_str()); - if (dumpCallback_) { - dumpCallback_->OnDumpSourceInfoCb(dumpStr, SUCCESS); - } -} - -void HpaeManager::HandleInitDeviceResult(std::string deviceName, int32_t result) -{ - AUDIO_INFO_LOG("deviceName:%{public}s result:%{public}d ", deviceName.c_str(), result); - auto serviceCallback = serviceCallback_.lock(); - if (serviceCallback && result == SUCCESS) { - if (sinkNameSinkIdMap_.find(deviceName) != sinkNameSinkIdMap_.end()) { - serviceCallback->OnOpenAudioPortCb(sinkNameSinkIdMap_[deviceName]); - } else if (sourceNameSourceIdMap_.find(deviceName) != sourceNameSourceIdMap_.end()) { - serviceCallback->OnOpenAudioPortCb(sourceNameSourceIdMap_[deviceName]); - } else { - AUDIO_ERR_LOG("device:%{public}s is not exist.", deviceName.c_str()); - serviceCallback->OnOpenAudioPortCb(ERROR); - } - } else if (serviceCallback) { - serviceCallback->OnOpenAudioPortCb(ERROR); - AUDIO_INFO_LOG("HandleInitDeviceResult deviceName:%{public}s " - "result:%{public}d error", - deviceName.c_str(), - result); - } else { - AUDIO_INFO_LOG("HandleInitDeviceResult OnOpenAudioPortCb is nullptr"); - } -} - -void HpaeManager::HandleDeInitDeviceResult(std::string deviceName, int32_t result) -{ - AUDIO_INFO_LOG("deviceName:%{public}s result:%{public}d ", deviceName.c_str(), result); - auto serviceCallback = serviceCallback_.lock(); - if (serviceCallback && result == SUCCESS && sinkNameSinkIdMap_.find(deviceName) != sinkNameSinkIdMap_.end()) { - serviceCallback->OnCloseAudioPortCb(sinkNameSinkIdMap_[deviceName]); - } else if (serviceCallback) { - serviceCallback->OnCloseAudioPortCb(ERROR); - AUDIO_INFO_LOG("deviceName:%{public}s " - "result:%{public}d error", - deviceName.c_str(), - result); - } else { - AUDIO_INFO_LOG("HandleDeInitDeviceResult is nullptr"); - } - if (rendererManagerMap_.find(deviceName) != rendererManagerMap_.end()) { - AUDIO_INFO_LOG("OnCloseAudioPortCb is sink"); - rendererManagerMap_[deviceName]->DeactivateThread(); - if (deviceName != defaultSink_) { - rendererManagerMap_.erase(deviceName); - sinkIdSinkNameMap_.erase(sinkNameSinkIdMap_[deviceName]); - sinkNameSinkIdMap_.erase(deviceName); - } - } else if (capturerManagerMap_.find(deviceName) != capturerManagerMap_.end()) { - AUDIO_INFO_LOG("OnCloseAudioPortCb is source"); - capturerManagerMap_[deviceName]->DeactivateThread(); - if (deviceName != defaultSource_) { - capturerManagerMap_.erase(deviceName); - sourceIdSourceNameMap_.erase(sourceNameSourceIdMap_[deviceName]); - sourceNameSourceIdMap_.erase(deviceName); - } - } else { - AUDIO_INFO_LOG("deviceName:%{public}s can not find", deviceName.c_str()); - } -} - -void HpaeManager::SendRequest(Request &&request) -{ - hpaeNoLockQueue_.PushRequest(std::move(request)); - CHECK_AND_RETURN_LOG(hpaeManagerThread_, "hpaeManagerThread_ is nullptr"); - hpaeManagerThread_->Notify(); -} -// play and record stream interface -int32_t HpaeManager::CreateStream(const HpaeStreamInfo &streamInfo) -{ - auto request = [this, streamInfo]() { - AUDIO_INFO_LOG("defaultSink_ is %{public}s defaultSource_ is %{public}s streamClassType %{public}u", - defaultSink_.c_str(), - defaultSource_.c_str(), - streamInfo.streamClassType); - AUDIO_INFO_LOG("streamType is %{public}d sessionId %{public}u sourceType is %{public}d", - streamInfo.streamType, - streamInfo.sessionId, - streamInfo.sourceType); - if (INNER_SOURCE_TYPE_SET.count(streamInfo.sourceType) != 0) { - return CreateStreamForCapInner(streamInfo); - } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { - std::string deviceName = streamInfo.deviceName == "" ? defaultSink_ : streamInfo.deviceName; - AUDIO_INFO_LOG("devicename:%{public}s, sessionId:%{public}u", deviceName.c_str(), streamInfo.sessionId); - CHECK_AND_RETURN_LOG(rendererManagerMap_.find(deviceName) != rendererManagerMap_.end(), - "can not find sink[%{public}s] in rendererManagerMap_", - deviceName.c_str()); - rendererIdSinkNameMap_[streamInfo.sessionId] = defaultSink_; - rendererManagerMap_[defaultSink_]->CreateStream(streamInfo); - rendererIdStreamInfoMap_[streamInfo.sessionId].streamInfo = streamInfo; - rendererIdStreamInfoMap_[streamInfo.sessionId].state = I_STATUS_IDLE; - AddStreamToCollection(streamInfo); - } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD) { - std::string deviceName = streamInfo.deviceName == "" ? defaultSource_ : streamInfo.deviceName; - AUDIO_INFO_LOG("source:%{public}s, sessionId:%{public}u", deviceName.c_str(), streamInfo.sessionId); - CHECK_AND_RETURN_LOG(capturerManagerMap_.find(deviceName) != capturerManagerMap_.end(), - "can not find source[%{public}s] in capturerManagerMap_", - deviceName.c_str()); - capturerIdSourceNameMap_[streamInfo.sessionId] = deviceName; - capturerManagerMap_[deviceName]->CreateStream(streamInfo); - capturerIdStreamInfoMap_[streamInfo.sessionId].streamInfo = streamInfo; - capturerIdStreamInfoMap_[streamInfo.sessionId].state = I_STATUS_IDLE; - AddStreamToCollection(streamInfo); - } else { - AUDIO_WARNING_LOG( - "can not find default sink or source streamClassType %{public}d", streamInfo.streamClassType); - } - }; - SendRequest(request); - AUDIO_WARNING_LOG( - "defaultSink_ is %{public}s streamClassType %{public}u", defaultSink_.c_str(), streamInfo.sessionId); - return SUCCESS; -} - -void HpaeManager::AddStreamToCollection(const HpaeStreamInfo &streamInfo) -{ - auto now = std::chrono::system_clock::now(); - auto ms = std::chrono::duration_cast(now.time_since_epoch()); - if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { - SinkInput sinkInput; - sinkInput.streamId = streamInfo.sessionId; - sinkInput.paStreamId = streamInfo.sessionId; - sinkInput.streamType = streamInfo.streamType; - sinkInput.sinkName = defaultSink_; - sinkInput.deviceSinkId = sinkNameSinkIdMap_[defaultSink_]; - sinkInput.pid = streamInfo.pid; - sinkInput.uid = streamInfo.uid; - sinkInput.startTime = ms.count(); - sinkInputs_[streamInfo.sessionId] = sinkInput; - } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD) { - SourceOutput sourceOutputInfo; - sourceOutputInfo.streamId = streamInfo.sessionId; - sourceOutputInfo.paStreamId = streamInfo.sessionId; - sourceOutputInfo.streamType = streamInfo.streamType; - sourceOutputInfo.deviceSourceId = sourceNameSourceIdMap_[defaultSource_]; - sourceOutputInfo.pid = streamInfo.pid; - sourceOutputInfo.uid = streamInfo.uid; - sourceOutputInfo.startTime = ms.count(); - sourceOutputs_[streamInfo.sessionId] = sourceOutputInfo; - } -} - -int32_t HpaeManager::DestroyStream(HpaeStreamClassType streamClassType, uint32_t sessionId) -{ - auto request = [this, streamClassType, sessionId]() { - AUDIO_INFO_LOG("DestroyStream streamClassType %{public}d, sessionId %{public}u", streamClassType, sessionId); - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && - rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->DestroyStream(sessionId); - rendererIdSinkNameMap_.erase(sessionId); - rendererIdStreamInfoMap_.erase(sessionId); - sinkInputs_.erase(sessionId); - } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && - capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { - rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->DestroyStream(sessionId); - } else { - capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->DestroyStream(sessionId); - } - capturerIdSourceNameMap_.erase(sessionId); - capturerIdStreamInfoMap_.erase(sessionId); - sourceOutputs_.erase(sessionId); - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->HandleSourceAudioStreamRemoved(sessionId); - } - } else { - AUDIO_WARNING_LOG( - "can not find sessionId streamClassType %{public}d, sessionId %{public}u", streamClassType, sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} -int32_t HpaeManager::Start(HpaeStreamClassType streamClassType, uint32_t sessionId) -{ - auto request = [this, streamClassType, sessionId]() { - AUDIO_INFO_LOG( - "HpaeManager::Start sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && - rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - AUDIO_INFO_LOG("renderer Start sessionId: %{public}u deviceName:%{public}s", - sessionId, - rendererIdSinkNameMap_[sessionId].c_str()); - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Start(sessionId); - rendererIdStreamInfoMap_[sessionId].state = I_STATUS_STARTING; - rendererIdStreamInfoMap_[sessionId].statusCallback.lock()->OnStatusUpdate(OPERATION_STARTED); - } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && - capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - AUDIO_INFO_LOG("capturer Start sessionId: %{public}u deviceName:%{public}s", - sessionId, - capturerIdSourceNameMap_[sessionId].c_str()); - if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { - rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Start(sessionId); - } else { - capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Start(sessionId); - } - capturerIdStreamInfoMap_[sessionId].state = I_STATUS_STARTING; - } else { - AUDIO_WARNING_LOG("Start can not find sessionId streamClassType %{public}d, sessionId %{public}u", - streamClassType, - sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} -int32_t HpaeManager::Pause(HpaeStreamClassType streamClassType, uint32_t sessionId) -{ - auto request = [this, streamClassType, sessionId]() { - AUDIO_INFO_LOG( - "HpaeManager::Pause sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && - rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - AUDIO_INFO_LOG("renderer Pause sessionId: %{public}u deviceName:%{public}s", - sessionId, - rendererIdSinkNameMap_[sessionId].c_str()); - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Pause(sessionId); - rendererIdStreamInfoMap_[sessionId].state = I_STATUS_PAUSING; - } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && - capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - AUDIO_INFO_LOG("capturer Pause sessionId: %{public}u deviceName:%{public}s", - sessionId, - capturerIdSourceNameMap_[sessionId].c_str()); - if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { - rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Pause(sessionId); - } else { - capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Pause(sessionId); - } - capturerIdStreamInfoMap_[sessionId].state = I_STATUS_PAUSING; - } else { - AUDIO_WARNING_LOG("Pause can not find sessionId streamClassType %{public}d, sessionId %{public}u", - streamClassType, - sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} -int32_t HpaeManager::Flush(HpaeStreamClassType streamClassType, uint32_t sessionId) -{ - auto request = [this, streamClassType, sessionId]() { - AUDIO_INFO_LOG( - "HpaeManager::Flush sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && - rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - AUDIO_INFO_LOG("renderer Flush sessionId: %{public}u deviceName:%{public}s", - sessionId, - rendererIdSinkNameMap_[sessionId].c_str()); - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Flush(sessionId); - rendererIdStreamInfoMap_[sessionId].state = I_STATUS_FLUSHING_WHEN_STOPPED; - } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && - capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - AUDIO_INFO_LOG("capturer Flush sessionId: %{public}u deviceName:%{public}s", - sessionId, - capturerIdSourceNameMap_[sessionId].c_str()); - if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { - rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Flush(sessionId); - } else { - capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Flush(sessionId); - } - capturerIdStreamInfoMap_[sessionId].state = I_STATUS_FLUSHING_WHEN_STOPPED; - } else { - AUDIO_WARNING_LOG("Flush can not find sessionId streamClassType %{public}d, sessionId %{public}u", - streamClassType, - sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} -int32_t HpaeManager::Drain(HpaeStreamClassType streamClassType, uint32_t sessionId) -{ - auto request = [this, streamClassType, sessionId]() { - AUDIO_INFO_LOG( - "HpaeManager::Drain sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && - rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - AUDIO_INFO_LOG("renderer Drain sessionId: %{public}u deviceName:%{public}s", - sessionId, - rendererIdSinkNameMap_[sessionId].c_str()); - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Drain(sessionId); - rendererIdStreamInfoMap_[sessionId].state = I_STATUS_DRAINING; - } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && - capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - AUDIO_INFO_LOG("capturer Drain sessionId: %{public}u deviceName:%{public}s", - sessionId, - capturerIdSourceNameMap_[sessionId].c_str()); - if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { - rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Drain(sessionId); - } else { - capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Drain(sessionId); - } - capturerIdStreamInfoMap_[sessionId].state = I_STATUS_DRAINING; - } else { - AUDIO_WARNING_LOG("Drain can not find sessionId streamClassType %{public}d, sessionId %{public}u", - streamClassType, - sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} -int32_t HpaeManager::Stop(HpaeStreamClassType streamClassType, uint32_t sessionId) -{ - auto request = [this, streamClassType, sessionId]() { - AUDIO_INFO_LOG( - "HpaeManager::Stop sessionId: %{public}u streamClassType:%{public}d", sessionId, streamClassType); - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && - rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - AUDIO_INFO_LOG("renderer Stop sessionId: %{public}u deviceName:%{public}s", - sessionId, - rendererIdSinkNameMap_[sessionId].c_str()); - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Stop(sessionId); - rendererIdStreamInfoMap_[sessionId].state = I_STATUS_STOPPING; - } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && - capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - AUDIO_INFO_LOG("capturer Stop sessionId: %{public}u deviceName:%{public}s", - sessionId, - capturerIdSourceNameMap_[sessionId].c_str()); - if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { - rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->Stop(sessionId); - } else { - capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->Stop(sessionId); - } - capturerIdStreamInfoMap_[sessionId].state = I_STATUS_STOPPING; - } else { - AUDIO_WARNING_LOG("Stop can not find sessionId streamClassType %{public}d, sessionId %{public}u", - streamClassType, - sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} -int32_t HpaeManager::Release(HpaeStreamClassType streamClassType, uint32_t sessionId) -{ - DestroyStream(streamClassType, sessionId); - return SUCCESS; -} -int32_t HpaeManager::RegisterStatusCallback( - HpaeStreamClassType streamClassType, uint32_t sessionId, const std::weak_ptr &callback) -{ - auto request = [this, streamClassType, sessionId, callback]() { - AUDIO_INFO_LOG( - "RegisterStatusCallback streamClassType %{public}d, sessionId %{public}u", streamClassType, sessionId); - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && - rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - AUDIO_INFO_LOG("renderer RegisterStatusCallback sessionId: %{public}u deviceName:%{public}s", - sessionId, - rendererIdSinkNameMap_[sessionId].c_str()); - rendererIdStreamInfoMap_[sessionId].statusCallback = callback; - } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && - capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - AUDIO_INFO_LOG("capturer RegisterStatusCallback sessionId: %{public}u deviceName:%{public}s", - sessionId, - capturerIdSourceNameMap_[sessionId].c_str()); - capturerIdStreamInfoMap_[sessionId].statusCallback = callback; - } else { - AUDIO_WARNING_LOG( - "RegisterStatusCallback can not find sessionId streamClassType %{public}d, sessionId %{public}u", - streamClassType, - sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} - -// record stream interface -void HpaeManager::RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) -{ - auto request = [this, sessionId, callback]() { - AUDIO_INFO_LOG("RegisterReadCallback sessionId %{public}u", sessionId); - if (capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - AUDIO_INFO_LOG("capturer RegisterReadCallback sessionId: %{public}u deviceName:%{public}s", - sessionId, - capturerIdSourceNameMap_[sessionId].c_str()); - if (INNER_SOURCE_TYPE_SET.count(capturerIdStreamInfoMap_[sessionId].streamInfo.sourceType) != 0) { - rendererManagerMap_[capturerIdSourceNameMap_[sessionId]]->RegisterReadCallback(sessionId, callback); - } else { - capturerManagerMap_[capturerIdSourceNameMap_[sessionId]]->RegisterReadCallback(sessionId, callback); - } - } else { - AUDIO_WARNING_LOG("RegisterReadCallback can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return; -} - -int32_t HpaeManager::GetSourceOutputInfo(uint32_t sessionId, HpaeStreamInfo &streamInfo) -{ - // to do - return SUCCESS; -} -// play stream interface -int32_t HpaeManager::SetClientVolume(uint32_t sessionId, float volume) -{ - auto request = [this, sessionId, volume]() { - AUDIO_INFO_LOG("SetClientVolume sessionId %{public}u %{public}f", sessionId, volume); - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetClientVolume(sessionId, volume); - } else { - AUDIO_WARNING_LOG("SetClientVolume can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetRate(uint32_t sessionId, int32_t rate) -{ - auto request = [this, sessionId, rate]() { - AUDIO_INFO_LOG("SetRate sessionId %{public}u %{public}d", sessionId, rate); - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetRate(sessionId, rate); - } else { - AUDIO_WARNING_LOG("SetRate can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) -{ - auto request = [this, sessionId, effectMode]() { - AUDIO_INFO_LOG("SetAudioEffectMode sessionId %{public}u %{public}d", sessionId, effectMode); - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetAudioEffectMode(sessionId, effectMode); - } else { - AUDIO_WARNING_LOG("SetAudioEffectMode can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) -{ - return SUCCESS; -} - -int32_t HpaeManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType) -{ - auto request = [this, sessionId, privacyType]() { - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetPrivacyType(sessionId, privacyType); - } else { - AUDIO_WARNING_LOG("SetPrivacyType can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType) -{ - return SUCCESS; -} -int32_t HpaeManager::RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) -{ - auto request = [this, sessionId, callback]() { - AUDIO_INFO_LOG("RegisterWriteCallback sessionId %{public}u", sessionId); - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - AUDIO_INFO_LOG("renderer RegisterWriteCallback sessionId: %{public}u deviceName:%{public}s", - sessionId, - rendererIdSinkNameMap_[sessionId].c_str()); - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->RegisterWriteCallback(sessionId, callback); - } else { - AUDIO_WARNING_LOG("RegisterWriteCallback can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} -int32_t HpaeManager::SetOffloadPolicy(uint32_t sessionId, int32_t state) -{ - auto request = [this, sessionId, state]() { - AUDIO_INFO_LOG("SetOffloadPolicy sessionId %{public}u %{public}d", sessionId, state); - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->SetOffloadPolicy(sessionId, state); - } else { - AUDIO_WARNING_LOG("SetOffloadPolicy can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} - -size_t HpaeManager::GetWritableSize(uint32_t sessionId) -{ - return SUCCESS; -} - -int32_t HpaeManager::UpdateSpatializationState(uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) -{ - auto request = [this, sessionId, spatializationEnabled, headTrackingEnabled]() { - AUDIO_INFO_LOG("UpdateSpatializationState sessionId %{public}u spatializationEnabled %{public}d " - "headTrackingEnabled %{public}d", - sessionId, - spatializationEnabled, - headTrackingEnabled); - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->UpdateSpatializationState( - sessionId, spatializationEnabled, headTrackingEnabled); - } else { - AUDIO_WARNING_LOG("UpdateSpatializationState can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) -{ - auto request = [this, sessionId, maxLength]() { - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->UpdateMaxLength(sessionId, maxLength); - } else { - AUDIO_WARNING_LOG("UpdateMaxLength can not find sessionId, sessionId %{public}u", sessionId); - } - }; - SendRequest(request); - return SUCCESS; -} - -// only interface for unit test -int32_t HpaeManager::GetSessionInfo( - HpaeStreamClassType streamClassType, uint32_t sessionId, HpaeSessionInfo &sessionInfo) -{ - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY && - rendererIdStreamInfoMap_.find(sessionId) != rendererIdStreamInfoMap_.end()) { - sessionInfo = rendererIdStreamInfoMap_[sessionId]; - } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && - capturerIdStreamInfoMap_.find(sessionId) != capturerIdStreamInfoMap_.end()) { - sessionInfo = capturerIdStreamInfoMap_[sessionId]; - } else { - return ERROR; - } - return SUCCESS; -} - -std::shared_ptr HpaeManager::GetRendererManagerByNmae(const std::string &sinkName) -{ - if (rendererManagerMap_.find(sinkName) == rendererManagerMap_.end()) { - AUDIO_WARNING_LOG("can not find sinkName: %{public}s ", sinkName.c_str()); - return nullptr; - } - return rendererManagerMap_[sinkName]; -} - -std::shared_ptr HpaeManager::GetCapturerManagerByName(const std::string &sourceName) -{ - if (capturerManagerMap_.find(sourceName) == capturerManagerMap_.end()) { - AUDIO_WARNING_LOG("can not find sourceName: %{public}s ", sourceName.c_str()); - return nullptr; - } - return capturerManagerMap_[sourceName]; -} - -std::shared_ptr HpaeManager::GetRendererManagerById(uint32_t sessionId) -{ - if (rendererIdSinkNameMap_.find(sessionId) != rendererIdSinkNameMap_.end()) { - return GetRendererManagerByNmae(rendererIdSinkNameMap_[sessionId]); - } - AUDIO_WARNING_LOG("can not find renderer by sessionId: %{public}u", sessionId); - return nullptr; -} - -std::shared_ptr HpaeManager::GetCapturerManagerById(uint32_t sessionId) -{ - if (capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { - return GetCapturerManagerByName(capturerIdSourceNameMap_[sessionId]); - } - AUDIO_WARNING_LOG("can not find capture by sessionId: %{public}u", sessionId); - return nullptr; -} - -void HpaeManager::InitAudioEffectChainManager(const std::vector &effectChains, - const EffectChainManagerParam &effectChainManagerParam, - const std::vector> &effectLibraryList) -{ - auto request = [this, effectChains, effectChainManagerParam, effectLibraryList]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->InitAudioEffectChainManager(effectChains, effectChainManagerParam, effectLibraryList); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); -} - -void HpaeManager::SetOutputDeviceSink(int32_t device, const std::string &sinkName) -{ - auto request = [this, device, sinkName]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetOutputDeviceSink(device, sinkName); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); -} - -int32_t HpaeManager::UpdateSpatializationState(AudioSpatializationState spatializationState) -{ - auto request = [this, spatializationState]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->UpdateSpatializationState(spatializationState); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) -{ - auto request = [this, spatialDeviceType]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->UpdateSpatialDeviceType(spatialDeviceType); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType) -{ - auto request = [this, spatializationSceneType]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetSpatializationSceneType(spatializationSceneType); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::EffectRotationUpdate(const uint32_t rotationState) -{ - auto request = [this, rotationState]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->EffectRotationUpdate(rotationState); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume) -{ - auto request = [this, systemVolumeType, systemVolume]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetEffectSystemVolume(systemVolumeType, systemVolume); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray) -{ - auto request = [this, propertyArray]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetAudioEffectProperty(propertyArray); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) -{ - auto request = [this, &propertyArray]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->GetAudioEffectProperty(propertyArray); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnGetAudioEffectPropertyCbV3(SUCCESS); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray) -{ - auto request = [this, propertyArray]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetAudioEffectProperty(propertyArray); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) -{ - auto request = [this, &propertyArray]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->GetAudioEffectProperty(propertyArray); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - if (auto serviceCallback = serviceCallback_.lock()) { - serviceCallback->OnGetAudioEffectPropertyCb(SUCCESS); - } - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeManager::InitHdiState() -{ - auto request = [this]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->InitHdiState(); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); -} - -void HpaeManager::UpdateEffectBtOffloadSupported(const bool &isSupported) -{ - auto request = [this, isSupported]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->UpdateEffectBtOffloadSupported(isSupported); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); -} - -void HpaeManager::UpdateParamExtra(const std::string &mainkey, const std::string &subkey, const std::string &value) -{ - auto request = [this, mainkey, subkey, value]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->UpdateParamExtra(mainkey, subkey, value); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); -} - -void HpaeManager::HandleRendererManager(const std::string &sinkName, const HpaeStreamInfo &streamInfo) -{ - auto it = rendererManagerMap_.find(sinkName); - if (it == rendererManagerMap_.end()) { - AUDIO_INFO_LOG("can not find sink[%{public}s] in rendererManagerMap_", sinkName.c_str()); - return; - } - it->second->CreateStream(streamInfo); - if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { - rendererIdSinkNameMap_[streamInfo.sessionId] = sinkName; - rendererIdStreamInfoMap_[streamInfo.sessionId] = {streamInfo, I_STATUS_IDLE}; - } else if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD) { - capturerIdSourceNameMap_[streamInfo.sessionId] = sinkName; - capturerIdStreamInfoMap_[streamInfo.sessionId] = {streamInfo, I_STATUS_IDLE}; - } -} - -void HpaeManager::CreateStreamForCapInner(const HpaeStreamInfo &streamInfo) -{ - if (streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_INVALID) { - AUDIO_INFO_LOG("streamInfo.streamClassType == HPAE_STREAM_CLASS_TYPE_INVALID"); - return; - } - std::string deviceName = streamInfo.deviceName; - HandleRendererManager(deviceName, streamInfo); - HandleRendererManager("RemoteCastInnerCapturer", streamInfo); - AddStreamToCollection(streamInfo); - return; -} - -void HpaeManager::InitAudioEnhanceChainManager(const std::vector &enhanceChains, - const EffectChainManagerParam &managerParam, - const std::vector> &enhanceLibraryList) -{ - auto request = [this, enhanceChains, managerParam, enhanceLibraryList]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->InitAudioEnhanceChainManager(enhanceChains, managerParam, enhanceLibraryList); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); -} - -int32_t HpaeManager::SetInputDevice( - const uint32_t &captureId, const DeviceType &inputDevice, const std::string &deviceName) -{ - auto request = [this, captureId, inputDevice, deviceName]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetInputDevice(captureId, inputDevice, deviceName); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice) -{ - auto request = [this, renderId, outputDevice]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetOutputDevice(renderId, outputDevice); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol) -{ - auto request = [this, volumeType, systemVol]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetVolumeInfo(volumeType, systemVol); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetMicrophoneMuteInfo(const bool &isMute) -{ - auto request = [this, isMute]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetMicrophoneMuteInfo(isMute); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol) -{ - auto request = [this, sessionId, streamVol]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetStreamVolumeInfo(sessionId, streamVol); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetAudioEnhanceProperty(const AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType) -{ - auto request = [this, propertyArray, deviceType]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetAudioEnhanceProperty(propertyArray, deviceType); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, DeviceType deviceType) -{ - auto request = [this, &propertyArray, deviceType]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->GetAudioEnhanceProperty(propertyArray, deviceType); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &propertyArray, DeviceType deviceType) -{ - auto request = [this, propertyArray, deviceType]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->SetAudioEnhanceProperty(propertyArray, deviceType); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeManager::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, DeviceType deviceType) -{ - auto request = [this, &propertyArray, deviceType]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->GetAudioEnhanceProperty(propertyArray, deviceType); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeManager::UpdateExtraSceneType( - const std::string &mainkey, const std::string &subkey, const std::string &extraSceneType) -{ - auto request = [this, mainkey, subkey, extraSceneType]() { - if (hpaePolicyManager_ != nullptr) { - hpaePolicyManager_->UpdateExtraSceneType(mainkey, subkey, extraSceneType); - } else { - AUDIO_WARNING_LOG("hpaePolicyManager_ is nullptr"); - } - }; - SendRequest(request); - return; -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/manager/src/hpae_offload_renderer_manager.cpp b/services/audio_engine/manager/src/hpae_offload_renderer_manager.cpp deleted file mode 100644 index 369616212a..0000000000 --- a/services/audio_engine/manager/src/hpae_offload_renderer_manager.cpp +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeOffloadRendererManager" -#endif - -#include "hpae_offload_renderer_manager.h" -#include "audio_stream_info.h" -#include "audio_errors.h" -#include "audio_engine_log.h" -#include "hpae_node_common.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -namespace { -constexpr uint32_t HISTORY_INTERVAL_S = 7; // 7s buffer for rewind -} - -HpaeOffloadRendererManager::HpaeOffloadRendererManager(HpaeSinkInfo &sinkInfo) - : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sinkInfo_(sinkInfo) -{} - -HpaeOffloadRendererManager::~HpaeOffloadRendererManager() -{ - AUDIO_INFO_LOG("destructor offload renderer"); - if (isInit_.load()) { - DeInit(); - } -} - -// private method -int32_t HpaeOffloadRendererManager::CreateInputSession(const HpaeStreamInfo &streamInfo) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.channels = streamInfo.channels; - nodeInfo.format = streamInfo.format; - nodeInfo.frameLen = streamInfo.frameLen; - nodeInfo.streamType = streamInfo.streamType; - nodeInfo.sessionId = streamInfo.sessionId; - nodeInfo.samplingRate = static_cast(streamInfo.samplingRate); - nodeInfo.sceneType = TransStreamTypeToSceneType(streamInfo.streamType); - nodeInfo.historyFrameCount = HISTORY_INTERVAL_S * nodeInfo.samplingRate / nodeInfo.frameLen; - nodeInfo.statusCallback = weak_from_this(); - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - nodeInfo.nodeId = OnGetNodeId(); - nodeInfo.nodeName = "HpaeSinkInputNode"; - sinkInputNode_ = std::make_shared(nodeInfo); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::AddNodeToSink(const std::shared_ptr &node) -{ - auto request = [this, node]() { AddSingleNodeToSink(node); }; - SendRequest(request); - return SUCCESS; -} - -void HpaeOffloadRendererManager::AddSingleNodeToSink(const std::shared_ptr &node, bool isConnect) -{ - HpaeNodeInfo nodeInfo = node->GetNodeInfo(); - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - // 7s history buffer to rewind - nodeInfo.historyFrameCount = HISTORY_INTERVAL_S * nodeInfo.samplingRate / nodeInfo.frameLen; - nodeInfo.statusCallback = weak_from_this(); - node->SetNodeInfo(nodeInfo); - uint32_t sessionId = nodeInfo.sessionId; - AUDIO_INFO_LOG("add node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); - sinkInputNode_ = node; - sessionInfo_.state = node->GetState(); - - if (!isConnect || sinkInputNode_->GetState() != RENDERER_RUNNING) { - AUDIO_INFO_LOG("not need connect session:%{public}d", sessionId); - return; - } - - if (node->GetState() == RENDERER_RUNNING) { - AUDIO_INFO_LOG("connect node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); - ConnectInputSession(); // todo: fadein - if (sinkOutputNode_->GetSinkState() != RENDERER_RUNNING) { - sinkOutputNode_->RenderSinkStart(); - } - } -} - -int32_t HpaeOffloadRendererManager::AddAllNodesToSink( - const std::vector> &sinkInputs, bool isConnect) -{ - auto request = [this, sinkInputs, isConnect]() { - for (const auto &it : sinkInputs) { - AddSingleNodeToSink(it, isConnect); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::CreateStream(const HpaeStreamInfo &streamInfo) -{ - if (!IsInit()) { - return ERR_INVALID_OPERATION; - } - auto request = [this, streamInfo]() { - CreateInputSession(streamInfo); - sessionInfo_.state = RENDERER_NEW; - sinkInputNode_->SetState(RENDERER_NEW); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::DestroyStream(uint32_t sessionId) -{ - if (!IsInit()) { - return ERR_INVALID_OPERATION; - } - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(), - "DestroyStream not find sessionId %{public}u", - sessionId); - AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId); - DisConnectInputSession(); - sinkInputNode_ = nullptr; - formatConverterNode_ = nullptr; - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::ConnectInputSession() -{ - if (sinkInputNode_->GetState() != RENDERER_RUNNING) { - return SUCCESS; - } - - if (CheckHpaeNodeInfoIsSame(sinkInputNode_->GetNodeInfo(), sinkOutputNode_->GetNodeInfo())) { - formatConverterNode_ = nullptr; - sinkOutputNode_->Connect(sinkInputNode_); - OnNotifyDfxNodeInfo(true, sinkOutputNode_->GetNodeId(), sinkInputNode_->GetNodeInfo()); - } else { - HpaeNodeInfo nodeInfo = sinkOutputNode_->GetNodeInfo(); - nodeInfo.nodeName = "HpaeAudioFormatConverterNode"; - nodeInfo.nodeId = OnGetNodeId(); - nodeInfo.sessionId = sinkInputNode_->GetSessionId(); - formatConverterNode_ = std::make_shared( - sinkInputNode_->GetNodeInfo(), nodeInfo); - formatConverterNode_->Connect(sinkInputNode_); - sinkOutputNode_->Connect(formatConverterNode_); - OnNotifyDfxNodeInfo(true, sinkOutputNode_->GetNodeId(), formatConverterNode_->GetNodeInfo()); - OnNotifyDfxNodeInfo(true, formatConverterNode_->GetNodeId(), sinkInputNode_->GetNodeInfo()); - } - // single stream manager - HpaeNodeInfo nodeInfo = sinkOutputNode_->GetNodeInfo(); - nodeInfo.sessionId = sinkInputNode_->GetSessionId(); - nodeInfo.streamType = sinkInputNode_->GetStreamType(); - sinkOutputNode_->SetNodeInfo(nodeInfo); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::Start(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG( - sessionId == sinkInputNode_->GetSessionId(), "Start not find sessionId %{public}u", sessionId); - AUDIO_INFO_LOG("Start sessionId %{public}u", sessionId); - sinkInputNode_->SetState(RENDERER_RUNNING); - ConnectInputSession(); - if (sinkOutputNode_->GetSinkState() != RENDERER_RUNNING) { - sinkOutputNode_->RenderSinkStart(); - } - sessionInfo_.state = RENDERER_RUNNING; - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_STARTED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::DisConnectInputSession() -{ - if (formatConverterNode_ == nullptr) { - sinkOutputNode_->DisConnect(sinkInputNode_); - OnNotifyDfxNodeInfo(false, sinkOutputNode_->GetNodeId(), sinkInputNode_->GetNodeInfo()); - } else { - formatConverterNode_->DisConnect(sinkInputNode_); - sinkOutputNode_->DisConnect(formatConverterNode_); - OnNotifyDfxNodeInfo(false, formatConverterNode_->GetNodeId(), sinkInputNode_->GetNodeInfo()); - OnNotifyDfxNodeInfo(false, sinkOutputNode_->GetNodeId(), formatConverterNode_->GetNodeInfo()); - } - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::Pause(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG( - sessionId == sinkInputNode_->GetSessionId(), "Pause not find sessionId %{public}u", sessionId); - AUDIO_INFO_LOG("Pause sessionId %{public}u", sessionId); - DisConnectInputSession(); - sinkInputNode_->SetState(RENDERER_PAUSED); - sinkOutputNode_->StopStream(); - sessionInfo_.state = RENDERER_PAUSED; - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_PAUSED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::Flush(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG( - sessionId == sinkInputNode_->GetSessionId(), "Pause not find sessionId %{public}u", sessionId); - AUDIO_INFO_LOG("Flush sessionId %{public}u", sessionId); - // flush history buffer - sinkInputNode_->Flush(); - // flush sinkoutput cache - sinkOutputNode_->FlushStream(); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_FLUSHED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::Drain(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG( - sessionId == sinkInputNode_->GetSessionId(), "Drain not find sessionId %{public}u", sessionId); - AUDIO_INFO_LOG("Drain sessionId %{public}u", sessionId); - sinkInputNode_->Drain(); - if (sessionInfo_.state != RENDERER_RUNNING) { - TriggerCallback( - UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_DRAINED); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::Stop(uint32_t sessionId) -{ - auto request = [this, sessionId]() { - CHECK_AND_RETURN_LOG( - sessionId == sinkInputNode_->GetSessionId(), "Stop not find sessionId %{public}u", sessionId); - AUDIO_INFO_LOG("Stop sessionId %{public}u", sessionId); - DisConnectInputSession(); - sinkInputNode_->SetState(RENDERER_STOPPED); - sessionInfo_.state = RENDERER_STOPPED; - sinkOutputNode_->StopStream(); - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_STOPPED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::Release(uint32_t sessionId) -{ - return DestroyStream(sessionId); -} - -void HpaeOffloadRendererManager::MoveAllStreamToNewSink(const std::string &sinkName, - const std::vector& moveIds, bool isMoveAll) -{ - std::string name = sinkName; - std::vector> sinkInputs; - std::vector sessionIds; - if (sinkInputNode_) { - uint32_t sessionId = sinkInputNode_->GetSessionId(); - if (isMoveAll || std::find(moveIds.begin(), moveIds.end(), sessionId) != moveIds.end()) { - sinkInputs.emplace_back(sinkInputNode_); - sessionIds.emplace_back(sinkInputNode_->GetSessionId()); - DisConnectInputSession(); - } - } - TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name); -} - -int32_t HpaeOffloadRendererManager::MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, - bool isMoveAll) -{ - if (!IsInit()) { - AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str()); - MoveAllStreamToNewSink(sinkName, sessionIds, isMoveAll); - } else { - AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str()); - auto request = [this, sinkName, sessionIds, isMoveAll]() { - MoveAllStreamToNewSink(sinkName, sessionIds, isMoveAll); - }; - SendRequest(request); - } - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::MoveStream(uint32_t sessionId, const std::string &sinkName) -{ - AUDIO_INFO_LOG("move session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); - auto request = [this, sessionId, sinkName]() { - CHECK_AND_RETURN_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(), - "could not find session:%{public}d,sink name:%{public}s", - sessionId, - sinkName.c_str()); - - std::shared_ptr inputNode = sinkInputNode_; - if (inputNode->GetState() == RENDERER_RUNNING) { - // todo: do fade out - } - DisConnectInputSession(); - sinkOutputNode_->StopStream(); - sinkInputNode_ = nullptr; - formatConverterNode_ = nullptr; - if (!sinkName.empty()) { - std::string name = sinkName; - AUDIO_ERR_LOG("trigger call back, sink name:%{public}s", sinkName.c_str()); - TriggerCallback(MOVE_SINK_INPUT, inputNode, name); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::SuspendStreamManager(bool isSuspend) -{ - auto request = [this, isSuspend]() { - if (isSuspend) { - // todo fadout - sinkOutputNode_->RenderSinkStop(); - } else { - // todo fadin - sinkOutputNode_->RenderSinkStart(); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::SetMute(bool isMute) -{ - auto request = [this, isMute]() { - isMute_ = isMute; // todo: set to sinkoutputnode - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeOffloadRendererManager::HandleMsg() -{ - hpaeNoLockQueue_.HandleRequests(); -} - -int32_t HpaeOffloadRendererManager::Init() -{ - hpaeSignalProcessThread_ = std::make_unique(); - auto request = [this] { - AUDIO_INFO_LOG("HpaeOffloadRendererManager::init"); - HpaeNodeInfo nodeInfo; - nodeInfo.channels = sinkInfo_.channels; - nodeInfo.format = sinkInfo_.format; - nodeInfo.frameLen = sinkInfo_.frameLen; - nodeInfo.nodeId = 0; - nodeInfo.samplingRate = sinkInfo_.samplingRate; - nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.statusCallback = weak_from_this(); - nodeInfo.nodeName = "HpaeOffloadSinkOutputNode"; - nodeInfo.nodeId = OnGetNodeId(); - sinkOutputNode_ = std::make_unique(nodeInfo); - OnNotifyDfxNodeInfo(true, 0, nodeInfo); - sinkOutputNode_->SetTimeoutStopThd(sinkInfo_.suspendTime); - // if failed, RenderSinkInit will failed either, so no need to deal ret - AUDIO_INFO_LOG("HpaeOffloadRendererManager::GetRenderSinkInstance"); - sinkOutputNode_->GetRenderSinkInstance(sinkInfo_.deviceClass, sinkInfo_.deviceNetId); - IAudioSinkAttr attr; - attr.adapterName = sinkInfo_.adapterName.c_str(); - attr.sampleRate = sinkInfo_.samplingRate; - attr.channel = sinkInfo_.channels; - attr.format = sinkInfo_.format; - attr.channelLayout = sinkInfo_.channelLayout; - attr.deviceType = sinkInfo_.deviceType; - attr.volume = sinkInfo_.volume; - attr.openMicSpeaker = sinkInfo_.openMicSpeaker; - attr.deviceNetworkId = sinkInfo_.deviceNetId.c_str(); - attr.filePath = sinkInfo_.filePath.c_str(); - int32_t ret = sinkOutputNode_->RenderSinkInit(attr); - isInit_.store(true); - TriggerCallback(INIT_DEVICE_RESULT, sinkInfo_.deviceName, ret); - AUDIO_INFO_LOG("HpaeOffloadRendererManager::inited"); - }; - SendRequest(request, true); - hpaeSignalProcessThread_->ActivateThread(shared_from_this()); - return SUCCESS; -} - -bool HpaeOffloadRendererManager::DeactivateThread() -{ - if (hpaeSignalProcessThread_ != nullptr) { - hpaeSignalProcessThread_->DeactivateThread(); - hpaeSignalProcessThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); - return true; -} - -int32_t HpaeOffloadRendererManager::DeInit(bool isMoveDefault) -{ - if (hpaeSignalProcessThread_ != nullptr) { - hpaeSignalProcessThread_->DeactivateThread(); - hpaeSignalProcessThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); - int32_t ret = sinkOutputNode_->RenderSinkDeInit(); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "RenderSinkDeInit error, ret %{public}d.", ret); - sinkOutputNode_->ResetAll(); - isInit_.store(false); - if (isMoveDefault) { - std::string sinkName = ""; - std::vector ids; - AUDIO_INFO_LOG("move all sink to default sink"); - MoveAllStreamToNewSink(sinkName, ids, true); - } - return SUCCESS; -} - -bool HpaeOffloadRendererManager::IsInit() -{ - return isInit_.load(); -} - -bool HpaeOffloadRendererManager::IsRunning(void) -{ - if (sinkOutputNode_ != nullptr && hpaeSignalProcessThread_ != nullptr) { - return sinkOutputNode_->GetSinkState() == RENDERER_RUNNING && hpaeSignalProcessThread_->IsRunning(); - } - return false; -} - -bool HpaeOffloadRendererManager::IsMsgProcessing() -{ - return !hpaeNoLockQueue_.IsFinishProcess(); -} - -int32_t HpaeOffloadRendererManager::SetClientVolume(uint32_t sessionId, float volume) -{ - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::SetRate(uint32_t sessionId, int32_t rate) -{ - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) -{ - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) -{ - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType) -{ - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType) -{ - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::RegisterWriteCallback( - uint32_t sessionId, const std::weak_ptr &callback) -{ - auto request = [this, sessionId, callback]() { - CHECK_AND_RETURN_LOG(sessionId == sinkInputNode_->GetSessionId(), - "RegisterWriteCallback not find sessionId %{public}u", - sessionId); - sinkInputNode_->RegisterWriteCallback(callback); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::RegisterReadCallback( - uint32_t sessionId, const std::weak_ptr &callback) -{ - return ERR_NOT_SUPPORTED; -} - -void HpaeOffloadRendererManager::Process() -{ - if (sinkOutputNode_ != nullptr && IsRunning()) { - sinkOutputNode_->DoProcess(); - } -} - -int32_t HpaeOffloadRendererManager::SetOffloadPolicy(uint32_t sessionId, int32_t state) -{ - auto request = [this, sessionId, state]() { - CHECK_AND_RETURN_LOG(sessionId == sinkInputNode_->GetSessionId(), - "RegisterWriteCallback not find sessionId %{public}u", - sessionId); - if (sinkOutputNode_) { - sinkOutputNode_->SetPolicyState(state); - } - }; - SendRequest(request); - return SUCCESS; -} - -size_t HpaeOffloadRendererManager::GetWritableSize(uint32_t sessionId) -{ - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::UpdateSpatializationState( - uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) -{ - return SUCCESS; -} - -int32_t HpaeOffloadRendererManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) -{ - return SUCCESS; -} - -std::vector HpaeOffloadRendererManager::GetAllSinkInputsInfo() -{ - std::vector sinkInputs; - return sinkInputs; -} - -int32_t HpaeOffloadRendererManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) -{ - CHECK_AND_RETURN_RET_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(), - ERR_INVALID_OPERATION, - "RegisterWriteCallback not find sessionId %{public}u", - sessionId); - sinkInputInfo.nodeInfo = sinkInputNode_->GetNodeInfo(); - sinkInputInfo.rendererSessionInfo = sessionInfo_; - return SUCCESS; -} - -HpaeSinkInfo HpaeOffloadRendererManager::GetSinkInfo() -{ - return sinkInfo_; -} - -void HpaeOffloadRendererManager::SendRequest(Request &&request, bool isInit) -{ - CHECK_AND_RETURN_LOG(isInit || IsInit(), "HpaeOffloadRendererManager not init"); - hpaeNoLockQueue_.PushRequest(std::move(request)); - CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ offloadrenderer is nullptr"); - hpaeSignalProcessThread_->Notify(); -} - -void HpaeOffloadRendererManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) -{ - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, operation); -} - -void HpaeOffloadRendererManager::OnRequestLatency(uint32_t sessionId, uint64_t &latency) -{ - latency = sinkOutputNode_->GetLatency(); -} - -void HpaeOffloadRendererManager::OnRewindAndFlush(uint64_t rewindTime) -{ - sinkInputNode_->RewindHistoryBuffer(rewindTime); -} - -void HpaeOffloadRendererManager::OnNotifyQueue() -{ - hpaeSignalProcessThread_->Notify(); -} - -std::string HpaeOffloadRendererManager::GetThreadName() -{ - return sinkInfo_.deviceName; -} - -void HpaeOffloadRendererManager::DumpSinkInfo() -{ - auto request = [this]() { - AUDIO_INFO_LOG("DumpSinkInfo deviceName %{public}s", sinkInfo_.deviceName.c_str()); - UploadDumpSinkInfo(sinkInfo_.deviceName); - }; - SendRequest(request); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_policy_manager.cpp b/services/audio_engine/manager/src/hpae_policy_manager.cpp deleted file mode 100644 index 63900974fa..0000000000 --- a/services/audio_engine/manager/src/hpae_policy_manager.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaePolicyManager" -#endif -#include "hpae_policy_manager.h" -#include -#include "audio_errors.h" -#include "audio_engine_log.h" -#include "audio_effect_chain_manager.h" -#include "audio_enhance_chain_manager.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -HpaePolicyManager::HpaePolicyManager() -{ - AUDIO_DEBUG_LOG("Hpae policy manager created"); -} - -HpaePolicyManager::~HpaePolicyManager() -{ - AUDIO_WARNING_LOG("Hpae policy manager destroyed"); -} - -void HpaePolicyManager::InitAudioEffectChainManager(const std::vector &effectChains, - const EffectChainManagerParam &effectChainManagerParam, - const std::vector> &effectLibraryList) -{ - AudioEffectChainManager::GetInstance()->InitAudioEffectChainManager(effectChains, - effectChainManagerParam, effectLibraryList); -} - -void HpaePolicyManager::SetOutputDeviceSink(int32_t device, const std::string &sinkName) -{ - AudioEffectChainManager::GetInstance()->SetOutputDeviceSink(device, sinkName); -} - -int32_t HpaePolicyManager::UpdateSpatializationState(AudioSpatializationState spatializationState) -{ - return AudioEffectChainManager::GetInstance()->UpdateSpatializationState(spatializationState); -} - -int32_t HpaePolicyManager::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType) -{ - return AudioEffectChainManager::GetInstance()->UpdateSpatialDeviceType(spatialDeviceType); -} - -int32_t HpaePolicyManager::SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType) -{ - return AudioEffectChainManager::GetInstance()->SetSpatializationSceneType(spatializationSceneType); -} - -int32_t HpaePolicyManager::EffectRotationUpdate(const uint32_t rotationState) -{ - return AudioEffectChainManager::GetInstance()->EffectRotationUpdate(rotationState); -} - -int32_t HpaePolicyManager::SetEffectSystemVolume(const int32_t systemVolumeType, const float systemVolume) -{ - return AudioEffectChainManager::GetInstance()->SetEffectSystemVolume(systemVolumeType, systemVolume); -} - -int32_t HpaePolicyManager::SetAudioEffectProperty(const AudioEffectPropertyArrayV3 &propertyArray) -{ - return AudioEffectChainManager::GetInstance()->SetAudioEffectProperty(propertyArray); -} - -int32_t HpaePolicyManager::GetAudioEffectProperty(AudioEffectPropertyArrayV3 &propertyArray) -{ - return AudioEffectChainManager::GetInstance()->GetAudioEffectProperty(propertyArray); -} - -int32_t HpaePolicyManager::SetAudioEffectProperty(const AudioEffectPropertyArray &propertyArray) -{ - return AudioEffectChainManager::GetInstance()->SetAudioEffectProperty(propertyArray); -} - -int32_t HpaePolicyManager::GetAudioEffectProperty(AudioEffectPropertyArray &propertyArray) -{ - return AudioEffectChainManager::GetInstance()->GetAudioEffectProperty(propertyArray); -} - -void HpaePolicyManager::InitHdiState() -{ - AudioEffectChainManager::GetInstance()->InitHdiState(); -} - -void HpaePolicyManager::UpdateEffectBtOffloadSupported(const bool &isSupported) -{ - AudioEffectChainManager::GetInstance()->UpdateEffectBtOffloadSupported(isSupported); -} - -void HpaePolicyManager::UpdateParamExtra(const std::string &mainkey, const std::string &subkey, - const std::string &value) -{ - AudioEffectChainManager::GetInstance()->UpdateParamExtra(mainkey, subkey, value); -} - -void HpaePolicyManager::InitAudioEnhanceChainManager(const std::vector &enhanceChains, - const EffectChainManagerParam &managerParam, - const std::vector> &enhanceLibraryList) -{ - AudioEnhanceChainManager::GetInstance()->InitAudioEnhanceChainManager(enhanceChains, managerParam, - enhanceLibraryList); -} - -int32_t HpaePolicyManager::SetInputDevice(const uint32_t &captureId, const DeviceType &inputDevice, - const std::string &deviceName) -{ - return AudioEnhanceChainManager::GetInstance()->SetInputDevice(captureId, inputDevice, deviceName); -} - -int32_t HpaePolicyManager::SetOutputDevice(const uint32_t &renderId, const DeviceType &outputDevice) -{ - return AudioEnhanceChainManager::GetInstance()->SetOutputDevice(renderId, outputDevice); -} - -int32_t HpaePolicyManager::SetVolumeInfo(const AudioVolumeType &volumeType, const float &systemVol) -{ - return AudioEnhanceChainManager::GetInstance()->SetVolumeInfo(volumeType, systemVol); -} - -int32_t HpaePolicyManager::SetMicrophoneMuteInfo(const bool &isMute) -{ - return AudioEnhanceChainManager::GetInstance()->SetMicrophoneMuteInfo(isMute); -} - -int32_t HpaePolicyManager::SetStreamVolumeInfo(const uint32_t &sessionId, const float &streamVol) -{ - return AudioEnhanceChainManager::GetInstance()->SetStreamVolumeInfo(sessionId, streamVol); -} - -int32_t HpaePolicyManager::SetAudioEnhanceProperty(const AudioEffectPropertyArrayV3 &propertyArray, - DeviceType deviceType) -{ - return AudioEnhanceChainManager::GetInstance()->SetAudioEnhanceProperty(propertyArray, deviceType); -} - -int32_t HpaePolicyManager::GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray, - DeviceType deviceType) -{ - return AudioEnhanceChainManager::GetInstance()->GetAudioEnhanceProperty(propertyArray, deviceType); -} - -int32_t HpaePolicyManager::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &propertyArray, - DeviceType deviceType) -{ - return AudioEnhanceChainManager::GetInstance()->SetAudioEnhanceProperty(propertyArray, deviceType); -} - -// todo: change to callback mode -int32_t HpaePolicyManager::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, - DeviceType deviceType) -{ - return AudioEnhanceChainManager::GetInstance()->GetAudioEnhanceProperty(propertyArray, deviceType); -} - -void HpaePolicyManager::UpdateExtraSceneType(const std::string &mainkey, const std::string &subkey, - const std::string &extraSceneType) -{ - return AudioEnhanceChainManager::GetInstance()->UpdateExtraSceneType(mainkey, subkey, extraSceneType); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/manager/src/hpae_renderer_manager.cpp b/services/audio_engine/manager/src/hpae_renderer_manager.cpp deleted file mode 100644 index 13a5c00be4..0000000000 --- a/services/audio_engine/manager/src/hpae_renderer_manager.cpp +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeRendererManager" -#endif -#include "hpae_renderer_manager.h" -#include "audio_stream_info.h" -#include "audio_errors.h" -#include "audio_engine_log.h" -#include "hpae_node_common.h" -#include "audio_effect_chain_manager.h" -#include "audio_utils.h" - -#define DEFAULT_EFFECT_RATE 48000 -#define DEFAULT_EFFECT_FRAME_LEN 960 - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -HpaeRendererManager::HpaeRendererManager(HpaeSinkInfo &sinkInfo) - : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sinkInfo_(sinkInfo) -{} - -HpaeRendererManager::~HpaeRendererManager() -{ - AUDIO_INFO_LOG("destructor renderer"); - if (isInit_.load()) { - DeInit(); - } -} - -bool HpaeRendererManager::IsMchDevice() -{ - return sinkInfo_.deviceName == "MCH_Speaker"; -} - -int32_t HpaeRendererManager::CreateInputSession(const HpaeStreamInfo &streamInfo) -{ - Trace trace("[" + std::to_string(streamInfo.sessionId) + "]HpaeRendererManager::CreateInputSession"); - HpaeNodeInfo nodeInfo; - nodeInfo.channels = streamInfo.channels; - nodeInfo.format = streamInfo.format; - nodeInfo.frameLen = streamInfo.frameLen; - nodeInfo.channelLayout = (AudioChannelLayout)streamInfo.channelLayout; - nodeInfo.streamType = streamInfo.streamType; - nodeInfo.sessionId = streamInfo.sessionId; - nodeInfo.samplingRate = static_cast(streamInfo.samplingRate); - nodeInfo.sceneType = TransStreamTypeToSceneType(streamInfo.streamType); - nodeInfo.effectInfo = streamInfo.effectInfo; - nodeInfo.fadeType = streamInfo.fadeType; - nodeInfo.statusCallback = weak_from_this(); - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - nodeInfo.nodeName = "HpaeSinkInputNode"; - nodeInfo.nodeId = OnGetNodeId(); - sinkInputNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); - - AUDIO_INFO_LOG("streamType %{public}u, sessionId = %{public}u, current sceneType is %{public}d", - nodeInfo.streamType, - nodeInfo.sessionId, - nodeInfo.sceneType); - if (IsMchDevice()) { - AUDIO_INFO_LOG("MCH device, only need create gain node"); - nodeInfo.nodeName = "HpaeGainNode"; - nodeInfo.nodeId = OnGetNodeId(); - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - mchIdGainNodeMap_[streamInfo.sessionId] = std::make_shared(nodeInfo); - return SUCCESS; - } - std::shared_ptr hpaeProcessCluster = CreateProcessCluster(nodeInfo); - if (hpaeProcessCluster != nullptr) { - sceneClusterMap_[nodeInfo.sceneType] = hpaeProcessCluster; - } - int32_t ret = sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo); - if (ret != SUCCESS) { - AUDIO_WARNING_LOG("update audio effect when creating failed, ret = %{public}d", ret); - } - return SUCCESS; -} - -int32_t HpaeRendererManager::AddNodeToSink(const std::shared_ptr &node) -{ - auto request = [this, node]() { AddSingleNodeToSink(node); }; - SendRequest(request); - return SUCCESS; -} - -void HpaeRendererManager::AddSingleNodeToSink(const std::shared_ptr &node, bool isConnect) -{ - Trace trace("HpaeRendererManager::AddSingleNodeToSink"); - HpaeNodeInfo nodeInfo = node->GetNodeInfo(); - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - // no need history buffer in not offload sink - nodeInfo.historyFrameCount = 0; - nodeInfo.statusCallback = weak_from_this(); - node->SetNodeInfo(nodeInfo); - uint32_t sessionId = nodeInfo.sessionId; - AUDIO_INFO_LOG("add node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); - sinkInputNodeMap_[sessionId] = node; - SetSessionState(sessionId, node->GetState()); - sessionNodeMap_[sessionId].sinkInputNodeId = nodeInfo.nodeId; - sessionNodeMap_[sessionId].sceneType = nodeInfo.sceneType; - - AUDIO_INFO_LOG("streamType %{public}u, sessionId = %{public}u, current sceneType is %{public}d", - nodeInfo.streamType, - nodeInfo.sessionId, - nodeInfo.sceneType); - HpaeNodeInfo processNodeInfo = nodeInfo; - processNodeInfo.samplingRate = (AudioSamplingRate)DEFAULT_EFFECT_RATE; - processNodeInfo.frameLen = (uint32_t)DEFAULT_EFFECT_FRAME_LEN; - processNodeInfo.channels = STEREO; - processNodeInfo.channelLayout = CH_LAYOUT_STEREO; - std::shared_ptr hpaeProcessCluster = CreateProcessCluster(processNodeInfo); - if (hpaeProcessCluster != nullptr) { - sceneClusterMap_[nodeInfo.sceneType] = hpaeProcessCluster; - } - int32_t ret = sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo); - if (ret != SUCCESS) { - AUDIO_WARNING_LOG("update audio effect when creating failed, ret = %{public}d", ret); - } - - if (!isConnect) { - AUDIO_INFO_LOG("not need connect session:%{public}d", sessionId); - return; - } - if (node->GetState() == RENDERER_RUNNING) { - AUDIO_INFO_LOG("connect node :%{public}d to sink:%{public}s", sessionId, sinkInfo_.deviceClass.c_str()); - ConnectInputSession(sessionId); // todo: fadein - if (outputCluster_->GetState() != RENDERER_RUNNING) { - outputCluster_->Start(); - } - } -} - -std::shared_ptr HpaeRendererManager::CreateProcessCluster(HpaeNodeInfo &nodeInfo) -{ - Trace trace("HpaeRendererManager::CreateProcessCluster"); - std::shared_ptr hpaeProcessCluster = nullptr; - std::string sceneType = TransProcessorTypeToSceneType(nodeInfo.sceneType); - int32_t processClusterDecision = AudioEffectChainManager::GetInstance()->CheckProcessClusterInstances(sceneType); - switch (processClusterDecision) { - case NO_NEED_TO_CREATE_PROCESSCLUSTER: - AUDIO_INFO_LOG("no need to create processCluster"); - if (sceneClusterMap_.find(nodeInfo.sceneType) == sceneClusterMap_.end()) { - AUDIO_INFO_LOG("processCluster is null, create a new processCluster"); - hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); - } - break; - case CREATE_NEW_PROCESSCLUSTER: - AUDIO_INFO_LOG("create new processCluster"); - hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); - break; - case CREATE_DEFAULT_PROCESSCLUSTER: - AUDIO_INFO_LOG("begin control, create default processCluster"); - hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); - sceneClusterMap_[HPAE_SCENE_DEFAULT] = hpaeProcessCluster; - sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++; - break; - case USE_DEFAULT_PROCESSCLUSTER: - AUDIO_INFO_LOG("use default processCluster"); - if (sceneClusterMap_.find(HPAE_SCENE_DEFAULT) == sceneClusterMap_.end()) { - AUDIO_INFO_LOG("default processCluster is null, create default processCluster"); - hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); - sceneClusterMap_[HPAE_SCENE_DEFAULT] = hpaeProcessCluster; - sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++; - } else { - hpaeProcessCluster = sceneClusterMap_[HPAE_SCENE_DEFAULT]; - sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++; - } - break; - case USE_NONE_PROCESSCLUSTER: - AUDIO_INFO_LOG("use none processCluster"); - hpaeProcessCluster = sceneClusterMap_[HPAE_SCENE_EFFECT_NONE]; - sceneTypeToProcessClusterCountMap_[HPAE_SCENE_EFFECT_NONE]++; - break; - case CREATE_EXTRA_PROCESSCLUSTER: - AUDIO_INFO_LOG("out of control"); - if (sceneClusterMap_.find(nodeInfo.sceneType) == sceneClusterMap_.end()) { - AUDIO_INFO_LOG("out of control, create a new processCluster"); - hpaeProcessCluster = std::make_shared(nodeInfo, sinkInfo_); - } - break; - default: - break; - } - sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]++; - return hpaeProcessCluster; -} - -int32_t HpaeRendererManager::AddAllNodesToSink( - const std::vector> &sinkInputs, bool isConnect) -{ - auto request = [this, sinkInputs, isConnect]() { - for (const auto &it : sinkInputs) { - AddSingleNodeToSink(it, isConnect); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::CreateStream(const HpaeStreamInfo &streamInfo) -{ - Trace trace("HpaeRendererManager::CreateStream id[" + - std::to_string(streamInfo.sessionId) + "]"); - if (!IsInit()) { - return ERR_INVALID_OPERATION; - } - auto request = [this, streamInfo]() { - AUDIO_INFO_LOG("CreateStream sessionId %{public}u deviceName %{public}s", - streamInfo.sessionId, - sinkInfo_.deviceName.c_str()); - CreateInputSession(streamInfo); - SetSessionState(streamInfo.sessionId, RENDERER_NEW); - sinkInputNodeMap_[streamInfo.sessionId]->SetState(RENDERER_NEW); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::DestroyStream(uint32_t sessionId) -{ - Trace trace("HpaeRendererManager::DestroyStream id[" + - std::to_string(sessionId) + "]"); - if (!IsInit()) { - return ERR_INVALID_OPERATION; - } - auto request = [this, sessionId]() { - AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId); - DeleteInputSession(sessionId); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::DeleteMchInputSession(uint32_t sessionId) -{ - DisConnectMchInputSession(sessionId); - sinkInputNodeMap_.erase(sessionId); - if (mchIdGainNodeMap_.find(sessionId) != mchIdGainNodeMap_.end()) { - mchIdGainNodeMap_.erase(sessionId); - } else { - AUDIO_ERR_LOG("could not find gain node id:%{public}d", sessionId); - return ERROR; - } - return SUCCESS; -} - -int32_t HpaeRendererManager::DeleteInputSession(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::DeleteInputSession"); - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("could not find session:%{public}d", sessionId); - return SUCCESS; - } - if (IsMchDevice()) { - return DeleteMchInputSession(sessionId); - } else { - HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); - int32_t effectMode = nodeInfo.effectInfo.effectMode; - HpaeProcessorType sceneType = (effectMode == EFFECT_NONE) ? HPAE_SCENE_EFFECT_NONE : nodeInfo.sceneType; - if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - DeleteProcessCluster(nodeInfo, sceneType, sessionId); - } - sinkInputNodeMap_.erase(sessionId); - } - return SUCCESS; -} - -void HpaeRendererManager::DeleteProcessCluster( - const HpaeNodeInfo &nodeInfo, HpaeProcessorType sceneType, uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + - "]HpaeRendererManager::DeleteProcessCluster sceneType:" + std::to_string(sessionId)); - sceneClusterMap_[nodeInfo.sceneType]->AudioRendererRelease(sinkInputNodeMap_[sessionId]->GetNodeInfo()); - sceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]); - sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]--; - if (sceneClusterMap_[nodeInfo.sceneType] == sceneClusterMap_[HPAE_SCENE_DEFAULT]) { - sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]--; - } - if (sceneClusterMap_[nodeInfo.sceneType] == sceneClusterMap_[HPAE_SCENE_EFFECT_NONE] && - nodeInfo.sceneType != HPAE_SCENE_EFFECT_NONE) { - sceneTypeToProcessClusterCountMap_[HPAE_SCENE_EFFECT_NONE]--; - } - - if (sceneClusterMap_[sceneType]->GetPreOutNum() == 0) { - outputCluster_->DisConnect(sceneClusterMap_[sceneType]); - } - - if (sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType] == 0) { - sceneClusterMap_.erase(nodeInfo.sceneType); - sceneTypeToProcessClusterCountMap_.erase(nodeInfo.sceneType); - } - if (sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT] == 0) { - sceneClusterMap_.erase(HPAE_SCENE_DEFAULT); - sceneTypeToProcessClusterCountMap_.erase(HPAE_SCENE_DEFAULT); - } -} - -int32_t HpaeRendererManager::ConnectMchInputSession(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectMchInputSession"); - AUDIO_INFO_LOG("Mch Device connect input session:%{public}d", sessionId); - if (mchIdGainNodeMap_.find(sessionId) == mchIdGainNodeMap_.end()) { - AUDIO_INFO_LOG("Mch Device connect can not find gain node, create it session:%{public}d", sessionId); - auto nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); - nodeInfo.nodeName = "HpaeGainNode"; - nodeInfo.nodeId = OnGetNodeId(); - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - mchIdGainNodeMap_[sessionId] = std::make_shared(nodeInfo); - } - mchIdGainNodeMap_[sessionId]->Connect(sinkInputNodeMap_[sessionId]); - outputCluster_->Connect(mchIdGainNodeMap_[sessionId]); - OnNotifyDfxNodeInfo(true, mchIdGainNodeMap_[sessionId]->GetNodeId(), sinkInputNodeMap_[sessionId]->GetNodeInfo()); - return SUCCESS; -} - -int32_t HpaeRendererManager::ConnectInputSession(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectInputSession"); - AUDIO_INFO_LOG("connect input session:%{public}d", sessionId); - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("could not input node by sessionid:%{public}d", sessionId); - return ERR_INVALID_PARAM; - } - if (sinkInputNodeMap_[sessionId]->GetState() != RENDERER_RUNNING) { - return SUCCESS; - } - if (IsMchDevice()) { - return ConnectMchInputSession(sessionId); - } - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); - int32_t effectMode = nodeInfo.effectInfo.effectMode; - if (effectMode == EFFECT_NONE) { - sceneType = HPAE_SCENE_EFFECT_NONE; - } - if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - ConnectProcessCluster(sessionId, sceneType); - } - return SUCCESS; -} - -void HpaeRendererManager::ConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectProcessCluster sceneType:" - + std::to_string(sceneType)); - int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStart(sinkInputNodeMap_[sessionId]->GetNodeInfo()); - if (ret != SUCCESS) { - AUDIO_WARNING_LOG("update audio effect when starting failed, ret = %{public}d", ret); - } - if (!outputCluster_->IsProcessClusterConnected(sceneType)) { - outputCluster_->Connect(sceneClusterMap_[sceneType]); - } - sceneClusterMap_[sceneType]->Connect(sinkInputNodeMap_[sessionId]); -} - -void HpaeRendererManager::MoveAllStreamToNewSink(const std::string &sinkName, - const std::vector& moveIds, bool isMoveAll) -{ - Trace trace("HpaeRendererManager::MoveAllStreamToNewSink[" + sinkName + "]"); - std::string name = sinkName; - std::vector> sinkInputs; - std::vector sessionIds; - for (const auto &it : sinkInputNodeMap_) { - if (isMoveAll || std::find(moveIds.begin(), moveIds.end(), it.first) != moveIds.end()) { - sinkInputs.emplace_back(it.second); - sessionIds.emplace_back(it.first); - } - } - for (const auto &it : sessionIds) { - DisConnectInputSession(it); - } - AUDIO_INFO_LOG("sink input count:%{public}zu", sinkInputs.size()); - TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name); -} - -int32_t HpaeRendererManager::MoveAllStream(const std::string &sinkName, const std::vector& sessionIds, - bool isMoveAll) -{ - if (!IsInit()) { - AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str()); - MoveAllStreamToNewSink(sinkName, sessionIds, isMoveAll); - } else { - AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str()); - auto request = [this, sinkName, sessionIds, isMoveAll]() { - MoveAllStreamToNewSink(sinkName, sessionIds, isMoveAll); - }; - SendRequest(request); - } - return SUCCESS; -} - -int32_t HpaeRendererManager::MoveStream(uint32_t sessionId, const std::string &sinkName) -{ - AUDIO_INFO_LOG("move session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); - auto request = [this, sessionId, sinkName]() { - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - AUDIO_ERR_LOG("could not find session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); - return; - } - AUDIO_INFO_LOG("move enter session:%{public}d,sink name:%{public}s", sessionId, sinkName.c_str()); - std::shared_ptr inputNode = sinkInputNodeMap_[sessionId]; - if (inputNode->GetState() == RENDERER_RUNNING) { - // todo: do fade out - } - DeleteInputSession(sessionId); - if (!sinkName.empty()) { - std::string name = sinkName; - AUDIO_ERR_LOG("trigger call back, sink name:%{public}s", sinkName.c_str()); - TriggerCallback(MOVE_SINK_INPUT, inputNode, name); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::Start(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Start"); - auto request = [this, sessionId]() { - AUDIO_INFO_LOG("Start sessionId %{public}u, deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str()); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->SetState(RENDERER_RUNNING); - } - ConnectInputSession(sessionId); - SetSessionState(sessionId, RENDERER_RUNNING); - if (outputCluster_->GetState() != RENDERER_RUNNING) { - outputCluster_->Start(); - } - SetSessionFade(sessionId, OPERATION_STARTED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::DisConnectMchInputSession(uint32_t sessionId) -{ - AUDIO_INFO_LOG("Mch Device Disconnect input session:%{public}d", sessionId); - if (mchIdGainNodeMap_.find(sessionId) == mchIdGainNodeMap_.end()) { - AUDIO_INFO_LOG("Mch Device DisConnect can not find gain node session:%{public}u", sessionId); - return ERROR; - } - mchIdGainNodeMap_[sessionId]->DisConnect(sinkInputNodeMap_[sessionId]); - outputCluster_->DisConnect(mchIdGainNodeMap_[sessionId]); - return SUCCESS; -} - -int32_t HpaeRendererManager::DisConnectInputSession(uint32_t sessionId) -{ - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("DisConnectInputSession sessionId %{public}u", sessionId); - return SUCCESS; - } - if (IsMchDevice()) { - return DisConnectMchInputSession(sessionId); - } - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); - int32_t effectMode = nodeInfo.effectInfo.effectMode; - if (effectMode == EFFECT_NONE) { - sceneType = HPAE_SCENE_EFFECT_NONE; - } - if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - DisConnectProcessCluster(sessionId, sceneType); - } - return SUCCESS; -} - -void HpaeRendererManager::DisConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType) -{ - sceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]); - int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStop(sinkInputNodeMap_[sessionId]->GetNodeInfo()); - if (ret != SUCCESS) { - AUDIO_WARNING_LOG("update audio effect when stopping failed, ret = %{public}d", ret); - } - if (sceneClusterMap_[sceneType]->GetPreOutNum() == 0) { - outputCluster_->DisConnect(sceneClusterMap_[sceneType]); - } -} - -void HpaeRendererManager::SetSessionState(uint32_t sessionId, RendererState renderState) -{ - sessionNodeMap_[sessionId].state = renderState; -} - -int32_t HpaeRendererManager::Pause(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Pause"); - auto request = [this, sessionId]() { - AUDIO_INFO_LOG("Pause sessionId %{public}u deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str()); - if (!SetSessionFade(sessionId, OPERATION_PAUSED)) { - DisConnectInputSession(sessionId); - } - SetSessionState(sessionId, RENDERER_PAUSED); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->SetState(RENDERER_PAUSED); - } - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - std::shared_ptr sessionGainNode = nullptr; - if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - sessionGainNode = sceneClusterMap_[sceneType]->GetGainNodeById(sessionId); - } - if (sessionGainNode == nullptr) { - TriggerCallback(UPDATE_STATUS, - HPAE_STREAM_CLASS_TYPE_PLAY, - sessionId, - sessionNodeMap_[sessionId].state, - OPERATION_PAUSED); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::Flush(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Flush"); - auto request = [this, sessionId]() { - AUDIO_INFO_LOG("Flush sessionId %{public}u deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str()); - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("Flush not find sessionId %{public}u", sessionId); - return; - } - // flush history buffer - sinkInputNodeMap_[sessionId]->Flush(); - TriggerCallback( - UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionNodeMap_[sessionId].state, OPERATION_FLUSHED); - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::Drain(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Drain"); - auto request = [this, sessionId]() { - AUDIO_INFO_LOG("Drain sessionId %{public}u deviceName %{public}s ", sessionId, sinkInfo_.deviceName.c_str()); - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - AUDIO_INFO_LOG("Drain not find sessionId %{public}u", sessionId); - return; - } - sinkInputNodeMap_[sessionId]->Drain(); - if (sessionNodeMap_[sessionId].state != RENDERER_RUNNING) { - AUDIO_INFO_LOG("TriggerCallback Drain sessionId %{public}u", sessionId); - TriggerCallback(UPDATE_STATUS, - HPAE_STREAM_CLASS_TYPE_PLAY, - sessionId, - sessionNodeMap_[sessionId].state, - OPERATION_DRAINED); - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::Stop(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Stop"); - auto request = [this, sessionId]() { - AUDIO_INFO_LOG("Stop sessionId %{public}u deviceName %{public}s ", sessionId, sinkInfo_.deviceName.c_str()); - if (!SetSessionFade(sessionId, OPERATION_STOPPED)) { - DisConnectInputSession(sessionId); - } - SetSessionState(sessionId, RENDERER_STOPPED); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->SetState(RENDERER_STOPPED); - } - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - std::shared_ptr sessionGainNode = nullptr; - if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - sessionGainNode = sceneClusterMap_[sceneType]->GetGainNodeById(sessionId); - } - if (sessionGainNode == nullptr) { - TriggerCallback(UPDATE_STATUS, - HPAE_STREAM_CLASS_TYPE_PLAY, - sessionId, - sessionNodeMap_[sessionId].state, - OPERATION_STOPPED); // if no gainnode, trigger - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::Release(uint32_t sessionId) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Release"); - return DestroyStream(sessionId); -} - -int32_t HpaeRendererManager::SuspendStreamManager(bool isSuspend) -{ - Trace trace("HpaeRendererManager::SuspendStreamManager: " + std::to_string(isSuspend)); - auto request = [this, isSuspend]() { - if (isSuspend) { - if (outputCluster_ != nullptr) { - // todo fade out - outputCluster_->Stop(); - } - } else { - if (outputCluster_ != nullptr) { - // todo fade in - outputCluster_->Start(); - } - } - }; - SendRequest(request); - return SUCCESS; -} - -int32_t HpaeRendererManager::SetMute(bool isMute) -{ - // to do check pulseaudio - auto request = [this, isMute]() { - if (isMute_ != isMute) { - isMute_ = isMute; // todo: fadein and fadeout and mute feature - } - }; - SendRequest(request); - return SUCCESS; -} - -void HpaeRendererManager::HandleMsg() -{ - hpaeNoLockQueue_.HandleRequests(); -} - -int32_t HpaeRendererManager::Init() -{ - Trace trace("HpaeRendererManager::Init"); - hpaeSignalProcessThread_ = std::make_unique(); - auto request = [this] { - AUDIO_INFO_LOG("HpaeRendererManager::init devicename:%{public}s", sinkInfo_.deviceName.c_str()); - HpaeNodeInfo nodeInfo; - nodeInfo.channels = sinkInfo_.channels; - nodeInfo.format = sinkInfo_.format; - nodeInfo.frameLen = sinkInfo_.frameLen; - nodeInfo.nodeId = 0; - nodeInfo.samplingRate = sinkInfo_.samplingRate; - nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT; - nodeInfo.deviceNetId = sinkInfo_.deviceNetId; - nodeInfo.deviceClass = sinkInfo_.deviceClass; - nodeInfo.statusCallback = weak_from_this(); - outputCluster_ = std::make_unique(nodeInfo); - outputCluster_->SetTimeoutStopThd(sinkInfo_.suspendTime); - int32_t ret = outputCluster_->GetInstance(sinkInfo_.deviceClass, sinkInfo_.deviceNetId); - IAudioSinkAttr attr; - attr.adapterName = sinkInfo_.adapterName.c_str(); - attr.sampleRate = sinkInfo_.samplingRate; - attr.channel = sinkInfo_.channels; - attr.format = sinkInfo_.format; - attr.channelLayout = sinkInfo_.channelLayout; - attr.deviceType = sinkInfo_.deviceType; - attr.volume = sinkInfo_.volume; - attr.openMicSpeaker = sinkInfo_.openMicSpeaker; - attr.deviceNetworkId = sinkInfo_.deviceNetId.c_str(); - attr.filePath = sinkInfo_.filePath.c_str(); - if (!sceneClusterMap_.count(HPAE_SCENE_EFFECT_NONE)) { - HpaeNodeInfo defaultNodeInfo; - defaultNodeInfo.frameLen = (uint32_t)DEFAULT_EFFECT_FRAME_LEN; - defaultNodeInfo.samplingRate = (AudioSamplingRate)DEFAULT_EFFECT_RATE; - defaultNodeInfo.format = AudioSampleFormat::INVALID_WIDTH; - defaultNodeInfo.channels = STEREO; - defaultNodeInfo.channelLayout = AudioChannelLayout::CH_LAYOUT_STEREO; - defaultNodeInfo.streamType = STREAM_DEFAULT; - defaultNodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE; - defaultNodeInfo.deviceNetId = sinkInfo_.deviceNetId; - defaultNodeInfo.deviceClass = sinkInfo_.deviceClass; - defaultNodeInfo.statusCallback = weak_from_this(); - sceneClusterMap_[HPAE_SCENE_EFFECT_NONE] = std::make_shared(defaultNodeInfo, sinkInfo_); - sceneTypeToProcessClusterCountMap_[HPAE_SCENE_EFFECT_NONE] = 1; - } - - ret = outputCluster_->Init(attr); - isInit_.store(ret == SUCCESS); - TriggerCallback(INIT_DEVICE_RESULT, sinkInfo_.deviceName, ret); - }; - SendRequest(request, true); - hpaeSignalProcessThread_->ActivateThread(shared_from_this()); - return SUCCESS; -} - -bool HpaeRendererManager::DeactivateThread() -{ - if (hpaeSignalProcessThread_ != nullptr) { - hpaeSignalProcessThread_->DeactivateThread(); - hpaeSignalProcessThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); - return true; -} - -int32_t HpaeRendererManager::DeInit(bool isMoveDefault) -{ - Trace trace("HpaeRendererManager::DeInit"); - if (hpaeSignalProcessThread_ != nullptr) { - hpaeSignalProcessThread_->DeactivateThread(); - hpaeSignalProcessThread_ = nullptr; - } - hpaeNoLockQueue_.HandleRequests(); - int32_t ret = outputCluster_->DeInit(); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "RenderSinkDeInit error, ret %{public}d.", ret); - outputCluster_->ResetAll(); - isInit_.store(false); - if (isMoveDefault) { - std::string sinkName = ""; - std::vector ids; - AUDIO_INFO_LOG("move all sink to default sink"); - MoveAllStreamToNewSink(sinkName, ids, true); - } - return SUCCESS; -} - -int32_t HpaeRendererManager::StartRenderSink() -{ - return SUCCESS; -} - -int32_t HpaeRendererManager::SetClientVolume(uint32_t sessionId, float volume) -{ - return SUCCESS; -} - -int32_t HpaeRendererManager::SetRate(uint32_t sessionId, int32_t rate) -{ - return SUCCESS; -} - -int32_t HpaeRendererManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode) -{ - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - return ERR_INVALID_OPERATION; - } - if (effectMode < EFFECT_NONE || effectMode > EFFECT_DEFAULT) { - return ERR_INVALID_OPERATION; - } - - HpaeNodeInfo &nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); - if (nodeInfo.effectInfo.effectMode != static_cast(effectMode)) { - nodeInfo.effectInfo.effectMode = static_cast(effectMode); - UpdateProcessClusterConnection(sessionId, effectMode); - } - return SUCCESS; -} - -int32_t HpaeRendererManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode) -{ - return SUCCESS; -} - -int32_t HpaeRendererManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType) -{ - return SUCCESS; -} - -int32_t HpaeRendererManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType) -{ - return SUCCESS; -} - -int32_t HpaeRendererManager::RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr &callback) -{ - auto request = [this, sessionId, callback]() { - AUDIO_INFO_LOG("RegisterWriteCallback sessionId %{public}u", sessionId); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->RegisterWriteCallback(callback); - } - }; - hpaeNoLockQueue_.PushRequest(request); - return SUCCESS; -} - -void HpaeRendererManager::Process() -{ - Trace trace("HpaeRendererManager::Process"); - if (outputCluster_ != nullptr && IsRunning()) { - outputCluster_->DoProcess(); - } -} - -size_t HpaeRendererManager::GetWritableSize(uint32_t sessionId) -{ - return SUCCESS; -} - -int32_t HpaeRendererManager::UpdateSpatializationState( - uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled) -{ - return SUCCESS; -} - -int32_t HpaeRendererManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength) -{ - return SUCCESS; -} - -std::vector HpaeRendererManager::GetAllSinkInputsInfo() -{ - return {}; -} - -int32_t HpaeRendererManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo) -{ - if (sinkInputNodeMap_.find(sessionId) == sinkInputNodeMap_.end()) { - return ERR_INVALID_OPERATION; - } - sinkInputInfo.nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo(); - sinkInputInfo.rendererSessionInfo = sessionNodeMap_[sessionId]; - return SUCCESS; -} - -HpaeSinkInfo HpaeRendererManager::GetSinkInfo() -{ - return sinkInfo_; -} - -bool HpaeRendererManager::IsInit() -{ - return isInit_.load(); -} - -bool HpaeRendererManager::IsMsgProcessing() -{ - return !hpaeNoLockQueue_.IsFinishProcess(); -} - -bool HpaeRendererManager::IsRunning(void) -{ - if (outputCluster_ != nullptr && hpaeSignalProcessThread_ != nullptr) { - return outputCluster_->GetState() == RENDERER_RUNNING && hpaeSignalProcessThread_->IsRunning(); - } else { - return false; - } -} - -void HpaeRendererManager::SendRequest(Request &&request, bool isInit) -{ - AUDIO_DEBUG_LOG("HpaeRendererManager::isInit is %{public}s", isInit ? "true" : "false"); - CHECK_AND_RETURN_LOG(isInit || IsInit(), "HpaeRendererManager not init"); - hpaeNoLockQueue_.PushRequest(std::move(request)); - CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ renderer is nullptr"); - hpaeSignalProcessThread_->Notify(); -} - -void HpaeRendererManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation) -{ - TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionNodeMap_[sessionId].state, operation); -} - -void HpaeRendererManager::OnFadeDone(uint32_t sessionId, IOperation operation) -{ - Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::OnFadeDone: " + std::to_string(operation)); - AUDIO_INFO_LOG("Fade done, call back at RendererManager"); - auto request = [this, sessionId, operation]() { - DisConnectInputSession(sessionId); - RendererState state = operation == OPERATION_STOPPED ? RENDERER_STOPPED : RENDERER_PAUSED; - SetSessionState(sessionId, state); - if (sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end()) { - sinkInputNodeMap_[sessionId]->SetState(state); - } - TriggerCallback( - UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionNodeMap_[sessionId].state, operation); - }; - SendRequest(request); -} - -int32_t HpaeRendererManager::RegisterReadCallback(uint32_t sessionId, const std::weak_ptr &callback) -{ - return SUCCESS; -} - -void HpaeRendererManager::OnRequestLatency(uint32_t sessionId, uint64_t &latency) -{ - // todo: add processLatency - return; -} - -void HpaeRendererManager::OnNotifyQueue() -{ - hpaeSignalProcessThread_->Notify(); -} - -void HpaeRendererManager::UpdateProcessClusterConnection(uint32_t sessionId, int32_t effectMode) -{ - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - if (sceneClusterMap_.find(sceneType) == sceneClusterMap_.end()) { - AUDIO_WARNING_LOG("miss corresponding process cluster for scene type %{public}d", sceneType); - return; - } - if (effectMode == EFFECT_NONE) { - DisConnectProcessCluster(sessionId, sceneType); - ConnectProcessCluster(sessionId, HPAE_SCENE_EFFECT_NONE); - } else { - DisConnectProcessCluster(sessionId, HPAE_SCENE_EFFECT_NONE); - ConnectProcessCluster(sessionId, sceneType); - } -} - -std::string HpaeRendererManager::GetThreadName() -{ - return sinkInfo_.deviceName; -} - -bool HpaeRendererManager::SetSessionFade(uint32_t sessionId, IOperation operation) -{ - CHECK_AND_RETURN_RET_LOG(sinkInputNodeMap_.find(sessionId) != sinkInputNodeMap_.end(), false, - "can not get input node of session %{public}u", sessionId); - HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType(); - std::shared_ptr sessionGainNode = nullptr; - if (sceneClusterMap_.find(sceneType) != sceneClusterMap_.end()) { - sessionGainNode = sceneClusterMap_[sceneType]->GetGainNodeById(sessionId); - AUDIO_INFO_LOG("get gain node of session %{public}d.", sessionId); - } - if (sessionGainNode != nullptr) { - sessionGainNode->SetFadeState(operation); - return true; - } - AUDIO_WARNING_LOG("session %{public}d do not have gain node!", sessionId); - return false; -} - -void HpaeRendererManager::DumpSinkInfo() -{ - auto request = [this]() { - AUDIO_INFO_LOG("DumpSinkInfo deviceName %{public}s", sinkInfo_.deviceName.c_str()); - UploadDumpSinkInfo(sinkInfo_.deviceName); - }; - SendRequest(request); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/hpae_signal_process_thread.cpp b/services/audio_engine/manager/src/hpae_signal_process_thread.cpp deleted file mode 100644 index 2736b8a095..0000000000 --- a/services/audio_engine/manager/src/hpae_signal_process_thread.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2025 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 "hpae_signal_process_thread.h" -#include "audio_schedule.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaeSignalProcessThread::~HpaeSignalProcessThread() -{ - DeactivateThread(); -} - -void HpaeSignalProcessThread::ActivateThread(const std::weak_ptr &streamManager) -{ - streamManager_ = streamManager; - running_.store(true); - auto threadFunc = std::bind(&HpaeSignalProcessThread::Run, this); - thread_ = std::thread(threadFunc); - if (streamManager_.lock() != nullptr) { - pthread_setname_np(thread_.native_handle(), streamManager_.lock()->GetThreadName().c_str()); - } -} - -void HpaeSignalProcessThread::DeactivateThread() -{ - running_.store(false); - Notify(); - if (thread_.joinable()) { - thread_.join(); - } -} - -void HpaeSignalProcessThread::Notify() -{ - recvSignal_.store(true); - condition_.notify_all(); -} - -void HpaeSignalProcessThread::Run() -{ - ScheduleThreadInServer(getpid(), gettid()); - while (running_.load() && streamManager_.lock() != nullptr) { - { - std::unique_lock lock(mutex_); - condition_.wait(lock, [this] { - return !running_.load() || streamManager_.lock()->IsRunning() || recvSignal_.load() || - streamManager_.lock()->IsMsgProcessing(); - }); - } - if (streamManager_.lock()) { - streamManager_.lock()->HandleMsg(); - streamManager_.lock()->Process(); - } - recvSignal_.store(false); - } - UnscheduleThreadInServer(getpid(), gettid()); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/manager/src/i_hpae_manager.cpp b/services/audio_engine/manager/src/i_hpae_manager.cpp deleted file mode 100644 index 853901df1c..0000000000 --- a/services/audio_engine/manager/src/i_hpae_manager.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2025 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 "hpae_manager.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -std::shared_ptr IHpaeManager::GetHpaeManager() -{ - static auto hpaeManager = std::make_shared(); - return hpaeManager; -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp b/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp deleted file mode 100644 index 226fd2815c..0000000000 --- a/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2025 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 "IHpaeRendererManager" -#endif -#include "i_hpae_renderer_manager.h" -#include "hpae_renderer_manager.h" -#include "hpae_offload_renderer_manager.h" -#include "hpae_inner_capturer_manager.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -static const std::string DEVICE_CLASS_OFFLOAD = "offload"; -static const std::string DEVICE_NAME_INNER_CAP = "InnerCapturerSink"; -static const std::string DEVICE_NAME_CAST_INNER_CAP = "RemoteCastInnerCapturer"; -std::shared_ptr IHpaeRendererManager::CreateRendererManager(HpaeSinkInfo &sinkInfo) -{ - if (sinkInfo.deviceClass == DEVICE_CLASS_OFFLOAD) { - return std::make_shared(sinkInfo); - } else if ((sinkInfo.deviceName.compare(0, DEVICE_NAME_INNER_CAP.length(), DEVICE_NAME_INNER_CAP) == 0) - || sinkInfo.deviceName == DEVICE_NAME_CAST_INNER_CAP) { - return std::make_shared(sinkInfo); - } - return std::make_shared(sinkInfo); -} - -void IHpaeRendererManager::UploadDumpSinkInfo(std::string& deviceName) -{ -#ifdef ENABLE_HIDUMP_DFX - std::string dumpStr; - dfxTree_.PrintTree(dumpStr); - TriggerCallback(DUMP_SINK_INFO, deviceName, dumpStr); -#endif -}; - -void IHpaeRendererManager::OnNotifyDfxNodeInfo(bool isConnect, uint32_t preNodeId, HpaeDfxNodeInfo &nodeInfo) -{ -#ifdef ENABLE_HIDUMP_DFX - AUDIO_INFO_LOG("%{public}s preNodeId %{public}u nodeName:%{public}s, NodeId: %{public}u", - isConnect ? "connect" : "disconnect", - preNodeId, - nodeInfo.nodeName.c_str(), - nodeInfo.nodeId); - if (isConnect) { - dfxTree_.Insert(preNodeId, nodeInfo); - } else { - dfxTree_.Remove(nodeInfo.nodeId); - } -#endif -}; - -uint32_t IHpaeRendererManager::OnGetNodeId() -{ - if (nodeIdCounter_.load() == std::numeric_limits::max()) { - nodeIdCounter_.store(MIN_START_NODE_ID); - } else { - nodeIdCounter_.fetch_add(1); - } - return nodeIdCounter_.load(); -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/node/include/hpae_audio_format_converter_node.h b/services/audio_engine/node/include/hpae_audio_format_converter_node.h deleted file mode 100644 index d7a0160193..0000000000 --- a/services/audio_engine/node/include/hpae_audio_format_converter_node.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_AUDIOFORMAT_CONVERTER_H -#define HPAE_AUDIOFORMAT_CONVERTER_H -#include "audio_stream_info.h" -#include "hpae_plugin_node.h" -#include "channel_converter.h" -#include "audio_proresampler.h" -#ifdef ENABLE_HOOK_PCM - #include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaeAudioFormatConverterNode : public HpaePluginNode { -public: - HpaeAudioFormatConverterNode(HpaeNodeInfo preNodeInfo, HpaeNodeInfo nodeInfo); - void RegisterCallback(INodeFormatInfoCallback *callback); - void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; - void DisConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) override; -protected: - HpaePcmBuffer* SignalProcess(const std::vector& inputs) override; -private: - bool CheckUpdateInInfo(HpaePcmBuffer *input); - bool CheckUpdateOutInfo(); - int32_t ConverterProcess(float *srcData, float *dstData, float *tmpData, HpaePcmBuffer *input); - void CheckAndUpdateInfo(HpaePcmBuffer *input); - void UpdateTmpOutPcmBufferInfo(const PcmBufferInfo &outPcmBufferInfo); - PcmBufferInfo pcmBufferInfo_; - HpaePcmBuffer converterOuput_; - HpaeNodeInfo preNodeInfo_; - std::unique_ptr resampler_ = nullptr; - ChannelConverter channelConverter_; - HpaePcmBuffer tmpOutBuf_; // cache between resample and converter - // if there is render effect, the effect node decides the output format of converter node - INodeFormatInfoCallback *nodeFormatInfoCallback_ = nullptr; -#ifdef ENABLE_HOOK_PCM - std::unique_ptr inputPcmDumper_ = nullptr; - std::unique_ptr outputPcmDumper_ = nullptr; -#endif -}; - -} // HPAE -} // AudioStandard -} // OHOS -#endif diff --git a/services/audio_engine/node/include/hpae_capture_effect_node.h b/services/audio_engine/node/include/hpae_capture_effect_node.h deleted file mode 100644 index 21bfba8cad..0000000000 --- a/services/audio_engine/node/include/hpae_capture_effect_node.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_CAPTURE_EFFECT_NODE_H -#define HPAE_CAPTURE_EFFECT_NODE_H -#include -#include "hpae_plugin_node.h" -#include "hpae_node.h" -#include "audio_effect.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -constexpr uint32_t SCENE_TYPE_OFFSET = 32; -constexpr uint32_t CAPTURER_ID_OFFSET = 16; -constexpr uint32_t BITLENGTH = 8; -constexpr uint32_t FRAME_LEN = 20; - -struct CaptureEffectAttr { - uint32_t micChannels; - uint32_t ecChannels; - uint32_t micRefChannels; -}; - -class HpaeCaptureEffectNode : public HpaePluginNode { -public: - HpaeCaptureEffectNode(HpaeNodeInfo &nodeInfo); - HpaeCaptureEffectNode(std::vector &nodeInfos); - virtual bool Reset() override; - void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; - void DisConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) override; - bool GetCapturerEffectConfig(HpaeNodeInfo& nodeInfo, HpaeSourceBufferType type = HPAE_SOURCE_BUFFER_TYPE_MIC); - int32_t CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr); - int32_t CaptureEffectRelease(uint64_t sceneKeyCode); -protected: - HpaePcmBuffer *SignalProcess(const std::vector &inputs) override; -private: - void SetCapturerEffectConfig(AudioBufferConfig micConfig, AudioBufferConfig ecConfig, - AudioBufferConfig micrefConfig); - - uint64_t sceneKeyCode_ = 0; - std::string sceneType_ = ""; - uint32_t micBufferLength_ = 0; - uint32_t ecBufferLength_ = 0; - uint32_t micrefBufferLength_ = 0; - std::vector cacheDataIn_; - std::vector cacheDataOut_; - std::unordered_map capturerEffectConfigMap_; -#ifdef ENABLE_HOOK_PCM - std::unique_ptr outputPcmDumper_; -#endif -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif // HPAE_CAPTURE_EFFECT_NODE_H \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_gain_node.h b/services/audio_engine/node/include/hpae_gain_node.h deleted file mode 100644 index 40e395884e..0000000000 --- a/services/audio_engine/node/include/hpae_gain_node.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_GAIN_NODE_H -#define HPAE_GAIN_NODE_H -#include "hpae_plugin_node.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#include "i_stream.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -enum class FadeOutState { - NO_FADEOUT, - DO_FADEOUT, - DONE_FADEOUT -}; -class HpaeGainNode : public HpaePluginNode { -public: - HpaeGainNode(HpaeNodeInfo &nodeInfo); - bool SetClientVolume(float gain); - float GetClientVolume(); - void SetFadeState(IOperation operation); -protected: - HpaePcmBuffer *SignalProcess(const std::vector &inputs) override; -private: - float preGain_ = 1.0f; - float curGain_ = 1.0f; - bool isGainChanged_ = false; - bool needGainState_ = true; - bool fadeInState_ = false; - FadeOutState fadeOutState_ = FadeOutState::NO_FADEOUT; - IOperation operation_; - void DoGain(HpaePcmBuffer *input, uint32_t frameLen, uint32_t channelCount); - void DoFading(HpaePcmBuffer *input); - void SlienceData(HpaePcmBuffer *pcmBuffer); - bool IsSilentData(HpaePcmBuffer *pcmBuffer); -#ifdef ENABLE_HOOK_PCM - std::unique_ptr inputPcmDumper_; - std::unique_ptr outputPcmDumper_; -#endif -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_inner_cap_sink_node.h b/services/audio_engine/node/include/hpae_inner_cap_sink_node.h deleted file mode 100644 index f59d56207b..0000000000 --- a/services/audio_engine/node/include/hpae_inner_cap_sink_node.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_INNER_CAP_SINK_NODE_H -#define HPAE_INNER_CAP_SINK_NODE_H -#include -#include "hpae_node.h" -#include "hpae_pcm_buffer.h" -#include "source/i_audio_capture_source.h" -#include "hpae_renderer_manager.h" -#include "hpae_source_input_node.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaeInnerCapSinkNode : public OutputNode, public InputNode { -public: - HpaeInnerCapSinkNode(HpaeNodeInfo& nodeInfo); - virtual ~HpaeInnerCapSinkNode() {}; - virtual void DoProcess() override; - virtual bool Reset() override; - virtual bool ResetAll() override; - - std::shared_ptr GetSharedInstance() override; - OutputPort* GetOutputPort() override; - void Connect(const std::shared_ptr>& preNode) override; - void DisConnect(const std::shared_ptr>& preNode) override; - size_t GetPreOutNum(); - size_t GetOutputPortNum(); - - int32_t InnerCapturerSinkInit(); - int32_t InnerCapturerSinkDeInit(); - int32_t InnerCapturerSinkFlush(); - int32_t InnerCapturerSinkPause(); - int32_t InnerCapturerSinkReset(); - int32_t InnerCapturerSinkResume(); - int32_t InnerCapturerSinkStart(); - int32_t InnerCapturerSinkStop(); - RendererState GetSinkState(); -private: - OutputPort outputStream_; - InputPort inputStream_; - PcmBufferInfo pcmBufferInfo_; - HpaePcmBuffer silenceData_; - - HighResolutionTimer intervalTimer_; - RendererState state_ = RENDERER_NEW; -#ifdef ENABLE_HOOK_PCM - std::unique_ptr outputPcmDumper_ = nullptr; -#endif -}; - -}}} - -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_mixer_node.h b/services/audio_engine/node/include/hpae_mixer_node.h deleted file mode 100644 index 87c470e885..0000000000 --- a/services/audio_engine/node/include/hpae_mixer_node.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_MIXER_NODE_H -#define HPAE_MIXER_NODE_H -#include -#include -#include "hpae_node.h" -#include "hpae_plugin_node.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaeMixerNode : public HpaePluginNode { -public: - HpaeMixerNode(HpaeNodeInfo &nodeInfo); - virtual bool Reset() override; -protected: - HpaePcmBuffer *SignalProcess(const std::vector &inputs) override; -private: - std::unordered_map streamVolumeMap_; - PcmBufferInfo pcmBufferInfo_; - HpaePcmBuffer mixedOutput_; -#ifdef ENABLE_HOOK_PCM - std::unique_ptr outputPcmDumper_ = nullptr;; -#endif -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_node.h b/services/audio_engine/node/include/hpae_node.h deleted file mode 100644 index 6d4ae57cd8..0000000000 --- a/services/audio_engine/node/include/hpae_node.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_NODE_H -#define HPAE_NODE_H -#include -#include -#include -#include -#include -#include "hpae_pcm_buffer.h" -#include "hpae_define.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaeNode : public std::enable_shared_from_this { -public: - HpaeNode(){}; - virtual ~HpaeNode(){}; - HpaeNode(HpaeNodeInfo& nodeInfo) : nodeInfo_(nodeInfo) - {} - virtual void DoProcess() = 0; - // for process node - virtual bool Reset() = 0; - virtual bool ResetAll() = 0; - - virtual HpaeNodeInfo& GetNodeInfo() - { - return nodeInfo_; - } - - virtual void SetNodeInfo(HpaeNodeInfo& nodeInfo) - { - nodeInfo_ = nodeInfo; - } - - virtual AudioSamplingRate GetSampleRate() - { - return nodeInfo_.samplingRate; - } - - virtual AudioSampleFormat GetBitWidth() - { - return nodeInfo_.format; - } - - virtual AudioChannel GetChannelCount() - { - return nodeInfo_.channels; - } - - virtual AudioChannelLayout GetChannelLayout() - { - return nodeInfo_.channelLayout; - } - - virtual size_t GetFrameLen() - { - return nodeInfo_.frameLen; - } - - virtual uint32_t GetNodeId() - { - return nodeInfo_.nodeId; - } - - virtual uint32_t GetSessionId() - { - return nodeInfo_.sessionId; - } - - virtual AudioStreamType GetStreamType() - { - return nodeInfo_.streamType; - } - - virtual HpaeProcessorType GetSceneType() - { - return nodeInfo_.sceneType; - } - - virtual std::string GetDeviceClass() - { - return nodeInfo_.deviceClass; - } - - virtual std::string GetDeviceNetId() - { - return nodeInfo_.deviceNetId; - } - - virtual std::string GetNodeName() - { - return nodeInfo_.nodeName; - } - - virtual std::weak_ptr GetNodeStatusCallback() - { - return nodeInfo_.statusCallback; - } -private: - HpaeNodeInfo nodeInfo_; -}; - -template -class InputPort; - -template -class OutputPort { -public: - explicit OutputPort(HpaeNode *node) : hpaeNode_(node) - {} - void WriteDataToOutput(T data); - OutputPort(const OutputPort &that) = delete; - T PullOutputData(); - void AddInput(InputPort *input); - bool RemoveInput(InputPort *input); - size_t GetInputNum() const; -private: - std::set*> inputPortSet_; - std::vector outputData_; - HpaeNode *hpaeNode_; -}; - -template -class OutputNode : virtual public HpaeNode { -public: - virtual ~OutputNode() - {} - virtual std::shared_ptr GetSharedInstance() = 0; - virtual std::shared_ptr GetSharedInstance(HpaeNodeInfo &nodeInfo) { return nullptr; } - virtual OutputPort* GetOutputPort() = 0; - virtual OutputPort* GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) { return nullptr; } - virtual HpaeSourceBufferType GetOutputPortBufferType(HpaeNodeInfo &nodeInfo) - { return HPAE_SOURCE_BUFFER_TYPE_DEFAULT; } -}; - -template -class InputNode : virtual public HpaeNode { -public: - virtual ~InputNode() - {} - virtual void Connect(const std::shared_ptr> &preNode) = 0; - virtual void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) {} - virtual void DisConnect(const std::shared_ptr> &preNode) = 0; - virtual void DisConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) {} -}; - -template -class InputPort { -public: - InputPort() - {} - ~InputPort(); - std::vector& ReadPreOutputData(); - - void Connect(const std::shared_ptr& node, OutputPort* output); - - void DisConnect(OutputPort* output); - - size_t GetPreOutputNum() const; - - const std::unordered_map *, std::shared_ptr>& GetPreOuputMap(); - - InputPort(const InputPort &that) = delete; - - void AddPreOutput(const std::shared_ptr &node, OutputPort* output); - void RemovePreOutput(OutputPort* output); -private: - std::unordered_map*, std::shared_ptr> outputPorts_; - std::vector inputData_; -}; - -template -InputPort::~InputPort() -{ - for (auto &o : outputPorts_) { - o.first->RemoveInput(this); - } -} - -template -std::vector& InputPort::ReadPreOutputData() -{ - inputData_.clear(); - for (auto &o : outputPorts_) { - T pcmData = o.first->PullOutputData(); - if (pcmData != nullptr) { - inputData_.emplace_back(std::move(pcmData)); - } - } - return inputData_; -} - -template -void InputPort::Connect(const std::shared_ptr &node, OutputPort* output) -{ - output->AddInput(this); - AddPreOutput(node, output); -} - -template -void InputPort::DisConnect(OutputPort* output) -{ - output->RemoveInput(this); - RemovePreOutput(output); -} - -template -size_t InputPort::GetPreOutputNum() const -{ - return outputPorts_.size(); -} - -template -const std::unordered_map *, std::shared_ptr>& InputPort::GetPreOuputMap() -{ - return outputPorts_; -} - -template -void InputPort::AddPreOutput(const std::shared_ptr &node, OutputPort *output) -{ - outputPorts_[output] = node; -} - -template -void InputPort::RemovePreOutput(OutputPort *output) -{ - outputPorts_.erase(output); -} - -template -T OutputPort::PullOutputData() -{ - if (outputData_.empty()) { - hpaeNode_->DoProcess(); - } - if (!outputData_.empty()) { - T retValue = std::move(outputData_.back()); - outputData_.pop_back(); - return retValue; - } else { - return nullptr; - } -} - -template -void OutputPort::WriteDataToOutput(T data) -{ - outputData_.clear(); - outputData_.emplace_back(std::move(data)); - - for (size_t i = 1; i < inputPortSet_.size(); i++) { - outputData_.push_back(outputData_[0]); - } -} - -template -void OutputPort::AddInput(InputPort *input) -{ - inputPortSet_.insert(input); -} -template -size_t OutputPort::GetInputNum() const -{ - return inputPortSet_.size(); -} -template -bool OutputPort::RemoveInput(InputPort *input) -{ - auto it = inputPortSet_.find(input); - if (it == inputPortSet_.end()) { - return false; - } - - inputPortSet_.erase(it); - return true; -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_node_common.h b/services/audio_engine/node/include/hpae_node_common.h deleted file mode 100644 index 903b0794e2..0000000000 --- a/services/audio_engine/node/include/hpae_node_common.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_NODE_COMMON_H -#define HPAE_NODE_COMMON_H -#include "hpae_define.h" -#include "audio_effect.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -bool CheckHpaeNodeInfoIsSame(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &curNodeInfo); -HpaeProcessorType TransStreamTypeToSceneType(AudioStreamType streamType); -HpaeProcessorType TransSourceTypeToSceneType(SourceType sourceType); -bool CheckSceneTypeNeedEc(HpaeProcessorType processorType); -bool CheckSceneTypeNeedMicRef(HpaeProcessorType processorType); -std::string TransHpaeResampleNodeInfoToStringKey(HpaeNodeInfo& nodeInfo); -AudioEnhanceScene TransProcessType2EnhanceScene(const HpaeProcessorType &processorType); -std::string TransProcessorTypeToSceneType(HpaeProcessorType processorType); -uint64_t ConvertDatalenToUs(size_t bufferSize, const HpaeNodeInfo &nodeInfo); -size_t ConvertUsToFrameCount(uint64_t usTime, const HpaeNodeInfo &nodeInfo); -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_offload_sinkoutput_node.h b/services/audio_engine/node/include/hpae_offload_sinkoutput_node.h deleted file mode 100644 index de7678c413..0000000000 --- a/services/audio_engine/node/include/hpae_offload_sinkoutput_node.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_OFFLOAD_SINK_OUTPUT_NODE_H -#define HPAE_OFFLOAD_SINK_OUTPUT_NODE_H -#include -#include "hpae_node.h" -#include "hpae_pcm_buffer.h" -#include "audio_info.h" -#include "sink/i_audio_render_sink.h" -#include "common/hdi_adapter_info.h" -#include "manager/hdi_adapter_manager.h" -#ifdef ENABLE_HOOK_PCM -#include "high_resolution_timer.h" -#include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -typedef void(*AppCallbackFunc)(void* pHndl); -class HpaeOffloadSinkOutputNode : public InputNode { -public: - HpaeOffloadSinkOutputNode(HpaeNodeInfo& nodeInfo); - virtual void DoProcess() override; - virtual bool Reset() override; - virtual bool ResetAll() override; - void Connect(const std::shared_ptr>& preNode) override; - void DisConnect(const std::shared_ptr>& preNode) override; - int32_t GetRenderSinkInstance(const std::string &deviceClass, const std::string &deviceNetworkId); - int32_t RenderSinkInit(IAudioSinkAttr& attr); - int32_t RenderSinkDeInit(); - int32_t RenderSinkFlush(); - int32_t RenderSinkStart(); - int32_t RenderSinkStop(); - size_t GetPreOutNum(); - RendererState GetSinkState(void); - const char* GetRenderFrameData(void); - // need flush hdi cache and rewind - void StopStream(); - // flush need clear sinkoutputjnode cache - void FlushStream(); - // set offload policy state - void SetPolicyState(int32_t policyState); - // get offload latency for sinkinputnode, maybe extend to all node - uint64_t GetLatency(); - // set timeout to suspend render and stop hdi - int32_t SetTimeoutStopThd(uint32_t timeoutThdMs); -private: - // lock/unlock running lock - void RunningLock(bool isLock); - // Set hdi buffer size, change after render frame success - void SetBufferSizeWhileRenderFrame(); - int32_t ProcessRenderFrame(); - // get presentation position from hdi, only trigger in offloadcallback - int32_t UpdatePresentationPosition(); - // return hdi cache len in us, cal by hdiPos_ - uint64_t CalcOffloadCacheLenInHdi(); - // set hdi volume when first write - void OffloadSetHdiVolume(); - // reset hdipos and firstWriteHdi - void OffloadReset(); - // register callback to hdi - void RegOffloadCallback(); - // offload callback reg to hdi - void OffloadCallback(const RenderCallbackType type); - // check when stop hdi, if need suspend - bool CheckIfSuspend(); - - InputPort inputStream_; - std::vector renderFrameData_; - std::vector interleveData_; - std::shared_ptr audioRendererSink_ = nullptr; - uint32_t renderId_ = HDI_INVALID_ID; - IAudioSinkAttr sinkOutAttr_; - RendererState state_ = RENDERER_NEW; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer intervalTimer_; - std::unique_ptr outputPcmDumper_ = nullptr; -#endif - - AudioOffloadType hdiPolicyState_ = OFFLOAD_ACTIVE_FOREGROUND; - struct OffloadPolicyTask { - bool flag = false; // indicate if task exsit - AudioOffloadType state; - TimePoint time; - } setPolicyStateTask_; - - bool firstWriteHdi_ = true; - uint64_t writePos_ = 0; - int32_t setHdiBufferSizeNum_ = 0; - - std::atomic isHdiFull_ = false; - - uint32_t frameLenMs_ = 0; - uint32_t timeoutThdFrames_ = 0; - // first stand for pos(in us), second stand for time - std::pair hdiPos_; -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS - -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_output_cluster.h b/services/audio_engine/node/include/hpae_output_cluster.h deleted file mode 100644 index eff788612d..0000000000 --- a/services/audio_engine/node/include/hpae_output_cluster.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_OUTPUT_CLUSTER_H -#define HPAE_OUTPUT_CLUSTER_H -#include "hpae_mixer_node.h" -#include "hpae_sink_output_node.h" -#include "hpae_audio_format_converter_node.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr uint32_t TIME_OUT_STOP_THD_DEFAULT_FRAME = 150; -constexpr uint32_t FRAME_LEN_MS_DEFAULT_MS = 20; -class HpaeOutputCluster : public InputNode { -public: - HpaeOutputCluster(HpaeNodeInfo &nodeInfo); - virtual ~HpaeOutputCluster(); - virtual void DoProcess() override; - virtual bool Reset() override; - virtual bool ResetAll() override; - void Connect(const std::shared_ptr> &preNode) override; - void DisConnect(const std::shared_ptr> &preNode) override; - int32_t GetConverterNodeCount(); - int32_t GetPreOutNum(); - int32_t GetInstance(std::string deviceClass, std::string deviceNetId); - int32_t Init(IAudioSinkAttr &attr); - int32_t DeInit(); - int32_t Flush(void); - int32_t Pause(void); - int32_t ResetRender(void); - int32_t Resume(void); - int32_t Start(void); - int32_t Stop(void); - int32_t SetTimeoutStopThd(uint32_t timeoutThdMs); - const char *GetFrameData(void); - RendererState GetState(void); - bool IsProcessClusterConnected(HpaeProcessorType sceneType); -private: - std::shared_ptr mixerNode_ = nullptr; - std::shared_ptr hpaeSinkOutputNode_ = nullptr; - std::unordered_map> sceneConverterMap_; - uint32_t timeoutThdFrames_ = TIME_OUT_STOP_THD_DEFAULT_FRAME; - uint32_t timeoutStopCount_ = 0; - uint32_t frameLenMs_ = FRAME_LEN_MS_DEFAULT_MS; - std::set connectedProcessCluster_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_plugin_node.h b/services/audio_engine/node/include/hpae_plugin_node.h deleted file mode 100644 index 26f727fd1e..0000000000 --- a/services/audio_engine/node/include/hpae_plugin_node.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_PLUGIN_NODE_H -#define HPAE_PLUGIN_NODE_H -#include -#include "hpae_node.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaePluginNode : public OutputNode, public InputNode { -public: - HpaePluginNode(HpaeNodeInfo& nodeInfo); - virtual ~HpaePluginNode() {}; - virtual void DoProcess() override; - virtual bool Reset() override; - virtual bool ResetAll() override; - - std::shared_ptr GetSharedInstance() override; - OutputPort* GetOutputPort() override; - void Connect(const std::shared_ptr>& preNode) override; - void DisConnect(const std::shared_ptr>& preNode) override; - virtual size_t GetPreOutNum(); - virtual size_t GetOutputPortNum(); - virtual int32_t EnableProcess(bool enable); - virtual bool IsEnableProcess(); - HpaePluginNode(const HpaePluginNode& others) = delete; -private: - OutputPort outputStream_; - bool enableProcess_; - PcmBufferInfo pcmBufferInfo_; -protected: - virtual HpaePcmBuffer* SignalProcess(const std::vector& inputs) = 0; - InputPort inputStream_; - HpaePcmBuffer silenceData_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_process_cluster.h b/services/audio_engine/node/include/hpae_process_cluster.h deleted file mode 100644 index aad56b6165..0000000000 --- a/services/audio_engine/node/include/hpae_process_cluster.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_PROCESS_CLUSTER_H -#define HPAE_PROCESS_CLUSTER_H -#include "hpae_mixer_node.h" -#include "hpae_audio_format_converter_node.h" -#include "hpae_gain_node.h" -#include "hpae_render_effect_node.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaeProcessCluster : public OutputNode, public InputNode, - public INodeFormatInfoCallback { -public: - HpaeProcessCluster(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &sinkInfo); - virtual ~HpaeProcessCluster(); - virtual void DoProcess() override; - virtual bool Reset() override; - virtual bool ResetAll() override; - std::shared_ptr GetSharedInstance() override; - OutputPort *GetOutputPort() override; - void Connect(const std::shared_ptr> &preNode) override; - void DisConnect(const std::shared_ptr> &preNode) override; - int32_t GetGainNodeCount(); - int32_t GetConverterNodeCount(); - int32_t GetPreOutNum(); - int32_t AudioRendererCreate(HpaeNodeInfo &nodeInfo); - int32_t AudioRendererStart(HpaeNodeInfo &nodeInfo); - int32_t AudioRendererStop(HpaeNodeInfo &nodeInfo); - int32_t AudioRendererRelease(HpaeNodeInfo &nodeInfo); - int32_t GetEffectNodeInputChannelInfo(uint32_t &channels, uint64_t &channelLayout) override; - std::shared_ptr GetGainNodeById(uint32_t id) const; - std::shared_ptr GetConverterNodeById(uint32_t id) const; -private: - std::shared_ptr mixerNode_; - std::shared_ptr renderEffectNode_ = nullptr; - std::unordered_map> idConverterMap_; - std::unordered_map> idGainMap_; - HpaeSinkInfo sinkInfo_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif // HPAE_PROCESS_CLUSTER_H \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_render_effect_node.h b/services/audio_engine/node/include/hpae_render_effect_node.h deleted file mode 100644 index 6c88b490aa..0000000000 --- a/services/audio_engine/node/include/hpae_render_effect_node.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_RENDER_EFFECT_NODE_H -#define HPAE_RENDER_EFFECT_NODE_H - -#include "hpae_plugin_node.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -enum ModifyAudioEffectChainInfoReason { - ADD_AUDIO_EFFECT_CHAIN_INFO = 0, - REMOVE_AUDIO_EFFECT_CHAIN_INFO = 1, -}; - -class HpaeRenderEffectNode : public HpaePluginNode { -public: - HpaeRenderEffectNode(HpaeNodeInfo &nodeInfo); - int32_t AudioRendererCreate(HpaeNodeInfo &nodeInfo); - int32_t AudioRendererStart(HpaeNodeInfo &nodeInfo); - int32_t AudioRendererStop(HpaeNodeInfo &nodeInfo); - int32_t AudioRendererRelease(HpaeNodeInfo &nodeInfo); - int32_t GetExpectedInputChannelInfo(uint32_t &channels, uint64_t &channelLayout); -protected: - HpaePcmBuffer* SignalProcess(const std::vector &inputs) override; -private: - void ReconfigOutputBuffer(); - int32_t CreateAudioEffectChain(HpaeNodeInfo &nodeInfo); - int32_t ReleaseAudioEffectChain(HpaeNodeInfo &nodeInfo); - void ModifyAudioEffectChainInfo(HpaeNodeInfo &nodeInfo, ModifyAudioEffectChainInfoReason reason); - void UpdateAudioEffectChainInfo(HpaeNodeInfo &nodeInfo); - PcmBufferInfo pcmBufferInfo_; - HpaePcmBuffer effectOutput_; - HpaeNodeInfo nodeInfo_; - std::string sceneType_ = "EFFECT_NONE"; -#ifdef ENABLE_HOOK_PCM - std::unique_ptr inputPcmDumper_; - std::unique_ptr outputPcmDumper_; -#endif -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS - -#endif // HPAE_RENDER_EFFECT_NODE_H \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_resample_node.h b/services/audio_engine/node/include/hpae_resample_node.h deleted file mode 100644 index 8c6b45cb99..0000000000 --- a/services/audio_engine/node/include/hpae_resample_node.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_RESAMPLE_NODE_H -#define HPAE_RESAMPLE_NODE_H -#include "audio_proresampler.h" -#include "hpae_plugin_node.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -enum class ResamplerType { - PRORESAMPLER -}; - -class HpaeResampleNode : public HpaePluginNode { -public: - HpaeResampleNode(HpaeNodeInfo& nodeInfo, HpaeNodeInfo& preNodeInfo, ResamplerType type); - HpaeResampleNode(HpaeNodeInfo& nodeInfo, HpaeNodeInfo& preNodeInfo); - ~HpaeResampleNode() = default; - virtual bool Reset() override; - void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; - void DisConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) override; -protected: - HpaePcmBuffer* SignalProcess(const std::vector& inputs) override; -private: - void ResampleProcess(float *srcData, uint32_t inputFrameLen, float *dstData, uint32_t outputFrameLen); - PcmBufferInfo pcmBufferInfo_; - HpaePcmBuffer resampleOuput_; - HpaeNodeInfo preNodeInfo_; - std::vector tempOuput_; -#ifdef ENABLE_HOOK_PCM - std::unique_ptr inputPcmDumper_ = nullptr; - std::unique_ptr outputPcmDumper_ = nullptr; -#endif - std::unique_ptr resampler_ = nullptr; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_sink_input_node.h b/services/audio_engine/node/include/hpae_sink_input_node.h deleted file mode 100644 index 4ff055eb3e..0000000000 --- a/services/audio_engine/node/include/hpae_sink_input_node.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_SINK_INPUT_NODE_H -#define HPAE_SINK_INPUT_NODE_H -#include -#include -#include "hpae_msg_channel.h" -#include "hpae_node.h" -#include "hpae_pcm_buffer.h" -#include "audio_info.h" -#include "i_renderer_stream.h" -#include "linear_pos_time_model.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -typedef void (*AppCallbackFunc)(void *pHndl); - -class HpaeSinkInputNode : public OutputNode { -public: - HpaeSinkInputNode(HpaeNodeInfo &nodeInfo); - ~HpaeSinkInputNode(); - virtual void DoProcess() override; - virtual bool Reset() override; // no implement, virtual class - virtual bool ResetAll() override; // no implement, virtual class - std::shared_ptr GetSharedInstance() override; - OutputPort *GetOutputPort() override; - bool RegisterWriteCallback(const std::weak_ptr &callback); - void Flush(); - bool Drain(); - int32_t SetState(RendererState renderState); - RendererState GetState(); - uint64_t GetFramesWritten(); - - int32_t GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp); - int32_t RewindHistoryBuffer(uint64_t rewindTime); - -private: - void CheckAndDestoryHistoryBuffer(); - bool GetAudioTime(uint64_t &framePos, int64_t &sec, int64_t &nanoSec); - std::weak_ptr writeCallback_; - AudioCallBackStreamInfo streamInfo_; - PcmBufferInfo pcmBufferInfo_; - HpaePcmBuffer inputAudioBuffer_; - OutputPort outputStream_; - std::vector interleveData_; - std::atomic framesWritten_; - uint64_t totalFrames_; - std::unique_ptr handleTimeModel_; - bool isDrain_ = false; - RendererState state_ = RENDERER_NEW; - - std::unique_ptr historyBuffer_; -#ifdef ENABLE_HOOK_PCM - std::unique_ptr inputPcmDumper_ = nullptr; -#endif -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS - -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_sink_output_node.h b/services/audio_engine/node/include/hpae_sink_output_node.h deleted file mode 100644 index 205cbc8a35..0000000000 --- a/services/audio_engine/node/include/hpae_sink_output_node.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_SINK_OUTPUT_NODE_H -#define HPAE_SINK_OUTPUT_NODE_H -#include -#include "hpae_node.h" -#include "hpae_pcm_buffer.h" -#include "audio_info.h" -#include "sink/i_audio_render_sink.h" -#include "common/hdi_adapter_info.h" -#include "manager/hdi_adapter_manager.h" -#include "high_resolution_timer.h" -#ifdef ENABLE_HOOK_PCM -#include "high_resolution_timer.h" -#include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -typedef void (*AppCallbackFunc)(void *pHndl); - -class HpaeSinkOutputNode : public InputNode { -public: - HpaeSinkOutputNode(HpaeNodeInfo &nodeInfo); - virtual void DoProcess() override; - virtual bool Reset() override; - virtual bool ResetAll() override; - void Connect(const std::shared_ptr> &preNode) override; - void DisConnect(const std::shared_ptr> &preNode) override; - int32_t GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId); - int32_t RenderSinkInit(IAudioSinkAttr &attr); - int32_t RenderSinkDeInit(); - int32_t RenderSinkFlush(void); - int32_t RenderSinkPause(void); - int32_t RenderSinkReset(void); - int32_t RenderSinkResume(void); - int32_t RenderSinkStart(void); - int32_t RenderSinkStop(void); - size_t GetPreOutNum(); - // for ut test - const char *GetRenderFrameData(void); - RendererState GetSinkState(void); - -private: - void HandleRemoteTiming(); - InputPort inputStream_; - std::vector renderFrameData_; - std::vector interleveData_; - std::shared_ptr audioRendererSink_ = nullptr; - uint32_t renderId_ = HDI_INVALID_ID; - IAudioSinkAttr sinkOutAttr_; - RendererState state_ = RENDERER_NEW; - HighResolutionTimer remoteTimer_; - TimePoint remoteTimePoint_; - std::chrono::milliseconds remoteSleepTime_ = std::chrono::milliseconds(0); -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer intervalTimer_; - std::unique_ptr outputPcmDumper_ = nullptr; -#endif -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS - -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_source_input_cluster.h b/services/audio_engine/node/include/hpae_source_input_cluster.h deleted file mode 100644 index fa83fe530f..0000000000 --- a/services/audio_engine/node/include/hpae_source_input_cluster.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_SOURCE_INPUT_CLUSTER_H -#define HPAE_SOURCE_INPUT_CLUSTER_H - -#include "hpae_source_input_node.h" -#include "hpae_audio_format_converter_node.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaeSourceInputCluster : public OutputNode{ -public: - HpaeSourceInputCluster(HpaeNodeInfo &nodeInfo); - HpaeSourceInputCluster(std::vector &nodeInfos); - virtual ~HpaeSourceInputCluster(); - virtual void DoProcess() final; - virtual bool Reset() final; - virtual bool ResetAll() final; - std::shared_ptr GetSharedInstance() final; - std::shared_ptr GetSharedInstance(HpaeNodeInfo &nodeInfo) final; - OutputPort *GetOutputPort() final; - OutputPort *GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) final; - int32_t GetCapturerSourceInstance(const std::string &deviceClass, const std::string &deviceNetId, - const SourceType &sourceType, const std::string &sourceName); - int32_t CapturerSourceInit(IAudioSourceAttr &attr); - int32_t CapturerSourceDeInit(); - int32_t CapturerSourceFlush(void); - int32_t CapturerSourcePause(void); - int32_t CapturerSourceReset(void); - int32_t CapturerSourceResume(void); - int32_t CapturerSourceStart(void); - int32_t CapturerSourceStop(void); - CapturerState GetSourceState(void); - size_t GetOutputPortNum(); - size_t GetOutputPortNum(HpaeNodeInfo &nodeInfo); - HpaeSourceInputNodeType GetSourceInputNodeType(); - void SetSourceInputNodeType(HpaeSourceInputNodeType type); - - // for test - uint32_t GetConverterNodeCount(); - uint32_t GetSourceInputNodeUseCount(); -private: - std::shared_ptr sourceInputNode_; - std::unordered_map> fmtConverterNodeMap_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_source_input_node.h b/services/audio_engine/node/include/hpae_source_input_node.h deleted file mode 100644 index 047f207149..0000000000 --- a/services/audio_engine/node/include/hpae_source_input_node.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_SOURCE_INTPUT_NODE_H -#define HPAE_SOURCE_INTPUT_NODE_H -#include -#include "hpae_node.h" -#include "hpae_pcm_buffer.h" -#include "source/i_audio_capture_source.h" -#include "common/hdi_adapter_type.h" -#include "common/hdi_adapter_info.h" -#include "manager/hdi_adapter_manager.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaeSourceInputNode : public OutputNode { -public: - HpaeSourceInputNode(HpaeNodeInfo &nodeInfo); - HpaeSourceInputNode(std::vector &nodeInfos); - virtual void DoProcess() override; - virtual bool Reset() override; - virtual bool ResetAll() override; - std::shared_ptr GetSharedInstance() final; - - OutputPort *GetOutputPort() final; - OutputPort *GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) final; - HpaeSourceBufferType GetOutputPortBufferType(HpaeNodeInfo &nodeInfo) final; - int32_t GetCapturerSourceInstance(const std::string &deviceClass, const std::string &deviceNetId, - const SourceType &sourceType, const std::string &sourceName); - int32_t CapturerSourceInit(IAudioSourceAttr &attr); - int32_t CapturerSourceDeInit(); - int32_t CapturerSourceFlush(void); - int32_t CapturerSourcePause(void); - int32_t CapturerSourceReset(void); - int32_t CapturerSourceResume(void); - int32_t CapturerSourceStart(void); - int32_t CapturerSourceStop(void); - CapturerState GetSourceState(void); - int32_t WriteCapturerData(char *data, int32_t dataSize); - size_t GetOutputPortNum(); - size_t GetOutputPortNum(HpaeNodeInfo &nodeInfo); - HpaeSourceInputNodeType GetSourceInputNodeType(); - void SetSourceInputNodeType(HpaeSourceInputNodeType type); -private: - int32_t GetCapturerSourceAdapter( - const std::string &deviceClass, const SourceType &sourceType, const std::string &info); - -private: - std::shared_ptr audioCapturerSource_ = nullptr; - uint32_t captureId_ = HDI_INVALID_ID; - IAudioSourceAttr audioSourceAttr_; - std::string defaultSinkName_; - std::string defaultSourceName_; - CapturerState state_ = CAPTURER_NEW; - HpaeSourceInputNodeType sourceInputNodeType_; - - std::unordered_map> outputStreamMap_; // output port - std::unordered_map nodeInfoMap_; // nodeInfo, portInfo - std::unordered_map pcmBufferInfoMap_; // bufferInfo - std::unordered_map inputAudioBufferMap_; // output buffer - std::unordered_map frameByteSizeMap_; - std::unordered_map> capturerFrameDataMap_; // input buffer - std::unordered_map fdescMap_; // CaptureframeWithEc argument struct - -#ifdef ENABLE_HOOK_PCM - std::unordered_map> inputPcmDumperMap_; -#endif -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_source_output_node.h b/services/audio_engine/node/include/hpae_source_output_node.h deleted file mode 100644 index 67cac88245..0000000000 --- a/services/audio_engine/node/include/hpae_source_output_node.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_SOURCE_OUTPUT_NODE_H -#define HPAE_SOURCE_OUTPUT_NODE_H -#include -#include "hpae_node.h" -#include "hpae_pcm_buffer.h" -#include "audio_info.h" -#include "i_capturer_stream.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class HpaeSourceOutputNode : public InputNode { -public: - HpaeSourceOutputNode(HpaeNodeInfo &nodeInfo); - virtual void DoProcess() final; - virtual bool Reset() final; - bool ResetAll() final; - void Connect(const std::shared_ptr> &preNode) override; - void ConnectWithInfo(const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; - void DisConnect(const std::shared_ptr> &preNode) override; - void DisConnectWithInfo( - const std::shared_ptr> &preNode, HpaeNodeInfo &nodeInfo) override; - bool RegisterReadCallback(const std::weak_ptr &callback); - -private: - InputPort inputStream_; - std::weak_ptr readCallback_; - std::vector sourceOuputData_; - std::vector interleveData_; -#ifdef ENABLE_HOOK_PCM - std::unique_ptr outputPcmDumper_ = nullptr; -#endif -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS - -#endif \ No newline at end of file diff --git a/services/audio_engine/node/include/hpae_source_process_cluster.h b/services/audio_engine/node/include/hpae_source_process_cluster.h deleted file mode 100644 index d478e397db..0000000000 --- a/services/audio_engine/node/include/hpae_source_process_cluster.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_SOURCE_PROCESS_CLUSTER_H -#define HPAE_SOURCE_PROCESS_CLUSTER_H -#include "hpae_capture_effect_node.h" -#include "hpae_audio_format_converter_node.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaeSourceProcessCluster : public OutputNode, public InputNode { -public: - HpaeSourceProcessCluster(HpaeNodeInfo &nodeInfo); - virtual ~HpaeSourceProcessCluster(); - virtual void DoProcess() override; - virtual bool Reset() override; - virtual bool ResetAll() override; - std::shared_ptr GetSharedInstance() override; - std::shared_ptr GetSharedInstance(HpaeNodeInfo &nodeInfo) override; - OutputPort *GetOutputPort() override; - OutputPort *GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) override; - - // HpaeNodeInfo& GetOutputNodeInfo() override; - void Connect(const std::shared_ptr>& preNode) override; - void DisConnect(const std::shared_ptr>& preNode) override; - void ConnectWithInfo(const std::shared_ptr>& preNode, HpaeNodeInfo &nodeInfo) override; - void DisConnectWithInfo(const std::shared_ptr>& preNode, - HpaeNodeInfo &nodeInfo) override; - bool GetCapturerEffectConfig(HpaeNodeInfo& nodeInfo, HpaeSourceBufferType type = HPAE_SOURCE_BUFFER_TYPE_MIC); - - size_t GetOutputPortNum(); - int32_t CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr); - int32_t CaptureEffectRelease(uint64_t sceneKeyCode); -private: - std::shared_ptr captureEffectNode_; - std::unordered_map> fmtConverterNodeMap_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp b/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp deleted file mode 100644 index 86ecff9c0a..0000000000 --- a/services/audio_engine/node/src/hpae_audio_format_converter_node.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeAudioFormatConverterNode" -#endif -#include "hpae_audio_format_converter_node.h" -#include "audio_engine_log.h" -#include "audio_utils.h" -#include "cinttypes" - -static constexpr uint32_t DEFAULT_EFFECT_RATE = 48000; - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr int REASAMPLE_QUAILTY = 5; -HpaeAudioFormatConverterNode::HpaeAudioFormatConverterNode(HpaeNodeInfo preNodeInfo, HpaeNodeInfo nodeInfo) - : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), - pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout), - converterOuput_(pcmBufferInfo_), preNodeInfo_(preNodeInfo), tmpOutBuf_(pcmBufferInfo_) -{ - UpdateTmpOutPcmBufferInfo(pcmBufferInfo_); - // use ProResamppler as default - resampler_ = std::make_unique(preNodeInfo_.samplingRate, nodeInfo.samplingRate, - std::min(preNodeInfo_.channels, nodeInfo.channels), REASAMPLE_QUAILTY); - - AudioChannelInfo inChannelInfo = { - .channelLayout = preNodeInfo.channelLayout, - .numChannels = preNodeInfo.channels, - }; - AudioChannelInfo outChannelInfo = { - .channelLayout = nodeInfo.channelLayout, - .numChannels = nodeInfo.channels, - }; - - // for now, work at float32le by default - channelConverter_.SetParam(inChannelInfo, outChannelInfo, SAMPLE_F32LE, true); - AUDIO_INFO_LOG("node id %{public}d, sessionid %{public}d, " - "input: bitformat %{public}d, sample rate %{public}d, channels %{public}d, channelLayout %{public}" PRIu64 "" - ", output: bitformat %{public}d, sample rate %{public}d, channels %{public}d, channelLayout %{public}" PRIu64 "", - GetNodeId(), GetSessionId(), preNodeInfo.format, preNodeInfo.samplingRate, inChannelInfo.numChannels, - inChannelInfo.channelLayout, nodeInfo.format, nodeInfo.samplingRate, outChannelInfo.numChannels, - outChannelInfo.channelLayout); -#ifdef ENABLE_HOOK_PCM - inputPcmDumper_ = std::make_unique("HpaeConverterNodeInput_id_" + std::to_string(GetSessionId()) + - "_ch_" + std::to_string(preNodeInfo_.channels) + "_rate_" + - std::to_string(preNodeInfo_.samplingRate) + "_" + GetTime() + ".pcm"); - outputPcmDumper_ = std::make_unique("HpaeConverterNodeOutput_id_" + std::to_string(GetSessionId()) + - "_ch_" + std::to_string(GetChannelCount()) + "_rate_" + - std::to_string(GetSampleRate()) + "_" + GetTime() + ".pcm"); -#endif -} - -void HpaeAudioFormatConverterNode::RegisterCallback(INodeFormatInfoCallback *callback) -{ - nodeFormatInfoCallback_ = callback; -} - -HpaePcmBuffer *HpaeAudioFormatConverterNode::SignalProcess(const std::vector &inputs) -{ - auto rate = "rate[" + std::to_string(GetSampleRate()) + "]_"; - auto ch = "ch[" + std::to_string(GetChannelCount()) + "]_"; - auto len = "len[" + std::to_string(GetFrameLen()) + "]"; - Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeAudioFormatConverterNode::SignalProcess " - + rate + ch + len); - if (inputs.empty()) { - AUDIO_WARNING_LOG("HpaeConverterNode inputs size is empty, SessionId:%{public}d", GetSessionId()); - return nullptr; - } - if (inputs.size() != 1) { - AUDIO_WARNING_LOG("error inputs size is not eqaul to 1, SessionId:%{public}d", GetSessionId()); - } - float *srcData = (*(inputs[0])).GetPcmDataBuffer(); -#ifdef ENABLE_HOOK_PCM - if (inputPcmDumper_ != nullptr) { - inputPcmDumper_->Dump((int8_t *)(srcData), - inputs[0]->GetFrameLen() * inputs[0]->GetChannelCount() * sizeof(float)); - } -#endif - converterOuput_.Reset(); - tmpOutBuf_.Reset(); - - CheckAndUpdateInfo(inputs[0]); - - float *dstData = converterOuput_.GetPcmDataBuffer(); - float *tmpData = tmpOutBuf_.GetPcmDataBuffer(); - - if (resampler_ == nullptr) { - return &silenceData_; - } - int32_t ret = ConverterProcess(srcData, dstData, tmpData, inputs[0]); - if (ret != EOK) { - AUDIO_ERR_LOG("NodeId %{public}d, sessionId %{public}d, Format Converter fail to process!", - GetNodeId(), GetSessionId()); - return &silenceData_; - } - -#ifdef ENABLE_HOOK_PCM - if (outputPcmDumper_ != nullptr) { - outputPcmDumper_->Dump((int8_t *)dstData, - converterOuput_.GetFrameLen() * sizeof(float) * channelConverter_.GetOutChannelInfo().numChannels); - } -#endif - AUDIO_DEBUG_LOG("NodeId %{public}d, buffer valid %{public}d", GetSessionId(), converterOuput_.IsValid()); - return &converterOuput_; -} - -int32_t HpaeAudioFormatConverterNode::ConverterProcess(float *srcData, float *dstData, float *tmpData, - HpaePcmBuffer *input) -{ - AudioChannelInfo inChannelInfo = channelConverter_.GetInChannelInfo(); - AudioChannelInfo outChannelInfo = channelConverter_.GetOutChannelInfo(); - uint32_t inRate = resampler_->GetInRate(); - uint32_t outRate = resampler_->GetOutRate(); - - uint32_t inputFrameLen = preNodeInfo_.frameLen; - uint32_t outputFrameLen = converterOuput_.GetFrameLen(); - uint32_t inputFrameBytes = inputFrameLen * inChannelInfo.numChannels * sizeof(float); - uint32_t outputFrameBytes = outputFrameLen * outChannelInfo.numChannels * sizeof(float); - int32_t ret = EOK; - - if ((inChannelInfo.numChannels == outChannelInfo.numChannels) && (inRate == outRate)) { - ret = memcpy_s(dstData, outputFrameBytes, srcData, inputFrameBytes); - } else if (inChannelInfo.numChannels == outChannelInfo.numChannels) { - ret = resampler_->Process(srcData, &inputFrameLen, dstData, &outputFrameLen); - } else if (inRate == outRate) { - ret = channelConverter_.Process(inputFrameLen, srcData, (*input).Size(), dstData, converterOuput_.Size()); - } else if (inChannelInfo.numChannels > outChannelInfo.numChannels) { // convert, then resample - ret = channelConverter_.Process(inputFrameLen, srcData, (*input).Size(), tmpData, tmpOutBuf_.Size()); - ret += resampler_->Process(tmpData, &inputFrameLen, dstData, &outputFrameLen); - } else { // output channels larger than input channels, resample, then convert - ret = resampler_->Process(srcData, &inputFrameLen, tmpData, &outputFrameLen); - ret += channelConverter_.Process(outputFrameLen, tmpData, tmpOutBuf_.Size(), dstData, converterOuput_.Size()); - } - return ret; -} - -// return true if output info is updated -bool HpaeAudioFormatConverterNode::CheckUpdateOutInfo() -{ - // update channelLayout and numChannels - if (nodeFormatInfoCallback_ == nullptr) { - return false; - } - - uint32_t numChannels = 0; - uint64_t channelLayout = CH_LAYOUT_UNKNOWN; - // effectnode input is 48k by default now - uint32_t sampleRate = DEFAULT_EFFECT_RATE; - - // if there exists an effect node, converter node output is effect node input - // update channels and channelLayout - - nodeFormatInfoCallback_->GetEffectNodeInputChannelInfo(numChannels, channelLayout); - - if (numChannels == 0 || channelLayout == CH_LAYOUT_UNKNOWN) { - // set to node info, which is device output info - AUDIO_INFO_LOG("Fail to check format into from effect node"); - numChannels = GetChannelCount(); - channelLayout = (uint64_t)GetChannelLayout(); - sampleRate = GetSampleRate(); - } - - AudioChannelInfo curOutChannelInfo = channelConverter_.GetOutChannelInfo(); - if ((curOutChannelInfo.numChannels == numChannels) && (curOutChannelInfo.channelLayout == channelLayout) && - (sampleRate == resampler_->GetOutRate())) { - return false; - } - // update channel info - if (curOutChannelInfo.numChannels != numChannels || curOutChannelInfo.channelLayout != channelLayout) { - AudioChannelInfo newOutChannelInfo = { - .channelLayout = (AudioChannelLayout)channelLayout, - .numChannels = numChannels, - }; - AUDIO_INFO_LOG("NodeId %{public}d, update out channels and channelLayout: channels %{public}d -> %{public}d", - GetNodeId(), curOutChannelInfo.numChannels, numChannels); - CHECK_AND_RETURN_RET_LOG(channelConverter_.SetOutChannelInfo(newOutChannelInfo) == DMIX_ERR_SUCCESS, false, - "NodeId: %{public}d, Fail to set output channel info from effectNode!", GetNodeId()); - - uint32_t resampleChannels = std::min(channelConverter_.GetInChannelInfo().numChannels, numChannels); - if (resampleChannels != resampler_->GetChannels()) { - AUDIO_INFO_LOG("NodeId: %{public}d, Update resampler work channel from effectNode!", GetNodeId()); - resampler_->UpdateChannels(resampleChannels); - } - } - // update sample rate - if (resampler_->GetOutRate() != sampleRate) { - AUDIO_INFO_LOG("NodeId: %{public}d, update output sample rate: %{public}d -> %{public}d", - GetNodeId(), resampler_->GetOutRate(), sampleRate); - resampler_->UpdateRates(preNodeInfo_.samplingRate, sampleRate); - } - - HpaeNodeInfo nodeInfo = GetNodeInfo(); - nodeInfo.channels = (AudioChannel)numChannels; - nodeInfo.channelLayout = (AudioChannelLayout)channelLayout; - nodeInfo.samplingRate = (AudioSamplingRate)resampler_->GetOutRate(); - SetNodeInfo(nodeInfo); - return true; -} - -// update channel info from processCluster. For now sample rate will not change -bool HpaeAudioFormatConverterNode::CheckUpdateInInfo(HpaePcmBuffer *input) -{ - uint32_t numChannels = input->GetChannelCount(); - uint64_t channelLayout = input->GetChannelLayout(); - uint32_t sampleRate = input->GetSampleRate(); - AudioChannelInfo curInChannelInfo = channelConverter_.GetInChannelInfo(); - bool isInfoUpdated = false; - // update channels and channelLayout - if ((curInChannelInfo.numChannels != numChannels) || (curInChannelInfo.channelLayout != channelLayout)) { - AUDIO_INFO_LOG("NodeId %{public}d: Update innput channel info from pcmBufferInfo, " - "channels: %{public}d -> %{public}d, channellayout: %{public}" PRIu64 " -> %{public}" PRIu64 ".", - GetNodeId(), curInChannelInfo.numChannels, numChannels, curInChannelInfo.channelLayout, channelLayout); - - AudioChannelInfo newInChannelInfo = { - .channelLayout = (AudioChannelLayout)channelLayout, - .numChannels = numChannels, - }; - channelConverter_.SetInChannelInfo(newInChannelInfo); - preNodeInfo_.channelLayout = (AudioChannelLayout)channelLayout; - preNodeInfo_.channels = (AudioChannel)numChannels; - - uint32_t resampleChannels = std::min(numChannels, channelConverter_.GetOutChannelInfo().numChannels); - if (resampleChannels != resampler_->GetChannels()) { - AUDIO_INFO_LOG("NodeId %{public}d: Update resampler work channel from effectNode!", GetNodeId()); - resampler_->UpdateChannels(resampleChannels); - } - isInfoUpdated = true; - } - // update sample rate - if (sampleRate != resampler_->GetInRate()) { - AUDIO_INFO_LOG("NodeId %{public}d: Update resampler input sample rate: %{public}d -> %{public}d", - GetNodeId(), resampler_->GetInRate(), sampleRate); - preNodeInfo_.frameLen = input->GetFrameLen(); - preNodeInfo_.samplingRate = (AudioSamplingRate)sampleRate; - resampler_->UpdateRates(sampleRate, resampler_->GetOutRate()); - isInfoUpdated = true; - } - return isInfoUpdated; -} - -void HpaeAudioFormatConverterNode::UpdateTmpOutPcmBufferInfo(const PcmBufferInfo &outPcmBufferInfo) -{ - if (outPcmBufferInfo.ch == preNodeInfo_.channels || outPcmBufferInfo.rate == preNodeInfo_.samplingRate) { - // do not need tmpOutput Buffer - return; - } - PcmBufferInfo tmpOutPcmBufferInfo = outPcmBufferInfo; - if (outPcmBufferInfo.ch < preNodeInfo_.channels) { // downmix, then resample - tmpOutPcmBufferInfo.rate = preNodeInfo_.samplingRate; - tmpOutPcmBufferInfo.frameLen = preNodeInfo_.frameLen; - } else { // resample, then upmix - tmpOutPcmBufferInfo.ch = preNodeInfo_.channels; - } - AUDIO_INFO_LOG("NodeId: %{public}d, updated tmp buffer rate %{public}d, frameLen %{public}d, channels %{public}d", - GetNodeId(), tmpOutPcmBufferInfo.rate, tmpOutPcmBufferInfo.frameLen, tmpOutPcmBufferInfo.ch); - tmpOutBuf_.ReConfig(tmpOutPcmBufferInfo); -} - - -void HpaeAudioFormatConverterNode::CheckAndUpdateInfo(HpaePcmBuffer *input) -{ - bool isInfoUpdated = CheckUpdateInInfo(input); - bool isOutInfoUpdated = CheckUpdateOutInfo(); - if ((!isInfoUpdated) && (!isOutInfoUpdated)) { - return; - } - - AudioChannelInfo outChannelInfo = channelConverter_.GetOutChannelInfo(); - PcmBufferInfo outPcmBufferInfo = pcmBufferInfo_; // isMultiFrames_ and frame_ are inheritated from sinkInputNode - outPcmBufferInfo.ch = outChannelInfo.numChannels; - outPcmBufferInfo.rate = resampler_->GetOutRate(); - outPcmBufferInfo.frameLen = preNodeInfo_.frameLen * resampler_->GetOutRate() / resampler_->GetInRate(); - outPcmBufferInfo.channelLayout = outChannelInfo.channelLayout; - - AUDIO_INFO_LOG("NodeId %{public}d: output or input format info is changed, update tmp PCM buffer info!", - GetNodeId()); - UpdateTmpOutPcmBufferInfo(outPcmBufferInfo); - - if (isOutInfoUpdated) { - AUDIO_INFO_LOG("NodeId %{public}d: output format info is changed, update output PCM buffer info!", GetNodeId()); - converterOuput_.ReConfig(outPcmBufferInfo); - silenceData_.ReConfig(outPcmBufferInfo); -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfoChanged(GetNodeId(), GetNodeInfo()); - } -#endif - } -} - -void HpaeAudioFormatConverterNode::ConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) -{ - inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort(nodeInfo)); - converterOuput_.SetSourceBufferType(nodeInfo.sourceBufferType); -} -void HpaeAudioFormatConverterNode::DisConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) -{ - inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true)); -} - -} // Hpae -} // AudioStandard -} // OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_capture_effect_node.cpp b/services/audio_engine/node/src/hpae_capture_effect_node.cpp deleted file mode 100644 index e0e28a7635..0000000000 --- a/services/audio_engine/node/src/hpae_capture_effect_node.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeCaptureEffectNode" -#endif - -#include "hpae_capture_effect_node.h" -#include -#include "hpae_pcm_buffer.h" -#include "audio_engine_log.h" -#include "audio_errors.h" -#include "hpae_format_convert.h" -#include "audio_enhance_chain_manager.h" -#include "audio_effect_map.h" -#include "audio_utils.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaeCaptureEffectNode::HpaeCaptureEffectNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo) -{ - const std::unordered_map &audioEnhanceSupportedSceneTypes = - GetEnhanceSupportedSceneType(); - auto item = audioEnhanceSupportedSceneTypes.find(nodeInfo.effectInfo.enhanceScene); - if (item != audioEnhanceSupportedSceneTypes.end()) { - sceneType_ = item->second; - AUDIO_INFO_LOG("HpaeCaptureEffectNode created scenetype: [%{public}s]", sceneType_.c_str()); - } else { - AUDIO_ERR_LOG("scenetype: %{public}u not supported", nodeInfo.effectInfo.enhanceScene); - } -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_ = std::make_unique( - "HpaeCaptureEffectNode_id_" + std::to_string(GetNodeId()) + "_" + sceneType_ + "_Out.pcm"); -#endif -} - -HpaeCaptureEffectNode::HpaeCaptureEffectNode(std::vector &nodeInfos) - : HpaeNode(*nodeInfos.begin()), HpaePluginNode(*nodeInfos.begin()) -{ - for (auto &nodeInfo : nodeInfos) { - capturerEffectConfigMap_.emplace(nodeInfo.sourceBufferType, nodeInfo); - } -} - -bool HpaeCaptureEffectNode::Reset() -{ - return HpaePluginNode::Reset(); -} - -HpaePcmBuffer *HpaeCaptureEffectNode::SignalProcess(const std::vector &inputs) -{ - Trace trace("[" + sceneType_ + "]HpaeRenderEffectNode::SignalProcess inputs num[" + - std::to_string(inputs.size()) + "]"); - if (inputs.empty()) { - AUDIO_WARNING_LOG("HpaeCaptureEffectNode inputs size is empty, SessionId:%{public}d", GetSessionId()); - return nullptr; - } - - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - uint32_t processLength = 0; - uint32_t outputIndex = 0; - for (uint32_t i = 0; i < inputs.size(); i++) { - if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_MIC) { - ConvertFromFloat(SAMPLE_S16LE, micBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE), - inputs[i]->GetPcmDataBuffer(), static_cast(cacheDataIn_.data())); - audioEnhanceChainManager->CopyToEnhanceBuffer(static_cast(cacheDataIn_.data()), micBufferLength_); - processLength = micBufferLength_; - outputIndex = i; - AUDIO_DEBUG_LOG("CopyToEnhanceBuffer size:%{public}u", processLength); - } else if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_EC) { - ConvertFromFloat(SAMPLE_S16LE, ecBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE), - inputs[i]->GetPcmDataBuffer(), static_cast(cacheDataIn_.data())); - audioEnhanceChainManager->CopyEcToEnhanceBuffer(static_cast(cacheDataIn_.data()), ecBufferLength_); - AUDIO_DEBUG_LOG("CopyEcToEnhanceBuffer size:%{public}u", ecBufferLength_); - } else if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_MICREF) { - ConvertFromFloat(SAMPLE_S16LE, micrefBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE), - inputs[i]->GetPcmDataBuffer(), static_cast(cacheDataIn_.data())); - audioEnhanceChainManager->CopyMicRefToEnhanceBuffer(static_cast(cacheDataIn_.data()), - micrefBufferLength_); - AUDIO_DEBUG_LOG("CopyMicRefToEnhanceBuffer size:%{public}u", micrefBufferLength_); - } - cacheDataIn_.clear(); - } - int32_t ret = audioEnhanceChainManager->ApplyAudioEnhanceChain(sceneKeyCode_, processLength); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, inputs[outputIndex], "effect apply failed, ret:%{public}d", ret); - audioEnhanceChainManager->CopyFromEnhanceBuffer(static_cast(cacheDataOut_.data()), processLength); - ConvertToFloat(SAMPLE_S16LE, micBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE), - static_cast(cacheDataOut_.data()), inputs[outputIndex]->GetPcmDataBuffer()); -#ifdef ENABLE_HOOK_PCM - if (outputPcmDumper_) { - outputPcmDumper_->Dump((int8_t *)inputs[outputIndex]->GetPcmDataBuffer(), - micBufferLength_ / GET_SIZE_FROM_FORMAT(SAMPLE_S16LE) * sizeof(float)); - } -#endif - return inputs[outputIndex]; -} - -void HpaeCaptureEffectNode::ConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) -{ - std::shared_ptr realPreNode = preNode->GetSharedInstance(nodeInfo); - inputStream_.Connect(realPreNode, preNode->GetOutputPort(nodeInfo)); -#ifdef ENABLE_HIDUMP_DFX - if (auto callback = realPreNode->GetNodeInfo().statusCallback.lock()) { - callback->OnNotifyDfxNodeInfo( - true, realPreNode->GetNodeId(), GetNodeInfo()); - } -#endif -} - -void HpaeCaptureEffectNode::DisConnectWithInfo(const std::shared_ptr>& preNode, - HpaeNodeInfo &nodeInfo) -{ - inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true)); -} - -bool HpaeCaptureEffectNode::GetCapturerEffectConfig(HpaeNodeInfo& nodeInfo, HpaeSourceBufferType type) -{ - CHECK_AND_RETURN_RET_LOG(capturerEffectConfigMap_.find(type) != capturerEffectConfigMap_.end(), - false, "not need resample node, type:%{public}u", type); - nodeInfo = capturerEffectConfigMap_[type]; - return true; -} - -void HpaeCaptureEffectNode::SetCapturerEffectConfig(AudioBufferConfig micConfig, AudioBufferConfig ecConfig, - AudioBufferConfig micrefConfig) -{ - HpaeNodeInfo micInfo = {}; - HpaeNodeInfo ecInfo = {}; - HpaeNodeInfo micrefInfo = {}; - micInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC; - micInfo.frameLen = FRAME_LEN * (micConfig.samplingRate / MILLISECOND_PER_SECOND); - micInfo.samplingRate = static_cast(micConfig.samplingRate); - micInfo.channels = static_cast(micConfig.channels); - micInfo.format = static_cast(micConfig.format / BITLENGTH - 1); - ecInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_EC; - ecInfo.frameLen = FRAME_LEN * (ecConfig.samplingRate / MILLISECOND_PER_SECOND); - ecInfo.samplingRate = static_cast(ecConfig.samplingRate); - ecInfo.channels = static_cast(ecConfig.channels); - ecInfo.format = static_cast(ecConfig.format / BITLENGTH - 1); - micrefInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MICREF; - micrefInfo.frameLen = FRAME_LEN * (micrefConfig.samplingRate / MILLISECOND_PER_SECOND); - micrefInfo.samplingRate = static_cast(micrefConfig.samplingRate); - micrefInfo.channels = static_cast(micrefConfig.channels); - micrefInfo.format = static_cast(micrefConfig.format / BITLENGTH - 1); - capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_MIC, micInfo); - capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_EC, ecInfo); - capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_MICREF, micrefInfo); -} - -int32_t HpaeCaptureEffectNode::CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr) -{ - sceneKeyCode_ = sceneKeyCode; - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager, ERR_ILLEGAL_STATE, "audioEnhanceChainManager is nullptr"); - AudioEnhanceDeviceAttr enhanceAttr = {}; - enhanceAttr.micChannels = attr.micChannels; - enhanceAttr.ecChannels = attr.ecChannels; - enhanceAttr.micRefChannels = attr.micRefChannels; - int32_t ret = audioEnhanceChainManager->CreateAudioEnhanceChainDynamic(sceneKeyCode, enhanceAttr); - if (ret != SUCCESS) { - AUDIO_ERR_LOG("CreateAudioEnhanceChainDynamic failed, ret:%{public}d", ret); - } - audioEnhanceChainManager->InitEnhanceBuffer(); - - AudioBufferConfig micConfig = {}; - AudioBufferConfig ecConfig = {}; - AudioBufferConfig micrefConfig = {}; - ret = audioEnhanceChainManager->AudioEnhanceChainGetAlgoConfig(sceneKeyCode, micConfig, ecConfig, micrefConfig); - if (ret != 0 || micConfig.samplingRate == 0) { - AUDIO_ERR_LOG("get algo config failed, ret:%{public}d", ret); - return ERROR; - } - SetCapturerEffectConfig(micConfig, ecConfig, micrefConfig); - micBufferLength_ = FRAME_LEN * micConfig.channels * (micConfig.samplingRate / MILLISECOND_PER_SECOND) * - (micConfig.format / BITLENGTH); - ecBufferLength_ = FRAME_LEN * ecConfig.channels * (ecConfig.samplingRate / MILLISECOND_PER_SECOND) * - (ecConfig.format / BITLENGTH); - micrefBufferLength_ = FRAME_LEN * micrefConfig.channels * (micrefConfig.samplingRate / MILLISECOND_PER_SECOND) * - (micrefConfig.format / BITLENGTH); - uint32_t maxLength = (micBufferLength_ > ecBufferLength_) ? - (micBufferLength_ > micrefBufferLength_ ? micBufferLength_ : micrefBufferLength_) : - (ecBufferLength_ > micrefBufferLength_ ? ecBufferLength_ : micrefBufferLength_); - AUDIO_INFO_LOG("micLength: %{public}u, ecLength: %{public}u, micrefLength: %{public}u, maxLength:%{public}u", - micBufferLength_, ecBufferLength_, micrefBufferLength_, maxLength); - cacheDataIn_.resize(maxLength); - cacheDataOut_.resize(maxLength); - return ret; -} - -int32_t HpaeCaptureEffectNode::CaptureEffectRelease(uint64_t sceneKeyCode) -{ - AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager, ERROR_ILLEGAL_STATE, "audioEnhanceChainManager is nullptr"); - return audioEnhanceChainManager->ReleaseAudioEnhanceChainDynamic(sceneKeyCode); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/node/src/hpae_gain_node.cpp b/services/audio_engine/node/src/hpae_gain_node.cpp deleted file mode 100644 index 7c36858d4e..0000000000 --- a/services/audio_engine/node/src/hpae_gain_node.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeGainNode" -#endif - -#include "hpae_gain_node.h" -#include "hpae_pcm_buffer.h" -#include "audio_volume_c.h" -#include "audio_engine_log.h" -#include "audio_utils.h" -#include "securec.h" -#include "volume_tools_c.h" -#include "audio_stream_info.h" -#include "hpae_info.h" - -#include -#include - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -static constexpr float FADE_LOW = 0.0f; -static constexpr float FADE_HIGH = 1.0f; -static constexpr float SHORT_FADE_PERIOD = 0.005f; // 5ms fade for 10ms < playback duration <= 40ms -static constexpr float EPSILON = 1e-6f; - -HpaeGainNode::HpaeGainNode(HpaeNodeInfo &nodeInfo) : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo) -{ - float curSystemGain = GetCurVolumeByStreamType(GetSessionId(), (int32_t)GetStreamType(), GetDeviceClass().c_str()); - SetPreVolume(GetSessionId(), curSystemGain); - AUDIO_INFO_LOG("HpaeGainNode curSystemGain:%{public}f streamType :%{public}d", curSystemGain, GetStreamType()); - AUDIO_INFO_LOG( - "HpaeGainNode SessionId:%{public}u deviceClass :%{public}s", GetSessionId(), GetDeviceClass().c_str()); -#ifdef ENABLE_HOOK_PCM - inputPcmDumper_ = std::make_unique("HpaeGainNodeInput_id_" + std::to_string(GetSessionId()) + - "_ch_" + std::to_string(GetChannelCount()) + "_rate_" + - std::to_string(GetSampleRate()) + "_" + GetTime() + ".pcm"); - outputPcmDumper_ = std::make_unique("HpaeGainNodeOut_id_" + std::to_string(GetSessionId()) + "_ch_" + - std::to_string(GetChannelCount()) + "_rate_" + - std::to_string(GetSampleRate()) + "_" + GetTime() + ".pcm"); -#endif -} - -HpaePcmBuffer *HpaeGainNode::SignalProcess(const std::vector &inputs) -{ - if (inputs.empty()) { - AUDIO_WARNING_LOG("HpaeGainNode inputs size is empty, SessionId:%{public}d", GetSessionId()); - return nullptr; - } - auto rate = "rate[" + std::to_string(inputs[0]->GetSampleRate()) + "]_"; - auto ch = "ch[" + std::to_string(inputs[0]->GetChannelCount()) + "]_"; - auto len = "len[" + std::to_string(inputs[0]->GetFrameLen()) + "]"; - Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeGainNode::SignalProcess " + rate + ch + len); - if (fadeOutState_ == FadeOutState::DONE_FADEOUT) { - AUDIO_INFO_LOG("HpaeGainNode: fadeout done, set session %{public}d slience", GetSessionId()); - SlienceData(inputs[0]); - } - float *inputData = (float *)inputs[0]->GetPcmDataBuffer(); - uint32_t frameLen = inputs[0]->GetFrameLen(); - uint32_t channelCount = inputs[0]->GetChannelCount(); - -#ifdef ENABLE_HOOK_PCM - if (inputPcmDumper_ != nullptr) { - inputPcmDumper_->Dump((int8_t *)(inputData), (frameLen * sizeof(float) * channelCount)); - } -#endif - - if (needGainState_) { - DoGain(inputs[0], frameLen, channelCount); - } - DoFading(inputs[0]); - -#ifdef ENABLE_HOOK_PCM - if (outputPcmDumper_ != nullptr) { - outputPcmDumper_->Dump((int8_t *)(inputData), (frameLen * sizeof(float) * channelCount)); - } -#endif - return inputs[0]; -} - -bool HpaeGainNode::SetClientVolume(float gain) -{ - preGain_ = curGain_; - curGain_ = gain; - isGainChanged_ = true; - return true; -} - -float HpaeGainNode::GetClientVolume() -{ - return curGain_; -} - -void HpaeGainNode::SetFadeState(IOperation operation) -{ - operation_ = operation; - // fade in - if (operation_ == OPERATION_STARTED) { - if (fadeInState_ == false) { // todo: add operation for softstart - fadeInState_ = true; - AUDIO_INFO_LOG("need to fade in"); - } else { - AUDIO_WARNING_LOG("fadeInState already set"); - } - fadeOutState_ = FadeOutState::NO_FADEOUT; // reset fadeOutState_ - } - - // fade out - if (operation_ == OPERATION_PAUSED || operation_ == OPERATION_STOPPED) { - if (fadeOutState_ == FadeOutState::NO_FADEOUT) { - fadeOutState_ = FadeOutState::DO_FADEOUT; - AUDIO_INFO_LOG("need to fade out"); - } else { - AUDIO_WARNING_LOG("current fadeout state %{public}d, cannot prepare fadeout", fadeOutState_); - } - } - AUDIO_DEBUG_LOG("fadeInState_[%{public}d], fadeOutState_[%{public}d]", fadeInState_, fadeOutState_); -} - - -void HpaeGainNode::DoFading(HpaePcmBuffer *input) -{ - if (!input->IsValid() && fadeOutState_ == FadeOutState::DO_FADEOUT) { - AUDIO_WARNING_LOG("after drain, get invalid data, no need to do fade out"); - fadeOutState_ = FadeOutState::DONE_FADEOUT; - auto statusCallback = GetNodeStatusCallback().lock(); - CHECK_AND_RETURN_LOG(statusCallback != nullptr, "statusCallback is null, cannot callback"); - statusCallback->OnFadeDone(GetSessionId(), operation_); - } - AudioRawFormat rawFormat; - rawFormat.format = SAMPLE_F32LE; // for now PCM in gain node is float32 - rawFormat.channels = GetChannelCount(); - uint32_t byteLength = 0; - uint8_t *data = (uint8_t *)input->GetPcmDataBuffer(); - switch (GetNodeInfo().fadeType) { - case FadeType::NONE_FADE: { - break; - } - case FadeType::SHORT_FADE: { - byteLength = (float)GetSampleRate() * SHORT_FADE_PERIOD * rawFormat.channels * sizeof(float); - AUDIO_DEBUG_LOG("GainNode: short fade length in Bytes: %{public}u", byteLength); - break; - } - case FadeType::DEFAULT_FADE: { - byteLength = input->Size(); - AUDIO_DEBUG_LOG("GainNode: default fade length in Bytes: %{public}u", byteLength); - break; - } - default: - break; - } - AUDIO_DEBUG_LOG("Final fade in/out length of GainNode in Bytes: %{public}u.", byteLength); - if (fadeInState_) { - CHECK_AND_RETURN_LOG(input->IsValid(), "GainNode: invalid data no need to do fade in"); - CHECK_AND_RETURN_LOG(!IsSilentData(input), "GainNode: silent data no need to do fade in"); - AUDIO_INFO_LOG("GainNode: fade in started!"); - ProcessVol(data, byteLength, rawFormat, FADE_LOW, FADE_HIGH); - fadeInState_ = false; - } - if (fadeOutState_ == FadeOutState::DO_FADEOUT) { - AUDIO_INFO_LOG("GainNode: fade out started!"); - ProcessVol(data, byteLength, rawFormat, FADE_HIGH, FADE_LOW); - fadeOutState_ = FadeOutState::DONE_FADEOUT; - return; - } - if (fadeOutState_ == FadeOutState::DONE_FADEOUT) { - AUDIO_INFO_LOG("fade out done, session %{public}d callback to update status", GetSessionId()); - auto statusCallback = GetNodeStatusCallback().lock(); - CHECK_AND_RETURN_LOG(statusCallback != nullptr, "statusCallback is null, cannot callback"); - statusCallback->OnFadeDone(GetSessionId(), operation_); // if operation is stop or pause, callback - } -} - -void HpaeGainNode::SlienceData(HpaePcmBuffer *pcmBuffer) -{ - void *data = pcmBuffer->GetPcmDataBuffer(); - if (GetNodeInfo().format == INVALID_WIDTH) { - AUDIO_WARNING_LOG("HpaePcmBuffer.SetDataSlience: invalid format"); - } else if (GetNodeInfo().format == SAMPLE_U8) { - // set silence data for all the frames - memset_s(data, pcmBuffer->Size(), 0x80, pcmBuffer->Size()); - } else { - memset_s(data, pcmBuffer->Size(), 0, pcmBuffer->Size()); - } -} - -void HpaeGainNode::DoGain(HpaePcmBuffer *input, uint32_t frameLen, uint32_t channelCount) -{ - float *inputData = (float *)input->GetPcmDataBuffer(); - float curSystemGain = GetCurVolumeByStreamType(GetSessionId(), (int32_t)GetStreamType(), GetDeviceClass().c_str()); - float preSystemGain = GetPreVolume(GetSessionId()); - float systemStepGain = (curSystemGain - preSystemGain) / frameLen; - AUDIO_DEBUG_LOG( - "curSystemGain:%{public}f, preSystemGain:%{public}f, systemStepGain:%{public}f deviceClass :%{public}s", - curSystemGain, - preSystemGain, - systemStepGain, - GetDeviceClass().c_str()); - SetPreVolume(GetSessionId(), curSystemGain); - for (uint32_t i = 0; i < frameLen; i++) { - for (uint32_t j = 0; j < channelCount; j++) { - inputData[channelCount * i + j] = inputData[channelCount * i + j] * (preSystemGain + systemStepGain * i); - } - } -} - -bool HpaeGainNode::IsSilentData(HpaePcmBuffer *pcmBuffer) -{ - float *data = pcmBuffer->GetPcmDataBuffer(); - size_t length = pcmBuffer->Size() / sizeof(float); - AUDIO_DEBUG_LOG("HpaeGainNode::Data length:%{public}zu", length); - return std::all_of(data, data + length, [](float value) { - return fabs(value) < EPSILON; - }); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_inner_cap_sink_node.cpp b/services/audio_engine/node/src/hpae_inner_cap_sink_node.cpp deleted file mode 100644 index 74e1b66c53..0000000000 --- a/services/audio_engine/node/src/hpae_inner_cap_sink_node.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeInnerCapSinkNode" -#endif - -#include "hpae_inner_cap_sink_node.h" -#include "hpae_format_convert.h" -#include "audio_errors.h" -#include "audio_policy_log.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif -#include -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -const int32_t DEFAULT_NANO_SECONDS = 20000000; -const int32_t NANO_SECONDS = 1000000; - -HpaeInnerCapSinkNode::HpaeInnerCapSinkNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), outputStream_(this), - pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), silenceData_(pcmBufferInfo_) -{ - silenceData_.Reset(); -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_ = std::make_unique("HpaeInnerCapSinkNode_bit_" + - std::to_string(GetBitWidth()) + "_ch_" + std::to_string(GetChannelCount()) + - "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); -#endif -} - -void HpaeInnerCapSinkNode::DoProcess() -{ - std::vector &outputVec = inputStream_.ReadPreOutputData(); - if (outputVec.empty()) { - outputStream_.WriteDataToOutput(&silenceData_); - } else { - HpaePcmBuffer *outputData = outputVec.front(); -#ifdef ENABLE_HOOK_PCM - if (outputPcmDumper_) { - outputPcmDumper_->Dump((int8_t *)outputData->GetPcmDataBuffer(), GetChannelCount() * - GetFrameLen() * GET_SIZE_FROM_FORMAT(GetBitWidth())); - } -#endif - // no need convert - outputStream_.WriteDataToOutput(outputVec[0]); - } - // sleep - intervalTimer_.Stop(); - auto elapsed = intervalTimer_.Elapsed(); - std::this_thread::sleep_for(std::chrono::nanoseconds(DEFAULT_NANO_SECONDS - elapsed)); - AUDIO_DEBUG_LOG("sleeptime : %{public}f", DEFAULT_NANO_SECONDS - ((static_cast(elapsed))/NANO_SECONDS)); - intervalTimer_.Start(); -} - -bool HpaeInnerCapSinkNode::Reset() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - inputStream_.DisConnect(output); - } - return true; -} - -bool HpaeInnerCapSinkNode::ResetAll() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - std::shared_ptr hpaeNode = preOutput.second; - if (hpaeNode->ResetAll()) { - inputStream_.DisConnect(output); - } - } - return true; -} - -// todo -std::shared_ptr HpaeInnerCapSinkNode::GetSharedInstance() -{ - return shared_from_this(); -} - -// todo -OutputPort *HpaeInnerCapSinkNode::GetOutputPort() -{ - return &outputStream_; -} - -void HpaeInnerCapSinkNode::Connect(const std::shared_ptr>& preNode) -{ - AUDIO_INFO_LOG("Connect"); - inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); -} - -void HpaeInnerCapSinkNode::DisConnect(const std::shared_ptr>& preNode) -{ - AUDIO_INFO_LOG("DisConnect"); - inputStream_.DisConnect(preNode->GetOutputPort()); -} - -int32_t HpaeInnerCapSinkNode::InnerCapturerSinkInit() -{ - AUDIO_INFO_LOG("Init"); - state_ = RENDERER_NEW; - return SUCCESS; -} - -int32_t HpaeInnerCapSinkNode::InnerCapturerSinkDeInit() -{ - AUDIO_INFO_LOG("DeInit"); - state_ = RENDERER_INVALID; - return SUCCESS; -} - -int32_t HpaeInnerCapSinkNode::InnerCapturerSinkFlush() -{ - AUDIO_INFO_LOG("Flush"); - return SUCCESS; -} - -int32_t HpaeInnerCapSinkNode::InnerCapturerSinkPause() -{ - AUDIO_INFO_LOG("Pause"); - state_ = RENDERER_PAUSED; - return SUCCESS; -} - -int32_t HpaeInnerCapSinkNode::InnerCapturerSinkReset() -{ - AUDIO_INFO_LOG("Reset"); - return SUCCESS; -} - -int32_t HpaeInnerCapSinkNode::InnerCapturerSinkResume() -{ - AUDIO_INFO_LOG("Resume"); - state_ = RENDERER_RUNNING; - return SUCCESS; -} - -int32_t HpaeInnerCapSinkNode::InnerCapturerSinkStart() -{ - AUDIO_INFO_LOG("Start"); - state_ = RENDERER_RUNNING; - return SUCCESS; -} - -int32_t HpaeInnerCapSinkNode::InnerCapturerSinkStop() -{ - AUDIO_INFO_LOG("Stop"); - state_ = RENDERER_STOPPED; - return SUCCESS; -} - -RendererState HpaeInnerCapSinkNode::GetSinkState(void) -{ - return state_; -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_mixer_node.cpp b/services/audio_engine/node/src/hpae_mixer_node.cpp deleted file mode 100644 index 41c2f5d6dc..0000000000 --- a/services/audio_engine/node/src/hpae_mixer_node.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeMixerNode" -#endif -#include -#include "hpae_mixer_node.h" -#include "hpae_pcm_buffer.h" -#include "audio_utils.h" -#include "cinttypes" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaeMixerNode::HpaeMixerNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), - pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout), - mixedOutput_(pcmBufferInfo_) -{ -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_ = std::make_unique("HpaeMixerNodeOut_ch_" + - std::to_string(nodeInfo.channels) + "_scenType_" + - std::to_string(GetSceneType()) + "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); - AUDIO_INFO_LOG("HpaeMixerNode scene type is %{public}d", GetSceneType()); -#endif -} - -bool HpaeMixerNode::Reset() -{ - return HpaePluginNode::Reset(); -} - -HpaePcmBuffer *HpaeMixerNode::SignalProcess(const std::vector &inputs) -{ - Trace trace("HpaeMixerNode::SignalProcess"); - CHECK_AND_RETURN_RET_LOG(!inputs.empty(), nullptr, "inputs is empty"); - - mixedOutput_.Reset(); - - bool isPCMBufferInfoUpdated = false; - if (pcmBufferInfo_.ch != inputs[0]->GetChannelCount()) { - AUDIO_INFO_LOG("Update channel count: %{public}d -> %{public}d", - pcmBufferInfo_.ch, inputs[0]->GetChannelCount()); - pcmBufferInfo_.ch = inputs[0]->GetChannelCount(); - isPCMBufferInfoUpdated = true; - } - if (pcmBufferInfo_.frameLen != inputs[0]->GetFrameLen()) { - AUDIO_INFO_LOG("Update frame len %{public}d -> %{public}d", - pcmBufferInfo_.frameLen, inputs[0]->GetFrameLen()); - pcmBufferInfo_.frameLen = inputs[0]->GetFrameLen(); - isPCMBufferInfoUpdated = true; - } - if (pcmBufferInfo_.rate != inputs[0]->GetSampleRate()) { - AUDIO_INFO_LOG("Update sample rate %{public}d -> %{public}d", - pcmBufferInfo_.rate, inputs[0]->GetSampleRate()); - pcmBufferInfo_.rate = inputs[0]->GetSampleRate(); - isPCMBufferInfoUpdated = true; - } - if (pcmBufferInfo_.channelLayout != inputs[0]->GetChannelLayout()) { - AUDIO_INFO_LOG("Update channel layout %{public}" PRIu64 " -> %{public}" PRIu64 "", - pcmBufferInfo_.channelLayout, inputs[0]->GetChannelLayout()); - pcmBufferInfo_.channelLayout = inputs[0]->GetChannelLayout(); - isPCMBufferInfoUpdated = true; - } - // if other bitwidth is supported, add check here - - if (isPCMBufferInfoUpdated) { - mixedOutput_.ReConfig(pcmBufferInfo_); - } - - for (auto input : inputs) { - mixedOutput_ += *input; - } -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_->CheckAndReopenHandlde(); - outputPcmDumper_->Dump((int8_t *)(mixedOutput_.GetPcmDataBuffer()), - mixedOutput_.GetChannelCount() * sizeof(float) * mixedOutput_.GetFrameLen()); -#endif - return &mixedOutput_; -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_node_common.cpp b/services/audio_engine/node/src/hpae_node_common.cpp deleted file mode 100644 index d584a0aef3..0000000000 --- a/services/audio_engine/node/src/hpae_node_common.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2025 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 "hpae_node_common.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -static constexpr uint64_t TIME_US_PER_S = 1000000; -static std::map g_streamTypeToSceneTypeMap = { - {STREAM_MUSIC, HPAE_SCENE_MUSIC}, - {STREAM_GAME, HPAE_SCENE_GAME}, - {STREAM_MOVIE, HPAE_SCENE_MOVIE}, - {STREAM_GAME, HPAE_SCENE_GAME}, - {STREAM_SPEECH, HPAE_SCENE_SPEECH}, - {STREAM_VOICE_RING, HPAE_SCENE_RING}, - {STREAM_VOICE_COMMUNICATION, HPAE_SCENE_VOIP_DOWN}, - {STREAM_MEDIA, HPAE_SCENE_OTHERS} -}; - -static std::unordered_map g_sourceTypeToSceneTypeMap = { - {SOURCE_TYPE_MIC, HPAE_SCENE_RECORD}, - {SOURCE_TYPE_CAMCORDER, HPAE_SCENE_RECORD}, - {SOURCE_TYPE_VOICE_CALL, HPAE_SCENE_VOIP_UP}, - {SOURCE_TYPE_VOICE_COMMUNICATION, HPAE_SCENE_VOIP_UP}, - {SOURCE_TYPE_VOICE_TRANSCRIPTION, HPAE_SCENE_PRE_ENHANCE}, - {SOURCE_TYPE_VOICE_MESSAGE, HPAE_SCENE_VOICE_MESSAGE} -}; - - -static std::unordered_set g_processorTypeNeedEcSet = { - HPAE_SCENE_VOIP_UP, - HPAE_SCENE_PRE_ENHANCE, -}; - -static std::unordered_set g_processorTypeNeedMicRefSet = { - HPAE_SCENE_VOIP_UP, - HPAE_SCENE_RECORD, -}; - -static std::unordered_map g_processorTypeToSceneTypeMap = { - {HPAE_SCENE_RECORD, SCENE_RECORD}, - {HPAE_SCENE_VOIP_UP, SCENE_VOIP_UP}, - {HPAE_SCENE_PRE_ENHANCE, SCENE_PRE_ENHANCE}, - {HPAE_SCENE_VOICE_MESSAGE, SCENE_VOICE_MESSAGE} -}; - -HpaeProcessorType TransStreamTypeToSceneType(AudioStreamType streamType) -{ - if (g_streamTypeToSceneTypeMap.find(streamType) == g_streamTypeToSceneTypeMap.end()) { - return HPAE_SCENE_EFFECT_NONE; - } else { - return g_streamTypeToSceneTypeMap[streamType]; - } -} - -HpaeProcessorType TransSourceTypeToSceneType(SourceType sourceType) -{ - if (g_sourceTypeToSceneTypeMap.find(sourceType) == g_sourceTypeToSceneTypeMap.end()) { - return HPAE_SCENE_EFFECT_NONE; - } else { - return g_sourceTypeToSceneTypeMap[sourceType]; - } -} - -bool CheckSceneTypeNeedEc(HpaeProcessorType processorType) -{ - return g_processorTypeNeedEcSet.find(processorType) != g_processorTypeNeedEcSet.end(); -} - -bool CheckSceneTypeNeedMicRef(HpaeProcessorType processorType) -{ - return g_processorTypeNeedMicRefSet.find(processorType) != g_processorTypeNeedMicRefSet.end(); -} - -static std::unordered_map g_processorTypeToEffectSceneTypeMap = { - {HPAE_SCENE_OTHERS, "SCENE_OTHERS"}, - {HPAE_SCENE_MUSIC, "SCENE_MUSIC"}, - {HPAE_SCENE_GAME, "SCENE_GAME"}, - {HPAE_SCENE_MOVIE, "SCENE_MOVIE"}, - {HPAE_SCENE_SPEECH, "SCENE_SPEECH"}, - {HPAE_SCENE_RING, "SCENE_RING"}, - {HPAE_SCENE_VOIP_DOWN, "SCENE_VOIP_DOWN"}}; - -std::string TransProcessorTypeToSceneType(HpaeProcessorType processorType) -{ - if (g_processorTypeToEffectSceneTypeMap.find(processorType) == g_processorTypeToEffectSceneTypeMap.end()) { - return "SCENE_EXTRA"; - } else { - return g_processorTypeToEffectSceneTypeMap[processorType]; - } -} - -bool CheckHpaeNodeInfoIsSame(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &curNodeInfo) -{ - return preNodeInfo.channels == curNodeInfo.channels && //&& preNodeInfo.format == curNodeInfo.format todo - preNodeInfo.samplingRate == curNodeInfo.samplingRate && - preNodeInfo.channelLayout == curNodeInfo.channelLayout; -} - -std::string TransHpaeResampleNodeInfoToStringKey(HpaeNodeInfo& nodeInfo) -{ - std::string nodeKey = std::to_string(nodeInfo.sourceBufferType) + "_" + - std::to_string(nodeInfo.samplingRate) + "_" + - std::to_string(nodeInfo.channels) + "_" + - std::to_string(nodeInfo.format); - return nodeKey; -} - -AudioEnhanceScene TransProcessType2EnhanceScene(const HpaeProcessorType &processorType) -{ - if (g_processorTypeToSceneTypeMap.find(processorType) == g_processorTypeToSceneTypeMap.end()) { - return SCENE_NONE; - } else { - return g_processorTypeToSceneTypeMap[processorType]; - } -} - -size_t ConvertUsToFrameCount(uint64_t usTime, const HpaeNodeInfo &nodeInfo) -{ - return usTime * nodeInfo.samplingRate / TIME_US_PER_S / - (nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); -} - -uint64_t ConvertDatalenToUs(size_t bufferSize, const HpaeNodeInfo &nodeInfo) -{ - if (nodeInfo.channels == 0 || GET_SIZE_FROM_FORMAT(nodeInfo.format) == 0 || nodeInfo.samplingRate == 0) { - AUDIO_ERR_LOG("invalid nodeInfo"); - return 0; - } - - double samples = static_cast(bufferSize) / - (nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); - double seconds = samples / static_cast(nodeInfo.samplingRate); - double microseconds = seconds * TIME_US_PER_S; - - return static_cast(microseconds); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp deleted file mode 100644 index 374499e47c..0000000000 --- a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeOffloadSinkOutputNode" -#endif - -#include "hpae_offload_sinkoutput_node.h" -#include "audio_errors.h" -#include -#include "hpae_format_convert.h" -#include "hpae_node_common.h" -#include "audio_engine_log.h" -#include "audio_volume.h" -#include "audio_common_utils.h" -#include "inttypes.h" -#ifdef ENABLE_HOOK_PCM -#include "hpae_pcm_dumper.h" -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -namespace { - constexpr uint32_t CACHE_FRAME_COUNT = 2; - constexpr uint32_t TIME_US_PER_MS = 1000; - constexpr uint32_t TIME_MS_PER_SEC = 1000; - constexpr uint32_t ERR_RETRY_COUNT = 20; - constexpr uint32_t FRAME_TIME_IN_MS = 20; - constexpr int32_t OFFLOAD_FULL = -1; - constexpr int32_t OFFLOAD_WRITE_FAILED = -2; - constexpr uint32_t OFFLOAD_HDI_CACHE_BACKGROUND_IN_MS = 7000; - constexpr uint32_t OFFLOAD_HDI_CACHE_FRONTGROUND_IN_MS = 200; - // hdi fallback, modify when hdi change - constexpr uint32_t OFFLOAD_FAD_INTERVAL_IN_US = 180; - constexpr uint32_t OFFLOAD_SET_BUFFER_SIZE_NUM = 5; - constexpr uint32_t POLICY_STATE_DELAY_IN_SEC = 3; - - const std::string DEVICE_CLASS_OFFLOAD = "offload"; -} -HpaeOffloadSinkOutputNode::HpaeOffloadSinkOutputNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), - renderFrameData_(nodeInfo.frameLen * nodeInfo.channels * - GET_SIZE_FROM_FORMAT(nodeInfo.format) * CACHE_FRAME_COUNT), - interleveData_(nodeInfo.frameLen * nodeInfo.channels) -{ -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_ = std::make_unique( - "HpaeOffloadSinkOutputNode_Out_bit_" + std::to_string(GetBitWidth()) + "_ch_" + - std::to_string(GetChannelCount()) + "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); -#endif - frameLenMs_ = nodeInfo.frameLen * TIME_MS_PER_SEC / nodeInfo.samplingRate; -} - -bool HpaeOffloadSinkOutputNode::CheckIfSuspend() -{ - static uint32_t suspendCount = 0; - if (!GetPreOutNum()) { - suspendCount++; - usleep(TIME_US_PER_MS * FRAME_TIME_IN_MS); - if (suspendCount > timeoutThdFrames_) { - RenderSinkStop(); - } - return true; - } else { - suspendCount = 0; - return false; - } -} - -void HpaeOffloadSinkOutputNode::DoProcess() -{ - CHECK_AND_RETURN_LOG(audioRendererSink_, "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - if (CheckIfSuspend()) { - return; - } - // if there are no enough frames in cache, read more data from pre-output - size_t frameSize = GET_SIZE_FROM_FORMAT(GetBitWidth()) * GetFrameLen() * GetChannelCount(); - while (renderFrameData_.size() < CACHE_FRAME_COUNT * frameSize) { - std::vector &outputVec = inputStream_.ReadPreOutputData(); - if (outputVec.front()->IsValid()) { - renderFrameData_.resize(renderFrameData_.size() + frameSize); - ConvertFromFloat(GetBitWidth(), GetChannelCount() * GetFrameLen(), - outputVec.front()->GetPcmDataBuffer(), renderFrameData_.data() + renderFrameData_.size() - frameSize); - } else { - break; - } - } - int32_t ret = ProcessRenderFrame(); - // if renderframe faild, sleep and return directly - // if renderframe full, unlock the powerlock - static uint32_t retryCount = 1; - if (ret != SUCCESS) { - if (ret == OFFLOAD_FULL) { - RunningLock(false); - isHdiFull_.store(true); - return; - } - usleep(std::min(retryCount, FRAME_TIME_IN_MS) * TIME_US_PER_MS); - if (retryCount < ERR_RETRY_COUNT) { - retryCount++; - } - return; - } - retryCount = 1; - return; -} - -bool HpaeOffloadSinkOutputNode::Reset() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - inputStream_.DisConnect(output); - } - return true; -} - -bool HpaeOffloadSinkOutputNode::ResetAll() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - std::shared_ptr hpaeNode = preOutput.second; - if (hpaeNode->ResetAll()) { - inputStream_.DisConnect(output); - } - } - return true; -} - -void HpaeOffloadSinkOutputNode::Connect(const std::shared_ptr> &preNode) -{ - inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); -} - -void HpaeOffloadSinkOutputNode::DisConnect(const std::shared_ptr> &preNode) -{ - inputStream_.DisConnect(preNode->GetOutputPort()); -} - -int32_t HpaeOffloadSinkOutputNode::GetRenderSinkInstance(const std::string &deviceClass, - const std::string &deviceNetworkId) -{ - renderId_ = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass( - deviceClass, HDI_ID_INFO_DEFAULT, true); - audioRendererSink_ = HdiAdapterManager::GetInstance().GetRenderSink(renderId_, true); - if (audioRendererSink_ == nullptr) { - AUDIO_ERR_LOG("get offload sink fail, deviceClass: %{public}s, renderId_: %{public}u", - deviceClass.c_str(), renderId_); - HdiAdapterManager::GetInstance().ReleaseId(renderId_); - return ERROR; - } - return SUCCESS; -} - -void HpaeOffloadSinkOutputNode::OffloadReset() -{ - writePos_ = 0; - hdiPos_ = std::make_pair(0, std::chrono::high_resolution_clock::now()); - firstWriteHdi_ = true; - isHdiFull_.store(false); - renderFrameData_.clear(); - setPolicyStateTask_.flag = false; // unset the task when reset - RunningLock(true); -} - -int32_t HpaeOffloadSinkOutputNode::RenderSinkInit(IAudioSinkAttr &attr) -{ - CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, - "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - - sinkOutAttr_ = attr; - state_ = RENDERER_PREPARED; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - int32_t ret = audioRendererSink_->Init(attr); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, - "audioRendererSink_ init failed, errCode is %{public}d", ret); -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkInit Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), interval); -#endif - return ret; -} - -int32_t HpaeOffloadSinkOutputNode::RenderSinkDeInit(void) -{ - CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, - "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - state_ = RENDERER_INVALID; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - audioRendererSink_->DeInit(); - audioRendererSink_ = nullptr; - HdiAdapterManager::GetInstance().ReleaseId(renderId_); -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkDeInit Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), interval); -#endif - return SUCCESS; -} - -int32_t HpaeOffloadSinkOutputNode::RenderSinkFlush(void) -{ - CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, - "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - int32_t ret; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - ret = audioRendererSink_->Flush(); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, - "audioRendererSink_ flush failed, errCode is %{public}d", ret); -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkFlush Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), interval); -#endif - return ret; -} - -int32_t HpaeOffloadSinkOutputNode::RenderSinkStart(void) -{ - CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, - "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - - int32_t ret; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - ret = audioRendererSink_->Start(); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, - "audioRendererSink_ start failed, errCode is %{public}d", ret); - RegOffloadCallback(); - // start need lock - RunningLock(true); - OffloadSetHdiVolume(); -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkStart Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), interval); -#endif - state_ = RENDERER_RUNNING; - return SUCCESS; -} - -int32_t HpaeOffloadSinkOutputNode::RenderSinkStop(void) -{ - CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, - "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - int32_t ret; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - ret = audioRendererSink_->Stop(); - OffloadReset(); - RunningLock(false); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, - "audioRendererSink_ stop failed, errCode is %{public}d", ret); -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderSinkStop Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), interval); -#endif - state_ = RENDERER_STOPPED; - return SUCCESS; -} - -void HpaeOffloadSinkOutputNode::FlushStream() -{ - renderFrameData_.clear(); -} - -size_t HpaeOffloadSinkOutputNode::GetPreOutNum() -{ - return inputStream_.GetPreOutputNum(); -} - -RendererState HpaeOffloadSinkOutputNode::GetSinkState(void) -{ - return isHdiFull_.load() ? RENDERER_PAUSED : state_; -} - -const char *HpaeOffloadSinkOutputNode::GetRenderFrameData(void) -{ - return renderFrameData_.data(); -} - -void HpaeOffloadSinkOutputNode::StopStream() -{ - // flush hdi when disconnect - RunningLock(true); - auto ret = RenderSinkFlush(); - CHECK_AND_RETURN_LOG(ret == SUCCESS, "RenderSinkFlush failed"); - uint64_t cacheLenInHdi = CalcOffloadCacheLenInHdi(); - cacheLenInHdi = cacheLenInHdi > OFFLOAD_FAD_INTERVAL_IN_US ? - cacheLenInHdi - OFFLOAD_FAD_INTERVAL_IN_US : 0; - uint64_t rewindTime = cacheLenInHdi + ConvertDatalenToUs(renderFrameData_.size(), GetNodeInfo()); - AUDIO_DEBUG_LOG("OffloadRewindAndFlush rewind time in us %{public}" PRIu64, rewindTime); - auto callback = GetNodeInfo().statusCallback.lock(); - callback->OnRewindAndFlush(rewindTime); - OffloadReset(); -} - -void HpaeOffloadSinkOutputNode::SetPolicyState(int32_t state) -{ - if (setPolicyStateTask_.flag) { - if (state == hdiPolicyState_) { - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: unset policy state task"); - setPolicyStateTask_.flag = false; - } - return; - } - if (hdiPolicyState_ != state && state == OFFLOAD_INACTIVE_BACKGROUND) { - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: set policy state task"); - setPolicyStateTask_.flag = true; - setPolicyStateTask_.time = std::chrono::high_resolution_clock::now(); - setPolicyStateTask_.state = OFFLOAD_INACTIVE_BACKGROUND; - return; - } - hdiPolicyState_ = static_cast(state); - int32_t bufferSize = hdiPolicyState_ == OFFLOAD_INACTIVE_BACKGROUND ? - OFFLOAD_HDI_CACHE_BACKGROUND_IN_MS : OFFLOAD_HDI_CACHE_FRONTGROUND_IN_MS; - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: set hdi buffer size to %{public}d", bufferSize); - audioRendererSink_->SetBufferSize(bufferSize); -} - -uint64_t HpaeOffloadSinkOutputNode::GetLatency() -{ - return CalcOffloadCacheLenInHdi() + ConvertDatalenToUs(renderFrameData_.size(), GetNodeInfo()); -} - -int32_t HpaeOffloadSinkOutputNode::SetTimeoutStopThd(uint32_t timeoutThdMs) -{ - if (frameLenMs_ != 0) { - timeoutThdFrames_ = timeoutThdMs / frameLenMs_; - } - AUDIO_INFO_LOG( - "SetTimeoutStopThd: timeoutThdFrames_:%{public}u, timeoutThdMs :%{public}u", timeoutThdFrames_, timeoutThdMs); - return SUCCESS; -} - -void HpaeOffloadSinkOutputNode::RunningLock(bool islock) -{ - if (islock) { - audioRendererSink_->LockOffloadRunningLock(); - } else if (!islock && hdiPolicyState_ == OFFLOAD_INACTIVE_BACKGROUND) { - // only unlock when background - audioRendererSink_->UnLockOffloadRunningLock(); - } -} - -void HpaeOffloadSinkOutputNode::SetBufferSizeWhileRenderFrame() -{ - // 3s delay works, when change to BACKGROUND - if (setPolicyStateTask_.flag) { - auto now = std::chrono::high_resolution_clock::now(); - if (std::chrono::duration_cast(now - setPolicyStateTask_.time).count() >= - POLICY_STATE_DELAY_IN_SEC) { - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: excute set policy state task"); - setPolicyStateTask_.flag = false; - hdiPolicyState_ = setPolicyStateTask_.state; - audioRendererSink_->SetBufferSize(hdiPolicyState_ == OFFLOAD_INACTIVE_BACKGROUND ? - OFFLOAD_HDI_CACHE_BACKGROUND_IN_MS : OFFLOAD_HDI_CACHE_FRONTGROUND_IN_MS); - } - return; // no need to set buffer size twice at one process - } - // first start need to set buffer size 5 times - if (setHdiBufferSizeNum_ > 0) { - setHdiBufferSizeNum_--; - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: set policy state cause first render"); - audioRendererSink_->SetBufferSize(hdiPolicyState_ == OFFLOAD_INACTIVE_BACKGROUND ? - OFFLOAD_HDI_CACHE_BACKGROUND_IN_MS : OFFLOAD_HDI_CACHE_FRONTGROUND_IN_MS); - } -} - -int32_t HpaeOffloadSinkOutputNode::ProcessRenderFrame() -{ - if (renderFrameData_.empty()) { - return OFFLOAD_WRITE_FAILED; - } - uint64_t writeLen = 0; - char *renderFrameData = (char *)renderFrameData_.data(); -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); - intervalTimer_.Stop(); - uint64_t interval = intervalTimer_.Elapsed(); - AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), interval); -#endif - auto now = std::chrono::high_resolution_clock::now(); - auto ret = audioRendererSink_->RenderFrame(*renderFrameData, renderFrameData_.size(), writeLen); - if (ret == SUCCESS && writeLen == 0 && !firstWriteHdi_) { - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode: offload renderFrame full"); - return OFFLOAD_FULL; - } - if (!(ret == SUCCESS && writeLen == renderFrameData_.size())) { - AUDIO_ERR_LOG("HpaeOffloadSinkOutputNode: offload renderFrame failed, errCode is %{public}d", ret); - return OFFLOAD_WRITE_FAILED; - } - // calc written data length - writePos_ += ConvertDatalenToUs(renderFrameData_.size(), GetNodeInfo()); - // now is the time to first write hdi - if (firstWriteHdi_) { - firstWriteHdi_ = false; - hdiPos_ = std::make_pair(0, now); - setHdiBufferSizeNum_ = OFFLOAD_SET_BUFFER_SIZE_NUM; - // if the hdi is flushing, it will block the volume setting. - // so the render frame judge it. - OffloadSetHdiVolume(); - AUDIO_INFO_LOG("offload write pos: %{public}" PRIu64 " hdi pos: %{public}" PRIu64 " ", - writePos_, hdiPos_.first); - } - // hdi fallback, dont modify - SetBufferSizeWhileRenderFrame(); -#ifdef ENABLE_HOOK_PCM - AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), interval); - if (outputPcmDumper_) { - outputPcmDumper_->Dump((int8_t *)renderFrameData, renderFrameData_.size()); - } - timer.Stop(); - uint64_t elapsed = timer.Elapsed(); - AUDIO_DEBUG_LOG("HpaeOffloadSinkOutputNode :name %{public}s, RenderFrame elapsed time: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), elapsed); - intervalTimer_.Start(); -#endif - renderFrameData_.clear(); - return SUCCESS; -} - -int32_t HpaeOffloadSinkOutputNode::UpdatePresentationPosition() -{ - CHECK_AND_RETURN_RET_LOG(audioRendererSink_, ERR_ILLEGAL_STATE, - "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - uint64_t frames; - int64_t timeSec; - int64_t timeNanoSec; - int ret = audioRendererSink_->GetPresentationPosition(frames, timeSec, timeNanoSec); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetPresentationPosition failed, errCode is %{public}d", ret); - auto total_ns = std::chrono::seconds(timeSec) + std::chrono::nanoseconds(timeNanoSec); - hdiPos_ = std::make_pair(frames, TimePoint(total_ns)); - return 0; -} - -uint64_t HpaeOffloadSinkOutputNode::CalcOffloadCacheLenInHdi() -{ - auto now = std::chrono::high_resolution_clock::now(); - uint64_t time = now > hdiPos_.second ? - std::chrono::duration_cast(now - hdiPos_.second).count() : 0; - uint64_t hdiPos = hdiPos_.first + time; - uint64_t cacheLenInHdi = writePos_ > hdiPos ? (writePos_ - hdiPos) : 0; - AUDIO_DEBUG_LOG("offload latency: %{public}" PRIu64 " write pos: %{public}" PRIu64 - " hdi pos: %{public}" PRIu64 " time: %{public}" PRIu64, - cacheLenInHdi, writePos_, hdiPos, time); - return cacheLenInHdi; -} - -void HpaeOffloadSinkOutputNode::OffloadSetHdiVolume() -{ - struct VolumeValues volumes; - AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(GetStreamType()); - float volumeEnd = AudioVolume::GetInstance()->GetVolume(GetSessionId(), volumeType, DEVICE_CLASS_OFFLOAD, &volumes); - float volumeBeg = AudioVolume::GetInstance()->GetHistoryVolume(GetSessionId()); - if (volumeBeg != volumeEnd) { - AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode::sessionID:%{public}u, volumeBeg:%{public}f, volumeEnd:%{public}f", - GetSessionId(), volumeBeg, volumeEnd); - AudioVolume::GetInstance()->SetHistoryVolume(GetSessionId(), volumeEnd); - AudioVolume::GetInstance()->Monitor(GetSessionId(), true); - } - CHECK_AND_RETURN_LOG(audioRendererSink_, "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - audioRendererSink_->SetVolume(volumeEnd, volumeEnd); -} - -void HpaeOffloadSinkOutputNode::OffloadCallback(const RenderCallbackType type) -{ - switch (type) { - case CB_NONBLOCK_WRITE_COMPLETED: { - if (isHdiFull_.load()) { - RunningLock(true); - UpdatePresentationPosition(); - auto callback = GetNodeInfo().statusCallback.lock(); - isHdiFull_.store(false); - if (callback) { - callback->OnNotifyQueue(); - } - } - break; - } - default: - break; - } -} - -void HpaeOffloadSinkOutputNode::RegOffloadCallback() -{ - CHECK_AND_RETURN_LOG(audioRendererSink_, "audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - audioRendererSink_->RegistOffloadHdiCallback([this](const RenderCallbackType type) { OffloadCallback(type); }); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/node/src/hpae_output_cluster.cpp b/services/audio_engine/node/src/hpae_output_cluster.cpp deleted file mode 100644 index f32fd61d3f..0000000000 --- a/services/audio_engine/node/src/hpae_output_cluster.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeOutputCluster" -#endif - -#include "hpae_output_cluster.h" -#include "hpae_node_common.h" -#include "audio_engine_log.h" -#include "audio_errors.h" -#include "audio_utils.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -HpaeOutputCluster::HpaeOutputCluster(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), mixerNode_(std::make_shared(nodeInfo)), - hpaeSinkOutputNode_(std::make_shared(nodeInfo)) -{ -#ifdef ENABLE_HIDUMP_DFX - if (nodeInfo.statusCallback.lock()) { - nodeInfo.nodeName = "hpaeSinkOutputNode"; - nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); - hpaeSinkOutputNode_->SetNodeInfo(nodeInfo); - nodeInfo.statusCallback.lock()->OnNotifyDfxNodeInfo(true, 0, nodeInfo); - nodeInfo.nodeName = "HpaeMixerNode"; - nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); - mixerNode_->SetNodeInfo(nodeInfo); - nodeInfo.statusCallback.lock()->OnNotifyDfxNodeInfo(true, hpaeSinkOutputNode_->GetNodeId(), nodeInfo); - } -#endif - hpaeSinkOutputNode_->Connect(mixerNode_); - frameLenMs_ = nodeInfo.frameLen * MILLISECOND_PER_SECOND / nodeInfo.samplingRate; - AUDIO_INFO_LOG( - "HpaeOutputCluster frameLenMs_:%{public}u ms, timeoutThdFrames_:%{public}u", frameLenMs_, timeoutThdFrames_); -} - -HpaeOutputCluster::~HpaeOutputCluster() -{ - Reset(); -} - -void HpaeOutputCluster::DoProcess() -{ - Trace trace("HpaeOutputCluster::DoProcess"); - hpaeSinkOutputNode_->DoProcess(); - if (mixerNode_->GetPreOutNum() == 0) { - timeoutStopCount_++; - } else { - timeoutStopCount_ = 0; - } - if (timeoutStopCount_ > timeoutThdFrames_) { - int32_t ret = hpaeSinkOutputNode_->RenderSinkStop(); - timeoutStopCount_ = 0; - AUDIO_INFO_LOG("HpaeOutputCluster timeout RenderSinkStop ret :%{public}d", ret); - } -} - -bool HpaeOutputCluster::Reset() -{ - mixerNode_->Reset(); - for (auto converterNode : sceneConverterMap_) { - converterNode.second->Reset(); - } - hpaeSinkOutputNode_->DisConnect(mixerNode_); -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = hpaeSinkOutputNode_->GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfo(false, hpaeSinkOutputNode_->GetNodeId(), hpaeSinkOutputNode_->GetNodeInfo()); - } -#endif - return true; -} - -bool HpaeOutputCluster::ResetAll() -{ - return hpaeSinkOutputNode_->ResetAll(); // Complete the code here -} - -void HpaeOutputCluster::Connect(const std::shared_ptr> &preNode) -{ - HpaeNodeInfo &preNodeInfo = preNode->GetSharedInstance()->GetNodeInfo(); - HpaeNodeInfo &curNodeInfo = GetNodeInfo(); - HpaeProcessorType sceneType = preNodeInfo.sceneType; - AUDIO_INFO_LOG("HpaeOutputCluster input sceneType is %{public}u", preNodeInfo.sceneType); - AUDIO_INFO_LOG("HpaeOutputCluster input rate is %{public}u, ch is %{public}u", preNodeInfo.samplingRate, preNodeInfo.channels); - AUDIO_INFO_LOG(" HpaeOutputCluster output rate is %{public}u, ch is %{public}u", curNodeInfo.samplingRate, curNodeInfo.channels); - AUDIO_INFO_LOG(" HpaeOutputCluster preNode name %{public}s, curNode name is %{public}s", preNodeInfo.nodeName.c_str(), curNodeInfo.nodeName.c_str()); - AUDIO_INFO_LOG("HpaeOutputCluster mixer id %{public}u, SinkOut id %{public}u", mixerNode_->GetNodeId(), hpaeSinkOutputNode_->GetNodeId()); - -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { - curNodeInfo.nodeId = callBack->OnGetNodeId(); - curNodeInfo.nodeName = "HpaeAudioFormatConverterNode"; - } -#endif - - if (sceneConverterMap_.find(sceneType) == sceneConverterMap_.end()) { - sceneConverterMap_[sceneType] = std::make_shared(preNodeInfo, curNodeInfo); - } else { -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfo(false, mixerNode_->GetNodeId(), sceneConverterMap_[sceneType]->GetNodeInfo()); - } -#endif - sceneConverterMap_.erase(sceneType); - sceneConverterMap_[sceneType] = std::make_shared(preNodeInfo, curNodeInfo); - } - sceneConverterMap_[sceneType]->Connect(preNode); -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { - AUDIO_INFO_LOG("HpaeOutputCluster connect curNodeInfo name %{public}s", curNodeInfo.nodeName.c_str()); - AUDIO_INFO_LOG("HpaeOutputCluster connect preNodeInfo name %{public}s", preNodeInfo.nodeName.c_str()); - callBack->OnNotifyDfxNodeInfo(true, mixerNode_->GetNodeId(), curNodeInfo); - callBack->OnNotifyDfxNodeInfo(true, curNodeInfo.nodeId, preNodeInfo); - } -#endif - mixerNode_->Connect(sceneConverterMap_[sceneType]); - connectedProcessCluster_.insert(sceneType); -} - -void HpaeOutputCluster::DisConnect(const std::shared_ptr> &preNode) -{ - HpaeNodeInfo &preNodeInfo = preNode->GetSharedInstance()->GetNodeInfo(); - HpaeProcessorType sceneType = preNodeInfo.sceneType; - AUDIO_INFO_LOG("HpaeOutputCluster input sceneType is %{public}u", preNodeInfo.sceneType); - if (sceneConverterMap_.find(sceneType) != sceneConverterMap_.end()) { - sceneConverterMap_[sceneType]->DisConnect(preNode); - mixerNode_->DisConnect(sceneConverterMap_[sceneType]); -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfo(false, mixerNode_->GetNodeId(), sceneConverterMap_[sceneType]->GetNodeInfo()); - } -#endif - sceneConverterMap_.erase(sceneType); - } else { - mixerNode_->DisConnect(preNode); -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfo(false, mixerNode_->GetNodeId(), preNodeInfo); - } -#endif - } - connectedProcessCluster_.erase(sceneType); -} - -int32_t HpaeOutputCluster::GetConverterNodeCount() -{ - return sceneConverterMap_.size(); -} - -int32_t HpaeOutputCluster::GetInstance(std::string deviceClass, std::string deviceNetId) -{ - return hpaeSinkOutputNode_->GetRenderSinkInstance(deviceClass, deviceNetId); -} - -int32_t HpaeOutputCluster::Init(IAudioSinkAttr &attr) -{ - return hpaeSinkOutputNode_->RenderSinkInit(attr); -} - -int32_t HpaeOutputCluster::DeInit() -{ - return hpaeSinkOutputNode_->RenderSinkDeInit(); -} - -int32_t HpaeOutputCluster::Flush(void) -{ - return hpaeSinkOutputNode_->RenderSinkFlush(); -} - -int32_t HpaeOutputCluster::Pause(void) -{ - return hpaeSinkOutputNode_->RenderSinkPause(); -} - -int32_t HpaeOutputCluster::ResetRender(void) -{ - return hpaeSinkOutputNode_->RenderSinkReset(); -} - -int32_t HpaeOutputCluster::Resume(void) -{ - return hpaeSinkOutputNode_->RenderSinkResume(); -} - -int32_t HpaeOutputCluster::Start(void) -{ - return hpaeSinkOutputNode_->RenderSinkStart(); -} - -int32_t HpaeOutputCluster::Stop(void) -{ - return hpaeSinkOutputNode_->RenderSinkStop(); -} - -const char *HpaeOutputCluster::GetFrameData(void) -{ - return hpaeSinkOutputNode_->GetRenderFrameData(); -} - -RendererState HpaeOutputCluster::GetState(void) -{ - return hpaeSinkOutputNode_->GetSinkState(); -} - -int32_t HpaeOutputCluster::GetPreOutNum() -{ - return mixerNode_->GetPreOutNum(); -} - -int32_t HpaeOutputCluster::SetTimeoutStopThd(uint32_t timeoutThdMs) -{ - if (frameLenMs_ != 0) { - timeoutThdFrames_ = timeoutThdMs / frameLenMs_; - } - AUDIO_INFO_LOG( - "SetTimeoutStopThd: timeoutThdFrames_:%{public}u, timeoutThdMs :%{public}u", timeoutThdFrames_, timeoutThdMs); - return SUCCESS; -} - -bool HpaeOutputCluster::IsProcessClusterConnected(HpaeProcessorType sceneType) -{ - return connectedProcessCluster_.find(sceneType) != connectedProcessCluster_.end(); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_plugin_node.cpp b/services/audio_engine/node/src/hpae_plugin_node.cpp deleted file mode 100644 index ed58c365d2..0000000000 --- a/services/audio_engine/node/src/hpae_plugin_node.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2025 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 "hpae_plugin_node.h" -#include "audio_errors.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaePluginNode::HpaePluginNode(HpaeNodeInfo& nodeInfo) - : HpaeNode(nodeInfo), outputStream_(this), enableProcess_(true), - pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), silenceData_(pcmBufferInfo_) - -{ - silenceData_.Reset(); - silenceData_.SetBufferValid(false); -} - -void HpaePluginNode::DoProcess() -{ - HpaePcmBuffer *tempOut = nullptr; - std::vector& preOutputs = inputStream_.ReadPreOutputData(); - // if buffer is not valid, write silence data(invalid) to output - if (enableProcess_ && !preOutputs.empty()) { - tempOut = SignalProcess(preOutputs); - outputStream_.WriteDataToOutput(tempOut); - } else if (!preOutputs.empty()) { - outputStream_.WriteDataToOutput(preOutputs[0]); - } else { - outputStream_.WriteDataToOutput(&silenceData_); - } -} - -bool HpaePluginNode::Reset() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - inputStream_.DisConnect(output); - } - return true; -} - -bool HpaePluginNode::ResetAll() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - std::shared_ptr hpaeNode = preOutput.second; - if (hpaeNode->ResetAll()) { - inputStream_.DisConnect(output); - } - } - return true; -} - -int32_t HpaePluginNode::EnableProcess(bool enable) -{ - enableProcess_ = enable; - return SUCCESS; -} - -bool HpaePluginNode::IsEnableProcess() -{ - return enableProcess_; -} - -std::shared_ptr HpaePluginNode::GetSharedInstance() -{ - return shared_from_this(); -} - -OutputPort* HpaePluginNode::GetOutputPort() -{ - return &outputStream_; -} - -void HpaePluginNode::Connect(const std::shared_ptr>& preNode) -{ - inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); -} - -void HpaePluginNode::DisConnect(const std::shared_ptr>& preNode) -{ - inputStream_.DisConnect(preNode->GetOutputPort()); -} - -size_t HpaePluginNode::GetPreOutNum() -{ - return inputStream_.GetPreOutputNum(); -} - -size_t HpaePluginNode::GetOutputPortNum() -{ - return outputStream_.GetInputNum(); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_process_cluster.cpp b/services/audio_engine/node/src/hpae_process_cluster.cpp deleted file mode 100644 index f22d5cee57..0000000000 --- a/services/audio_engine/node/src/hpae_process_cluster.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeProcessCluster" -#endif - -#include - -#include "audio_errors.h" -#include "hpae_process_cluster.h" -#include "hpae_node_common.h" -#include "audio_engine_log.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaeProcessCluster::HpaeProcessCluster(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &sinkInfo) - : HpaeNode(nodeInfo), mixerNode_(std::make_shared(nodeInfo)), sinkInfo_(sinkInfo) -{ - if (TransProcessorTypeToSceneType(nodeInfo.sceneType) != "SCENE_EXTRA") { - renderEffectNode_ = std::make_shared(nodeInfo); - } else { - renderEffectNode_ = nullptr; - } -#ifdef ENABLE_HIDUMP_DFX - if (nodeInfo.statusCallback.lock()) { - nodeInfo.nodeName = "HpaeMixerNode"; - nodeInfo.sessionId = 0; - nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); - AUDIO_INFO_LOG("HpaeProcessCluster, HpaeMixerNode id %{public}u ", nodeInfo.nodeId); - mixerNode_->SetNodeInfo(nodeInfo); - if (renderEffectNode_) { - nodeInfo.nodeName = "HpaeRenderEffectNode"; - nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); - nodeInfo.sessionId = 0; - renderEffectNode_->SetNodeInfo(nodeInfo); - AUDIO_INFO_LOG("HpaeProcessCluster, HpaeRenderEffectNode id %{public}u ", nodeInfo.nodeId); - } - } -#endif -} - -HpaeProcessCluster::~HpaeProcessCluster() -{ - AUDIO_INFO_LOG("process cluster destroyed, processor scene type is %{public}d", GetSceneType()); - Reset(); -} - -void HpaeProcessCluster::DoProcess() -{ - if (renderEffectNode_ != nullptr) { - renderEffectNode_->DoProcess(); - return; - } - mixerNode_->DoProcess(); -} - -bool HpaeProcessCluster::Reset() -{ - mixerNode_->Reset(); - for (auto converterNode : idConverterMap_) { - converterNode.second->Reset(); - } - for (auto gainNode : idGainMap_) { - gainNode.second->Reset(); - } - if (renderEffectNode_ != nullptr) { - renderEffectNode_->Reset(); - renderEffectNode_ = nullptr; - } - return true; -} - -bool HpaeProcessCluster::ResetAll() -{ - return renderEffectNode_ != nullptr ? renderEffectNode_->ResetAll() : mixerNode_->ResetAll(); -} - -std::shared_ptr HpaeProcessCluster::GetSharedInstance() -{ - if (renderEffectNode_ != nullptr) { - AUDIO_INFO_LOG("HpaeProcessCluster, GetSharedInstance renderEffectNode_ name %{public}s id: %{public}u ", - renderEffectNode_->GetNodeName().c_str(), - renderEffectNode_->GetNodeId()); - return renderEffectNode_; - } - AUDIO_INFO_LOG("HpaeProcessCluster, GetSharedInstance mixerNode_ name %{public}s id: %{public}u ", - mixerNode_->GetNodeName().c_str(), - mixerNode_->GetNodeId()); - return mixerNode_; -} - -OutputPort *HpaeProcessCluster::GetOutputPort() -{ - return renderEffectNode_ != nullptr ? renderEffectNode_->GetOutputPort() : mixerNode_->GetOutputPort(); -} - -int32_t HpaeProcessCluster::GetGainNodeCount() -{ - return idGainMap_.size(); -} - -int32_t HpaeProcessCluster::GetConverterNodeCount() -{ - return idConverterMap_.size(); -} - -int32_t HpaeProcessCluster::GetPreOutNum() -{ - return mixerNode_->GetPreOutNum(); -} - -void HpaeProcessCluster::Connect(const std::shared_ptr> &preNode) -{ - HpaeNodeInfo &preNodeInfo = preNode->GetNodeInfo(); - uint32_t sessionId = preNodeInfo.sessionId; - AUDIO_INFO_LOG("HpaeProcessCluster sessionId is %{public}u, streamType is %{public}d, " - "HpaeProcessCluster rate is %{public}u, ch is %{public}u, " - "HpaeProcessCluster preNodeId %{public}u, preNodeName is %{public}s", - preNodeInfo.sessionId, preNodeInfo.streamType, preNodeInfo.samplingRate, preNodeInfo.channels, - preNodeInfo.nodeId, preNodeInfo.nodeName.c_str()); - - if (renderEffectNode_ != nullptr && renderEffectNode_->GetPreOutNum() == 0) { - renderEffectNode_->Connect(mixerNode_); - AUDIO_INFO_LOG("Process Connect mixerNode_"); -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = renderEffectNode_->GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfo(true, renderEffectNode_->GetNodeId(), mixerNode_->GetNodeInfo()); - } -#endif - } - if (idGainMap_.find(sessionId) == idGainMap_.end()) { - HpaeNodeInfo gainNodeInfo = preNodeInfo; -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { - gainNodeInfo.nodeName = "HpaeGainNode"; - gainNodeInfo.nodeId = callBack->OnGetNodeId(); - } -#endif - idGainMap_[sessionId] = std::make_shared(gainNodeInfo); - } - HpaeNodeInfo outNodeInfo = preNodeInfo; - outNodeInfo.frameLen = sinkInfo_.frameLen; - outNodeInfo.samplingRate = sinkInfo_.samplingRate; - outNodeInfo.channels = sinkInfo_.channels; - outNodeInfo.channelLayout = (AudioChannelLayout)sinkInfo_.channelLayout; - outNodeInfo.format = sinkInfo_.format; -#ifdef ENABLE_HIDUMP_DFX - outNodeInfo.nodeName = "HpaeAudioFormatConverterNode"; - if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { - outNodeInfo.nodeId = callBack->OnGetNodeId(); - } -#endif - idConverterMap_[sessionId] = std::make_shared(preNodeInfo, outNodeInfo); - if (renderEffectNode_ != nullptr) { - idConverterMap_[sessionId]->RegisterCallback(this); - } - idGainMap_[sessionId]->Connect(preNode); - idConverterMap_[sessionId]->Connect(idGainMap_[sessionId]); - mixerNode_->Connect(idConverterMap_[sessionId]); -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = mixerNode_->GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfo(true, mixerNode_->GetNodeId(), idConverterMap_[sessionId]->GetNodeInfo()); - callBack->OnNotifyDfxNodeInfo( - true, idConverterMap_[sessionId]->GetNodeId(), idGainMap_[sessionId]->GetNodeInfo()); - callBack->OnNotifyDfxNodeInfo(true, idGainMap_[sessionId]->GetNodeId(), preNodeInfo); - } -#endif -} - -void HpaeProcessCluster::DisConnect(const std::shared_ptr> &preNode) -{ - uint32_t sessionId = preNode->GetNodeInfo().sessionId; - AUDIO_INFO_LOG( - "Process DisConnect sessionId is %{public}u, streamType is %{public}d", sessionId, preNode->GetNodeInfo().streamType); -#ifdef ENABLE_HIDUMP_DFX - auto callBack = mixerNode_->GetNodeStatusCallback().lock(); - if (callBack != nullptr && idConverterMap_.find(sessionId) != idConverterMap_.end()) { - callBack->OnNotifyDfxNodeInfo(false, idConverterMap_[sessionId]->GetNodeId(), idConverterMap_[sessionId]->GetNodeInfo()); - } -#endif - if (idConverterMap_.find(sessionId) != idConverterMap_.end()) { - idGainMap_[sessionId]->DisConnect(preNode); - idConverterMap_[sessionId]->DisConnect(idGainMap_[sessionId]); - mixerNode_->DisConnect(idConverterMap_[sessionId]); - idConverterMap_.erase(sessionId); - idGainMap_.erase(sessionId); - AUDIO_INFO_LOG("Process DisConnect Exist converterNode preOutNum is %{public}zu", mixerNode_->GetPreOutNum()); - } - if (renderEffectNode_ != nullptr && mixerNode_->GetPreOutNum() == 0) { - renderEffectNode_->DisConnect(mixerNode_); - AUDIO_INFO_LOG("Process DisConnect mixerNode_"); -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = renderEffectNode_->GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfo(false, renderEffectNode_->GetNodeId(), mixerNode_->GetNodeInfo()); - } -#endif - } -} - -int32_t HpaeProcessCluster::GetEffectNodeInputChannelInfo(uint32_t &channels, uint64_t &channelLayout) -{ - if (renderEffectNode_ == nullptr) { - return ERR_READ_FAILED; - } - int32_t ret = renderEffectNode_->GetExpectedInputChannelInfo(channels, channelLayout); - return ret; -} - -int32_t HpaeProcessCluster::AudioRendererCreate(HpaeNodeInfo &nodeInfo) -{ - if (renderEffectNode_ == nullptr) { - return 0; - } - return renderEffectNode_->AudioRendererCreate(nodeInfo); -} - -int32_t HpaeProcessCluster::AudioRendererStart(HpaeNodeInfo &nodeInfo) -{ - if (renderEffectNode_ == nullptr) { - return 0; - } - return renderEffectNode_->AudioRendererStart(nodeInfo); -} - -int32_t HpaeProcessCluster::AudioRendererStop(HpaeNodeInfo &nodeInfo) -{ - if (renderEffectNode_ == nullptr) { - return 0; - } - return renderEffectNode_->AudioRendererStop(nodeInfo); -} - -int32_t HpaeProcessCluster::AudioRendererRelease(HpaeNodeInfo &nodeInfo) -{ - if (renderEffectNode_ == nullptr) { - return 0; - } - return renderEffectNode_->AudioRendererRelease(nodeInfo); -} - -std::shared_ptr HpaeProcessCluster::GetGainNodeById(uint32_t sessionId) const -{ - auto it = idGainMap_.find(sessionId); - if (it != idGainMap_.end()) { - return it->second; - } - return nullptr; -} - -std::shared_ptr HpaeProcessCluster::GetConverterNodeById(uint32_t sessionId) const -{ - auto it = idConverterMap_.find(sessionId); - if (it != idConverterMap_.end()) { - return it->second; - } - return nullptr; -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_render_effect_node.cpp b/services/audio_engine/node/src/hpae_render_effect_node.cpp deleted file mode 100644 index 716028fa22..0000000000 --- a/services/audio_engine/node/src/hpae_render_effect_node.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeRenderEffectNode" -#endif - -#include -#include "audio_errors.h" -#include "audio_engine_log.h" -#include "hpae_render_effect_node.h" -#include "hpae_pcm_buffer.h" -#include "audio_effect_chain_manager.h" -#include "audio_effect_map.h" -#include "audio_utils.h" - -static constexpr uint32_t DEFUALT_EFFECT_RATE = 48000; -static constexpr uint32_t DEFAULT_EFFECT_FRAMELEN = 960; - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -HpaeRenderEffectNode::HpaeRenderEffectNode(HpaeNodeInfo &nodeInfo) : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), - // DEFAUT effect out format - pcmBufferInfo_(nodeInfo.channels, DEFAULT_EFFECT_FRAMELEN, DEFUALT_EFFECT_RATE, nodeInfo.channelLayout), - effectOutput_(pcmBufferInfo_), - nodeInfo_(nodeInfo) -{ - const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); - if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != - audioSupportedSceneTypes.end()) { - sceneType_ = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); - } - AUDIO_INFO_LOG("render effect node created, scene type: %{public}s", sceneType_.c_str()); -#ifdef ENABLE_HOOK_PCM - inputPcmDumper_ = std::make_unique( - "HpaeRenderEffectNodeInput_id_" + std::to_string(GetNodeId()) + ".pcm"); - outputPcmDumper_ = std::make_unique( - "HpaeRenderEffectNodeOutput_id_" + std::to_string(GetNodeId()) + ".pcm"); -#endif -} - -HpaePcmBuffer *HpaeRenderEffectNode::SignalProcess(const std::vector &inputs) -{ - AUDIO_DEBUG_LOG("render effect node signal process in"); - if (inputs.empty()) { - AUDIO_WARNING_LOG("HpaeRenderEffectNode inputs size is empty"); - return nullptr; - } - auto rate = "rate[" + std::to_string(inputs[0]->GetSampleRate()) + "]_"; - auto ch = "ch[" + std::to_string(inputs[0]->GetChannelCount()) + "]_"; - auto len = "len[" + std::to_string(inputs[0]->GetFrameLen()) + "]"; - Trace trace("[" + sceneType_ + "]HpaeRenderEffectNode::SignalProcess " + rate + ch + len); - - if (AudioEffectChainManager::GetInstance()->GetOffloadEnabled()) { - return inputs[0]; - } - -#ifdef ENABLE_HOOK_PCM - if (inputPcmDumper_) { - inputPcmDumper_->Dump((int8_t *)inputs[0]->GetPcmDataBuffer(), - inputs[0]->GetFrameLen() * sizeof(float) * inputs[0]->GetChannelCount()); - } -#endif - - ReconfigOutputBuffer(); - - auto eBufferAttr = std::make_unique( - inputs[0]->GetPcmDataBuffer(), - effectOutput_.GetPcmDataBuffer(), - static_cast(inputs[0]->GetChannelCount()), - static_cast(inputs[0]->GetFrameLen()), - 0, - 0 - ); - - int32_t ret = AudioEffectChainManager::GetInstance()->ApplyAudioEffectChain(sceneType_, eBufferAttr); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, inputs[0], "apply audio effect chain fail"); - -#ifdef ENABLE_HOOK_PCM - if (outputPcmDumper_) { - outputPcmDumper_->Dump((int8_t *)effectOutput_.GetPcmDataBuffer(), - effectOutput_.GetFrameLen() * sizeof(float) * effectOutput_.GetChannelCount()); - } -#endif - - return &effectOutput_; -} - -int32_t HpaeRenderEffectNode::AudioRendererCreate(HpaeNodeInfo &nodeInfo) -{ - AUDIO_INFO_LOG("notify audio effect when audio renderer create in"); - int32_t ret = CreateAudioEffectChain(nodeInfo); - if (ret != 0) { - AUDIO_WARNING_LOG("create audio effect chain failed, ret: %{public}d", ret); - } - AUDIO_INFO_LOG("notify audio effect when audio renderer create out"); - return SUCCESS; -} - -int32_t HpaeRenderEffectNode::AudioRendererStart(HpaeNodeInfo &nodeInfo) -{ - AUDIO_INFO_LOG("notify audio effect when audio renderer start in"); - ModifyAudioEffectChainInfo(nodeInfo, ADD_AUDIO_EFFECT_CHAIN_INFO); - AUDIO_INFO_LOG("notify audio effect when audio renderer start out"); - return SUCCESS; -} - -int32_t HpaeRenderEffectNode::AudioRendererStop(HpaeNodeInfo &nodeInfo) -{ - AUDIO_INFO_LOG("notify audio effect when audio renderer stop in"); - ModifyAudioEffectChainInfo(nodeInfo, REMOVE_AUDIO_EFFECT_CHAIN_INFO); - AUDIO_INFO_LOG("notify audio effect when audio renderer stop out"); - return SUCCESS; -} - -int32_t HpaeRenderEffectNode::AudioRendererRelease(HpaeNodeInfo &nodeInfo) -{ - AUDIO_INFO_LOG("notify audio effect when audio renderer release in"); - int32_t ret = ReleaseAudioEffectChain(nodeInfo); - if (ret != 0) { - AUDIO_WARNING_LOG("release audio effect chain failed, ret: %{public}d", ret); - } - ModifyAudioEffectChainInfo(nodeInfo, REMOVE_AUDIO_EFFECT_CHAIN_INFO); - AUDIO_INFO_LOG("notify audio effect when audio renderer release out"); - return SUCCESS; -} - -int32_t HpaeRenderEffectNode::CreateAudioEffectChain(HpaeNodeInfo &nodeInfo) -{ - AUDIO_INFO_LOG("Create Audio Effect Chain In, sessionID is %{public}u, sceneType is %{public}d", - nodeInfo.sessionId, nodeInfo.effectInfo.effectScene); - // todo: deal with remote case - // todo: if boot music, do not create audio effect - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager"); - std::string sceneType = "EFFECT_NONE"; - const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); - if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != - audioSupportedSceneTypes.end()) { - sceneType = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); - } - // todo: could be removed - if (!audioEffectChainManager->CheckAndAddSessionID(std::to_string(nodeInfo.sessionId))) { - return SUCCESS; - } - audioEffectChainManager->UpdateSceneTypeList(sceneType, ADD_SCENE_TYPE); - // todo: should be considered - if (audioEffectChainManager->GetOffloadEnabled()) { - return SUCCESS; - } - int32_t ret = audioEffectChainManager->CreateAudioEffectChainDynamic(sceneType); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "create effect chain fail"); - AUDIO_INFO_LOG("Create Audio Effect Chain Success, sessionID is %{public}u, sceneType is %{public}d", - nodeInfo.sessionId, nodeInfo.effectInfo.effectScene); - return SUCCESS; -} - -int32_t HpaeRenderEffectNode::ReleaseAudioEffectChain(HpaeNodeInfo &nodeInfo) -{ - AUDIO_INFO_LOG("Release Audio Effect Chain In, sessionID is %{public}u, sceneType is %{public}d", - nodeInfo.sessionId, nodeInfo.effectInfo.effectScene); - // todo: deal with remote case - // todo: if boot music, do not release audio effect - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager"); - std::string sceneType = "EFFECT_NONE"; - const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); - if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != - audioSupportedSceneTypes.end()) { - sceneType = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); - } - // todo: could be removed - if (!audioEffectChainManager->CheckAndRemoveSessionID(std::to_string(nodeInfo.sessionId))) { - return SUCCESS; - } - audioEffectChainManager->UpdateSceneTypeList(sceneType, REMOVE_SCENE_TYPE); - // todo: should be considered - if (audioEffectChainManager->GetOffloadEnabled()) { - return SUCCESS; - } - int32_t ret = audioEffectChainManager->ReleaseAudioEffectChainDynamic(sceneType); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "release effect chain fail"); - AUDIO_INFO_LOG("Release Audio Effect Chain Success, sessionID is %{public}u, sceneType is %{public}d", - nodeInfo.sessionId, nodeInfo.effectInfo.effectScene); - return SUCCESS; -} - -void HpaeRenderEffectNode::ModifyAudioEffectChainInfo(HpaeNodeInfo &nodeInfo, - ModifyAudioEffectChainInfoReason reason) -{ - std::string sessionID = std::to_string(nodeInfo.sessionId); - std::string sceneType = "EFFECT_NONE"; - const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); - if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != - audioSupportedSceneTypes.end()) { - sceneType = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); - } - int32_t ret = 0; - switch (reason) { - case ADD_AUDIO_EFFECT_CHAIN_INFO: { - SessionEffectInfo info; - info.sceneMode = std::to_string(nodeInfo.effectInfo.effectMode); - info.sceneType = sceneType; - info.channels = static_cast(nodeInfo.channels); - info.channelLayout = nodeInfo.channelLayout; - info.streamUsage = nodeInfo.effectInfo.streamUsage; - info.systemVolumeType = nodeInfo.effectInfo.volumeType; - ret = AudioEffectChainManager::GetInstance()->SessionInfoMapAdd(sessionID, info); - break; - } - case REMOVE_AUDIO_EFFECT_CHAIN_INFO: - ret = AudioEffectChainManager::GetInstance()->SessionInfoMapDelete(sceneType, sessionID); - break; - default: - break; - } - CHECK_AND_RETURN_LOG(ret == SUCCESS, "modify session info failed"); - UpdateAudioEffectChainInfo(nodeInfo); -} - -void HpaeRenderEffectNode::UpdateAudioEffectChainInfo(HpaeNodeInfo &nodeInfo) -{ - AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); - CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "null audioEffectChainManager"); - std::string sceneType = "EFFECT_NONE"; - const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); - if (audioSupportedSceneTypes.find(nodeInfo.effectInfo.effectScene) != - audioSupportedSceneTypes.end()) { - sceneType = audioSupportedSceneTypes.at(nodeInfo.effectInfo.effectScene); - } - audioEffectChainManager->UpdateMultichannelConfig(sceneType); - audioEffectChainManager->EffectVolumeUpdate(); - audioEffectChainManager->UpdateDefaultAudioEffect(); - audioEffectChainManager->UpdateStreamUsage(); -} - -void HpaeRenderEffectNode::ReconfigOutputBuffer() -{ - uint32_t channels = static_cast(nodeInfo_.channels); - uint64_t channelLayout = nodeInfo_.channelLayout; - int32_t ret = AudioEffectChainManager::GetInstance()->GetOutputChannelInfo(sceneType_, channels, channelLayout); - if (ret != SUCCESS || channels == 0 || channelLayout == 0) { - AUDIO_WARNING_LOG("output channel info incorrect, scene type: %{public}s, " - "channels: %{public}u, channelLayout: %{public}" PRIu64, sceneType_.c_str(), channels, channelLayout); - } else if (static_cast(nodeInfo_.channels) != channels || - static_cast(nodeInfo_.channelLayout) != channelLayout) { - AUDIO_INFO_LOG("output channel info changed, scene type: %{public}s, " - "channels change from %{public}u to %{public}u, " - "channelLayout change from %{public}" PRIu64 " to %{public}" PRIu64, - sceneType_.c_str(), nodeInfo_.channels, channels, nodeInfo_.channelLayout, channelLayout); - nodeInfo_.channels = static_cast(channels); - nodeInfo_.channelLayout = static_cast(channelLayout); - PcmBufferInfo pcmBufferInfo = PcmBufferInfo(channels, DEFAULT_EFFECT_FRAMELEN, - DEFUALT_EFFECT_RATE, channelLayout, effectOutput_.GetFrames(), effectOutput_.IsMultiFrames()); - effectOutput_.ReConfig(pcmBufferInfo); - nodeInfo_.channels = (AudioChannel)channels; - nodeInfo_.channelLayout = (AudioChannelLayout)channelLayout; - nodeInfo_.samplingRate = (AudioSamplingRate)DEFUALT_EFFECT_RATE; - nodeInfo_.frameLen = (uint32_t)DEFAULT_EFFECT_FRAMELEN; -#ifdef ENABLE_HIDUMP_DFX - if (auto callBack = GetNodeStatusCallback().lock()) { - callBack->OnNotifyDfxNodeInfoChanged(GetNodeId(), nodeInfo_); - } -#endif - } -} - -int32_t HpaeRenderEffectNode::GetExpectedInputChannelInfo(uint32_t &channels, uint64_t &channelLayout) -{ - return AudioEffectChainManager::GetInstance()->ReturnEffectChannelInfo(sceneType_, channels, channelLayout); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_resample_node.cpp b/services/audio_engine/node/src/hpae_resample_node.cpp deleted file mode 100644 index be57740c22..0000000000 --- a/services/audio_engine/node/src/hpae_resample_node.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. - */ -/* - * Copyright (c) 2025 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 "HpaeResampleNode" -#endif - -#include -#include -#include -#include "hpae_resample_node.h" -#include "hpae_pcm_buffer.h" -#include "audio_engine_log.h" -#include "audio_utils.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr int REASAMPLE_QUAILTY = 5; -HpaeResampleNode::HpaeResampleNode(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &nodeInfo, ResamplerType type) - : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), - pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), - resampleOuput_(pcmBufferInfo_), preNodeInfo_(preNodeInfo), tempOuput_(preNodeInfo.channels * nodeInfo.frameLen) -{ - if (type == ResamplerType::PRORESAMPLER) { - resampler_ = std::make_unique(preNodeInfo_.samplingRate, nodeInfo.samplingRate, - preNodeInfo_.channels, REASAMPLE_QUAILTY); - } -#ifdef ENABLE_HOOK_PCM - inputPcmDumper_ = std::make_unique("HpaeResampleNodeInput1_id_" + - std::to_string(GetSessionId()) + "_ch_" + std::to_string(preNodeInfo_.channels) + - "_rate_" + std::to_string(preNodeInfo_.samplingRate) + "_scene_" + - std::to_string(HpaeNode::GetSceneType()) + "_" + GetTime() + ".pcm"); - outputPcmDumper_ = std::make_unique("HpaeResampleNodeOutput1_id_" + - std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) + - "_rate_" + std::to_string(GetSampleRate()) + "_scene_" + - std::to_string(HpaeNode::GetSceneType())+ "_" + GetTime() + ".pcm"); -#endif -} - -HpaeResampleNode::HpaeResampleNode(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo), - pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), - resampleOuput_(pcmBufferInfo_), preNodeInfo_(preNodeInfo), tempOuput_(preNodeInfo.channels * nodeInfo.frameLen) -{ // use ProResampler as default - resampler_ = std::make_unique(preNodeInfo_.samplingRate, nodeInfo.samplingRate, - preNodeInfo_.channels, REASAMPLE_QUAILTY); - -#ifdef ENABLE_HOOK_PCM - inputPcmDumper_ = std::make_unique("HpaeResampleNodeInput1_id_" + - std::to_string(HpaeNode::GetSessionId()) + "_ch_" + std::to_string(preNodeInfo_.channels) + "_rate_" + - std::to_string(preNodeInfo_.samplingRate) + "_scene_" + std::to_string(HpaeNode::GetSceneType())+".pcm"); - - outputPcmDumper_ = std::make_unique("HpaeResampleNodeOutput1_id_" + - std::to_string(HpaeNode::GetSessionId()) + "_ch_" + std::to_string(HpaeNode::GetChannelCount()) + - "_rate_" + std::to_string(HpaeNode::GetSampleRate()) + - "_scene_"+ std::to_string(HpaeNode::GetSceneType())+".pcm"); -#endif - AUDIO_INFO_LOG("input rate %{public}u, output rate %{public}u", preNodeInfo_.samplingRate, nodeInfo.samplingRate); - AUDIO_INFO_LOG("input SessionId %{public}u, output streamType %{public}u", HpaeNode::GetSessionId(), - nodeInfo.streamType); - AUDIO_INFO_LOG("input ch %{public}u, output ch %{public}u", preNodeInfo_.channels, HpaeNode::GetChannelCount()); -} - -bool HpaeResampleNode::Reset() -{ - if (resampler_ == nullptr) { - AUDIO_WARNING_LOG("resampler_ is nullptr, SessionId:%{public}d", GetSessionId()); - return false; - } - resampler_->Reset(); - return true; -} - -HpaePcmBuffer *HpaeResampleNode::SignalProcess(const std::vector &inputs) -{ - Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeResampleNode::SignalProcess"); - if (inputs.empty()) { - AUDIO_WARNING_LOG("HpaeResampleNode inputs size is empty, SessionId:%{public}d", GetSessionId()); - return nullptr; - } - if (inputs.size() != 1) { - AUDIO_WARNING_LOG("error inputs size is not eqaul to 1, SessionId:%{public}d", GetSessionId()); - } - if (resampler_ == nullptr) { - return &silenceData_; - } - resampleOuput_.Reset(); - uint32_t inputFrameLen = preNodeInfo_.frameLen; - uint32_t outputFrameLen = GetFrameLen(); - float *srcData = (*(inputs[0])).GetPcmDataBuffer(); - float *dstData = tempOuput_.data(); - if (preNodeInfo_.channels == GetChannelCount()) { - dstData = resampleOuput_.GetPcmDataBuffer(); - } -#ifdef ENABLE_HOOK_PCM - inputPcmDumper_->CheckAndReopenHandlde(); - if (inputPcmDumper_ != nullptr) { - inputPcmDumper_->Dump((int8_t *)(srcData), (inputFrameLen * sizeof(float) * preNodeInfo_.channels)); - } -#endif - ResampleProcess(srcData, inputFrameLen, dstData, outputFrameLen); - return &resampleOuput_; -} - -void HpaeResampleNode::ResampleProcess(float *srcData, uint32_t inputFrameLen, float *dstData, uint32_t outputFrameLen) -{ - resampler_->Process(srcData, &inputFrameLen, dstData, &outputFrameLen); - int32_t addZeroLen = GetFrameLen() - outputFrameLen > 0 ? GetFrameLen() - outputFrameLen : 0; - - if (preNodeInfo_.channels == GetChannelCount()) { -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_->CheckAndReopenHandlde(); - if (outputPcmDumper_ != nullptr) { - outputPcmDumper_->Dump( - (int8_t *)(resampleOuput_.GetPcmDataBuffer()), GetFrameLen() * sizeof(float) * GetChannelCount()); - } -#endif - return; - } - - float *targetData = resampleOuput_.GetPcmDataBuffer(); - size_t targetChannels = GetChannelCount(); - for (int32_t i = 0; i < (int32_t)outputFrameLen; ++i) { - for (int32_t ch = 0; ch < (int32_t)targetChannels; ++ch) { - size_t leftChIndex = std::min(ch, (preNodeInfo_.channels - 1)); - if (i < addZeroLen) { - targetData[i * targetChannels + ch] = 0; - } else { - targetData[i * targetChannels + ch] = - dstData[(i - addZeroLen) * preNodeInfo_.channels + leftChIndex]; - } - } - } - -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_->CheckAndReopenHandlde(); - if (outputPcmDumper_ != nullptr) { - outputPcmDumper_->Dump( - (int8_t *)(resampleOuput_.GetPcmDataBuffer()), GetFrameLen() * sizeof(float) * GetChannelCount()); - } -#endif -} - -void HpaeResampleNode::ConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) -{ - inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort(nodeInfo)); - resampleOuput_.SetSourceBufferType(preNode->GetOutputPortBufferType(nodeInfo)); -} - -void HpaeResampleNode::DisConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) -{ - inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true)); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_sinkInput_node.cpp b/services/audio_engine/node/src/hpae_sinkInput_node.cpp deleted file mode 100644 index d12359ca29..0000000000 --- a/services/audio_engine/node/src/hpae_sinkInput_node.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeSinkInputNode" -#endif -#include "hpae_sink_input_node.h" -#include -#include "hpae_format_convert.h" -#include "hpae_node_common.h" -#include "audio_engine_log.h" -#include "audio_errors.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -static constexpr int32_t DEFAULT_BUFFER_MICROSECOND = 20000000; -static constexpr uint64_t AUDIO_NS_PER_S = 1000000000; - -HpaeSinkInputNode::HpaeSinkInputNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), - pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, (uint64_t)nodeInfo.channelLayout), - inputAudioBuffer_(pcmBufferInfo_), outputStream_(this), - interleveData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), framesWritten_(0), - totalFrames_(0) -{ - AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}" PRIu64 ", " - "frameLen %{public}d", nodeInfo.sessionId, inputAudioBuffer_.GetChannelCount(), - inputAudioBuffer_.GetChannelLayout(), inputAudioBuffer_.GetFrameLen()); - - handleTimeModel_ = std::make_unique(); - handleTimeModel_->ConfigSampleRate(nodeInfo.samplingRate); -#ifdef ENABLE_HOOK_PCM - inputPcmDumper_ = std::make_unique( - "HpaeSinkInputNode_id_" + std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) + - "_rate_" + std::to_string(GetSampleRate()) + "_bit_" + std::to_string(GetBitWidth()) + ".pcm"); -#endif - if (nodeInfo.historyFrameCount > 0) { - PcmBufferInfo pcmInfo = PcmBufferInfo{ - nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, - nodeInfo.historyFrameCount, true}; - historyBuffer_ = std::make_unique(pcmInfo); - AUDIO_INFO_LOG("HpaeSinkInputNode::historybuffer created"); - } else { - historyBuffer_ = nullptr; - } -} - -HpaeSinkInputNode::~HpaeSinkInputNode() -{} - -void HpaeSinkInputNode::CheckAndDestoryHistoryBuffer() -{ - HpaeNodeInfo nodeInfo = GetNodeInfo(); - // historyBuffer_ has no data, check if historyFrameCount is 0 and distory it - if (nodeInfo.historyFrameCount == 0) { - if (historyBuffer_) { - AUDIO_INFO_LOG("HpaeSinkInputNode::historyBuffer_ useless, distory it"); - } - historyBuffer_ = nullptr; - } else if (historyBuffer_ == nullptr) { // this case need to create historyBuffer_ - PcmBufferInfo pcmInfo = PcmBufferInfo{ - nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, - nodeInfo.historyFrameCount, true}; - historyBuffer_ = std::make_unique(pcmInfo); - AUDIO_INFO_LOG("HpaeSinkInputNode::historybuffer created"); - } -} - -void HpaeSinkInputNode::DoProcess() -{ - CHECK_AND_RETURN_LOG( - writeCallback_.lock(), "HpaeSinkInputNode writeCallback_ is nullptr, SessionId:%{public}d", GetSessionId()); - - auto nodeCallback = GetNodeStatusCallback().lock(); - if (nodeCallback) { - nodeCallback->OnRequestLatency(GetSessionId(), streamInfo_.latency); - } - - streamInfo_ = {.framesWritten = framesWritten_.load(), - .inputData = interleveData_.data(), - .requestDataLen = interleveData_.size(), - .deviceClass = GetDeviceClass(), - .deviceNetId = GetDeviceNetId(), - .needData = !(historyBuffer_ && historyBuffer_->GetCurFrames())}; - GetCurrentPosition(streamInfo_.framePosition, streamInfo_.timestamp); - int32_t ret = writeCallback_.lock()->OnStreamData(streamInfo_); - - // if historyBuffer has enough data, write to outputStream - if (!streamInfo_.needData) { - historyBuffer_->GetFrameData(inputAudioBuffer_); - outputStream_.WriteDataToOutput(&inputAudioBuffer_); - return; - } - CheckAndDestoryHistoryBuffer(); - if (nodeCallback && ret) { - nodeCallback->OnNodeStatusUpdate(GetSessionId(), OPERATION_UNDERFLOW); - if (isDrain_) { - AUDIO_INFO_LOG("OnNodeStatusUpdate Drain sessionId:%{public}u", GetSessionId()); - nodeCallback->OnNodeStatusUpdate(GetSessionId(), OPERATION_DRAINED); - isDrain_ = false; - } - } - inputAudioBuffer_.SetBufferValid(ret ? false : true); - -#ifdef ENABLE_HOOK_PCM - if (inputPcmDumper_ != nullptr && inputAudioBuffer_.IsValid()) { - inputPcmDumper_->CheckAndReopenHandlde(); - inputPcmDumper_->Dump(static_cast(interleveData_.data()), - GetChannelCount() * GetFrameLen() * GET_SIZE_FROM_FORMAT(GetBitWidth())); - } -#endif - - ConvertToFloat( - GetBitWidth(), GetChannelCount() * GetFrameLen(), interleveData_.data(), inputAudioBuffer_.GetPcmDataBuffer()); - if (ret != 0) { - AUDIO_WARNING_LOG("request data is not enough sessionId:%{public}u", GetSessionId()); - memset_s(inputAudioBuffer_.GetPcmDataBuffer(), inputAudioBuffer_.Size(), 0, inputAudioBuffer_.Size()); - } else { - totalFrames_ = totalFrames_ + GetFrameLen(); - framesWritten_.store(totalFrames_); - if (historyBuffer_) { - historyBuffer_->StoreFrameData(inputAudioBuffer_); - } - } - outputStream_.WriteDataToOutput(&inputAudioBuffer_); -} - -bool HpaeSinkInputNode::Reset() -{ - return true; -} - -bool HpaeSinkInputNode::ResetAll() -{ - return true; -} - -std::shared_ptr HpaeSinkInputNode::GetSharedInstance() -{ - return shared_from_this(); -} - -OutputPort *HpaeSinkInputNode::GetOutputPort() -{ - return &outputStream_; -} - -bool HpaeSinkInputNode::RegisterWriteCallback(const std::weak_ptr &callback) -{ - writeCallback_ = callback; - return true; -} -// reset historyBuffer -void HpaeSinkInputNode::Flush() -{ - if (GetNodeInfo().historyFrameCount == 0) { - historyBuffer_ = nullptr; - } else if (historyBuffer_ && historyBuffer_->GetFrames() == GetNodeInfo().historyFrameCount) { - historyBuffer_->Reset(); - } else { - HpaeNodeInfo nodeInfo = GetNodeInfo(); - PcmBufferInfo pcmInfo = PcmBufferInfo{ - nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, - nodeInfo.historyFrameCount, true}; - historyBuffer_ = std::make_unique(pcmInfo); - } -} - -bool HpaeSinkInputNode::Drain() -{ - isDrain_ = true; - return true; -} - -int32_t HpaeSinkInputNode::SetState(RendererState renderState) -{ - state_ = renderState; - return SUCCESS; -} - -RendererState HpaeSinkInputNode::GetState() -{ - return state_; -} - -uint64_t HpaeSinkInputNode::GetFramesWritten() -{ - return framesWritten_.load(); -} - -bool HpaeSinkInputNode::GetAudioTime(uint64_t &framePos, int64_t &sec, int64_t &nanoSec) -{ - framePos = GetFramesWritten(); - int64_t time = handleTimeModel_->GetTimeOfPos(framePos); - int64_t deltaTime = DEFAULT_BUFFER_MICROSECOND; // note: 20ms - time += deltaTime; - sec = time / AUDIO_NS_PER_S; - nanoSec = time % AUDIO_NS_PER_S; - return true; -} - -int32_t HpaeSinkInputNode::GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp) -{ - int64_t timeSec = 0; - int64_t timeNsec = 0; - bool ret = GetAudioTime(framePosition, timeSec, timeNsec); - if (historyBuffer_) { - framePosition = framePosition > historyBuffer_->GetCurFrames() * GetNodeInfo().frameLen - ? framePosition - historyBuffer_->GetCurFrames() * GetNodeInfo().frameLen - : 0; - } - CHECK_AND_RETURN_RET_LOG(ret, ERROR, "GetAudioTime error"); - timespec tm{}; - clock_gettime(CLOCK_MONOTONIC, &tm); - timestamp = static_cast(tm.tv_sec) * AUDIO_NS_PER_S + static_cast(tm.tv_nsec); - return SUCCESS; -} - -int32_t HpaeSinkInputNode::RewindHistoryBuffer(uint64_t rewindTime) -{ - CHECK_AND_RETURN_RET_LOG(historyBuffer_, ERROR, "historyBuffer_ is nullptr"); - AUDIO_INFO_LOG("HpaeSinkInputNode::rewind %{public}zu frames", ConvertUsToFrameCount(rewindTime, GetNodeInfo())); - return historyBuffer_->RewindBuffer(ConvertUsToFrameCount(rewindTime, GetNodeInfo())); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_sink_input_node.cpp b/services/audio_engine/node/src/hpae_sink_input_node.cpp deleted file mode 100644 index 0ca1b86b62..0000000000 --- a/services/audio_engine/node/src/hpae_sink_input_node.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeSinkInputNode" -#endif - -#include "hpae_sink_input_node.h" -#include -#include "hpae_format_convert.h" -#include "hpae_node_common.h" -#include "audio_engine_log.h" -#include "audio_errors.h" -#include "audio_utils.h" -#include "cinttypes" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -static constexpr int32_t DEFAULT_BUFFER_MICROSECOND = 20000000; -static constexpr uint64_t AUDIO_NS_PER_S = 1000000000; - -HpaeSinkInputNode::HpaeSinkInputNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), - pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, (uint64_t)nodeInfo.channelLayout), - inputAudioBuffer_(pcmBufferInfo_), outputStream_(this), - interleveData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), framesWritten_(0), - totalFrames_(0) -{ - AUDIO_INFO_LOG("sinkinput sessionId %{public}d, channelcount %{public}d, channelLayout %{public}" PRIu64 ", " - "frameLen %{public}d", nodeInfo.sessionId, inputAudioBuffer_.GetChannelCount(), - inputAudioBuffer_.GetChannelLayout(), inputAudioBuffer_.GetFrameLen()); - - handleTimeModel_ = std::make_unique(); - handleTimeModel_->ConfigSampleRate(nodeInfo.samplingRate); -#ifdef ENABLE_HOOK_PCM - inputPcmDumper_ = std::make_unique( - "HpaeSinkInputNode_id_" + std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) + - "_rate_" + std::to_string(GetSampleRate()) + "_bit_" + std::to_string(GetBitWidth()) + ".pcm"); -#endif - if (nodeInfo.historyFrameCount > 0) { - PcmBufferInfo pcmInfo = PcmBufferInfo{ - nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, - nodeInfo.historyFrameCount, true}; - historyBuffer_ = std::make_unique(pcmInfo); - AUDIO_INFO_LOG("HpaeSinkInputNode::historybuffer created"); - } else { - historyBuffer_ = nullptr; - } -} - -HpaeSinkInputNode::~HpaeSinkInputNode() -{} - -void HpaeSinkInputNode::CheckAndDestoryHistoryBuffer() -{ - HpaeNodeInfo nodeInfo = GetNodeInfo(); - // historyBuffer_ has no data, check if historyFrameCount is 0 and distory it - if (nodeInfo.historyFrameCount == 0) { - if (historyBuffer_) { - AUDIO_INFO_LOG("HpaeSinkInputNode::historyBuffer_ useless, distory it"); - } - historyBuffer_ = nullptr; - } else if (historyBuffer_ == nullptr) { // this case need to create historyBuffer_ - PcmBufferInfo pcmInfo = PcmBufferInfo{ - nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, - nodeInfo.historyFrameCount, true}; - historyBuffer_ = std::make_unique(pcmInfo); - AUDIO_INFO_LOG("HpaeSinkInputNode::historybuffer created"); - } -} - -void HpaeSinkInputNode::DoProcess() -{ - auto rate = "rate[" + std::to_string(GetSampleRate()) + "]_"; - auto ch = "ch[" + std::to_string(GetChannelCount()) + "]_"; - auto len = "len[" + std::to_string(GetFrameLen()) + "]_"; - auto format = "bit[" + std::to_string(GetBitWidth()) + "]"; - Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeSinkInputNode::DoProcess " + - rate + ch + len + format); - CHECK_AND_RETURN_LOG( - writeCallback_.lock(), "HpaeSinkInputNode writeCallback_ is nullptr, SessionId:%{public}d", GetSessionId()); - - auto nodeCallback = GetNodeStatusCallback().lock(); - if (nodeCallback) { - nodeCallback->OnRequestLatency(GetSessionId(), streamInfo_.latency); - } - - streamInfo_ = {.framesWritten = framesWritten_.load(), - .inputData = interleveData_.data(), - .requestDataLen = interleveData_.size(), - .deviceClass = GetDeviceClass(), - .deviceNetId = GetDeviceNetId(), - .needData = !(historyBuffer_ && historyBuffer_->GetCurFrames())}; - GetCurrentPosition(streamInfo_.framePosition, streamInfo_.timestamp); - int32_t ret = writeCallback_.lock()->OnStreamData(streamInfo_); - - // if historyBuffer has enough data, write to outputStream - if (!streamInfo_.needData) { - historyBuffer_->GetFrameData(inputAudioBuffer_); - outputStream_.WriteDataToOutput(&inputAudioBuffer_); - return; - } - CheckAndDestoryHistoryBuffer(); - if (nodeCallback && ret) { - nodeCallback->OnNodeStatusUpdate(GetSessionId(), OPERATION_UNDERFLOW); - if (isDrain_) { - AUDIO_INFO_LOG("OnNodeStatusUpdate Drain sessionId:%{public}u", GetSessionId()); - nodeCallback->OnNodeStatusUpdate(GetSessionId(), OPERATION_DRAINED); - isDrain_ = false; - } - } - inputAudioBuffer_.SetBufferValid(ret ? false : true); - -#ifdef ENABLE_HOOK_PCM - if (inputPcmDumper_ != nullptr && inputAudioBuffer_.IsValid()) { - inputPcmDumper_->CheckAndReopenHandlde(); - inputPcmDumper_->Dump(static_cast(interleveData_.data()), - GetChannelCount() * GetFrameLen() * GET_SIZE_FROM_FORMAT(GetBitWidth())); - } -#endif - - ConvertToFloat( - GetBitWidth(), GetChannelCount() * GetFrameLen(), interleveData_.data(), inputAudioBuffer_.GetPcmDataBuffer()); - if (ret != 0) { - AUDIO_WARNING_LOG("request data is not enough sessionId:%{public}u", GetSessionId()); - memset_s(inputAudioBuffer_.GetPcmDataBuffer(), inputAudioBuffer_.Size(), 0, inputAudioBuffer_.Size()); - } else { - totalFrames_ = totalFrames_ + GetFrameLen(); - framesWritten_.store(totalFrames_); - if (historyBuffer_) { - historyBuffer_->StoreFrameData(inputAudioBuffer_); - } - } - outputStream_.WriteDataToOutput(&inputAudioBuffer_); -} - -bool HpaeSinkInputNode::Reset() -{ - return true; -} - -bool HpaeSinkInputNode::ResetAll() -{ - return true; -} - -std::shared_ptr HpaeSinkInputNode::GetSharedInstance() -{ - return shared_from_this(); -} - -OutputPort *HpaeSinkInputNode::GetOutputPort() -{ - return &outputStream_; -} - -bool HpaeSinkInputNode::RegisterWriteCallback(const std::weak_ptr &callback) -{ - writeCallback_ = callback; - return true; -} -// reset historyBuffer -void HpaeSinkInputNode::Flush() -{ - if (GetNodeInfo().historyFrameCount == 0) { - historyBuffer_ = nullptr; - } else if (historyBuffer_ && historyBuffer_->GetFrames() == GetNodeInfo().historyFrameCount) { - historyBuffer_->Reset(); - } else { - HpaeNodeInfo nodeInfo = GetNodeInfo(); - PcmBufferInfo pcmInfo = PcmBufferInfo{ - nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate, nodeInfo.channelLayout, - nodeInfo.historyFrameCount, true}; - historyBuffer_ = std::make_unique(pcmInfo); - } -} - -bool HpaeSinkInputNode::Drain() -{ - isDrain_ = true; - return true; -} - -int32_t HpaeSinkInputNode::SetState(RendererState renderState) -{ - state_ = renderState; - return SUCCESS; -} - -RendererState HpaeSinkInputNode::GetState() -{ - return state_; -} - -uint64_t HpaeSinkInputNode::GetFramesWritten() -{ - return framesWritten_.load(); -} - -bool HpaeSinkInputNode::GetAudioTime(uint64_t &framePos, int64_t &sec, int64_t &nanoSec) -{ - framePos = GetFramesWritten(); - int64_t time = handleTimeModel_->GetTimeOfPos(framePos); - int64_t deltaTime = DEFAULT_BUFFER_MICROSECOND; // note: 20ms - time += deltaTime; - sec = time / AUDIO_NS_PER_S; - nanoSec = time % AUDIO_NS_PER_S; - return true; -} - -int32_t HpaeSinkInputNode::GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp) -{ - int64_t timeSec = 0; - int64_t timeNsec = 0; - bool ret = GetAudioTime(framePosition, timeSec, timeNsec); - if (historyBuffer_) { - framePosition = framePosition > historyBuffer_->GetCurFrames() * GetNodeInfo().frameLen - ? framePosition - historyBuffer_->GetCurFrames() * GetNodeInfo().frameLen - : 0; - } - CHECK_AND_RETURN_RET_LOG(ret, ERROR, "GetAudioTime error"); - timespec tm{}; - clock_gettime(CLOCK_MONOTONIC, &tm); - timestamp = static_cast(tm.tv_sec) * AUDIO_NS_PER_S + static_cast(tm.tv_nsec); - return SUCCESS; -} - -int32_t HpaeSinkInputNode::RewindHistoryBuffer(uint64_t rewindTime) -{ - CHECK_AND_RETURN_RET_LOG(historyBuffer_, ERROR, "historyBuffer_ is nullptr"); - AUDIO_INFO_LOG("HpaeSinkInputNode::rewind %{public}zu frames", ConvertUsToFrameCount(rewindTime, GetNodeInfo())); - return historyBuffer_->RewindBuffer(ConvertUsToFrameCount(rewindTime, GetNodeInfo())); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_sink_output_node.cpp b/services/audio_engine/node/src/hpae_sink_output_node.cpp deleted file mode 100644 index 2343ed6ba8..0000000000 --- a/services/audio_engine/node/src/hpae_sink_output_node.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeSinkOutputNode" -#endif - -#include -#include "audio_errors.h" -#include -#include "hpae_format_convert.h" -#include "audio_engine_log.h" -#include "audio_utils.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -namespace { -constexpr uint32_t SLEEP_TIME_IN_US = 2000; -} - -HpaeSinkOutputNode::HpaeSinkOutputNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), - renderFrameData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), - interleveData_(nodeInfo.frameLen * nodeInfo.channels) -{ -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_ = std::make_unique("HpaeSinkOutputNode_Out_bit_" + std::to_string(GetBitWidth()) + - "_ch_" + std::to_string(GetChannelCount()) + "_rate_" + - std::to_string(GetSampleRate()) + ".pcm"); - AUDIO_INFO_LOG("HpaeSinkOutputNode name is %{public}s", sinkOutAttr_.adapterName.c_str()); -#endif -} - -void HpaeSinkOutputNode::HandleRemoteTiming() -{ - remoteTimer_.Stop(); - uint64_t remoteElapsed = remoteTimer_.Elapsed(); - auto now = std::chrono::high_resolution_clock::now(); - remoteTimePoint_ += std::chrono::milliseconds(20); - std::this_thread::sleep_for(remoteSleepTime_); - if (remoteTimePoint_ > now + std::chrono::milliseconds(remoteElapsed)) { - remoteSleepTime_ = std::chrono::duration_cast(remoteTimePoint_ - now) - - std::chrono::milliseconds(remoteElapsed); - } else { - remoteSleepTime_ = std::chrono::milliseconds(0); - } - remoteTimer_.Start(); -} - -void HpaeSinkOutputNode::DoProcess() -{ - auto rate = "rate[" + std::to_string(GetSampleRate()) + "]_"; - auto ch = "ch[" + std::to_string(GetChannelCount()) + "]_"; - auto len = "len[" + std::to_string(GetFrameLen()) + "]_"; - auto format = "bit[" + std::to_string(GetBitWidth()) + "]"; - Trace trace("HpaeSinkOutputNode::DoProcess " + rate + ch + len + format); - if (audioRendererSink_ == nullptr) { - AUDIO_WARNING_LOG("audioRendererSink_ is nullptr sessionId: %{public}u", GetSessionId()); - return; - } - std::vector &outputVec = inputStream_.ReadPreOutputData(); - if (outputVec.empty()) { - return; - } - HpaePcmBuffer *outputData = outputVec.front(); - ConvertFromFloat( - GetBitWidth(), GetChannelCount() * GetFrameLen(), outputData->GetPcmDataBuffer(), renderFrameData_.data()); - uint64_t writeLen = 0; - char *renderFrameData = (char *)renderFrameData_.data(); - -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); - intervalTimer_.Stop(); - uint64_t interval = intervalTimer_.Elapsed(); - AUDIO_DEBUG_LOG("HpaeSinkOutputNode: name %{public}s, RenderFrame interval: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), - interval); - outputPcmDumper_->CheckAndReopenHandlde(); - if (outputPcmDumper_) { - outputPcmDumper_->Dump((int8_t *)renderFrameData, renderFrameData_.size()); - } -#endif - if (GetDeviceClass() == "remote") { - HandleRemoteTiming(); - } - auto ret = audioRendererSink_->RenderFrame(*renderFrameData, renderFrameData_.size(), writeLen); - if (ret != SUCCESS) { - AUDIO_ERR_LOG("HpaeSinkOutputNode: RenderFrame failed"); - usleep(SLEEP_TIME_IN_US); - return; - } -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t elapsed = timer.Elapsed(); - AUDIO_DEBUG_LOG("HpaeSinkOutputNode :name %{public}s, RenderFrame elapsed time: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), - elapsed); - intervalTimer_.Start(); -#endif - return; -} - -const char *HpaeSinkOutputNode::GetRenderFrameData(void) -{ - return renderFrameData_.data(); -} - -bool HpaeSinkOutputNode::Reset() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - inputStream_.DisConnect(output); - } - return true; -} - -bool HpaeSinkOutputNode::ResetAll() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - std::shared_ptr hpaeNode = preOutput.second; - if (hpaeNode->ResetAll()) { - inputStream_.DisConnect(output); - } - } - return true; -} - -void HpaeSinkOutputNode::Connect(const std::shared_ptr> &preNode) -{ - inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); -} - -void HpaeSinkOutputNode::DisConnect(const std::shared_ptr> &preNode) -{ - inputStream_.DisConnect(preNode->GetOutputPort()); -} - -int32_t HpaeSinkOutputNode::GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId) -{ - if (deviceNetId.empty()) { - renderId_ = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, HDI_ID_INFO_DEFAULT, true); - } else { - renderId_ = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, deviceNetId, true); - } - audioRendererSink_ = HdiAdapterManager::GetInstance().GetRenderSink(renderId_, true); - if (audioRendererSink_ == nullptr) { - AUDIO_ERR_LOG("get sink fail, deviceClass: %{public}s, deviceNetId: %{public}s, renderId_: %{public}u", - deviceClass.c_str(), - deviceNetId.c_str(), - renderId_); - HdiAdapterManager::GetInstance().ReleaseId(renderId_); - return ERROR; - } - return SUCCESS; -} - -int32_t HpaeSinkOutputNode::RenderSinkInit(IAudioSinkAttr &attr) -{ - if (audioRendererSink_ == nullptr) { - return ERROR; - } - - sinkOutAttr_ = attr; - state_ = RENDERER_PREPARED; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - int32_t ret = audioRendererSink_->Init(attr); -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkInit Elapsed: %{public}" PRIu64 - " ms ret: %{public}d", - sinkOutAttr_.adapterName.c_str(), - interval, - ret); - std::string adapterName = sinkOutAttr_.adapterName; - outputPcmDumper_ = std::make_unique( - "HpaeSinkOutputNode_" + adapterName + "_bit_" + std::to_string(GetBitWidth()) + "_ch_" + - std::to_string(GetChannelCount()) + "_rate_" + std::to_string(GetSampleRate()) + ".pcm"); -#endif - return ret; -} - -int32_t HpaeSinkOutputNode::RenderSinkDeInit(void) -{ - if (audioRendererSink_ == nullptr) { - return ERROR; - } - state_ = RENDERER_INVALID; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - audioRendererSink_->DeInit(); - audioRendererSink_ = nullptr; - HdiAdapterManager::GetInstance().ReleaseId(renderId_); -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkDeInit Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), - interval); -#endif - return SUCCESS; -} - -int32_t HpaeSinkOutputNode::RenderSinkFlush(void) -{ - if (audioRendererSink_ == nullptr) { - return ERROR; - } - return audioRendererSink_->Flush(); -} - -int32_t HpaeSinkOutputNode::RenderSinkPause(void) -{ - if (audioRendererSink_ == nullptr) { - return ERROR; - } - audioRendererSink_->Pause(); - state_ = RENDERER_PAUSED; - return SUCCESS; -} - -int32_t HpaeSinkOutputNode::RenderSinkReset(void) -{ - if (audioRendererSink_ == nullptr) { - return ERROR; - } - return audioRendererSink_->Reset(); -} - -int32_t HpaeSinkOutputNode::RenderSinkResume(void) -{ - if (audioRendererSink_ == nullptr) { - return ERROR; - } - int32_t ret = audioRendererSink_->Resume(); - if (ret != SUCCESS) { - return ret; - } - state_ = RENDERER_RUNNING; - return SUCCESS; -} - -int32_t HpaeSinkOutputNode::RenderSinkStart(void) -{ - if (audioRendererSink_ == nullptr) { - return ERROR; - } - - int32_t ret; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - ret = audioRendererSink_->Start(); - if (ret != SUCCESS) { - return ERROR; - } -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkStart Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), - interval); -#endif - state_ = RENDERER_RUNNING; - if (GetDeviceClass() == "remote") { - remoteTimePoint_ = std::chrono::high_resolution_clock::now(); - } - return SUCCESS; -} - -int32_t HpaeSinkOutputNode::RenderSinkStop(void) -{ - if (audioRendererSink_ == nullptr) { - return ERROR; - } - int32_t ret; -#ifdef ENABLE_HOOK_PCM - HighResolutionTimer timer; - timer.Start(); -#endif - ret = audioRendererSink_->Stop(); - if (ret != SUCCESS) { - return ret; - } -#ifdef ENABLE_HOOK_PCM - timer.Stop(); - uint64_t interval = timer.Elapsed(); - AUDIO_INFO_LOG("HpaeSinkOutputNode: name %{public}s, RenderSinkStop Elapsed: %{public}" PRIu64 " ms", - sinkOutAttr_.adapterName.c_str(), interval); -#endif - state_ = RENDERER_STOPPED; - return SUCCESS; -} - -RendererState HpaeSinkOutputNode::GetSinkState(void) -{ - return state_; -} - -size_t HpaeSinkOutputNode::GetPreOutNum() -{ - return inputStream_.GetPreOutputNum(); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/node/src/hpae_source_input_cluster.cpp b/services/audio_engine/node/src/hpae_source_input_cluster.cpp deleted file mode 100644 index f1f063f127..0000000000 --- a/services/audio_engine/node/src/hpae_source_input_cluster.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeSourceInputCluster" -#endif - -#include "hpae_source_input_cluster.h" -#include "hpae_node_common.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -static std::string TransSourceBufferTypeToString(HpaeSourceBufferType &type) -{ - if (type == HPAE_SOURCE_BUFFER_TYPE_MIC) { - return "MIC"; - } else if (type == HPAE_SOURCE_BUFFER_TYPE_EC) { - return "EC"; - } else if (type == HPAE_SOURCE_BUFFER_TYPE_MICREF) { - return "MICREF"; - } - return "DEFAULT"; -} - -HpaeSourceInputCluster::HpaeSourceInputCluster(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), sourceInputNode_(std::make_shared(nodeInfo)) -{ -#ifdef ENABLE_HIDUMP_DFX - if (nodeInfo.statusCallback.lock()) { - nodeInfo.nodeName = "HpaeSourceInputNode[" + TransSourceBufferTypeToString(nodeInfo.sourceBufferType) + "]"; - nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); - sourceInputNode_->SetNodeInfo(nodeInfo); - nodeInfo.statusCallback.lock()->OnNotifyDfxNodeInfo(true, 0, nodeInfo); - } -#endif -} - -HpaeSourceInputCluster::HpaeSourceInputCluster(std::vector &nodeInfos) - : HpaeNode(*nodeInfos.begin()), sourceInputNode_(std::make_shared(nodeInfos)) -{ -#ifdef ENABLE_HIDUMP_DFX - auto nodeInfo = *nodeInfos.begin(); - nodeInfo.nodeName = "HpaeSourceInputNode[" + TransSourceBufferTypeToString(nodeInfo.sourceBufferType) + "]"; - nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); - sourceInputNode_->SetNodeInfo(nodeInfo); - nodeInfo.statusCallback.lock()->OnNotifyDfxNodeInfo(true, 0, nodeInfo); -#endif -} - -HpaeSourceInputCluster::~HpaeSourceInputCluster() -{ - Reset(); -} - -void HpaeSourceInputCluster::DoProcess() -{ -} - -bool HpaeSourceInputCluster::Reset() -{ - for (auto fmtConverterNode : fmtConverterNodeMap_) { - fmtConverterNode.second->Reset(); - } - sourceInputNode_->Reset(); - return true; -} - -bool HpaeSourceInputCluster::ResetAll() -{ - for (auto fmtConverterNode : fmtConverterNodeMap_) { - fmtConverterNode.second->ResetAll(); - } - sourceInputNode_->ResetAll(); - return true; -} - -std::shared_ptr HpaeSourceInputCluster::GetSharedInstance() -{ - return sourceInputNode_; -} - -std::shared_ptr HpaeSourceInputCluster::GetSharedInstance(HpaeNodeInfo &nodeInfo) -{ - // todo: change function name - std::string nodeKey = TransHpaeResampleNodeInfoToStringKey(nodeInfo); - std::string inputNodeKey = TransHpaeResampleNodeInfoToStringKey(GetNodeInfo()); - AUDIO_INFO_LOG("sourceinput nodekey:[%{public}s] effectnodekey:[%{public}s]", - inputNodeKey.c_str(), nodeKey.c_str()); - if (CheckHpaeNodeInfoIsSame(nodeInfo, GetNodeInfo())) { - AUDIO_INFO_LOG("sourceinputnode nodekey is same as capture effect"); - return sourceInputNode_; - } - if (fmtConverterNodeMap_.find(nodeKey) == fmtConverterNodeMap_.end()) { - fmtConverterNodeMap_[nodeKey] = std::make_shared(GetNodeInfo(), nodeInfo); - nodeInfo.nodeName = "HpaeAudioFormatConverterNode"; - nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); - fmtConverterNodeMap_[nodeKey]->SetNodeInfo(nodeInfo); - } - fmtConverterNodeMap_[nodeKey]->ConnectWithInfo(sourceInputNode_, fmtConverterNodeMap_[nodeKey]->GetNodeInfo()); -#ifdef ENABLE_HIDUMP_DFX - if (auto callback = sourceInputNode_->GetNodeInfo().statusCallback.lock()) { - callback->OnNotifyDfxNodeInfo( - true, sourceInputNode_->GetNodeId(), fmtConverterNodeMap_[nodeKey]->GetNodeInfo()); - } -#endif - return fmtConverterNodeMap_[nodeKey]; -} - -OutputPort *HpaeSourceInputCluster::GetOutputPort() -{ - return sourceInputNode_->GetOutputPort(); -} - -OutputPort *HpaeSourceInputCluster::GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect) -{ - std::string nodeKey = TransHpaeResampleNodeInfoToStringKey(nodeInfo); - std::string inputNodeKey = TransHpaeResampleNodeInfoToStringKey(GetNodeInfo()); - AUDIO_INFO_LOG("sourceinput nodekey:[%{public}s] effectnodekey:[%{public}s]", - inputNodeKey.c_str(), nodeKey.c_str()); - if (CheckHpaeNodeInfoIsSame(nodeInfo, GetNodeInfo())) { - AUDIO_INFO_LOG("sourceinputnode nodekey is same as capture effect"); - return sourceInputNode_->GetOutputPort(nodeInfo); - } - CHECK_AND_RETURN_RET_LOG(fmtConverterNodeMap_.find(nodeKey) != fmtConverterNodeMap_.end(), nullptr, - "HpaeSourceProcessCluster not find the nodeKey = %{public}s", nodeKey.c_str()); - if (isDisConnect && fmtConverterNodeMap_[nodeKey]->GetOutputPortNum() <= 1) { - AUDIO_INFO_LOG("disconnect fmtConverterNode between effectnode[[%{public}s] and sourceinputnode[%{public}s]", - nodeKey.c_str(), inputNodeKey.c_str()); - fmtConverterNodeMap_[nodeKey]->DisConnectWithInfo(sourceInputNode_, fmtConverterNodeMap_[nodeKey]->GetNodeInfo()); - } - return fmtConverterNodeMap_[nodeKey]->GetOutputPort(); -} - -int32_t HpaeSourceInputCluster::GetCapturerSourceInstance(const std::string &deviceClass, - const std::string &deviceNetId, const SourceType &sourceType, const std::string &sourceName) -{ - return sourceInputNode_->GetCapturerSourceInstance(deviceClass, deviceNetId, sourceType, sourceName); -} - -int32_t HpaeSourceInputCluster::CapturerSourceInit(IAudioSourceAttr &attr) -{ - return sourceInputNode_->CapturerSourceInit(attr); -} - -int32_t HpaeSourceInputCluster::CapturerSourceDeInit() -{ - return sourceInputNode_->CapturerSourceDeInit(); -} - -int32_t HpaeSourceInputCluster::CapturerSourceFlush(void) -{ - return sourceInputNode_->CapturerSourceFlush(); -} - -int32_t HpaeSourceInputCluster::CapturerSourcePause(void) -{ - return sourceInputNode_->CapturerSourcePause(); -} - -int32_t HpaeSourceInputCluster::CapturerSourceReset(void) -{ - return sourceInputNode_->CapturerSourceReset(); -} - -int32_t HpaeSourceInputCluster::CapturerSourceResume(void) -{ - return sourceInputNode_->CapturerSourceResume(); -} - -int32_t HpaeSourceInputCluster::CapturerSourceStart(void) -{ - return sourceInputNode_->CapturerSourceStart(); -} - -int32_t HpaeSourceInputCluster::CapturerSourceStop(void) -{ - return sourceInputNode_->CapturerSourceStop(); -} - -CapturerState HpaeSourceInputCluster::GetSourceState(void) -{ - return sourceInputNode_->GetSourceState(); -} - -size_t HpaeSourceInputCluster::GetOutputPortNum() -{ - return sourceInputNode_->GetOutputPortNum(); -} - -size_t HpaeSourceInputCluster::GetOutputPortNum(HpaeNodeInfo &nodeInfo) -{ - return sourceInputNode_->GetOutputPortNum(nodeInfo); -} - -HpaeSourceInputNodeType HpaeSourceInputCluster::GetSourceInputNodeType() -{ - return sourceInputNode_->GetSourceInputNodeType(); -} - -void HpaeSourceInputCluster::SetSourceInputNodeType(HpaeSourceInputNodeType type) -{ - sourceInputNode_->SetSourceInputNodeType(type); -} - -// for test -uint32_t HpaeSourceInputCluster::GetConverterNodeCount() -{ - return fmtConverterNodeMap_.size(); -} - -uint32_t HpaeSourceInputCluster::GetSourceInputNodeUseCount() -{ - return sourceInputNode_.use_count(); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_source_input_node.cpp b/services/audio_engine/node/src/hpae_source_input_node.cpp deleted file mode 100644 index 91ee4f5f5d..0000000000 --- a/services/audio_engine/node/src/hpae_source_input_node.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeSourceInputNode" -#endif - -#include "hpae_source_input_node.h" -#include "hpae_format_convert.h" -#include "hpae_node_common.h" -#include "audio_errors.h" -#include "audio_engine_log.h" - -#define BYTE_SIZE_SAMPLE_U8 1 -#define BYTE_SIZE_SAMPLE_S16 2 -#define BYTE_SIZE_SAMPLE_S24 3 -#define BYTE_SIZE_SAMPLE_S32 4 -#define FRAME_DURATION_DEFAULT 20 -#define MILLISECOND_PER_SECOND 1000 - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - static std::string TransSourceBufferTypeToString(HpaeSourceBufferType &type) -{ - switch (type) { - case HPAE_SOURCE_BUFFER_TYPE_EC: - return "_EC.pcm"; - case HPAE_SOURCE_BUFFER_TYPE_MICREF: - return "_MICREF.pcm"; - default: - return ".pcm"; - } -} - -HpaeSourceInputNode::HpaeSourceInputNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), sourceInputNodeType_(nodeInfo.sourceInputNodeType) -{ - HpaeSourceBufferType sourceBufferType = nodeInfo.sourceBufferType; - nodeInfoMap_.emplace(sourceBufferType, nodeInfo); - pcmBufferInfoMap_.emplace( - sourceBufferType, PcmBufferInfo(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate)); - inputAudioBufferMap_.emplace(sourceBufferType, HpaePcmBuffer(pcmBufferInfoMap_.at(sourceBufferType))); - inputAudioBufferMap_.at(sourceBufferType).SetSourceBufferType(sourceBufferType); - frameByteSizeMap_.emplace( - sourceBufferType, nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); - capturerFrameDataMap_.emplace(sourceBufferType, frameByteSizeMap_.at(sourceBufferType)); - outputStreamMap_.emplace(sourceBufferType, this); - -#ifdef ENABLE_HOOK_PCM - inputPcmDumperMap_.emplace(sourceBufferType, - std::make_unique("HpaeSourceInputNode_id_"+ std::to_string(GetSessionId()) + - "_ch_" + std::to_string(GetChannelCount()) + - "_rate_" + std::to_string(GetSampleRate()) + - "_bit_"+ std::to_string(GetBitWidth()) + TransSourceBufferTypeToString(sourceBufferType))); -#endif -} - -HpaeSourceInputNode::HpaeSourceInputNode(std::vector &nodeInfos) - : HpaeNode(*nodeInfos.begin()), sourceInputNodeType_((*nodeInfos.begin()).sourceInputNodeType) -{ - for (auto nodeInfo : nodeInfos) { - HpaeSourceBufferType sourceBufferType = nodeInfo.sourceBufferType; - nodeInfoMap_.emplace(sourceBufferType, nodeInfo); - pcmBufferInfoMap_.emplace( - sourceBufferType, PcmBufferInfo(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate)); - inputAudioBufferMap_.emplace(sourceBufferType, HpaePcmBuffer(pcmBufferInfoMap_.at(sourceBufferType))); - inputAudioBufferMap_.at(sourceBufferType).SetSourceBufferType(sourceBufferType); - frameByteSizeMap_.emplace( - sourceBufferType, nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); - capturerFrameDataMap_.emplace(sourceBufferType, frameByteSizeMap_.at(sourceBufferType)); - fdescMap_.emplace(sourceBufferType, - FrameDesc{capturerFrameDataMap_.at(sourceBufferType).data(), frameByteSizeMap_.at(sourceBufferType)}); - outputStreamMap_.emplace(sourceBufferType, this); -#ifdef ENABLE_HOOK_PCM - inputPcmDumperMap_.emplace(sourceBufferType, - std::make_unique("HpaeSourceInputNode_id_"+ std::to_string(GetSessionId()) + - "_ch_" + std::to_string(nodeInfo.channels) + - "_rate_" + std::to_string(nodeInfo.samplingRate) + - "_bit_"+ std::to_string(nodeInfo.format) + TransSourceBufferTypeToString(sourceBufferType))); -#endif - } -} - -void HpaeSourceInputNode::DoProcess() -{ - if (audioCapturerSource_ == nullptr) { - AUDIO_WARNING_LOG("audioCapturerSource_ is nullptr NodeId: %{public}u", GetNodeId()); - return; - } - uint64_t replyBytes = 0; - if (sourceInputNodeType_ == HpaeSourceInputNodeType::HPAE_SOURCE_MIC_EC) { - uint64_t replyBytesEc = 0; - audioCapturerSource_->CaptureFrameWithEc(&fdescMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC), replyBytes, - &fdescMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC), replyBytesEc); -#ifdef ENABLE_HOOK_PCM - if (inputPcmDumperMap_.find(HPAE_SOURCE_BUFFER_TYPE_MIC) != inputPcmDumperMap_.end() && - inputPcmDumperMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC)) { - inputPcmDumperMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC)->Dump( - (int8_t *) capturerFrameDataMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC).data(), replyBytes); - } - if (inputPcmDumperMap_.find(HPAE_SOURCE_BUFFER_TYPE_EC) != inputPcmDumperMap_.end() && - inputPcmDumperMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC)) { - inputPcmDumperMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC)->Dump( - (int8_t *) capturerFrameDataMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).data(), replyBytesEc); - } -#endif - // todo: do not convert to float in SourceInputNode - ConvertToFloat(GetBitWidth(), GetChannelCount() * GetFrameLen(), - capturerFrameDataMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC).data(), - inputAudioBufferMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC).GetPcmDataBuffer()); - ConvertToFloat(nodeInfoMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).format, - nodeInfoMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).channels * nodeInfoMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).frameLen, - capturerFrameDataMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).data(), - inputAudioBufferMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).GetPcmDataBuffer()); - outputStreamMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC).WriteDataToOutput( - &inputAudioBufferMap_.at(HPAE_SOURCE_BUFFER_TYPE_MIC)); - outputStreamMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC).WriteDataToOutput( - &inputAudioBufferMap_.at(HPAE_SOURCE_BUFFER_TYPE_EC)); - } else { - HpaeSourceBufferType sourceBufferType = nodeInfoMap_.begin()->second.sourceBufferType; - audioCapturerSource_->CaptureFrame(capturerFrameDataMap_.at(sourceBufferType).data(), - (uint64_t)frameByteSizeMap_.at(sourceBufferType), replyBytes); -#ifdef ENABLE_HOOK_PCM - if (inputPcmDumperMap_.find(sourceBufferType) != inputPcmDumperMap_.end() && - inputPcmDumperMap_.at(sourceBufferType)) { - inputPcmDumperMap_.at(sourceBufferType)->Dump( - (int8_t *) capturerFrameDataMap_.at(sourceBufferType).data(), replyBytes); - } -#endif - // todo: do not convert to float in SourceInputNode - ConvertToFloat(GetBitWidth(), GetChannelCount() * GetFrameLen(), capturerFrameDataMap_.at(sourceBufferType).data(), - inputAudioBufferMap_.at(sourceBufferType).GetPcmDataBuffer()); - outputStreamMap_.at(sourceBufferType).WriteDataToOutput(&inputAudioBufferMap_.at(sourceBufferType)); - } -} - -int32_t HpaeSourceInputNode::WriteCapturerData(char *data, int32_t dataSize) -{ - auto itCapturerFrameData = capturerFrameDataMap_.begin(); - auto itFrameByteSize = frameByteSizeMap_.begin(); - CHECK_AND_RETURN_RET_LOG( - itCapturerFrameData != capturerFrameDataMap_.end() && itFrameByteSize != frameByteSizeMap_.end(), - ERROR, "outStreamMap_ is empty.\n"); - memcpy_s(itCapturerFrameData->second.data(), itFrameByteSize->second, data, dataSize); - return 0; -} - -bool HpaeSourceInputNode::Reset() -{ - return true; -} - -bool HpaeSourceInputNode::ResetAll() -{ - return true; -} - -std::shared_ptr HpaeSourceInputNode::GetSharedInstance() -{ - return shared_from_this(); -} - -OutputPort *HpaeSourceInputNode::GetOutputPort() -{ - std::unordered_map>::iterator it; - if (sourceInputNodeType_ != HPAE_SOURCE_MIC_EC) { - it = outputStreamMap_.begin(); - } else { - it = outputStreamMap_.find(HPAE_SOURCE_BUFFER_TYPE_MIC); - } - CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), nullptr, "outStreamMap_ is empty.\n"); - return &(it->second); -} - -OutputPort *HpaeSourceInputNode::GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect) -{ - auto it = outputStreamMap_.find(nodeInfo.sourceBufferType); - CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), nullptr, - "can't find nodeKey in outStreamMap_, sourceBufferType = %{public}d.\n", - nodeInfo.sourceBufferType); - return &(it->second); -} - -HpaeSourceBufferType HpaeSourceInputNode::GetOutputPortBufferType(HpaeNodeInfo &nodeInfo) -{ - auto it = outputStreamMap_.find(nodeInfo.sourceBufferType); - CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), HPAE_SOURCE_BUFFER_TYPE_DEFAULT, - "can't find nodeKey in outStreamMap_, sourceBufferType = %{public}d.\n", nodeInfo.sourceBufferType); - // todo: rewrite this function - if (sourceInputNodeType_ == HpaeSourceInputNodeType::HPAE_SOURCE_MIC_EC) { - if (nodeInfo.sourceBufferType == HPAE_SOURCE_BUFFER_TYPE_MIC) { - return HPAE_SOURCE_BUFFER_TYPE_MIC; - } else { - return HPAE_SOURCE_BUFFER_TYPE_EC; - } - } else { - return inputAudioBufferMap_.at(nodeInfo.sourceBufferType).GetSourceBufferType(); - } -} - -int32_t HpaeSourceInputNode::GetCapturerSourceAdapter( - const std::string &deviceClass, const SourceType &sourceType, const std::string &info) { - captureId_ = HDI_INVALID_ID; - if (info.empty()) { - captureId_ = HdiAdapterManager::GetInstance().GetCaptureIdByDeviceClass( - deviceClass, sourceType, HDI_ID_INFO_DEFAULT, true); - } else { - captureId_ = HdiAdapterManager::GetInstance().GetCaptureIdByDeviceClass( - deviceClass, sourceType, info, true); - } - audioCapturerSource_ = HdiAdapterManager::GetInstance().GetCaptureSource(captureId_, true); - if (audioCapturerSource_ == nullptr) { - AUDIO_ERR_LOG("get source fail, deviceClass: %{public}s, info: %{public}s, captureId_: %{public}u", - deviceClass.c_str(), info.c_str(), captureId_); - HdiAdapterManager::GetInstance().ReleaseId(captureId_); - return ERROR; - } - return SUCCESS; -} - -int32_t HpaeSourceInputNode::GetCapturerSourceInstance(const std::string &deviceClass, const std::string &deviceNetId, - const SourceType &sourceType, const std::string &sourceName) -{ - if (sourceType == SOURCE_TYPE_WAKEUP || sourceName == HDI_ID_INFO_EC || sourceName == HDI_ID_INFO_MIC_REF) { - return GetCapturerSourceAdapter(deviceClass, sourceType, sourceName); - } - return GetCapturerSourceAdapter(deviceClass, sourceType, deviceNetId); -} - -int32_t HpaeSourceInputNode::CapturerSourceInit(IAudioSourceAttr &attr) -{ - if (audioCapturerSource_ == nullptr) { - return ERROR; - } - - if (audioCapturerSource_->IsInited()) { - return SUCCESS; - } - - audioSourceAttr_ = attr; - CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Init(attr) == SUCCESS, ERROR, "Source init fail"); - state_ = CAPTURER_NEW; - return SUCCESS; -} - -int32_t HpaeSourceInputNode::CapturerSourceDeInit() -{ - if (audioCapturerSource_ == nullptr) { - return ERROR; - } - audioCapturerSource_->DeInit(); - audioCapturerSource_ = nullptr; - // todo: check where to release captureId_ - HdiAdapterManager::GetInstance().ReleaseId(captureId_); - return SUCCESS; -} - -int32_t HpaeSourceInputNode::CapturerSourceFlush(void) -{ - if (audioCapturerSource_ == nullptr) { - return ERROR; - } - return audioCapturerSource_->Flush(); -} - -int32_t HpaeSourceInputNode::CapturerSourcePause(void) -{ - if (audioCapturerSource_ == nullptr) { - return ERROR; - } - CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Pause() == SUCCESS, ERROR, "Source pause fail"); - state_ = CAPTURER_PAUSED; - return SUCCESS; -} - -int32_t HpaeSourceInputNode::CapturerSourceReset(void) -{ - if (audioCapturerSource_ == nullptr) { - return ERROR; - } - return audioCapturerSource_->Reset(); -} - -int32_t HpaeSourceInputNode::CapturerSourceResume(void) -{ - if (audioCapturerSource_ == nullptr) { - return ERROR; - } - CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Resume() == SUCCESS, ERROR, "Source resume fail"); - state_ = CAPTURER_RUNNING; - return SUCCESS; -} - -int32_t HpaeSourceInputNode::CapturerSourceStart(void) -{ - if (audioCapturerSource_ == nullptr) { - return ERROR; - } - CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Start() == SUCCESS, ERROR, "Source start fail"); - state_ = CAPTURER_RUNNING; - return SUCCESS; -} - -int32_t HpaeSourceInputNode::CapturerSourceStop(void) -{ - if (audioCapturerSource_ == nullptr) { - return ERROR; - } - CHECK_AND_RETURN_RET_LOG(audioCapturerSource_->Stop() == SUCCESS, ERROR, "Source stop fail"); - state_ = CAPTURER_STOPPED; - return SUCCESS; -} - -CapturerState HpaeSourceInputNode::GetSourceState(void) -{ - return state_; -} - -size_t HpaeSourceInputNode::GetOutputPortNum() -{ - std::unordered_map>::iterator it; - if (sourceInputNodeType_ != HPAE_SOURCE_MIC_EC) { - it = outputStreamMap_.begin(); - } else { - it = outputStreamMap_.find(HPAE_SOURCE_BUFFER_TYPE_MIC); - } - CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), 0, "outStreamMap_ is empty.\n"); - return it->second.GetInputNum(); -} - -size_t HpaeSourceInputNode::GetOutputPortNum(HpaeNodeInfo &nodeInfo) -{ - auto it = outputStreamMap_.find(nodeInfo.sourceBufferType); - CHECK_AND_RETURN_RET_LOG(it != outputStreamMap_.end(), 0, "can't find nodeKey in outStreamMap_.\n"); - return it->second.GetInputNum(); -} - -HpaeSourceInputNodeType HpaeSourceInputNode::GetSourceInputNodeType() -{ - return sourceInputNodeType_; -} - -void HpaeSourceInputNode::SetSourceInputNodeType(HpaeSourceInputNodeType type) -{ - sourceInputNodeType_ = type; -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/node/src/hpae_source_output_node.cpp b/services/audio_engine/node/src/hpae_source_output_node.cpp deleted file mode 100644 index db70e96c69..0000000000 --- a/services/audio_engine/node/src/hpae_source_output_node.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeSourceOutputNode" -#endif - -#include -#include "audio_engine_log.h" -#include "hpae_format_convert.h" -#include "audio_utils.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaeSourceOutputNode::HpaeSourceOutputNode(HpaeNodeInfo &nodeInfo) - : HpaeNode(nodeInfo), - sourceOuputData_(nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)), - interleveData_(nodeInfo.frameLen * nodeInfo.channels) -{ -#ifdef ENABLE_HOOK_PCM - outputPcmDumper_ = std::make_unique( - "HpaeSourceOutputNode_id_" + std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) + - "_rate_" + std::to_string(GetSampleRate()) + "_bit_" + std::to_string(GetBitWidth()) + ".pcm"); -#endif -} - -void HpaeSourceOutputNode::DoProcess() -{ - auto rate = "rate[" + std::to_string(GetSampleRate()) + "]_"; - auto ch = "ch[" + std::to_string(GetChannelCount()) + "]_"; - auto len = "len[" + std::to_string(GetFrameLen()) + "]_"; - auto format = "bit[" + std::to_string(GetBitWidth()) + "]"; - Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeSourceOutputNode::DoProcess " + - rate + ch + len + format); - if (readCallback_.lock() == nullptr) { - AUDIO_WARNING_LOG("HpaeSourceOutputNode readCallback_ is nullptr"); - return; - } - std::vector &outputVec = inputStream_.ReadPreOutputData(); - if (outputVec.empty()) { - return; - } - HpaePcmBuffer *outputData = outputVec.front(); - ConvertFromFloat( - GetBitWidth(), GetChannelCount() * GetFrameLen(), outputData->GetPcmDataBuffer(), sourceOuputData_.data()); -#ifdef ENABLE_HOOK_PCM - if (outputPcmDumper_) { - outputPcmDumper_->Dump( - (int8_t *)sourceOuputData_.data(), GetChannelCount() * GetFrameLen() * GET_SIZE_FROM_FORMAT(GetBitWidth())); - } -#endif - int32_t ret = readCallback_.lock()->OnReadData(sourceOuputData_, sourceOuputData_.size()); - if (ret != 0) { - AUDIO_WARNING_LOG("sessionId %{public}u, readCallback_ write read data error", GetSessionId()); - } - return; -} - -bool HpaeSourceOutputNode::Reset() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - inputStream_.DisConnect(output); - } - return true; -} - -bool HpaeSourceOutputNode::ResetAll() -{ - const auto preOutputMap = inputStream_.GetPreOuputMap(); - for (const auto &preOutput : preOutputMap) { - OutputPort *output = preOutput.first; - std::shared_ptr hpaeNode = preOutput.second; - if (hpaeNode->ResetAll()) { - inputStream_.DisConnect(output); - } - } - return true; -} - -bool HpaeSourceOutputNode::RegisterReadCallback(const std::weak_ptr &callback) -{ - if (callback.lock() == nullptr) { - return false; - } - readCallback_ = callback; - return true; -} - -void HpaeSourceOutputNode::Connect(const std::shared_ptr> &preNode) -{ - inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort()); -} - -void HpaeSourceOutputNode::ConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) -{ - std::shared_ptr realPreNode = preNode->GetSharedInstance(nodeInfo); - inputStream_.Connect(realPreNode, preNode->GetOutputPort(nodeInfo)); -#ifdef ENABLE_HIDUMP_DFX - if (auto callback = GetNodeInfo().statusCallback.lock()) { - callback->OnNotifyDfxNodeInfo( - true, realPreNode->GetNodeId(), GetNodeInfo()); - } -#endif -} - -void HpaeSourceOutputNode::DisConnect(const std::shared_ptr> &preNode) -{ - inputStream_.DisConnect(preNode->GetOutputPort()); -} - -void HpaeSourceOutputNode::DisConnectWithInfo(const std::shared_ptr> &preNode, - HpaeNodeInfo &nodeInfo) -{ - inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true)); -} - - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/node/src/hpae_source_process_cluster.cpp b/services/audio_engine/node/src/hpae_source_process_cluster.cpp deleted file mode 100644 index 26ad3a9fb9..0000000000 --- a/services/audio_engine/node/src/hpae_source_process_cluster.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeSourceProcessCluster" -#endif - -#include "hpae_source_process_cluster.h" -#include "hpae_node_common.h" -#include "audio_engine_log.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -HpaeSourceProcessCluster::HpaeSourceProcessCluster(HpaeNodeInfo& nodeInfo) - : HpaeNode(nodeInfo), captureEffectNode_(std::make_shared(nodeInfo)) -{ - AUDIO_INFO_LOG("Create scene ProcessCluster, sceneType = %{public}u", nodeInfo.sceneType); -} - -HpaeSourceProcessCluster::~HpaeSourceProcessCluster() -{ - Reset(); -} - -void HpaeSourceProcessCluster::DoProcess() -{ -} - -bool HpaeSourceProcessCluster::Reset() -{ - captureEffectNode_->Reset(); - for (auto fmtConverterNode : fmtConverterNodeMap_) { - fmtConverterNode.second->Reset(); - } - return true; -} - -bool HpaeSourceProcessCluster::ResetAll() -{ - return captureEffectNode_->ResetAll(); -} - -std::shared_ptr HpaeSourceProcessCluster::GetSharedInstance() -{ - return captureEffectNode_; -} - -OutputPort *HpaeSourceProcessCluster::GetOutputPort() -{ - return captureEffectNode_->GetOutputPort(); -} - -std::shared_ptr HpaeSourceProcessCluster::GetSharedInstance(HpaeNodeInfo &nodeInfo) -{ - std::string nodeKey = TransHpaeResampleNodeInfoToStringKey(nodeInfo); - HpaeNodeInfo effectNodeInfo; - captureEffectNode_->GetCapturerEffectConfig(effectNodeInfo); - std::string effectNodeKey = TransHpaeResampleNodeInfoToStringKey(effectNodeInfo); - AUDIO_INFO_LOG("sourceoutput nodekey:[%{public}s] effectnodekey:[%{public}s]", - nodeKey.c_str(), effectNodeKey.c_str()); - if (CheckHpaeNodeInfoIsSame(nodeInfo, effectNodeInfo)) { - AUDIO_INFO_LOG("sourceoutputnode nodekey is same as capture effect"); - return captureEffectNode_; - } - if (fmtConverterNodeMap_.find(nodeKey) == fmtConverterNodeMap_.end()) { - fmtConverterNodeMap_[nodeKey] = std::make_shared(effectNodeInfo, nodeInfo); - nodeInfo.nodeName = "HpaeAudioFormatConverterNode"; - nodeInfo.nodeId = nodeInfo.statusCallback.lock()->OnGetNodeId(); - fmtConverterNodeMap_[nodeKey]->SetNodeInfo(nodeInfo); - } - fmtConverterNodeMap_[nodeKey]->Connect(captureEffectNode_); -#ifdef ENABLE_HIDUMP_DFX - if (auto callback = nodeInfo.statusCallback.lock()) { - callback->OnNotifyDfxNodeInfo( - true, captureEffectNode_->GetNodeId(), fmtConverterNodeMap_[nodeKey]->GetNodeInfo()); - } -#endif - return fmtConverterNodeMap_[nodeKey]; -} - -OutputPort *HpaeSourceProcessCluster::GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect) -{ - std::string nodeKey = TransHpaeResampleNodeInfoToStringKey(nodeInfo); - HpaeNodeInfo effectNodeInfo; - captureEffectNode_->GetCapturerEffectConfig(effectNodeInfo); - std::string effectNodeKey = TransHpaeResampleNodeInfoToStringKey(effectNodeInfo); - AUDIO_INFO_LOG("sourceoutput nodekey:[%{public}s] effectnodekey:[%{public}s]", - nodeKey.c_str(), effectNodeKey.c_str()); - if (CheckHpaeNodeInfoIsSame(nodeInfo, effectNodeInfo)) { - AUDIO_INFO_LOG("sourceoutputnode nodekey is same as capture effect"); - return captureEffectNode_->GetOutputPort(); - } - CHECK_AND_RETURN_RET_LOG(fmtConverterNodeMap_.find(nodeKey) != fmtConverterNodeMap_.end(), nullptr, - "HpaeSourceProcessCluster not find the nodeKey = %{public}s", nodeKey.c_str()); - if (isDisConnect && fmtConverterNodeMap_[nodeKey]->GetOutputPortNum() <= 1) { - // disconnect fmtConverterNode->upEffectNode - AUDIO_INFO_LOG("disconnect fmtConverterNode between effectnode[[%{public}s] and sourceoutputnode[%{public}s]", - effectNodeKey.c_str(), nodeKey.c_str()); - fmtConverterNodeMap_[nodeKey]->DisConnect(captureEffectNode_); - } - return fmtConverterNodeMap_[nodeKey]->GetOutputPort(); -} - -void HpaeSourceProcessCluster::Connect(const std::shared_ptr> &preNode) -{ - HpaeNodeInfo effectNodeInfo; - captureEffectNode_->GetCapturerEffectConfig(effectNodeInfo); - captureEffectNode_->ConnectWithInfo(preNode, effectNodeInfo); -} - -void HpaeSourceProcessCluster::DisConnect(const std::shared_ptr> &preNode) -{ - HpaeNodeInfo effectNodeInfo; - captureEffectNode_->GetCapturerEffectConfig(effectNodeInfo); - captureEffectNode_->DisConnectWithInfo(preNode, effectNodeInfo); -} - -void HpaeSourceProcessCluster::ConnectWithInfo(const std::shared_ptr>& preNode, - HpaeNodeInfo &nodeInfo) -{ - captureEffectNode_->ConnectWithInfo(preNode, nodeInfo); -} - -void HpaeSourceProcessCluster::DisConnectWithInfo(const std::shared_ptr>& preNode, - HpaeNodeInfo &nodeInfo) -{ - captureEffectNode_->DisConnectWithInfo(preNode, nodeInfo); -} - -bool HpaeSourceProcessCluster::GetCapturerEffectConfig(HpaeNodeInfo &nodeInfo, HpaeSourceBufferType type) -{ - return captureEffectNode_->GetCapturerEffectConfig(nodeInfo, type); -} - -size_t HpaeSourceProcessCluster::GetOutputPortNum() -{ - return captureEffectNode_->GetOutputPortNum(); -} - -int32_t HpaeSourceProcessCluster::CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr) -{ - CHECK_AND_RETURN_RET_LOG(captureEffectNode_, ERROR_ILLEGAL_STATE, "captureEffectNode_ is nullptr"); - return captureEffectNode_->CaptureEffectCreate(sceneKeyCode, attr); -} - -int32_t HpaeSourceProcessCluster::CaptureEffectRelease(uint64_t sceneKeyCode) -{ - CHECK_AND_RETURN_RET_LOG(captureEffectNode_, ERROR_ILLEGAL_STATE, "captureEffectNode_ is nullptr"); - return captureEffectNode_->CaptureEffectRelease(sceneKeyCode); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.c b/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.c deleted file mode 100644 index 5bebe28106..0000000000 --- a/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include -#include "bitdepth_converter.h" - -#ifndef NULL -#define NULL 0 -#endif - -#define INDEX_TWO 2 -#define INDEX_THREE 3 -#define SHIFTS_8BIT 8 -#define SHIFTS_16BIT 16 -#define SHIFTS_24BIT 24 - -#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) - -static inline uint32_t READ24LE(const uint8_t *p) -{ - return ((uint32_t)p[INDEX_TWO] << SHIFTS_16BIT) | - ((uint32_t)p[1] << SHIFTS_8BIT) | - ((uint32_t)p[0]); -} - -static inline void WRITE24LE(uint8_t *p, uint32_t u) -{ - p[INDEX_TWO] = (uint8_t)(u >> SHIFTS_16BIT); - p[1] = (uint8_t)(u >> SHIFTS_8BIT); - p[0] = (uint8_t)u; -} - -// SAMPLE_U8 -// U8ToS16Le -static void U8ToS16Le(unsigned n, const uint8_t* a, int16_t* b) -{ - for (; n > 0; n--, a++, b++) { - *b = (int16_t)(*a - (uint8_t)0x80U) << SHIFTS_8BIT; - } -} -// U8ToS24Le -static void U8ToS24Le(unsigned n, const uint8_t* a, uint8_t* b) -{ - for (; n > 0; n--) { - WRITE24LE(b, (uint32_t)(*a - (uint8_t)0x80U) << SHIFTS_16BIT); - a++; - b += INDEX_THREE; - } -} -// U8ToS32Le -static void U8ToS32Le(unsigned n, const uint8_t* a, int32_t* b) -{ - for (; n > 0; n--, a++, b++) { - *b = (int32_t)(*a - (uint8_t)0x80U) << SHIFTS_24BIT; - } -} -// U8ToF32Le -static void U8ToF32Le(unsigned n, const uint8_t* a, float* b) -{ - for (; n > 0; n--, a++, b++) { - *b = (float)(*a - (uint8_t)0x80U) * (1.0 / 0x80U); - } -} - -// SAMPLE_S16LE -// S16LeToU8 -static void S16LeToU8(unsigned n, const int16_t* a, uint8_t* b) -{ - for (; n > 0; n--, a++, b++) { - *b = (uint8_t)((uint16_t)(*a) >> SHIFTS_8BIT) + (uint8_t)0x80U; - } -} -// S16LeToS24Le -static void S16LeToS24Le(unsigned n, const int16_t* a, uint8_t* b) -{ - for (; n > 0; n--) { - WRITE24LE(b, ((uint32_t)*a) << SHIFTS_8BIT); - a++; - b += INDEX_THREE; - } -} -// S16LeToS32Le -static void S16LeToS32Le(unsigned n, const int16_t* a, int32_t* b) -{ - for (; n > 0; n--, a++, b++) { - *b = ((int32_t)*a) << SHIFTS_16BIT; - } -} -// S16LeToF32Le -static void S16LeToF32Le(unsigned n, const int16_t* a, float* b) -{ - for (; n > 0; n--) { - *(b++) = *(a++) * (1.0f / (1 << 0x0F)); - } -} - -// SAMPLE_S24LE -// S24LeToU8 -static void S24LeToU8(unsigned n, const uint8_t* a, uint8_t* b) -{ - for (; n > 0; n--) { - *b = (uint8_t)(READ24LE(a) >> SHIFTS_16BIT) + (uint8_t)0x80U; - a += INDEX_THREE; - b++; - } -} -// S24LeToS16Le -static void S24LeToS16Le(unsigned n, const uint8_t* a, int16_t* b) -{ - for (; n > 0; n--) { - *b = (int16_t)(READ24LE(a) >> SHIFTS_8BIT); - a += INDEX_THREE; - b++; - } -} -// S24LeToS32Le -static void S24LeToS32Le(unsigned n, const uint8_t* a, int32_t* b) -{ - for (; n > 0; n--) { - *b = (int32_t)(READ24LE(a) << SHIFTS_8BIT); - a += INDEX_THREE; - b++; - } -} -// S24LeToF32Le -static void S24LeToF32Le(unsigned n, const uint8_t* a, float* b) -{ - for (; n > 0; n--) { - int32_t s = (int32_t)READ24LE(a) << SHIFTS_8BIT; - *b = s * (1.0f / (1U << 0x1F)); - a += INDEX_THREE; - b++; - } -} - -// SAMPLE_S32LE -// S32LeToU8 -static void S32LeToU8(unsigned n, const int32_t* a, uint8_t* b) -{ - for (; n > 0; n--, a++, b++) { - *b = (uint8_t)((int32_t)(*a) >> SHIFTS_24BIT) + (uint8_t)0x80U; - } -} -// S32LeToS16Le -static void S32LeToS16Le(unsigned n, const int32_t* a, int16_t* b) -{ - for (; n > 0; n--, a++, b++) { - *b = (int16_t)((int32_t)(*a) >> SHIFTS_16BIT); - } -} -// S32LeToS24Le -static void S32LeToS24Le(unsigned n, const int32_t* a, uint8_t* b) -{ - for (; n > 0; n--) { - WRITE24LE(b, ((uint32_t)*a) >> SHIFTS_8BIT); - a++; - b += INDEX_THREE; - } -} -// S32LeToF32Le -static void S32LeToF32Le(unsigned n, const int32_t* a, float* b) -{ - for (; n > 0; n--) { - *(b++) = *(a++) * (1.0f / (1U << 0x1F)); - } -} - -// SAMPLE_F32LE -// F32LeToU8 -static void F32LeToU8(unsigned n, const float* a, uint8_t* b) -{ - for (; n > 0; n--) { - float v = *(a++); - *(b++) = (uint8_t)(CLAMP(v, -1.0, 1.0) * 127.0f + 128.0f); - } -} -// F32LeToS16Le -static void F32LeToS16Le(unsigned n, const float* a, int16_t* b) -{ - for (; n > 0; n--) { - float v = *(a++) * (1 << 15); - *(b++) = (int16_t)CLAMP((int32_t)v, -0x8000, 0x7FFF); - } -} -// F32LeToS24Le -static void F32LeToS24Le(unsigned n, const float* a, uint8_t* b) -{ - for (; n > 0; n--) { - float v = *(a++) * (1 << 23); - WRITE24LE(b, (uint32_t)CLAMP((int32_t)v, -0x800000LL, 0x7FFFFFLL)); - b += INDEX_THREE; - } -} -// F32LeToS32Le -static void F32LeToS32Le(unsigned n, const float* a, int32_t* b) -{ - for (; n > 0; n--) { - float v = *(a++) * (1U << 31); - *(b++) = (int32_t)CLAMP((int64_t)v, -0x80000000LL, 0x7FFFFFFFLL); - } -} - -// function table -static FmtConversionFunction sample_u8_table[] = { - [SAMPLE_S16LE] = (FmtConversionFunction)S16LeToU8, - [SAMPLE_S24LE] = (FmtConversionFunction)S24LeToU8, - [SAMPLE_S32LE] = (FmtConversionFunction)S32LeToU8, - [SAMPLE_F32LE] = (FmtConversionFunction)F32LeToU8, -}; - -static FmtConversionFunction sample_s16le_table[] = { - [SAMPLE_U8] = (FmtConversionFunction)U8ToS16Le, - [SAMPLE_S24LE] = (FmtConversionFunction)S24LeToS16Le, - [SAMPLE_S32LE] = (FmtConversionFunction)S32LeToS16Le, - [SAMPLE_F32LE] = (FmtConversionFunction)F32LeToS16Le, -}; - -static FmtConversionFunction sample_s24le_table[] = { - [SAMPLE_U8] = (FmtConversionFunction)U8ToS24Le, - [SAMPLE_S16LE] = (FmtConversionFunction)S16LeToS24Le, - [SAMPLE_S32LE] = (FmtConversionFunction)S32LeToS24Le, - [SAMPLE_F32LE] = (FmtConversionFunction)F32LeToS24Le, -}; - -static FmtConversionFunction sample_s32le_table[] = { - [SAMPLE_U8] = (FmtConversionFunction)U8ToS32Le, - [SAMPLE_S16LE] = (FmtConversionFunction)S16LeToS32Le, - [SAMPLE_S24LE] = (FmtConversionFunction)S24LeToS32Le, - [SAMPLE_F32LE] = (FmtConversionFunction)F32LeToS32Le, -}; - -static FmtConversionFunction sample_f32le_table[] = { - [SAMPLE_U8] = (FmtConversionFunction)U8ToF32Le, - [SAMPLE_S16LE] = (FmtConversionFunction)S16LeToF32Le, - [SAMPLE_S24LE] = (FmtConversionFunction)S24LeToF32Le, - [SAMPLE_S32LE] = (FmtConversionFunction)S32LeToF32Le, -}; - -// choose function from function table -FmtConversionFunction GetFmtConversionU8(audio_sample_format_t fmt) -{ - return sample_u8_table[fmt]; -} - -FmtConversionFunction GetFmtConversionS16Le(audio_sample_format_t fmt) -{ - return sample_s16le_table[fmt]; -} - -FmtConversionFunction GetFmtConversionS24Le(audio_sample_format_t fmt) -{ - return sample_s24le_table[fmt]; -} - -FmtConversionFunction GetFmtConversionS32Le(audio_sample_format_t fmt) -{ - return sample_s32le_table[fmt]; -} - -FmtConversionFunction GetFmtConversionF32Le(audio_sample_format_t fmt) -{ - return sample_f32le_table[fmt]; -} - -// BitDepthConversion implementation -BitDepthConversionState* FmtConversionInit(uint32_t inputFormat, uint32_t outputFormat, - uint32_t numChannels, int* err) -{ - BitDepthConversionState* state; - - if (numChannels == 0 || inputFormat == outputFormat) { - if (err) { - *err = FMTCONV_ERR_INVALID_ARG; - } - return NULL; - } - state = (BitDepthConversionState*)calloc(sizeof(BitDepthConversionState), 1); - if (!state) { - if (err) { - *err = FMTCONV_ERR_ALLOC_FAILED; - } - return NULL; - } - state->inputFormat = inputFormat; - state->outputFormat = outputFormat; - state->numChannels = numChannels; - - if (inputFormat != outputFormat) { - switch (outputFormat) { - case SAMPLE_U8: - state->fmtConversionProcess = GetFmtConversionU8(inputFormat); - break; - case SAMPLE_S16LE: - state->fmtConversionProcess = GetFmtConversionS16Le(inputFormat); - break; - case SAMPLE_S24LE: - state->fmtConversionProcess = GetFmtConversionS24Le(inputFormat); - break; - case SAMPLE_S32LE: - state->fmtConversionProcess = GetFmtConversionS32Le(inputFormat); - break; - case SAMPLE_F32LE: - default: - state->fmtConversionProcess = GetFmtConversionF32Le(inputFormat); - break; - } - } - - return state; -} -void FmtConversionStateFree(BitDepthConversionState* state) -{ - free(state); - state = NULL; -} \ No newline at end of file diff --git a/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.h b/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.h deleted file mode 100644 index 217fb25d7e..0000000000 --- a/services/audio_engine/plugin/bitdepth_converter/bitdepth_converter.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2025 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 BITDEPTH_CONVERTER_H -#define BITDEPTH_CONVERTER_H -#include - -#ifdef __cplusplus -extern "C" { -#endif - enum { - FMTCONV_ERR_SUCCESS = 0, - FMTCONV_ERR_ALLOC_FAILED = 1, - FMTCONV_ERR_INVALID_ARG = 2 - }; - - /** Audio sample format */ - typedef enum audio_sample_format { - SAMPLE_U8 = 0, - SAMPLE_S16LE = 1, - SAMPLE_S24LE = 2, - SAMPLE_S32LE = 3, - SAMPLE_F32LE = 4, - INVALID_WIDTH = -1 - } audio_sample_format_t; - - - typedef void (*FmtConversionFunction)(unsigned n, const void* in, const void* out); - - FmtConversionFunction GetFmtConversionU8(audio_sample_format_t fmt); - FmtConversionFunction GetFmtConversionS16Le(audio_sample_format_t fmt); - FmtConversionFunction GetFmtConversionS24Le(audio_sample_format_t fmt); - FmtConversionFunction GetFmtConversionS32Le(audio_sample_format_t fmt); - FmtConversionFunction GetFmtConversionF32Le(audio_sample_format_t fmt); - - typedef struct BitDepthConversionState BitDepthConversionState; - - struct BitDepthConversionState { - uint32_t inputFormat; - uint32_t outputFormat; - uint32_t numChannels; - uint32_t length; - - FmtConversionFunction fmtConversionProcess; - }; - - BitDepthConversionState* FmtConversionInit(uint32_t inputFormat, uint32_t outputFormat, - uint32_t numChannels, int* err); - - void FmtConversionStateFree(BitDepthConversionState* state); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/channel_converter/include/channel_converter.h b/services/audio_engine/plugin/channel_converter/include/channel_converter.h deleted file mode 100644 index 9b3089ac45..0000000000 --- a/services/audio_engine/plugin/channel_converter/include/channel_converter.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2025 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 CHANNEL_CONVERTER_H -#define CHANNEL_CONVERTER_H - -#include "down_mixer.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -class ChannelConverter { -public: - ChannelConverter() = default; - int32_t Process(uint32_t framesize, float* in, uint32_t inLen, float* out, uint32_t outLen); - // input and output stream format must be workFormat - int32_t SetParam(AudioChannelInfo inChannelInfo, AudioChannelInfo outChannelInfo, - AudioSampleFormat workFormat, bool mixLfe); - AudioChannelInfo GetInChannelInfo() const; - AudioChannelInfo GetOutChannelInfo() const; - int32_t SetInChannelInfo(AudioChannelInfo inChannelInfo); - int32_t SetOutChannelInfo(AudioChannelInfo outChannelInfo); - void Reset(); -private: - int32_t Upmix(uint32_t frameSize, float* in, uint32_t inLen, float* out, uint32_t outLen); - DownMixer downMixer_; - AudioChannelInfo inChannelInfo_; - AudioChannelInfo outChannelInfo_; - AudioSampleFormat workFormat_ = INVALID_WIDTH; // work format, for now only supports float - uint32_t workSize_ = 0; // work format, for now only supports float - bool mixLfe_ = true; -}; -} // HPAE -} // AudioStandard -} // OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/channel_converter/include/down_mixer.h b/services/audio_engine/plugin/channel_converter/include/down_mixer.h deleted file mode 100644 index 63c13350f5..0000000000 --- a/services/audio_engine/plugin/channel_converter/include/down_mixer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2025 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 DOWN_MIXER_H -#define DOWN_MIXER_H -#include -#include "audio_stream_info.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr uint32_t MAX_CHANNELS = 16; - -constexpr float COEF_ZERO_F = 0.0f; -constexpr float COEF_0DB_F = 1.0f; -constexpr float COEF_M3DB_F = 0.7071f; -constexpr float COEF_M6DB_F = 0.5f; -constexpr float COEF_M435DB_F = 0.6057f; -constexpr float COEF_M45DB_F = 0.5946f; -constexpr float COEF_M9DB_F = 0.3544f; -constexpr float COEF_M899DB_F = 0.3552f; -constexpr float COEF_M12DB_F = 0.2509f; - -enum { - DMIX_ERR_SUCCESS = 0, - DMIX_ERR_ALLOC_FAILED = -1, - DMIX_ERR_INVALID_ARG = -2 -}; - -class DownMixer { -public: - DownMixer(); - int32_t Process(uint32_t framesize, float* in, uint32_t inLen, float* out, uint32_t outLen); - - int32_t SetParam(AudioChannelInfo inChannelInfo_, AudioChannelInfo outChannelInfo_, - uint32_t formatSize, bool mixLfe); - void Reset(); -private: - AudioChannelLayout inLayout_ = CH_LAYOUT_UNKNOWN; - uint32_t inChannels_ = 0; - AudioChannelLayout outLayout_ = CH_LAYOUT_UNKNOWN; - uint32_t outChannels_ = 0; - uint32_t formatSize_ = INVALID_WIDTH; // work format, for now only supports float - std::vector> downMixTable_; - bool mixLfe_ = true; - bool isInitialized_ = false; - void SetupStereoDmixTable(); - void Setup5Point1DmixTable(); - void Setup5Point1Point2DmixTable(); - void Setup5Point1Point4DmixTable(); - void Setup7Point1DmixTable(); - void Setup7Point1Point2DmixTable(); - void Setup7Point1Point4DmixTable(); - void SetupGeneralDmixTable(); - void ResetSelf(); - int32_t SetupDownMixTable(); - /**** helper functions for settiing up specific downmix table ***/ - void SetupStereoDmixTablePart1(uint64_t bit_t, uint32_t i); - void SetupStereoDmixTablePart2(uint64_t bit_t, uint32_t i); - void Setup5Point1DmixTablePart1(uint64_t bit_t, uint32_t i); - void Setup5Point1DmixTablePart2(uint64_t bit_t, uint32_t i); - void Setup5Point1Point2DmixTablePart1(uint64_t bit_t, uint32_t i); - void Setup5Point1Point2DmixTablePart2(uint64_t bit_t, uint32_t i); - void Setup5Point1Point4DmixTablePart1(uint64_t bit_t, uint32_t i); - void Setup5Point1Point4DmixTablePart2(uint64_t bit_t, uint32_t i); - void Setup7Point1DmixTablePart1(uint64_t bit_t, uint32_t i); - void Setup7Point1DmixTablePart2(uint64_t bit_t, uint32_t i); - void Setup7Point1Point2DmixTablePart1(uint64_t bit_t, uint32_t i); - void Setup7Point1Point2DmixTablePart2(uint64_t bit_t, uint32_t i); - void Setup7Point1Point4DmixTablePart1(uint64_t bit_t, uint32_t i); - void Setup7Point1Point4DmixTablePart2(uint64_t bit_t, uint32_t i); - /**** helper functions for setting up general downmix table ***/ - void DownMixBottom(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); - void DownMixLfe(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); - void DownMixMidFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); - void DownMixMidRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); - void DownMixTopCenter(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); - void DownMixTopFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); - void DownMixTopRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j); - void NormalizeDMixTable(); -}; -} // HPAE -} // AudioStandard -} // OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/channel_converter/src/channel_converter.cpp b/services/audio_engine/plugin/channel_converter/src/channel_converter.cpp deleted file mode 100644 index 0ebfa15c82..0000000000 --- a/services/audio_engine/plugin/channel_converter/src/channel_converter.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeChannelConverter" -#endif -#include "channel_converter.h" -#include "audio_engine_log.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -static inline uint32_t Min(uint32_t a, uint32_t b) -{ - return a < b ? a : b; -} - -static inline uint32_t GetFormatSize(AudioSampleFormat format) -{ - uint32_t sampleSize = 0; - switch (format) { - case SAMPLE_U8: - sampleSize = sizeof(uint8_t); - break; - case SAMPLE_S16LE: - sampleSize = sizeof(int16_t); - break; - case SAMPLE_S24LE: - sampleSize = SAMPLE_S24LE + 1; - break; - case SAMPLE_S32LE: - sampleSize = sizeof(int32_t); - break; - case SAMPLE_F32LE: - sampleSize = sizeof(float); - break; - default: - AUDIO_ERR_LOG("unsupported format %{public}d", format); - } - return sampleSize; -} - -int32_t ChannelConverter::SetParam(AudioChannelInfo inChannelInfo, AudioChannelInfo outChannelInfo, - AudioSampleFormat format, bool mixLfe) -{ - inChannelInfo_.channelLayout = inChannelInfo.channelLayout; - outChannelInfo_.channelLayout = outChannelInfo.channelLayout; - inChannelInfo_.numChannels = inChannelInfo.numChannels; - outChannelInfo_.numChannels = outChannelInfo.numChannels; - workFormat_ = format; - workSize_ = GetFormatSize(format); - mixLfe_ = mixLfe; - int32_t ret = DMIX_ERR_SUCCESS; - if (inChannelInfo_.numChannels > outChannelInfo_.numChannels) { - ret = downMixer_.SetParam(inChannelInfo, outChannelInfo, workSize_, mixLfe); - } - return ret; -} - -int32_t ChannelConverter::SetInChannelInfo(AudioChannelInfo inChannelInfo) -{ - inChannelInfo_.channelLayout = inChannelInfo.channelLayout; - inChannelInfo_.numChannels = inChannelInfo.numChannels; - if (inChannelInfo_.numChannels > outChannelInfo_.numChannels) { - return downMixer_.SetParam(inChannelInfo_, outChannelInfo_, workSize_, mixLfe_); - } - return DMIX_ERR_SUCCESS; -} - - -int32_t ChannelConverter::SetOutChannelInfo(AudioChannelInfo outChannelInfo) -{ - outChannelInfo_.channelLayout = outChannelInfo.channelLayout; - outChannelInfo_.numChannels = outChannelInfo.numChannels; - if (inChannelInfo_.numChannels > outChannelInfo_.numChannels) { - return downMixer_.SetParam(inChannelInfo_, outChannelInfo_, workSize_, mixLfe_); - } - return DMIX_ERR_SUCCESS; -} - -AudioChannelInfo ChannelConverter::GetInChannelInfo() const -{ - return inChannelInfo_; -} - -AudioChannelInfo ChannelConverter::GetOutChannelInfo() const -{ - return outChannelInfo_; -} - -int32_t ChannelConverter::Process(uint32_t frameSize, float* in, uint32_t inLen, float* out, uint32_t outLen) -{ - if ((in == nullptr) || (out == nullptr) || frameSize <= 0 || inLen <= 0 || outLen <= 0) { - return DMIX_ERR_ALLOC_FAILED; - } - if (inChannelInfo_.numChannels < outChannelInfo_.numChannels) { - return Upmix(frameSize, in, inLen, out, outLen); - } - return downMixer_.Process(frameSize, in, inLen, out, outLen); -} - -void ChannelConverter::Reset() -{ - downMixer_.Reset(); -} - -int32_t ChannelConverter::Upmix(uint32_t frameSize, float* in, uint32_t inLen, float* out, uint32_t outLen) -{ - uint32_t expectInLen = frameSize * inChannelInfo_.numChannels * workSize_; // to be added size of other formats - uint32_t expectOutLen = frameSize * outChannelInfo_.numChannels * workSize_; - if ((expectInLen > inLen) || (expectOutLen > outLen)) { - AUDIO_ERR_LOG("expect Input Len: %{public}d, inLen: %{public}d," - "expected output len: %{public}d, outLen %{public}d", - expectInLen, inLen, expectOutLen, outLen); - return DMIX_ERR_ALLOC_FAILED; - } - for (uint32_t i = 0; i < frameSize; ++i) { - for (uint32_t ch = 0; ch < outChannelInfo_.numChannels; ++ch) { - uint32_t leftChIndex = Min(ch, inChannelInfo_.numChannels - 1); - out[i * outChannelInfo_.numChannels + ch] = in[i * inChannelInfo_.numChannels + leftChIndex]; - } - } - return DMIX_ERR_SUCCESS; -} - -} // HPAE -} // AudioStandard -} // OHOS \ No newline at end of file diff --git a/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp b/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp deleted file mode 100644 index bff518c98c..0000000000 --- a/services/audio_engine/plugin/channel_converter/src/down_mixer.cpp +++ /dev/null @@ -1,1088 +0,0 @@ -/* - * Copyright (c) 2025 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 "HpaeDownMixer" -#endif -#include -#include "securec.h" -#include "inttypes.h" -#include "audio_engine_log.h" -#include "down_mixer.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -// Initial output channel index -enum OutChannelIndex : uint32_t { - FL = 0, - FR, - FC, - SW, -// Back channel should be placed before side channel - BL, - BR -}; - -static uint32_t SL = 6; -static uint32_t SR = 7; -static uint32_t TFL = 8; -static uint32_t TFR = 9; -static uint32_t TBL = 10; -static uint32_t TBR = 11; -static uint32_t TSL = 12; -static uint32_t TSR = 13; - -static constexpr uint32_t INDEX_SIX = 6; -static constexpr uint32_t INDEX_SEVEN = 7; -static constexpr uint32_t INDEX_EIGHT = 8; -static constexpr uint32_t INDEX_NINE = 9; -static constexpr uint32_t INDEX_TEN = 10; -static constexpr uint32_t INDEX_ELEVEN = 11; - -// channel masks for downmixing general output channel layout -static constexpr uint64_t MASK_MIDDLE_FRONT = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | -FRONT_LEFT_OF_CENTER | FRONT_RIGHT_OF_CENTER | WIDE_LEFT | WIDE_RIGHT; - -static constexpr uint64_t MASK_MIDDLE_REAR = BACK_LEFT | BACK_RIGHT | BACK_CENTER -| SIDE_LEFT -| SIDE_RIGHT; - -static constexpr uint64_t MASK_TOP_FRONT = TOP_FRONT_LEFT -| TOP_FRONT_CENTER -| TOP_FRONT_RIGHT; - -static constexpr uint64_t MASK_TOP_REAR = TOP_CENTER -| TOP_BACK_LEFT -| TOP_BACK_CENTER -| TOP_BACK_RIGHT -| TOP_SIDE_LEFT -| TOP_SIDE_RIGHT; - -static constexpr uint64_t MASK_BOTTOM = BOTTOM_FRONT_CENTER -| BOTTOM_FRONT_LEFT -| BOTTOM_FRONT_RIGHT; - -static constexpr uint64_t MASK_LFE = LOW_FREQUENCY -| LOW_FREQUENCY_2; - -static uint32_t bitCounts(uint64_t bits); -static bool isValidChLayout(AudioChannelLayout &chLayout, uint32_t chCounts); -static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels); - -// 改成默认构造 -DownMixer::DownMixer() -{ - downMixTable_.resize(MAX_CHANNELS, std::vector(MAX_CHANNELS, 0)); -} - -// setParam -int32_t DownMixer::SetParam(AudioChannelInfo inChannelInfo, AudioChannelInfo outChannelInfo, - uint32_t formatSize, bool mixLfe) -{ - ResetSelf(); - inLayout_ = inChannelInfo.channelLayout; - outLayout_ = outChannelInfo.channelLayout; - inChannels_ = inChannelInfo.numChannels; - outChannels_ = outChannelInfo.numChannels; - mixLfe_ = mixLfe; - - formatSize_ = formatSize; - int32_t ret = SetupDownMixTable(); - if (ret == DMIX_ERR_SUCCESS) { - isInitialized_ = true; - } - return ret; -} - -int32_t DownMixer::Process(uint32_t frameLen, float* in, uint32_t inLen, float* out, uint32_t outLen) -{ - if ((in == nullptr) || (out == nullptr) || frameLen <= 0) { - AUDIO_ERR_LOG("invalid input params for downmix process, frameLen %{public}d", frameLen); - return DMIX_ERR_ALLOC_FAILED; - } - if (!isInitialized_) { - AUDIO_DEBUG_LOG("Downmixe table has not been initialized!"); - return DMIX_ERR_ALLOC_FAILED; - } - uint32_t expectInLen = frameLen * inChannels_ * formatSize_; - uint32_t expectOutLen = frameLen * outChannels_ * formatSize_; - if ((expectInLen > inLen) || (expectOutLen > outLen)) { - memcpy_s(out, outLen, in, inLen); - AUDIO_ERR_LOG("expect Input Len: %{public}d, inLen: %{public}d," - "expected output len: %{public}d, outLen %{public}d", - expectInLen, inLen, expectOutLen, outLen); - return DMIX_ERR_ALLOC_FAILED; - } - AUDIO_DEBUG_LOG("Downmixing: frameLen: %{public}d,", frameLen); - float a; - for (; frameLen > 0; frameLen--) { - for (uint32_t i = 0; i < outChannels_; i++) { - a = 0.0f; - for (uint32_t j = 0; j < inChannels_; j++) { - a += in[j] * downMixTable_[i][j]; - } - *(out++) = a; - } - in += inChannels_; - } - return DMIX_ERR_SUCCESS; -} - -int32_t DownMixer::SetupDownMixTable() -{ - if ((!isValidChLayout(inLayout_, inChannels_)) || (!isValidChLayout(outLayout_, outChannels_)) - || inLayout_ == outLayout_ || inChannels_ <= outChannels_) { - AUDIO_ERR_LOG("invalid input or output channellayout: input channel count %{public}d, " - "inLayout_ %{public}" PRIu64 "output channel count %{public}d, outLayout_ %{public}" PRIu64 "", - inChannels_, inLayout_, outChannels_, outLayout_); - return DMIX_ERR_INVALID_ARG; - } - switch (outLayout_) { - case CH_LAYOUT_STEREO: { - SetupStereoDmixTable(); - break; - } - case CH_LAYOUT_5POINT1: { - Setup5Point1DmixTable(); - break; - } - case CH_LAYOUT_5POINT1POINT2: { - Setup5Point1Point2DmixTable(); - break; - } - case CH_LAYOUT_5POINT1POINT4: { - Setup5Point1Point4DmixTable(); - break; - } - case CH_LAYOUT_7POINT1: { - Setup7Point1DmixTable(); - break; - } - case CH_LAYOUT_7POINT1POINT2: { - Setup7Point1Point2DmixTable(); - break; - } - case CH_LAYOUT_7POINT1POINT4: { - Setup7Point1Point4DmixTable(); - break; - } - default: { - SetupGeneralDmixTable(); - break; - } - } - NormalizeDMixTable(); - AUDIO_INFO_LOG("setup downmix table success!"); - isInitialized_ = true; - return DMIX_ERR_SUCCESS; -} - -void DownMixer::NormalizeDMixTable() -{ - float maxx = 0.0f; - for (uint32_t i = 0; i < outChannels_; i++) { - float summ = 0.0f; - for (uint32_t j = 0; j < inChannels_; j++) { - summ += downMixTable_[i][j]; - } - maxx = std::max(maxx, summ); - } - maxx = 1.0f / maxx; - for (uint32_t i = 0; i < outChannels_; i++) { - for (uint32_t j = 0; j < inChannels_; j++) { - downMixTable_[i][j] *= maxx; - } - } -} - -void DownMixer::ResetSelf() -{ - isInitialized_ = false; - inChannels_ = 0; - outChannels_ = 0; - inLayout_ = CH_LAYOUT_UNKNOWN; - outLayout_ = CH_LAYOUT_UNKNOWN; - for (auto &row : downMixTable_) { - std::fill(row.begin(), row.end(), 0.0f); - } -} - -void DownMixer::Reset() -{ - ResetSelf(); -} - -void DownMixer::SetupStereoDmixTable() -{ - uint64_t inChMsk = inLayout_; - for (uint32_t i = 0; i < inChannels_; i++) { - uint64_t bit = inChMsk & -(int64_t)inChMsk; - downMixTable_[FL][i] = 0.f; - downMixTable_[FR][i] = 0.f; - SetupStereoDmixTablePart1(bit, i); - SetupStereoDmixTablePart2(bit, i); - inChMsk ^= bit; - } -} - -void DownMixer::Setup5Point1DmixTable() -{ - uint64_t inChMsk = inLayout_; - for (uint32_t i = 0; i < inChannels_; i++) { - downMixTable_[FL][i] = 0.f; - downMixTable_[FR][i] = 0.f; - downMixTable_[FC][i] = 0.f; - downMixTable_[SW][i] = 0.f; - downMixTable_[BL][i] = 0.f; - downMixTable_[BR][i] = 0.f; - uint64_t bit = inChMsk & -(int64_t)inChMsk; - Setup5Point1DmixTablePart1(bit, i); - Setup5Point1DmixTablePart2(bit, i); - inChMsk ^= bit; - } -} -void DownMixer::Setup5Point1Point2DmixTable() -{ - TSL = INDEX_SIX; - TSR = INDEX_SEVEN; - uint64_t inChMsk = inLayout_; - for (unsigned i = 0; i < inChannels_; i++) { - uint64_t bit = inChMsk & -(int64_t)inChMsk; - downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; - downMixTable_[SW][i] = downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; - downMixTable_[TSL][i] = downMixTable_[TSR][i] = 0.f; - Setup5Point1Point2DmixTablePart1(bit, i); - Setup5Point1Point2DmixTablePart2(bit, i); - inChMsk ^= bit; - } -} -void DownMixer::Setup5Point1Point4DmixTable() -{ - TFL = INDEX_SIX; - TFR = INDEX_SEVEN; - TBL = INDEX_EIGHT; - TBR = INDEX_NINE; - uint64_t inChMsk = inLayout_; - for (unsigned i = 0; i < inChannels_; i++) { - uint64_t bit = inChMsk & -(int64_t)inChMsk; - downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; - downMixTable_[SW][i] = downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; - downMixTable_[TFL][i] = downMixTable_[TFR][i] = 0.f; - downMixTable_[TBL][i] = downMixTable_[TBR][i] = 0.f; - Setup5Point1Point4DmixTablePart1(bit, i); - Setup5Point1Point4DmixTablePart2(bit, i); - inChMsk ^= bit; - } -} -void DownMixer::Setup7Point1DmixTable() -{ - SL = INDEX_SIX; - SR = INDEX_SEVEN; - uint64_t inChMsk = inLayout_; - for (unsigned i = 0; i < inChannels_; i++) { - uint64_t bit = inChMsk & -(int64_t)inChMsk; - downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; - downMixTable_[SW][i] = downMixTable_[SL][i] = downMixTable_[SR][i] = 0.f; - downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; - Setup7Point1DmixTablePart1(bit, i); - Setup7Point1DmixTablePart2(bit, i); - inChMsk ^= bit; - } -} -void DownMixer::Setup7Point1Point2DmixTable() -{ - SL = INDEX_SIX; - SR = INDEX_SEVEN; - TSL = INDEX_EIGHT; - TSR = INDEX_NINE; - uint64_t inChMsk = inLayout_; - for (unsigned i = 0; i < inChannels_; i++) { - uint64_t bit = inChMsk & -(int64_t)inChMsk; - downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; - downMixTable_[SW][i] = downMixTable_[SL][i] = downMixTable_[SR][i] = 0.f; - downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; - downMixTable_[TSL][i] = downMixTable_[TSR][i] = 0.f; - Setup7Point1Point2DmixTablePart1(bit, i); - Setup7Point1Point2DmixTablePart2(bit, i); - inChMsk ^= bit; - } -} -void DownMixer::Setup7Point1Point4DmixTable() -{ - SL = INDEX_SIX; - SR = INDEX_SEVEN; - TFL = INDEX_EIGHT; - TFR = INDEX_NINE; - TBL = INDEX_TEN; - TBR = INDEX_ELEVEN; - uint64_t inChMsk = inLayout_; - for (unsigned i = 0; i < inChannels_; i++) { - uint64_t bit = inChMsk & -(int64_t)inChMsk; - downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f; - downMixTable_[SW][i] = downMixTable_[SL][i] = downMixTable_[SR][i] = 0.f; - downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f; - downMixTable_[TFL][i] = downMixTable_[TFR][i] = 0.f; - downMixTable_[TBL][i] = downMixTable_[TBR][i] = 0.f; - Setup7Point1Point4DmixTablePart1(bit, i); - Setup7Point1Point4DmixTablePart2(bit, i); - inChMsk ^= bit; - } -} - -void DownMixer::SetupGeneralDmixTable() -{ - // MONO - if (outLayout_ == CH_LAYOUT_MONO) { - for (uint32_t i = 0; i < inChannels_; i++) { - downMixTable_[0][i] = COEF_0DB_F; - } - } - // check invalid output musk later in init() - uint64_t outChMsk = outLayout_; - - for (uint32_t i = 0; i < outChannels_; i++) { - uint64_t outBit = outChMsk & -(int64_t)outChMsk; - uint64_t inChMsk = inLayout_; - for (uint32_t j = 0; j < inChannels_; j++) { - uint64_t inBit = inChMsk & -(int64_t)inChMsk; - if (inBit & outBit) { // if in channel and out channel is the same - downMixTable_[i][j] = COEF_0DB_F; - } else if (inBit == TOP_CENTER) { - // check general downmix table! - DownMixTopCenter(inBit, outBit, i, j); - } else if ((inBit & MASK_MIDDLE_FRONT) != 0) { - DownMixMidFront(inBit, outBit, i, j); - } else if ((inBit & MASK_MIDDLE_REAR) != 0) { - DownMixMidRear(inBit, outBit, i, j); - } else if ((inBit & MASK_BOTTOM) != 0) { - DownMixBottom(inBit, outBit, i, j); - } else if ((inBit & MASK_LFE) != 0) { - DownMixLfe(inBit, outBit, i, j); - } else if ((inBit & MASK_TOP_FRONT) != 0) { - DownMixTopFront(inBit, outBit, i, j); - } else if ((inBit & MASK_TOP_REAR) != 0) { - DownMixTopRear(inBit, outBit, i, j); - } - inChMsk ^= inBit; - } - outChMsk ^= outBit; - } -} - -void DownMixer::SetupStereoDmixTablePart1(uint64_t bit, uint32_t i) -{ - switch (bit) { - case FRONT_LEFT: - case TOP_FRONT_LEFT: - case BOTTOM_FRONT_LEFT: - downMixTable_[FL][i] = COEF_0DB_F; - downMixTable_[FR][i] = COEF_ZERO_F; - break; - case FRONT_RIGHT: - case TOP_FRONT_RIGHT: - case BOTTOM_FRONT_RIGHT: - downMixTable_[FL][i] = COEF_ZERO_F; - downMixTable_[FR][i] = COEF_0DB_F; - break; - case FRONT_CENTER: - case TOP_FRONT_CENTER: - case BOTTOM_FRONT_CENTER: - downMixTable_[FL][i] = COEF_M3DB_F; - downMixTable_[FR][i] = COEF_M3DB_F; - break; - case BACK_LEFT: - case SIDE_LEFT: - case TOP_BACK_LEFT: - case TOP_SIDE_LEFT: - case WIDE_LEFT: - downMixTable_[FL][i] = COEF_M3DB_F; - downMixTable_[FR][i] = COEF_ZERO_F; - break; - case BACK_RIGHT: - case SIDE_RIGHT: - case TOP_BACK_RIGHT: - case TOP_SIDE_RIGHT: - case WIDE_RIGHT: - downMixTable_[FL][i] = COEF_ZERO_F; - downMixTable_[FR][i] = COEF_M3DB_F; - break; - case BACK_CENTER: - downMixTable_[FL][i] = COEF_M6DB_F; - downMixTable_[FR][i] = COEF_M6DB_F; - break; - default: - break; - } -} - -void DownMixer::SetupStereoDmixTablePart2(uint64_t bit, uint32_t i) -{ - switch (bit) { - case FRONT_LEFT_OF_CENTER: - downMixTable_[FL][i] = COEF_M435DB_F; - downMixTable_[FR][i] = COEF_M12DB_F; - break; - case FRONT_RIGHT_OF_CENTER: - downMixTable_[FL][i] = COEF_M12DB_F; - downMixTable_[FR][i] = COEF_M435DB_F; - break; - case TOP_BACK_CENTER: - downMixTable_[FL][i] = COEF_M9DB_F; - downMixTable_[FR][i] = COEF_M9DB_F; - break; - case TOP_CENTER: - downMixTable_[FL][i] = COEF_M899DB_F; - downMixTable_[FR][i] = COEF_M899DB_F; - break; - case LOW_FREQUENCY_2: - if (mixLfe_) { - downMixTable_[FL][i] = COEF_ZERO_F; - downMixTable_[FR][i] = COEF_M6DB_F; - } - break; - case LOW_FREQUENCY: - if ((mixLfe_) & (inLayout_ & (LOW_FREQUENCY_2))) { - downMixTable_[FL][i] = COEF_M6DB_F; - downMixTable_[FR][i] = COEF_ZERO_F; - } else if (mixLfe_) { - downMixTable_[FL][i] = COEF_M6DB_F; - downMixTable_[FR][i] = COEF_M6DB_F; - } - break; - default: - break; - } -} - -void DownMixer::Setup5Point1DmixTablePart1(uint64_t bit, uint32_t i) -{ - switch (bit) { - case FRONT_LEFT: - case TOP_FRONT_LEFT: - case BOTTOM_FRONT_LEFT: - case WIDE_LEFT: - downMixTable_[FL][i] = COEF_0DB_F; - break; - case FRONT_RIGHT: - case TOP_FRONT_RIGHT: - case BOTTOM_FRONT_RIGHT: - case WIDE_RIGHT: - downMixTable_[FR][i] = COEF_0DB_F; - break; - case FRONT_CENTER: - case TOP_FRONT_CENTER: - case BOTTOM_FRONT_CENTER: - downMixTable_[FC][i] = COEF_0DB_F; - break; - case SIDE_LEFT: - case BACK_LEFT: - case TOP_BACK_LEFT: - case TOP_SIDE_LEFT: - downMixTable_[BL][i] = COEF_0DB_F; - break; - case (SIDE_RIGHT): - case (BACK_RIGHT): - case (TOP_BACK_RIGHT): - case (TOP_SIDE_RIGHT): - downMixTable_[BR][i] = COEF_0DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup5Point1DmixTablePart2(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (LOW_FREQUENCY): - case (LOW_FREQUENCY_2): - if (mixLfe_) { - downMixTable_[SW][i] = COEF_0DB_F; - } - break; - case (FRONT_LEFT_OF_CENTER): - downMixTable_[FL][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (FRONT_RIGHT_OF_CENTER): - downMixTable_[FR][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (BACK_CENTER): - case (TOP_BACK_CENTER): - downMixTable_[BL][i] = COEF_M3DB_F; - downMixTable_[BR][i] = COEF_M3DB_F; - break; - case (TOP_CENTER): - downMixTable_[FC][i] = COEF_M6DB_F; - downMixTable_[BL][i] = COEF_M6DB_F; - downMixTable_[BR][i] = COEF_M6DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup5Point1Point2DmixTablePart1(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (FRONT_LEFT): - case (TOP_FRONT_LEFT): - case (BOTTOM_FRONT_LEFT): - case (WIDE_LEFT): - downMixTable_[FL][i] = COEF_0DB_F; - break; - case (FRONT_RIGHT): - case (TOP_FRONT_RIGHT): - case (BOTTOM_FRONT_RIGHT): - case (WIDE_RIGHT): - downMixTable_[FR][i] = COEF_0DB_F; - break; - case (FRONT_CENTER): - case (TOP_FRONT_CENTER): - case (BOTTOM_FRONT_CENTER): - downMixTable_[FC][i] = COEF_0DB_F; - break; - case (SIDE_LEFT): - case (BACK_LEFT): - downMixTable_[BL][i] = COEF_0DB_F; - break; - case (SIDE_RIGHT): - case (BACK_RIGHT): - downMixTable_[BR][i] = COEF_0DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup5Point1Point2DmixTablePart2(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (TOP_BACK_LEFT): - case (TOP_SIDE_LEFT): - downMixTable_[TSL][i] = COEF_0DB_F; - break; - case (TOP_BACK_RIGHT): - case (TOP_SIDE_RIGHT): - downMixTable_[TSR][i] = COEF_0DB_F; - break; - case (LOW_FREQUENCY): - case (LOW_FREQUENCY_2): - if (mixLfe_) { - downMixTable_[SW][i] = COEF_0DB_F; - } - break; - case (FRONT_LEFT_OF_CENTER): - downMixTable_[FL][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (FRONT_RIGHT_OF_CENTER): - downMixTable_[FR][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (BACK_CENTER): - downMixTable_[BL][i] = COEF_M3DB_F; - downMixTable_[BR][i] = COEF_M3DB_F; - break; - case (TOP_BACK_CENTER): - case (TOP_CENTER): - downMixTable_[TSL][i] = COEF_M3DB_F; - downMixTable_[TSR][i] = COEF_M3DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup5Point1Point4DmixTablePart1(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (FRONT_LEFT): - case (BOTTOM_FRONT_LEFT): - case (WIDE_LEFT): - downMixTable_[FL][i] = COEF_0DB_F; - break; - case (FRONT_RIGHT): - case (BOTTOM_FRONT_RIGHT): - case (WIDE_RIGHT): - downMixTable_[FR][i] = COEF_0DB_F; - break; - case (FRONT_CENTER): - case (BOTTOM_FRONT_CENTER): - downMixTable_[FC][i] = COEF_0DB_F; - break; - case (SIDE_LEFT): - case (BACK_LEFT): - downMixTable_[BL][i] = COEF_0DB_F; - break; - case (SIDE_RIGHT): - case (BACK_RIGHT): - downMixTable_[BR][i] = COEF_0DB_F; - break; - case (TOP_FRONT_LEFT): - downMixTable_[TFL][i] = COEF_0DB_F; - break; - case (TOP_FRONT_RIGHT): - downMixTable_[TFR][i] = COEF_0DB_F; - break; - case (TOP_BACK_LEFT): - case (TOP_SIDE_LEFT): - downMixTable_[TBL][i] = COEF_0DB_F; - break; - case (TOP_BACK_RIGHT): - case (TOP_SIDE_RIGHT): - downMixTable_[TBR][i] = COEF_0DB_F; - break; - case (LOW_FREQUENCY): - case (LOW_FREQUENCY_2): - if (mixLfe_) { - downMixTable_[SW][i] = COEF_0DB_F; - } - break; - } -} - -void DownMixer::Setup5Point1Point4DmixTablePart2(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (FRONT_LEFT_OF_CENTER): - downMixTable_[FL][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (FRONT_RIGHT_OF_CENTER): - downMixTable_[FR][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (BACK_CENTER): - downMixTable_[BL][i] = COEF_M3DB_F; - downMixTable_[BR][i] = COEF_M3DB_F; - break; - case (TOP_FRONT_CENTER): - downMixTable_[TFL][i] = COEF_M3DB_F; - downMixTable_[TFR][i] = COEF_M3DB_F; - break; - case (TOP_BACK_CENTER): - downMixTable_[TBL][i] = COEF_M3DB_F; - downMixTable_[TBR][i] = COEF_M3DB_F; - break; - case (TOP_CENTER): - downMixTable_[TFL][i] = COEF_M6DB_F; - downMixTable_[TFR][i] = COEF_M6DB_F; - downMixTable_[TBL][i] = COEF_M6DB_F; - downMixTable_[TBR][i] = COEF_M6DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup7Point1DmixTablePart1(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (FRONT_LEFT): - case (TOP_FRONT_LEFT): - case (BOTTOM_FRONT_LEFT): - case (WIDE_LEFT): - downMixTable_[FL][i] = COEF_0DB_F; - break; - case (FRONT_RIGHT): - case (TOP_FRONT_RIGHT): - case (BOTTOM_FRONT_RIGHT): - case (WIDE_RIGHT): - downMixTable_[FR][i] = COEF_0DB_F; - break; - case (FRONT_CENTER): - case (TOP_FRONT_CENTER): - case (BOTTOM_FRONT_CENTER): - downMixTable_[FC][i] = COEF_0DB_F; - break; - case (SIDE_LEFT): - case (TOP_SIDE_LEFT): - downMixTable_[SL][i] = COEF_0DB_F; - break; - case (SIDE_RIGHT): - case (TOP_SIDE_RIGHT): - downMixTable_[SR][i] = COEF_0DB_F; - break; - case (BACK_LEFT): - case (TOP_BACK_LEFT): - downMixTable_[BL][i] = COEF_0DB_F; - break; - case (BACK_RIGHT): - case (TOP_BACK_RIGHT): - downMixTable_[BR][i] = COEF_0DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup7Point1DmixTablePart2(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (LOW_FREQUENCY): - case (LOW_FREQUENCY_2): - if (mixLfe_) { - downMixTable_[SW][i] = COEF_0DB_F; - } - break; - case (FRONT_LEFT_OF_CENTER): - downMixTable_[FL][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (FRONT_RIGHT_OF_CENTER): - downMixTable_[FR][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (BACK_CENTER): - case (TOP_BACK_CENTER): - downMixTable_[BL][i] = COEF_M3DB_F; - downMixTable_[BR][i] = COEF_M3DB_F; - break; - case (TOP_CENTER): - downMixTable_[FC][i] = COEF_M6DB_F; - downMixTable_[SL][i] = COEF_M6DB_F; - downMixTable_[SR][i] = COEF_M6DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup7Point1Point2DmixTablePart1(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (FRONT_LEFT): - case (TOP_FRONT_LEFT): - case (BOTTOM_FRONT_LEFT): - case (WIDE_LEFT): - downMixTable_[FL][i] = COEF_0DB_F; - break; - case (FRONT_RIGHT): - case (TOP_FRONT_RIGHT): - case (BOTTOM_FRONT_RIGHT): - case (WIDE_RIGHT): - downMixTable_[FR][i] = COEF_0DB_F; - break; - case (FRONT_CENTER): - case (TOP_FRONT_CENTER): - case (BOTTOM_FRONT_CENTER): - downMixTable_[FC][i] = COEF_0DB_F; - break; - case (SIDE_LEFT): - downMixTable_[SL][i] = COEF_0DB_F; - break; - case (SIDE_RIGHT): - downMixTable_[SR][i] = COEF_0DB_F; - break; - case (BACK_LEFT): - downMixTable_[BL][i] = COEF_0DB_F; - break; - case (BACK_RIGHT): - downMixTable_[BR][i] = COEF_0DB_F; - break; - case (TOP_BACK_LEFT): - case (TOP_SIDE_LEFT): - downMixTable_[TSL][i] = COEF_0DB_F; - break; - case (TOP_BACK_RIGHT): - case (TOP_SIDE_RIGHT): - downMixTable_[TSR][i] = COEF_0DB_F; - break; - case (LOW_FREQUENCY): - case (LOW_FREQUENCY_2): - if (mixLfe_) { - downMixTable_[SW][i] = COEF_0DB_F; - } - break; - default: - break; - } -} - -void DownMixer::Setup7Point1Point2DmixTablePart2(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (FRONT_LEFT_OF_CENTER): - downMixTable_[FL][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (FRONT_RIGHT_OF_CENTER): - downMixTable_[FR][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (BACK_CENTER): - downMixTable_[BL][i] = COEF_M3DB_F; - downMixTable_[BR][i] = COEF_M3DB_F; - break; - case (TOP_BACK_CENTER): - case (TOP_CENTER): - downMixTable_[TSL][i] = COEF_M3DB_F; - downMixTable_[TSR][i] = COEF_M3DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup7Point1Point4DmixTablePart1(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (FRONT_LEFT): - case (BOTTOM_FRONT_LEFT): - case (WIDE_LEFT): - downMixTable_[FL][i] = COEF_0DB_F; - break; - case (FRONT_RIGHT): - case (BOTTOM_FRONT_RIGHT): - case (WIDE_RIGHT): - downMixTable_[FR][i] = COEF_0DB_F; - break; - case (FRONT_CENTER): - case (BOTTOM_FRONT_CENTER): - downMixTable_[FC][i] = COEF_0DB_F; - break; - case (SIDE_LEFT): - downMixTable_[SL][i] = COEF_0DB_F; - break; - case (SIDE_RIGHT): - downMixTable_[SR][i] = COEF_0DB_F; - break; - case (BACK_LEFT): - downMixTable_[BL][i] = COEF_0DB_F; - break; - case (BACK_RIGHT): - downMixTable_[BR][i] = COEF_0DB_F; - break; - case (TOP_FRONT_LEFT): - downMixTable_[TFL][i] = COEF_0DB_F; - break; - case (TOP_FRONT_RIGHT): - downMixTable_[TFR][i] = COEF_0DB_F; - break; - case (TOP_BACK_LEFT): - case (TOP_SIDE_LEFT): - downMixTable_[TBL][i] = COEF_0DB_F; - break; - case (TOP_BACK_RIGHT): - case (TOP_SIDE_RIGHT): - downMixTable_[TBR][i] = COEF_0DB_F; - break; - default: - break; - } -} - -void DownMixer::Setup7Point1Point4DmixTablePart2(uint64_t bit, uint32_t i) -{ - switch (bit) { - case (LOW_FREQUENCY): - case (LOW_FREQUENCY_2): - if (mixLfe_) { - downMixTable_[SW][i] = COEF_0DB_F; - } - break; - case (FRONT_LEFT_OF_CENTER): - downMixTable_[FL][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (FRONT_RIGHT_OF_CENTER): - downMixTable_[FR][i] = COEF_M45DB_F; - downMixTable_[FC][i] = COEF_M3DB_F; - break; - case (BACK_CENTER): - downMixTable_[BL][i] = COEF_M3DB_F; - downMixTable_[BR][i] = COEF_M3DB_F; - break; - case (TOP_FRONT_CENTER): - downMixTable_[TFL][i] = COEF_M3DB_F; - downMixTable_[TFR][i] = COEF_M3DB_F; - break; - case (TOP_BACK_CENTER): - downMixTable_[TBL][i] = COEF_M3DB_F; - downMixTable_[TBR][i] = COEF_M3DB_F; - break; - case (TOP_CENTER): - downMixTable_[TFL][i] = COEF_M6DB_F; - downMixTable_[TFR][i] = COEF_M6DB_F; - downMixTable_[TBL][i] = COEF_M6DB_F; - downMixTable_[TBR][i] = COEF_M6DB_F; - break; - default: - break; - } -} - -void DownMixer::DownMixBottom(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) -{ - if ((inBit & MASK_BOTTOM) && (outBit & MASK_BOTTOM)) { - downMixTable_[i][j] = COEF_M3DB_F; - } else { - DownMixMidFront(inBit, outBit, i, j); - } -} - -void DownMixer::DownMixMidFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) -{ - if ((inBit & MASK_MIDDLE_FRONT) && (outBit & MASK_MIDDLE_FRONT)) { - downMixTable_[i][j] = COEF_M3DB_F; - } -} - -void DownMixer::DownMixMidRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) -{ - // Middle layer - switch (inBit) { - case BACK_CENTER: - if ((outBit == BACK_LEFT) || (outBit == SIDE_LEFT) || (outBit == WIDE_LEFT) || (outBit == FRONT_LEFT) || - (outBit == BACK_RIGHT) || outBit == SIDE_RIGHT || outBit == WIDE_RIGHT || outBit == FRONT_RIGHT) { - downMixTable_[i][j] = COEF_M3DB_F; - } - break; - case BACK_LEFT: - if (outBit == SIDE_LEFT) { - downMixTable_[i][j] = COEF_0DB_F; - } else if (outBit == BACK_CENTER) { - downMixTable_[i][j] = COEF_0DB_F; - } else { - DownMixMidFront(WIDE_LEFT, outBit, i, j); - } - break; - case BACK_RIGHT: - if (outBit == SIDE_RIGHT) { - downMixTable_[i][j] = COEF_0DB_F; - } else if (outBit == BACK_CENTER) { - downMixTable_[i][j] = COEF_0DB_F; - } else { - DownMixMidFront(WIDE_RIGHT, outBit, i, j); - } - break; - } -} - -void DownMixer::DownMixLfe(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) -{ - if ((MASK_LFE & inBit) && (MASK_LFE & outBit)) { - downMixTable_[i][j] = COEF_0DB_F; - } else { - if ((inBit == LOW_FREQUENCY) && ((outBit & CH_LAYOUT_STEREO)!= 0)) { - downMixTable_[i][j] = COEF_M6DB_F; - } else if ((inBit == LOW_FREQUENCY_2) && ((outBit & CH_LAYOUT_STEREO) != 0)) { - downMixTable_[i][j] = COEF_M6DB_F; - } - } -} - -void DownMixer::DownMixTopCenter(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) -{ - uint64_t exitTopOuts = outLayout_ & (MASK_TOP_FRONT | MASK_TOP_REAR); - uint64_t exitMiddleOuts = outLayout_ & (MASK_MIDDLE_FRONT | MASK_MIDDLE_REAR); - if (exitTopOuts != 0) { // exist top outs - uint32_t numChannels = bitCounts(exitTopOuts); - uint32_t coeff = 1.0f / sqrt((float)numChannels); - if ((outBit & exitTopOuts) != 0) { - downMixTable_[i][j] = coeff; - } - } else if (exitMiddleOuts != 0) { - uint32_t numChannels = bitCounts(exitMiddleOuts); - uint32_t coeff = 1.0f / sqrt((float)numChannels); - if ((outBit & exitMiddleOuts) != 0) { - downMixTable_[i][j] = coeff; - } - } -} - -void DownMixer::DownMixTopFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) -{ - uint64_t existTopFrontOuts = outLayout_ & MASK_TOP_FRONT; - if (existTopFrontOuts != 0) { - if ((outBit & MASK_TOP_FRONT) != 0) { - downMixTable_[i][j] = COEF_M3DB_F; - } - } else { - DownMixMidFront(TOP_FRONT_CENTER, outBit, i, j); - } -} - -void DownMixer::DownMixTopRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j) -{ - uint64_t existTopRearOuts = outLayout_ & MASK_TOP_REAR; - if (existTopRearOuts != 0) { - if ((outBit & MASK_TOP_REAR) != 0) { - downMixTable_[i][j] = COEF_M3DB_F; - } - } else { - DownMixMidRear(BACK_CENTER, outBit, i, j); - } -} - -static uint32_t bitCounts(uint64_t bits) -{ - uint32_t num = 0; - for (; bits != 0; bits &= bits - 1) { - num++; - } - return num; -} - -static bool isValidChLayout(AudioChannelLayout &chLayout, uint32_t chCounts) -{ - if (chCounts < MONO || chCounts > CHANNEL_16) { - return false; - } - if (chLayout == CH_LAYOUT_UNKNOWN || bitCounts(chLayout) != chCounts) { - chLayout = SetDefaultChannelLayout((AudioChannel)chCounts); - } - return true; -} - -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; - } -} - -} // HPAE -} // AudioStandard -} // OHOS \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/include/audio_proresampler.h b/services/audio_engine/plugin/resample/include/audio_proresampler.h deleted file mode 100644 index 0b3aa0f00e..0000000000 --- a/services/audio_engine/plugin/resample/include/audio_proresampler.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2025 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 AUDIO_PRORESAMPLER_H -#define AUDIO_PRORESAMPLER_H - -#include "resampler.h" -#include "audio_proresampler_process.h" -#include -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class ProResampler : public Resampler { -public: - ProResampler(uint32_t inRate, uint32_t outRate, uint32_t channels, uint32_t quality); - ~ProResampler() override; - // disable deep copy, enable move semantics to manage memory allocated by C malloc - ProResampler(const ProResampler &) = delete; - ProResampler &operator=(const ProResampler &) = delete; - ProResampler(ProResampler &&) noexcept; - ProResampler &operator=(ProResampler &&) noexcept; - void Reset() override; - int Process(const float *inBuffer, uint32_t *inFrameSize, float *outBuffer, uint32_t *outFrameSize) - override; - int32_t UpdateRates(uint32_t inRate, uint32_t outRate) override; - void UpdateChannels(uint32_t channels) override; - uint32_t GetInRate() const override; - uint32_t GetOutRate() const override; - uint32_t GetChannels() const override; - uint32_t GetQuality() const; -private: - std::string ErrCodeToString(int32_t errCode); - uint32_t inRate_; - uint32_t outRate_; - uint32_t channels_; - uint32_t quality_; - SingleStagePolyphaseResamplerState* state_ = nullptr; -}; -} // HPAE -} // AudioStandard -} // OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/include/audio_proresampler_process.h b/services/audio_engine/plugin/resample/include/audio_proresampler_process.h deleted file mode 100644 index 67067a7eef..0000000000 --- a/services/audio_engine/plugin/resample/include/audio_proresampler_process.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2025 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 AUDIO_PRORESAMPLER_PROCESS_H -#define AUDIO_PRORESAMPLER_PROCESS_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - typedef enum MultiplyFilterFunMethod { - MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP, - MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP, - MULTIPLY_FILTER_FUN_UP, - MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN, - MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN, - MULTIPLY_FILTER_FUN_DOWN, - MULTIPLY_FILTER_FUN_MAX - } MultiplyFilterFun_t; - - enum { - RESAMPLER_ERR_SUCCESS = 0, - RESAMPLER_ERR_ALLOC_FAILED = -1, - RESAMPLER_ERR_INVALID_ARG = -2, - RESAMPLER_ERR_OVERFLOW = -3 - }; - - #define MAX_RATIO_INTEGRAL_METHOD 32 - - typedef struct SingleStagePolyphaseResamplerState SingleStagePolyphaseResamplerState; - - typedef int32_t (*ResamplerMethod)(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength); - typedef void (*MultiplyFilterFun)(SingleStagePolyphaseResamplerState* state, - const float* coeffs, const float* inputs, float* outputs, int32_t subfilterNum); - - - /** - * @brief Resampler state - * - */ - struct SingleStagePolyphaseResamplerState { - uint32_t decimateFactor; /** Integer decimation factor */ - uint32_t interpolateFactor; /** Integer interpolation factor */ - - int32_t quality; /** Parameter for resampler quality (0~10) */ - uint32_t numChannels; /** Number of channels */ - uint32_t filterLength; /** Number of taps of anti-aliasing/imaging filter */ - uint32_t bufferSize; /** Number of buffer samples for each channel */ - int32_t quoSamplerateRatio; /** Quotient of (input sampling frequency)/(output sampling frequency) */ - int32_t remSamplerateRatio; /** remainder of (input sampling frequency)/(output sampling frequency) */ - float cutoff; /** Normalized cutoff frequency of anti-aliasing/imaging filter */ - float coshParameter; /** Parameter of cosh window for adjusting side-lobe decay of filter */ - int32_t isInitialized; /** If the state is initialized, isInitialized=1. */ - int32_t isStarted; /** Once the resampler has processed, isStarted = 1. */ - - int32_t inputIndex; /** Index of the input to be processed. */ - uint32_t subfilterNum; /** What number of polyphase subfilters to use. */ - uint32_t magicSamples; /** Used for variable sampling frequency (don't need this?) */ - - float* inputMemory; /** An array that stores the inputs to be processed. */ - uint32_t inputMemorySize; /** Size of inputMemory. (bufferSize + filterLength + 1) */ - float* filterCoefficients; /** An array that stores the polyphase filters. */ - uint32_t filterCoefficientsSize; /** Size of filterCoefficients. */ - ResamplerMethod resamplerFunction; /** A pointer to the function used for resampling. */ - MultiplyFilterFun multiplyFunSeq[MAX_RATIO_INTEGRAL_METHOD]; - }; - -/** - * @brief Create a new resampler state. - * - * @param numChannels Number of channels. - * @param decimateFactor Integer decimation factor (input sampling frequency). - * @param interpolateFactor Integer interpolation factor (output sampling frequency). - * @param quality Parameter for determining resampling quality level between 0 (poor) and 10 (best). - * @param err - * @return SingleStagePolyphaseResamplerState* Created resampler state used for process - */ - SingleStagePolyphaseResamplerState* SingleStagePolyphaseResamplerInit(uint32_t numChannels, - uint32_t decimateFactor, uint32_t interpolateFactor, int32_t quality, int32_t* err); - - - /** - * @brief Set (update) the input/output sampling rates. - * - * @param state Resampler state - * @param decimateFactor Integer decimation factor (input sampling frequency). - * @param interpolateFactor Integer interpolation factor (output sampling frequency). - * @return int32_t returns 0 if the function terminates normally. - */ - int32_t SingleStagePolyphaseResamplerSetRate(SingleStagePolyphaseResamplerState* state, - uint32_t decimateFactor, uint32_t interpolateFactor); - - /** - * @brief - * - * @param state Resampler state. - * @return int32_t returns 0 if the function terminates normally. - */ - int32_t SingleStagePolyphaseResamplerSkipHalfTaps(SingleStagePolyphaseResamplerState* state); - - - /** - * @brief Reset the buffers of the resampler. - * - * @param state Resampler state. - * @return int32_t returns 0 if the function terminates normally. - */ - int32_t SingleStagePolyphaseResamplerResetMem(SingleStagePolyphaseResamplerState* state); - - /** - * @brief Release the memory for the resampler state - * - * @param state Resampler state. - */ - void SingleStagePolyphaseResamplerFree(SingleStagePolyphaseResamplerState* state); - - - /** - * @brief Resample an input array. - * - * @param state resampler state - * @param in Input array. - * @param inputLength Number of input samples. - * @param out Output array. - * @param outputLength Number of input samples. - * @return int32_t returns 0 if the function terminates normally. - */ - int32_t SingleStagePolyphaseResamplerProcess(SingleStagePolyphaseResamplerState* state, - const float* in, uint32_t* inputLength, float* out, uint32_t* outputLength); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/include/resampler.h b/services/audio_engine/plugin/resample/include/resampler.h deleted file mode 100644 index 7c088a2f97..0000000000 --- a/services/audio_engine/plugin/resample/include/resampler.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2025 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 RESAMPLER_H -#define RESAMPLER_H -#include -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class Resampler { -public: - virtual ~Resampler() = default; - virtual void Reset() = 0; - virtual int Process(const float *in_buffer, uint32_t *inFrameSize, float *out_buffer, - uint32_t *outFrameSize) = 0; - virtual int32_t UpdateRates(uint32_t inRate, uint32_t outRate) = 0; - virtual uint32_t GetInRate() const = 0; - virtual uint32_t GetOutRate() const = 0; - virtual uint32_t GetChannels() const = 0; - virtual void UpdateChannels(uint32_t channels) = 0; -}; - -} // HPAE -} // AudioStandard -} // OHOS - -#endif \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp b/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp deleted file mode 100644 index 8d0ad5773a..0000000000 --- a/services/audio_engine/plugin/resample/proresampler/audio_proresampler.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2025 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 "audio_proresampler.h" -#include "audio_policy_log.h" -#include "securec.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -ProResampler::ProResampler(uint32_t inRate, uint32_t outRate, uint32_t channels, uint32_t quality) - : inRate_(inRate), outRate_(outRate), channels_(channels), quality_(quality) -{ - int32_t errRet; - state_ = SingleStagePolyphaseResamplerInit(channels_, inRate_, outRate_, quality_, &errRet); - if (state_) { - SingleStagePolyphaseResamplerSkipHalfTaps(state_); - AUDIO_INFO_LOG("Proresampler: Init success inRate: %{public}d, outRate: %{public}d, channels: %{public}d, " - "quality: %{public}d.", inRate_, outRate_, channels_, quality_); - } else { - AUDIO_ERR_LOG("Proresampler: Init failed! failed with error %{public}s.", - ErrCodeToString(errRet).c_str()); - } -} - -int32_t ProResampler::Process(const float *inBuffer, uint32_t *inFrameSize, float *outBuffer, - uint32_t *outFrameSize) -{ - CHECK_AND_RETURN_RET_LOG(state_ != nullptr, RESAMPLER_ERR_ALLOC_FAILED, - "ProResampler Process: resampler is %{public}s", ErrCodeToString(RESAMPLER_ERR_ALLOC_FAILED).c_str()); - uint32_t expectedOutFrameSize = *outFrameSize; - std::vector tmpOutBuf(expectedOutFrameSize * channels_, 0.0f); - int32_t ret = - SingleStagePolyphaseResamplerProcess(state_, inBuffer, inFrameSize, tmpOutBuf.data(), outFrameSize); - if (ret != 0) { - 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)); - ret += memcpy_s(outBuffer + fillZeroSize * channels_, - (expectedOutFrameSize - fillZeroSize) * channels_ * sizeof(float), - tmpOutBuf.data(), *outFrameSize * channels_ * sizeof(float)); - if (ret != EOK) { - ret = RESAMPLER_ERR_ALLOC_FAILED; - } - return ret; -} - -int32_t ProResampler::UpdateRates(uint32_t inRate, uint32_t outRate) -{ - inRate_ = inRate; - outRate_ = outRate; - CHECK_AND_RETURN_RET_LOG(state_ != nullptr, RESAMPLER_ERR_ALLOC_FAILED, "ProResampler: resampler is null"); - int32_t ret = SingleStagePolyphaseResamplerSetRate(state_, inRate_, outRate_); - if (ret != 0) { - AUDIO_WARNING_LOG("ProResampler update rate failed with error code %{public}s", ErrCodeToString(ret).c_str()); - } - return ret; -} - -void ProResampler::UpdateChannels(uint32_t channels) -{ - uint32_t oldChannels = channels_; - channels_ = channels; - SingleStagePolyphaseResamplerFree(state_); - int32_t errRet; - state_ = SingleStagePolyphaseResamplerInit(channels_, inRate_, outRate_, quality_, &errRet); - if (state_) { - SingleStagePolyphaseResamplerSkipHalfTaps(state_); - AUDIO_INFO_LOG("Proresampler: update work channel success old channels: %{public}d, new channels: %{public}d", - oldChannels, channels_); - } else { - AUDIO_ERR_LOG("Proresampler: update work channels failed with error %{public}s.", - ErrCodeToString(errRet).c_str()); - } -} - -ProResampler::ProResampler(ProResampler &&other) noexcept - : inRate_(other.inRate_), outRate_(other.outRate_), channels_(other.channels_), - quality_(other.quality_), state_(other.state_) -{ - other.state_ = nullptr; -} - -ProResampler &ProResampler::operator=(ProResampler &&other) noexcept -{ - if (this != &other) { - if (state_ != nullptr) { - SingleStagePolyphaseResamplerFree(state_); - } - inRate_ = other.inRate_; - outRate_ = other.outRate_; - channels_ = other.channels_; - quality_ = other.quality_; - state_ = other.state_; - other.state_ = nullptr; - } - return *this; -} - -void ProResampler::Reset() -{ - CHECK_AND_RETURN_LOG(state_ != nullptr, "ProResampler: resampler is null"); - SingleStagePolyphaseResamplerResetMem(state_); - SingleStagePolyphaseResamplerSkipHalfTaps(state_); -} - -uint32_t ProResampler::GetInRate() const -{ - return inRate_; -} - -uint32_t ProResampler::GetOutRate() const -{ - return outRate_; -} - -uint32_t ProResampler::GetChannels() const -{ - return channels_; -} - -uint32_t ProResampler::GetQuality() const -{ - return quality_; -} - -ProResampler::~ProResampler() -{ - if (state_ != nullptr) { - SingleStagePolyphaseResamplerFree(state_); - state_ = nullptr; - } -} - -std::string ProResampler::ErrCodeToString(int32_t errCode) -{ - switch (errCode) { - case RESAMPLER_ERR_SUCCESS: { - return "RESAMPLER_ERR_SUCCESS"; - break; - } - case RESAMPLER_ERR_ALLOC_FAILED: { - return "RESAMPLER_ERR_ALLOC_FAILED"; - break; - } - case RESAMPLER_ERR_INVALID_ARG: { - return "RESAMPLER_ERR_INVALID_ARG"; - break; - } - case RESAMPLER_ERR_OVERFLOW: { - return "RESAMPLER_ERR_OVERFLOW"; - break; - } - default: { - return "Unknown Error Code"; - } - } -} - -} // HPAE -} // AudioStandard -} // OHOS \ No newline at end of file diff --git a/services/audio_engine/plugin/resample/proresampler/audio_proresampler_process.c b/services/audio_engine/plugin/resample/proresampler/audio_proresampler_process.c deleted file mode 100644 index db518888d0..0000000000 --- a/services/audio_engine/plugin/resample/proresampler/audio_proresampler_process.c +++ /dev/null @@ -1,1490 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. - */ - - -#include -#include -#include -#include -#include "audio_proresampler_process.h" -#include "securec.h" -/** - * @brief Ratio of circumference to diameter - * - */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -/** - * @brief Maximum number of numChannels - * - */ -#define MAX_NUM_CHANNEL 16 - - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef MONO -#define MONO 1 -#endif - -#ifndef STEREO -#define STEREO 2 -#endif - -#define TWO_STEPS 2 -#define THREE_STEPS 3 -#define FOUR_STEPS 4 -#define QUALITY_LEVEL_TEN 10 -#define BUFFER_SIZE 160 - -// WARNING: Code for support to sudden changes in sampling frequency is deprecated! -// It is disabled because it is complex and untested. -// It is desirable to re-initialize for such a change in the sampling frequency. - -/** - * @brief A function that compares two values and returns the smaller one - * - */ -#define COMPARE_MIN(a, b) ((a) > (b) ? (b) : (a)) - -/** - * @brief A function that compares two values and returns the larger one - * - */ -#define COMPARE_MAX(a, b) ((a) < (b) ? (b) : (a)) - -/** - * @brief A function that helps update resampler state - * -*/ -static int32_t UpdateFilterMemory(SingleStagePolyphaseResamplerState* state, uint32_t oldFilterLength); -struct QualityTable { - int32_t filterLength; - float coshParameter; -}; - - -/** - * @brief This table contains internal parameters corresponding to quality levels. - * - * The relationship between coshParameter and side lobe decay is as follows: - * coshParameter = -8.722e-5 * attenuation^TWO_STEPS + 0.1335 * attenuation - 1.929 (50 < attenuation) - */ -static const struct QualityTable qualityTable[11] = { - { 8, 5.767008}, /* Q0 */ - { 16, 5.767008}, /* Q1 */ - { 32, 5.767008}, /* Q2 */ /* ( ~60 dB stop) 6 */ - { 48, 8.192792}, /* Q3 */ /* ( ~80 dB stop) 8 */ - { 64, 8.192792}, /* Q4 */ /* ( ~80 dB stop) 8 */ - { 80, 10.5488}, /* Q5 */ /* (~100 dB stop) 10 */ - { 96, 10.5488}, /* Q6 */ /* (~100 dB stop) 10 */ - {128, 10.5488}, /* Q7 */ /* (~100 dB stop) 10 */ - {160, 10.5488}, /* Q8 */ /* (~100 dB stop) 10 */ - {192, 10.5488}, /* Q9 */ /* (~100 dB stop) 10 */ - {256, 10.5488}, /* Q10 */ /* (~100 dB stop) 10 */ -}; - - -static double CompHyperbolicCosineWindow(double x, float alpha) -{ - double x2; - double w; - - x2 = x * x; - if (x2 >= 1.0) { - return 0.f; - } - - w = alpha * sqrt(1.0f - x2); - w = cosh(w) / cosh(alpha); - return w; -} - - -static float Sinc(float x) -{ - if (fabs(x) < 1e-6) { - return 1.0f; - } - return sin(M_PI * x) / (M_PI * x); -} - - -static int32_t CalculateFilter(SingleStagePolyphaseResamplerState* state) -{ - uint32_t i; - int32_t j; - float phi0 = 0; - float phi = 0; - double w; - uint32_t requiredFilterCoefficientsSize; - float cutoff = state->cutoff; - - if (INT_MAX / sizeof(float) / state->interpolateFactor < state->filterLength) { - return RESAMPLER_ERR_ALLOC_FAILED; - } - - requiredFilterCoefficientsSize = state->filterLength * state->interpolateFactor; - - if (state->filterCoefficientsSize < requiredFilterCoefficientsSize) { - if (state->filterCoefficients == NULL) { - state->filterCoefficients = (float*)malloc(requiredFilterCoefficientsSize * sizeof(float)); - if (!state->filterCoefficients) { - return RESAMPLER_ERR_ALLOC_FAILED; - } - } else { - float* filterCoefficients = (float*)malloc(requiredFilterCoefficientsSize * sizeof(float)); - if (!filterCoefficients) { - return RESAMPLER_ERR_ALLOC_FAILED; - } - if (memcpy_s(filterCoefficients, requiredFilterCoefficientsSize * sizeof(float), - state->filterCoefficients, state->filterCoefficientsSize * sizeof(float)) != 0) { - return RESAMPLER_ERR_ALLOC_FAILED; - } - free(state->filterCoefficients); - state->filterCoefficients = filterCoefficients; - } - state->filterCoefficientsSize = requiredFilterCoefficientsSize; - } - - for (i = 0; i < state->interpolateFactor; i++) { - for (j = 0; j < state->filterLength; j++) { - phi = (j - (int32_t)state->filterLength / TWO_STEPS + 1) - phi0; - w = CompHyperbolicCosineWindow(fabs((double)TWO_STEPS * phi / state->filterLength), - state->coshParameter); - state->filterCoefficients[i * state->filterLength + j] = w * cutoff * Sinc(cutoff * phi); - } - phi0 += 1.0 / state->interpolateFactor; - } - return 0; -} - -/*====== Filter multiplication function for general cases =====*/ -static void MultiplyFilterMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - float sum = 0; - - for (int32_t j = 0; j < state->filterLength; j += FOUR_STEPS) { - sum += (*coeffs++) * (*inputs++); - sum += (*coeffs++) * (*inputs++); - sum += (*coeffs++) * (*inputs++); - sum += (*coeffs++) * (*inputs++); - } - *outputs = sum; -} - -static void MultiplyFilterStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - float sumL = 0; - float sumR = 0; - float h; - - for (int32_t j = 0; j < state->filterLength; j += FOUR_STEPS) { - h = *coeffs++; - sumL += h * (*inputs++); - sumR += h * (*inputs++); - - h = *coeffs++; - sumL += h * (*inputs++); - sumR += h * (*inputs++); - - h = *coeffs++; - sumL += h * (*inputs++); - sumR += h * (*inputs++); - - h = *coeffs++; - sumL += h * (*inputs++); - sumR += h * (*inputs++); - } - *outputs++ = sumL; - *outputs = sumR; -} - -static void MultiplyFilterMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t numChannels = state->numChannels; - int32_t ch, j; - float h; - float sum[MAX_NUM_CHANNEL]; - - for (ch = 0; ch < numChannels; ch++) { - sum[ch] = 0; - } - for (j = 0; j < state->filterLength; j += FOUR_STEPS) { - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (*inputs++); - } - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (*inputs++); - } - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (*inputs++); - } - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (*inputs++); - } - } - for (ch = 0; ch < numChannels; ch++) { - *outputs++ = sum[ch]; - } -} - -/*===== Filter multiplication function for coarse (integral) upsampling =====*/ -static void MultiplyFilterSymmetricOddUpMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - *outputs = inputs[state->filterLength / TWO_STEPS - 1]; -} - -static void MultiplyFilterSymmetricOddUpStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - *outputs++ = inputs[state->filterLength - TWO_STEPS]; - *outputs = inputs[state->filterLength - 1]; -} - -static void MultiplyFilterSymmetricOddUpMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t indCenter = state->filterLength / TWO_STEPS - 1; - for (int32_t ch = 0; ch < state->numChannels; ch++) { - *outputs++ = inputs[state->numChannels * indCenter + ch]; - } -} - -static void MultiplyFilterSymmetricEvenUpMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - float sum = 0; - - for (int32_t j = 0; j < N / TWO_STEPS; j += FOUR_STEPS) { - sum += (*coeffs++) * (inputs[j] + inputs[(N - j - 1)]); - sum += (*coeffs++) * (inputs[j + 1] + inputs[(N - (j + 1) - 1)]); - sum += (*coeffs++) * (inputs[j + TWO_STEPS] + inputs[(N - (j + TWO_STEPS) - 1)]); - sum += (*coeffs++) * (inputs[j + THREE_STEPS] + inputs[(N - (j + THREE_STEPS) - 1)]); - } - *outputs = sum; -} - -static void MultiplyFilterSymmetricEvenUpStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - float sumL = 0; - float sumR = 0; - float h; - - for (int32_t j = 0; j < N / TWO_STEPS; j += FOUR_STEPS) { - h = *coeffs++; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - 1) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - 1) * STEREO + 1]); - h = *coeffs++; - sumL += h * (inputs[(j + 1) * STEREO] + inputs[(N - (j + 1) - 1) * STEREO]); - sumR += h * (inputs[(j + 1) * STEREO + 1] + inputs[(N - (j + 1) - 1) * STEREO + 1]); - h = *coeffs++; - sumL += h * (inputs[(j + TWO_STEPS) * STEREO] + inputs[(N - (j + TWO_STEPS) - 1) * STEREO]); - sumR += h * (inputs[(j + TWO_STEPS) * STEREO + 1] + inputs[(N - (j + TWO_STEPS) - 1) * STEREO + 1]); - h = *coeffs++; - sumL += h * (inputs[(j + THREE_STEPS) * STEREO] + inputs[(N - (j + THREE_STEPS) - 1) * STEREO]); - sumR += h * (inputs[(j + THREE_STEPS) * STEREO + 1] + inputs[(N - (j + THREE_STEPS) - 1) * STEREO + 1]); - } - *outputs++ = sumL; - *outputs++ = sumR; -} - -static void MultiplyFilterSymmetricEvenUpMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const int32_t numChannels = state->numChannels; - int32_t ch, j; - float sum[MAX_NUM_CHANNEL]; - float h; - - for (ch = 0; ch < numChannels; ch++) { - sum[ch] = 0; - } - for (j = 0; j < N / TWO_STEPS; j++) { - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - 1) * numChannels + ch]); - } - } - for (ch = 0; ch < numChannels; ch++) { - *outputs++ = sum[ch]; - } -} - -static void MultiplyFilterSymmetricOddDownMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - const uint32_t decimateFactor = state->decimateFactor; - float sum; - int32_t rem = indCenter % decimateFactor; - int32_t L = indCenter / decimateFactor; - int32_t i, j, l; - // center index - sum = coeffs[indCenter] * inputs[indCenter]; - // symmetric indices - for (j = 0; j < rem; j++) { - sum += (*coeffs++) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); - } - for (l = 0; l < L; l++) { - coeffs++; - j++; - for (i = 1; i < decimateFactor; i++) { - sum += (*coeffs++) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); - j++; - } - } - - *outputs = sum; -} - -static void MultiplyFilterSymmetricOddDownStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - const uint32_t decimateFactor = state->decimateFactor; - float sumL, sumR, h; - int32_t rem = indCenter % decimateFactor; - int32_t L = indCenter / decimateFactor; - int32_t i, j, l; - - // center - h = coeffs[indCenter]; - sumL = h * inputs[N - TWO_STEPS]; - sumR = h * inputs[N - 1]; - // symmetric indices - for (j = 0; j < rem; j++) { - h = *coeffs++; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); - } - for (l = 0; l < L; l++) { - coeffs++; - j++; - for (i = 1; i < decimateFactor; i++) { - h = *coeffs++; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); - j++; - } - } - - *outputs++ = sumL; - *outputs = sumR; -} - -static void MultiplyFilterSymmetricOddDownMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const int32_t numChannels = state->numChannels; - const int32_t indCenter = N / TWO_STEPS - 1; - const uint32_t decimateFactor = state->decimateFactor; - int32_t i, j, l, ch; - float sum[MAX_NUM_CHANNEL]; - float h; - int32_t rem = indCenter % decimateFactor; - int32_t L = indCenter / decimateFactor; - - // center index - h = coeffs[indCenter]; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] = h * (inputs[indCenter * numChannels + ch]); - } - // symmetric indices - for (j = 0; j < rem; j++) { - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); - } - } - for (l = 0; l < L; l++) { - coeffs++; - j++; - for (i = 1; i < decimateFactor; i++) { - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); - } - j++; - } - } - - for (ch = 0; ch < numChannels; ch++) { - *outputs++ = sum[ch]; - } -} - - -static void MultiplyFilterSymmetricEvenDownMono(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const uint32_t decimateFactor = state->decimateFactor; - int32_t i, j, l; - int32_t rem = (N / TWO_STEPS) % decimateFactor; - int32_t L = (N / TWO_STEPS) / decimateFactor; - float h; - - float sum = 0; - - // symmetric indices - for (j = 0; j < rem; j++) { - h = *coeffs++; - sum += h * (inputs[j] + inputs[(N - j - 1)]); - } - for (l = 0; l < L; l++) { - for (i = 0; i < decimateFactor / TWO_STEPS; i++) { - h = *coeffs++; - sum += h * (inputs[j] + inputs[(N - j - 1)]); - j++; - } - // Skip zero - coeffs++; - j++; - for (i = 0; i < decimateFactor / TWO_STEPS; i++) { - h = *coeffs++; - sum += h * (inputs[j] + inputs[(N - j - 1)]); - j++; - } - } - *outputs = sum; -} - -static void MultiplyFilterSymmetricEvenDownStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const uint32_t decimateFactor = state->decimateFactor; - int32_t i, j, l; - int32_t rem = (N / TWO_STEPS) % decimateFactor; - int32_t L = (N / TWO_STEPS) / decimateFactor; - float h; - - float sumL = 0; - float sumR = 0; - - // symmetric indices - for (j = 0; j < rem; j++) { - h = *coeffs++; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - 1) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - 1) * STEREO + 1]); - } - for (l = 0; l < L; l++) { - for (i = 0; i < decimateFactor / TWO_STEPS; i++) { - h = *coeffs++; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - 1) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - 1) * STEREO + 1]); - j++; - } - // Skip zero - coeffs++; - j++; - for (i = 0; i < decimateFactor / TWO_STEPS; i++) { - h = *coeffs++; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - 1) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - 1) * STEREO + 1]); - j++; - } - } - *outputs++ = sumL; - *outputs++ = sumR; -} - - -static void MultiplyFilterSymmetricEvenDownMultichannel(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const int32_t numChannels = state->numChannels; - const uint32_t decimateFactor = state->decimateFactor; - int32_t i, j, l, ch; - float sum[MAX_NUM_CHANNEL]; - float h; - int32_t rem = (N / TWO_STEPS) % decimateFactor; - int32_t L = (N / TWO_STEPS) / decimateFactor; - - for (ch = 0; ch < numChannels; ch++) { - sum[ch] = 0; - } - // symmetric indices - for (j = 0; j < rem; j++) { - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - 1) * numChannels + ch]); - } - } - for (l = 0; l < L; l++) { - for (i = 0; i < decimateFactor / TWO_STEPS; i++) { - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - 1) * numChannels + ch]); - } - j++; - } - //Skip zero - coeffs++; - j++; - for (i = 0; i < decimateFactor / TWO_STEPS; i++) { - h = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - 1) * numChannels + ch]); - } - j++; - } - } - - for (ch = 0; ch < numChannels; ch++) { - *outputs++ = sum[ch]; - } -} - -static void MultiplyFilterDownMono(SingleStagePolyphaseResamplerState *state, const float *coeffs, - const float *inputs, float *outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - const uint32_t decimateFactor = state->decimateFactor; - int32_t j; - float h; - float sum = 0; - - int32_t counts = indCenter % decimateFactor - subfilterNum; - if (counts < 0) { - counts += state->interpolateFactor; - } - - for (j = 0; j < N; j++) { - h = *coeffs++; - if (counts == 0) { // Skip zero coefficients - counts = decimateFactor - 1; - inputs++; - continue; - } - sum += h * (*inputs++); - counts--; - } - *outputs = sum; -} - -static void MultiplyFilterDownStereo(SingleStagePolyphaseResamplerState* state, const float* coeffs, - const float* inputs, float* outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - const uint32_t decimateFactor = state->decimateFactor; - int32_t j; - float sumL = 0; - float sumR = 0; - float h; - - int32_t counts = indCenter % decimateFactor - subfilterNum; - if (counts < 0) { - counts += state->interpolateFactor; - } - - for (j = 0; j < N; j++) { - h = *coeffs++; - if (counts == 0) { // Skip zero coefficients - counts = decimateFactor - 1; - inputs += STEREO; - continue; - } - sumL += h * (*inputs++); - sumR += h * (*inputs++); - counts--; - } - *outputs++ = sumL; - *outputs = sumR; -} - -static void MultiplyFilterDownMultichannel(SingleStagePolyphaseResamplerState *state, const float *coeffs, - const float *inputs, float *outputs, int32_t subfilterNum) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - const uint32_t decimateFactor = state->decimateFactor; - const int32_t numChannels = state->numChannels; - int32_t j, ch; - float h; - float sum[MAX_NUM_CHANNEL]; - - int32_t counts = indCenter % decimateFactor - subfilterNum; - if (counts < 0) { - counts += state->interpolateFactor; - } - - for (ch = 0; ch < numChannels; ch++) { - sum[ch] = 0; - } - for (j = 0; j < N; j++) { - h = *coeffs++; - if (counts == 0) { // Skip zero coefficients - counts = decimateFactor - 1; - inputs += numChannels; - continue; - } - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (*inputs++); - } - counts--; - } - for (ch = 0; ch < numChannels; ch++) { - *outputs++ = sum[ch]; - } -} - - -/*===== Function pointers of filter multiplication functions =====*/ -static MultiplyFilterFun multiplyFilterFunTable[] = { - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP] = MultiplyFilterSymmetricOddUpMono, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP + 1] = MultiplyFilterSymmetricOddUpStereo, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP + TWO_STEPS] = MultiplyFilterSymmetricOddUpMultichannel, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP] = MultiplyFilterSymmetricEvenUpMono, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP + 1] = MultiplyFilterSymmetricEvenUpStereo, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP + TWO_STEPS] = MultiplyFilterSymmetricEvenUpMultichannel, - [THREE_STEPS * MULTIPLY_FILTER_FUN_UP] = MultiplyFilterMono, - [THREE_STEPS * MULTIPLY_FILTER_FUN_UP + 1] = MultiplyFilterStereo, - [THREE_STEPS * MULTIPLY_FILTER_FUN_UP + TWO_STEPS] = MultiplyFilterMultichannel, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN] = MultiplyFilterSymmetricOddDownMono, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN + 1] = MultiplyFilterSymmetricOddDownStereo, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN + TWO_STEPS] = - MultiplyFilterSymmetricOddDownMultichannel, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN] = MultiplyFilterSymmetricEvenDownMono, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN + 1] = MultiplyFilterSymmetricEvenDownStereo, - [THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN + TWO_STEPS] = - MultiplyFilterSymmetricEvenDownMultichannel, - [THREE_STEPS * MULTIPLY_FILTER_FUN_DOWN] = MultiplyFilterDownMono, - [THREE_STEPS * MULTIPLY_FILTER_FUN_DOWN + 1] = MultiplyFilterDownStereo, - [THREE_STEPS * MULTIPLY_FILTER_FUN_DOWN + TWO_STEPS] = MultiplyFilterDownMultichannel -}; - -static int32_t PolyphaseResamplerMono(SingleStagePolyphaseResamplerState *state, const float *in, uint32_t *inputLength, - float *out, uint32_t *outputLength) -{ - const int32_t N = state->filterLength; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - uint32_t subfilterNum = state->subfilterNum; - const float* filterCoefficients = state->filterCoefficients; - const int32_t quoSamplerateRatio = state->quoSamplerateRatio; - const int32_t remSamplerateRatio = state->remSamplerateRatio; - const uint32_t decimateFactor = state->decimateFactor; - const uint32_t interpolateFactor = state->interpolateFactor; - int32_t i; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - - subfilterNum) - 1) / decimateFactor + 1); - } - - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[subfilterNum * N]; - const float* inputs = &in[inputIndex * MONO]; - MultiplyFilterMono(state, coeffs, inputs, out, subfilterNum); - out++; - - inputIndex += quoSamplerateRatio; - subfilterNum += remSamplerateRatio; - if (subfilterNum >= interpolateFactor) { - subfilterNum -= interpolateFactor; - inputIndex++; - } - } - - state->inputIndex = inputIndex; - state->subfilterNum = subfilterNum; - return outSample; -} - -static int32_t PolyphaseResamplerStereo(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - uint32_t subfilterNum = state->subfilterNum; - const float* filterCoefficients = state->filterCoefficients; - const int32_t quoSamplerateRatio = state->quoSamplerateRatio; - const int32_t remSamplerateRatio = state->remSamplerateRatio; - const uint32_t decimateFactor = state->decimateFactor; - const uint32_t interpolateFactor = state->interpolateFactor; - int32_t i; - - if (inputIndex < (int32_t) (*inputLength)) { - outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - - subfilterNum) - 1) / decimateFactor + 1); - } - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[subfilterNum * N]; - const float* inputs = &in[inputIndex * STEREO]; - MultiplyFilterStereo(state, coeffs, inputs, out, subfilterNum); - out += STEREO; - - inputIndex += quoSamplerateRatio; - subfilterNum += remSamplerateRatio; - if (subfilterNum >= interpolateFactor) { - subfilterNum -= interpolateFactor; - inputIndex++; - } - } - - state->inputIndex = inputIndex; - state->subfilterNum = subfilterNum; - return outSample; -} - -static int32_t PolyphaseResamplerMultichannel(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - uint32_t subfilterNum = state->subfilterNum; - const float* filterCoefficients = state->filterCoefficients; - const int32_t quoSamplerateRatio = state->quoSamplerateRatio; - const int32_t remSamplerateRatio = state->remSamplerateRatio; - const uint32_t decimateFactor = state->decimateFactor; - const uint32_t interpolateFactor = state->interpolateFactor; - const int32_t numChannels = state->numChannels; - int32_t i; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - - subfilterNum) - 1) / decimateFactor + 1); - } - - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[subfilterNum * N]; - const float* inputs = &in[inputIndex * numChannels]; - MultiplyFilterMultichannel(state, coeffs, inputs, out, subfilterNum); - out += numChannels; - - inputIndex += quoSamplerateRatio; - subfilterNum += remSamplerateRatio; - if (subfilterNum >= interpolateFactor) { - subfilterNum -= interpolateFactor; - inputIndex++; - } - } - - state->inputIndex = inputIndex; - state->subfilterNum = subfilterNum; - return outSample; -} - -static int32_t PolyphaseDownsamplerHalfbandMono(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - const float* filterCoefficients = state->filterCoefficients; - float hCenter = filterCoefficients[indCenter]; - int32_t i, j; - float sum; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / TWO_STEPS + 1); - } - - for (i = 0; i < outSample; i++) { - const float *coeffs = &filterCoefficients[0]; - - const float *inputs = &in[inputIndex]; - // center - sum = hCenter * inputs[indCenter]; - // symmetric indices - for (j = 0; j < indCenter; j += TWO_STEPS) { - sum += (*coeffs) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); - coeffs += TWO_STEPS; - } - *out++ = sum; - inputIndex += TWO_STEPS; - } - - state->inputIndex = inputIndex; - return outSample; -} - -static int32_t PolyphaseDownsamplerHalfbandStereo(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - const float* filterCoefficients = state->filterCoefficients; - float hCenter = filterCoefficients[indCenter]; - int32_t i, j; - float sumL, sumR, h; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / TWO_STEPS + 1); - } - - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[0]; - const float* inputs = &in[inputIndex * STEREO]; - - // center - sumL = hCenter * inputs[N - TWO_STEPS]; - sumR = hCenter * inputs[N - 1]; - // symmetric indices - for (j = 0; j < indCenter; j += TWO_STEPS) { - h = *coeffs; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); - coeffs += TWO_STEPS; - } - *out++ = sumL; - *out++ = sumR; - inputIndex += TWO_STEPS; - } - - state->inputIndex = inputIndex; - return outSample; -} - -static int32_t PolyphaseDownsamplerHalfbandMultichannel(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - const float* filterCoefficients = state->filterCoefficients; - float hCenter = filterCoefficients[indCenter]; - int32_t i, j, ch; - float h; - float sum[MAX_NUM_CHANNEL]; - const int32_t numChannels = state->numChannels; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / TWO_STEPS + 1); - } - - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[0]; - const float* inputs = &in[inputIndex * numChannels]; - - // center - for (ch = 0; ch < numChannels; ch++) { - sum[ch] = hCenter * inputs[indCenter * numChannels + ch]; - } - // symmetric indices - for (j = 0; j < indCenter; j += TWO_STEPS) { - h = *coeffs; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); - } - coeffs += TWO_STEPS; - } - for (ch = 0; ch < numChannels; ch++) { - *out++ = sum[ch]; - } - inputIndex += TWO_STEPS; - } - - state->inputIndex = inputIndex; - return outSample; -} - -static int32_t PolyphaseDownsamplerThirdbandMono(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - const float* filterCoefficients = state->filterCoefficients; - int32_t i, j; - float sum; - int32_t rem = indCenter % THREE_STEPS; - float hCenter = filterCoefficients[indCenter]; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / THREE_STEPS + 1); - } - - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[0]; - const float* inputs = &in[inputIndex]; - - // center - sum = hCenter * inputs[indCenter]; - // symmetric indices - for (j = 0; j < rem; j++) { - sum += (*coeffs++) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); - } - coeffs++; - for (j = rem + 1; j < indCenter; j += THREE_STEPS) { - sum += (*coeffs++) * (inputs[j] + inputs[(N - j - TWO_STEPS)]); - sum += (*coeffs++) * (inputs[(j + 1)] + inputs[(N - (j + 1) - TWO_STEPS)]); - coeffs++; - } - *out++ = sum; - inputIndex += THREE_STEPS; - } - - state->inputIndex = inputIndex; - return outSample; -} - -static int32_t PolyphaseDownsamplerThirdbandStereo(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - const float* filterCoefficients = state->filterCoefficients; - int32_t i, j; - float sumL, sumR, h; - int32_t rem = indCenter % THREE_STEPS; - float hCenter = filterCoefficients[indCenter]; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / THREE_STEPS + 1); - } - - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[0]; - const float* inputs = &in[inputIndex * STEREO]; - - // center - sumL = hCenter * inputs[N - TWO_STEPS]; - sumR = hCenter * inputs[N - 1]; - - // symmetric indices - for (j = 0; j < rem; j++) { - h = *coeffs++; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); - } - coeffs++; - for (j = rem + 1; j < indCenter; j += THREE_STEPS) { - h = *coeffs++; - sumL += h * (inputs[j * STEREO] + inputs[(N - j - TWO_STEPS) * STEREO]); - sumR += h * (inputs[j * STEREO + 1] + inputs[(N - j - TWO_STEPS) * STEREO + 1]); - h = *coeffs++; - sumL += h * (inputs[(j + 1) * STEREO] + inputs[(N - (j + 1) - TWO_STEPS) * STEREO]); - sumR += h * (inputs[(j + 1) * STEREO + 1] + inputs[(N - (j + 1) - TWO_STEPS) * STEREO + 1]); - coeffs++; - } - *out++ = sumL; - *out++ = sumR; - inputIndex += THREE_STEPS; - } - - state->inputIndex = inputIndex; - return outSample; -} - -static int32_t PolyphaseDownsamplerThirdbandMultichannel(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - const int32_t indCenter = N / TWO_STEPS - 1; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - const float* filterCoefficients = state->filterCoefficients; - int32_t i, j, ch; - float h1, h2; - float sum[MAX_NUM_CHANNEL]; - const int32_t numChannels = state->numChannels; - int32_t rem = indCenter % THREE_STEPS; - float hCenter = filterCoefficients[indCenter]; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), (((*inputLength) - inputIndex) - 1) / THREE_STEPS + 1); - } - - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[0]; - const float* inputs = &in[inputIndex * numChannels]; - - // center - for (ch = 0; ch < numChannels; ch++) { - sum[ch] = hCenter * (inputs[indCenter * numChannels + ch]); - } - - // symmetric indices - for (j = 0; j < rem; j++) { - h1 = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h1 * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); - } - } - coeffs++; - for (j = rem + 1; j < indCenter; j += THREE_STEPS) { - h1 = *coeffs++; - h2 = *coeffs++; - for (ch = 0; ch < numChannels; ch++) { - sum[ch] += h1 * (inputs[j * numChannels + ch] + inputs[(N - j - TWO_STEPS) * numChannels + ch]); - sum[ch] += h2 * (inputs[(j + 1) * numChannels + ch] + inputs[(N - (j + 1) - TWO_STEPS) * - numChannels + ch]); - } - coeffs++; - } - for (ch = 0; ch < numChannels; ch++) { - *out++ = sum[ch]; - } - inputIndex += THREE_STEPS; - } - - state->inputIndex = inputIndex; - return outSample; -} - -static int32_t PolyphaseResamplerCoarse(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - uint32_t subfilterNum = state->subfilterNum; - const float* filterCoefficients = state->filterCoefficients; - const int32_t quoSamplerateRatio = state->quoSamplerateRatio; - const int32_t remSamplerateRatio = state->remSamplerateRatio; - const uint32_t decimateFactor = state->decimateFactor; - const uint32_t interpolateFactor = state->interpolateFactor; - const int32_t numChannels = state->numChannels; - int32_t i; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - - subfilterNum) - 1) / decimateFactor + 1); - } - - for (i = 0; i < outSample; i++) { - const float* coeffs = &filterCoefficients[subfilterNum * N]; - const float* inputs = &in[inputIndex * numChannels]; - - state->multiplyFunSeq[subfilterNum](state, coeffs, inputs, out, subfilterNum); - out += numChannels; - - inputIndex += quoSamplerateRatio; - subfilterNum += remSamplerateRatio; - if (subfilterNum >= interpolateFactor) { - subfilterNum -= interpolateFactor; - inputIndex++; - } - } - - state->inputIndex = inputIndex; - state->subfilterNum = subfilterNum; - return outSample; -} - -/* - * This resampler is used to produce zero output in situations where memory for the filter could not be allocated. - */ -static int32_t PolyphaseResamplerZero(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - int32_t outSample = 0; - int32_t inputIndex = state->inputIndex; - uint32_t subfilterNum = state->subfilterNum; - const int32_t quoSamplerateRatio = state->quoSamplerateRatio; - const int32_t remSamplerateRatio = state->remSamplerateRatio; - const uint32_t decimateFactor = state->decimateFactor; - const uint32_t interpolateFactor = state->interpolateFactor; - const int32_t numChannels = state->numChannels; - int32_t i, ch; - - (void)in; - - if (inputIndex < (int32_t)(*inputLength)) { - outSample = COMPARE_MIN((*outputLength), ((interpolateFactor * ((*inputLength) - inputIndex) - - subfilterNum) - 1) / decimateFactor + 1); - } - - for (i = 0; i < outSample; i++) { - for (ch = 0; ch < numChannels; ch++) { - *out++ = 0; - } - - inputIndex += quoSamplerateRatio; - subfilterNum += remSamplerateRatio; - if (subfilterNum >= interpolateFactor) { - subfilterNum -= interpolateFactor; - inputIndex++; - } - } - - state->inputIndex = inputIndex; - state->subfilterNum = subfilterNum; - return outSample; -} - -static MultiplyFilterFun GetMultiplyFilterFun(SingleStagePolyphaseResamplerState* state, int32_t i) -{ - int32_t channelMode = COMPARE_MIN(state->numChannels - 1, STEREO); - - if (state->interpolateFactor < state->decimateFactor) { // downsampling - if (i == 0) { - return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_DOWN + channelMode]; - } - if (TWO_STEPS * i == state->interpolateFactor) { - return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_DOWN + channelMode]; - } - return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_DOWN + channelMode]; - } else { // upsampling - if (i == 0) { - return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_ODD_UP + channelMode]; - } - if (TWO_STEPS * i == state->interpolateFactor) { - return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_SYMMETRIC_EVEN_UP + channelMode]; - } - return multiplyFilterFunTable[THREE_STEPS * MULTIPLY_FILTER_FUN_UP + channelMode]; - } -} - -static ResamplerMethod SetResamplerFunctionCoarse(SingleStagePolyphaseResamplerState* state) -{ - if (TWO_STEPS * state->interpolateFactor == state->decimateFactor) { - // Specific function for downsample by 2 - switch (state->numChannels) { - case MONO: - return PolyphaseDownsamplerHalfbandMono; - case STEREO: - return PolyphaseDownsamplerHalfbandStereo; - default: - return PolyphaseDownsamplerHalfbandMultichannel; - } - } - if (THREE_STEPS * state->interpolateFactor == state->decimateFactor) { - // Specific function for downsample by 3 - switch (state->numChannels) { - case MONO: - return PolyphaseDownsamplerThirdbandMono; - case STEREO: - return PolyphaseDownsamplerThirdbandStereo; - default: - return PolyphaseDownsamplerThirdbandMultichannel; - } - } - - for (int32_t j = 0; j < state->interpolateFactor; j++) { - state->multiplyFunSeq[j] = GetMultiplyFilterFun(state, j); - } - return PolyphaseResamplerCoarse; -} - -static int32_t UpdateResamplerState(SingleStagePolyphaseResamplerState* state) -{ - uint32_t oldFilterLength = state->filterLength; - - state->quoSamplerateRatio = state->decimateFactor / state->interpolateFactor; - state->remSamplerateRatio = state->decimateFactor % state->interpolateFactor; - state->filterLength = qualityTable[state->quality].filterLength; - state->coshParameter = qualityTable[state->quality].coshParameter; - - if (state->interpolateFactor < state->decimateFactor) { // downsampling - state->cutoff = (float)state->interpolateFactor / state->decimateFactor; - state->filterLength = state->filterLength * state->decimateFactor / state->interpolateFactor; - - // Round up to make sure filterLength be multiple of 8 - state->filterLength = 8 * ((state->filterLength - 1) / 8) + 8; - } else { // upsampling - state->cutoff = 1; - } - - // modified for new requirements (extended i/o sample rate combination) 2025.2.28 - if ((COMPARE_MAX(state->decimateFactor, state->interpolateFactor) <= MAX_RATIO_INTEGRAL_METHOD) & - ((state->decimateFactor == 1 || state->interpolateFactor == 1) || - ((float)state->decimateFactor / (float)state->interpolateFactor < 2.0f))) { - state->resamplerFunction = SetResamplerFunctionCoarse(state); - } else { // fine (non-integral) sampling rate ratio - switch (state->numChannels) { - case MONO: - state->resamplerFunction = PolyphaseResamplerMono; - break; - case STEREO: - state->resamplerFunction = PolyphaseResamplerStereo; - break; - default: - state->resamplerFunction = PolyphaseResamplerMultichannel; - } - } - - CalculateFilter(state); - - /* Here's the place where we update the filter memory to take into account - the change in filter length. It's probably the messiest part of the code - due to handling of lots of corner cases. */ - return UpdateFilterMemory(state, oldFilterLength); -} - -static int32_t UpdateFilterMemory(SingleStagePolyphaseResamplerState* state, uint32_t oldFilterLength) -{ - /* Adding bufferSize to filterLength won't overflow here because filterLength - could be multiplied by sizeof(float) above. */ - uint32_t requiredInputMemorySize = state->filterLength - 1 + state->bufferSize; - if (requiredInputMemorySize > state->inputMemorySize) { - if (state->inputMemory == NULL) { // first time initiaization - state->inputMemory = (float*)malloc(state->numChannels * requiredInputMemorySize * sizeof(float)); - if (state->inputMemory == NULL) { - return RESAMPLER_ERR_ALLOC_FAILED; - } - } else { - float* inputMemory = (float*)malloc(state->numChannels * requiredInputMemorySize * sizeof(float)); - int32_t ret = memcpy_s(inputMemory, requiredInputMemorySize * state->numChannels * sizeof(float), - state->inputMemory, state->inputMemorySize * state->numChannels * sizeof(float)); - if (INT_MAX / sizeof(float) / state->numChannels < requiredInputMemorySize || ret != 0) { - state->resamplerFunction = PolyphaseResamplerZero; - /* state->mem may still contain consumed input samples for the filter. - Restore filterLength so that filterLength - 1 still points to the position after - the last of these samples. */ - state->filterLength = oldFilterLength; - return RESAMPLER_ERR_ALLOC_FAILED; - } - free(state->inputMemory); - state->inputMemory = inputMemory; - } - state->inputMemorySize = requiredInputMemorySize; - } - /* codes for sudden sample rate change are deprecated and deleted so far */ - uint32_t i; - for (i = 0; i < state->numChannels * state->inputMemorySize; i++) { - state->inputMemory[i] = 0; - } - return RESAMPLER_ERR_SUCCESS; -} - -static int32_t SingleStagePolyphaseResamplerSetQuality(SingleStagePolyphaseResamplerState* state, int32_t quality) -{ - if (quality > QUALITY_LEVEL_TEN || quality < 0) { - return RESAMPLER_ERR_INVALID_ARG; - } - if (state->quality == quality) { - return RESAMPLER_ERR_SUCCESS; - } - state->quality = quality; - if (state->isInitialized) { - return UpdateResamplerState(state); - } - return RESAMPLER_ERR_SUCCESS; -} - -SingleStagePolyphaseResamplerState* SingleStagePolyphaseResamplerInit(uint32_t numChannels, - uint32_t decimateFactor, uint32_t interpolateFactor, int32_t quality, int32_t* err) -{ - SingleStagePolyphaseResamplerState* state; - int32_t filterErr; - - if (numChannels == 0 || decimateFactor == 0 || interpolateFactor == 0 || quality > QUALITY_LEVEL_TEN || - quality < 0) { - if (err) { - *err = RESAMPLER_ERR_INVALID_ARG; - } - return NULL; - } - state = (SingleStagePolyphaseResamplerState*)calloc(sizeof(SingleStagePolyphaseResamplerState), 1); - if (!state) { - if (err) { - *err = RESAMPLER_ERR_ALLOC_FAILED; - } - return NULL; - } - state->isInitialized = 0; - state->isStarted = 0; - state->decimateFactor = 0; - state->interpolateFactor = 0; - state->quality = -1; - state->filterCoefficientsSize = 0; - state->inputMemorySize = 0; - state->filterLength = 0; - state->filterCoefficients = NULL; - state->inputMemory = NULL; - state->resamplerFunction = 0; - - state->cutoff = 1.f; - state->numChannels = numChannels; - - state->bufferSize = BUFFER_SIZE; - - state->inputIndex = 0; - state->magicSamples = 0; - state->subfilterNum = 0; - - SingleStagePolyphaseResamplerSetQuality(state, quality); - filterErr = SingleStagePolyphaseResamplerSetRate(state, decimateFactor, interpolateFactor); - filterErr = UpdateResamplerState(state); - if (filterErr == RESAMPLER_ERR_SUCCESS) { - state->isInitialized = 1; - } else { - SingleStagePolyphaseResamplerFree(state); - state = NULL; - } - if (err) { - *err = filterErr; - } - return state; -} - -static void ApplyResampler(SingleStagePolyphaseResamplerState* state, uint32_t* inputLength, - float* out, uint32_t* outputLength) -{ - const int32_t N = state->filterLength; - int32_t outSample = 0; - float* inputMemory = state->inputMemory; - uint32_t inputSize; - const int32_t numChannels = state->numChannels; - int32_t j; - - state->isStarted = 1; - /* Call resampler function */ - outSample = state->resamplerFunction(state, inputMemory, inputLength, out, outputLength); - - if (state->inputIndex < (int32_t)*inputLength) { - *inputLength = state->inputIndex; - } - *outputLength = outSample; - state->inputIndex -= *inputLength; - - inputSize = (*inputLength) * numChannels; - for (j = 0; j < (N - 1) * numChannels; j++) { - inputMemory[j] = inputMemory[j + inputSize]; - } -} - - -static inline uint32_t ComputeGcd(uint32_t a, uint32_t b) -{ - while (b != 0) { - uint32_t temp = a; - - a = b; - b = temp % b; - } - return a; -} - - -int32_t SingleStagePolyphaseResamplerProcess(SingleStagePolyphaseResamplerState* state, const float* in, - uint32_t* inputLength, float* out, uint32_t* outputLength) -{ - int32_t j; - uint32_t remainingInputLength = *inputLength; - uint32_t remainingOutputLength = *outputLength; - const int32_t filtOffs = state->filterLength - 1; - const uint32_t bufferLen = state->inputMemorySize - filtOffs; - const int32_t numChannels = state->numChannels; - float* buf = state->inputMemory + filtOffs * numChannels; - - while (remainingInputLength && remainingOutputLength) { - uint32_t processInputLength = (remainingInputLength > bufferLen) ? bufferLen : remainingInputLength; - uint32_t processOutputLength = remainingOutputLength; - - if (in) { - for (j = 0; j < processInputLength * numChannels; j++) { - buf[j] = in[j]; - } - } else { - for (j = 0; j < processInputLength * numChannels; j++) { - buf[j] = 0; - } - } - ApplyResampler(state, &processInputLength, out, &processOutputLength); - remainingInputLength -= processInputLength; - remainingOutputLength -= processOutputLength; - out += processOutputLength * numChannels; - if (in) { - in += processInputLength * numChannels; - } - } - - *inputLength -= remainingInputLength; - *outputLength -= remainingOutputLength; - return state->resamplerFunction == PolyphaseResamplerZero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS; -} - -int32_t SingleStagePolyphaseResamplerSetRate(SingleStagePolyphaseResamplerState* state, uint32_t decimateFactor, - uint32_t interpolateFactor) -{ - uint32_t fact; - uint32_t oldInterpolateFactor; - - if (decimateFactor == 0 || interpolateFactor == 0) { - return RESAMPLER_ERR_INVALID_ARG; - } - - if (state->decimateFactor == decimateFactor && state->interpolateFactor == interpolateFactor) { - return RESAMPLER_ERR_SUCCESS; - } - - oldInterpolateFactor = state->interpolateFactor; - state->decimateFactor = decimateFactor; - state->interpolateFactor = interpolateFactor; - - fact = ComputeGcd(state->decimateFactor, state->interpolateFactor); - state->decimateFactor /= fact; - state->interpolateFactor /= fact; - - if (oldInterpolateFactor > 0) { - state->subfilterNum = state->subfilterNum * state->interpolateFactor / oldInterpolateFactor; - - /* Safety net */ - if (state->subfilterNum >= state->interpolateFactor) { - state->subfilterNum = state->interpolateFactor - 1; - } - } - - if (state->isInitialized) { - return UpdateResamplerState(state); - } - return RESAMPLER_ERR_SUCCESS; -} - -int32_t SingleStagePolyphaseResamplerSkipHalfTaps(SingleStagePolyphaseResamplerState* state) -{ - state->inputIndex = state->filterLength / TWO_STEPS; - return RESAMPLER_ERR_SUCCESS; -} - - -void SingleStagePolyphaseResamplerFree(SingleStagePolyphaseResamplerState* state) -{ - free(state->inputMemory); - state->inputMemory = NULL; - free(state->filterCoefficients); - state->filterCoefficients = NULL; - free(state); - state = NULL; -} - - -int32_t SingleStagePolyphaseResamplerResetMem(SingleStagePolyphaseResamplerState* state) -{ - uint32_t i; - state->inputIndex = 0; - state->magicSamples = 0; - state->subfilterNum = 0; - - for (i = 0; i < state->numChannels * state->inputMemorySize; i++) { - state->inputMemory[i] = 0; - } - return RESAMPLER_ERR_SUCCESS; -} \ No newline at end of file diff --git a/services/audio_engine/simd/SimdUtils.cpp b/services/audio_engine/simd/SimdUtils.cpp deleted file mode 100644 index 97abfc5944..0000000000 --- a/services/audio_engine/simd/SimdUtils.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2025 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 "SimdUtils.h" -#include -#include - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -#if USE_ARM_NEON == 1 -constexpr int ALIGIN_FLOAT_SIZE = 4; -#endif -void SimdPointByPointAdd(size_t length, const float* inputLeft, const float* inputRight, float* output) -{ -#if USE_ARM_NEON == 1 - if (length < ALIGIN_FLOAT_SIZE) { - for (size_t i = 0; i < length; i++) { - output[i] = inputLeft[i] + inputRight[i]; - } - } else { - size_t procLen = length >> 2; - float32x4_t left32x4, right32x4, out32x4; - for (size_t i = 0; i < procLen; i++) { - left32x4 = vld1q_f32(inputLeft + i * ALIGIN_FLOAT_SIZE); - right32x4 = vld1q_f32(inputRight + i * ALIGIN_FLOAT_SIZE); - out32x4 = vaddq_f32(left32x4, right32x4); - vst1q_f32(output + i * ALIGIN_FLOAT_SIZE, out32x4); - } - size_t odd = length - procLen * ALIGIN_FLOAT_SIZE; - if (odd) { - for (size_t j = length - odd; j < length; j++) { - output[j] = inputLeft[j] + inputRight[j]; - } - } - } -#else - for (size_t i = 0; i < length; i++) { - output[i] = inputLeft[i] + inputRight[i]; - } -#endif -} -void SimdPointByPointSub(size_t length, const float* inputLeft, const float* inputRight, float* output) -{ -#if USE_ARM_NEON == 1 - if (length < ALIGIN_FLOAT_SIZE) { - for (size_t i = 0; i < length; i++) { - output[i] = inputLeft[i] - inputRight[i]; - } - } else { - size_t procLen = length >> 2; - float32x4_t left32x4, right32x4, out32x4; - for (size_t i = 0; i < procLen; i++) { - left32x4 = vld1q_f32(inputLeft + i * ALIGIN_FLOAT_SIZE); - right32x4 = vld1q_f32(inputRight + i * ALIGIN_FLOAT_SIZE); - out32x4 = vsubq_f32(left32x4, right32x4); - vst1q_f32(output + i * ALIGIN_FLOAT_SIZE, out32x4); - } - size_t odd = length - procLen * ALIGIN_FLOAT_SIZE; - if (odd) { - for (size_t j = length - odd; j < length; j++) { - output[j] = inputLeft[j] - inputRight[j]; - } - } - } -#else - for (size_t i = 0; i < length; i++) { - output[i] = inputLeft[i] - inputRight[i]; - } -#endif -} - -void SimdPointByPointMul(size_t length, const float* inputLeft, const float* inputRight, float* output) -{ -#if USE_ARM_NEON == 1 - if (length < ALIGIN_FLOAT_SIZE) { - for (size_t i = 0; i < length; i++) { - output[i] = inputLeft[i] * inputRight[i]; - } - } else { - size_t procLen = length >> 2; - float32x4_t left32x4, right32x4, out32x4; - for (size_t i = 0; i < procLen; i++) { - left32x4 = vld1q_f32(inputLeft + i * ALIGIN_FLOAT_SIZE); - right32x4 = vld1q_f32(inputRight + i * ALIGIN_FLOAT_SIZE); - out32x4 = vmulq_f32(left32x4, right32x4); - vst1q_f32(output + i * ALIGIN_FLOAT_SIZE, out32x4); - } - size_t odd = length - procLen * ALIGIN_FLOAT_SIZE; - if (odd) { - for (size_t j = length - odd; j < length; j++) { - output[j] = inputLeft[j] * inputRight[j]; - } - } - } -#else - for (size_t i = 0; i < length; i++) { - output[i] = inputLeft[i] * inputRight[i]; - } -#endif -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/simd/SimdUtils.h b/services/audio_engine/simd/SimdUtils.h deleted file mode 100644 index beb7e889f1..0000000000 --- a/services/audio_engine/simd/SimdUtils.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2025 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 SIMD_UTILS_H -#define SIMD_UTILS_H - -#include -#include - -#if !defined(DISABLE_SIMD) && \ - (defined(__aarch64__) || (defined(__arm__) && defined(__ARM_NEON__))) -// enable arm Simd -#include -#define USE_ARM_NEON 1 -#else -// disable SIMD. -#define USE_ARM_NEON 0 -#endif -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -void SimdPointByPointAdd(size_t length, const float* inputLeft, const float* inputRight, float* output); -void SimdPointByPointSub(size_t length, const float* inputLeft, const float* inputRight, float* output); -void SimdPointByPointMul(size_t length, const float* inputLeft, const float* inputRight, float* output); -}}} - -#endif \ No newline at end of file diff --git a/services/audio_engine/test/unittest/BUILD.gn b/services/audio_engine/test/unittest/BUILD.gn deleted file mode 100644 index 03f927f0c4..0000000000 --- a/services/audio_engine/test/unittest/BUILD.gn +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright (c) 2022 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("//build/test.gni") -import("../../../../config.gni") - -module_output_path = "multimedia_audio_framework/audio_engine" - -config("audio_engine_private_config") { - visibility = [ ":*" ] - - include_dirs = [ - "./common", - "./unittest/include", - "../../simd", - "../../dfx", - "../../buffer", - "../../node/include", - "../../common", - "../../utils", - "../../plugin/resample/include", - "../../plugin/channel_converter/include", - "../../plugin/bitdepth_converter", - "../../manager/include", - "../../../../interfaces/inner_api/native/audiocommon/include", - "../../../audio_service/server/include", - "../../../audio_service/common/include", - "../../../audio_policy/server/include/service/common", - "../../../../frameworks/native/audioeffect/include", - "../../../../frameworks/native/hdiadapter_new/include", - ] -} - -ohos_unittest("audio_engine_unit_test") { - module_out_path = module_output_path - sources = [ - "common/test_case_common.cpp", - "dfx/hpae_dfx_tree_test.cpp", - "node/hpae_pcm_process_test.cpp", - "node/hpae_pcm_buffer_test.cpp", - "node/hpae_sink_input_node_test.cpp", - "node/hpae_sink_output_node_test.cpp", - "node/hpae_mixer_node_test.cpp", - "node/hpae_source_input_cluster_test.cpp", - "node/hpae_source_input_node_test.cpp", - "node/hpae_source_output_node_test.cpp", - "node/hpae_resample_node_test.cpp", - "node/hpae_process_cluster_test.cpp", - "node/hpae_output_cluster_test.cpp", - "node/hpae_gain_node_test.cpp", - "manager/hpae_manager_test.cpp", - "manager/hpae_render_manager_test.cpp", - "manager/hpae_capturer_manager_test.cpp", - "manager/hpae_audio_service_callback_unit_test.cpp", - "manager/hpae_inner_capturer_unit_test.cpp", - ] - - configs = [ ":audio_engine_private_config" ] - - deps = [ - "../../:audio_engine_node", - "../../:audio_engine_buffer", - "../../:audio_engine_manager", - "../../:audio_engine_utils", - ] - - external_deps = [ - "c_utils:utils", - "googletest:gtest", - "hilog:libhilog", - "hisysevent:libhisysevent", - "ipc:ipc_single", - "safwk:system_ability_fwk", - "samgr:samgr_proxy", - ] - - resource_config_file = "./resource/ohos_test.xml" -} - diff --git a/services/audio_engine/test/unittest/common/hpae_audio_service_callback_unit_test.h b/services/audio_engine/test/unittest/common/hpae_audio_service_callback_unit_test.h deleted file mode 100644 index 4935a1e879..0000000000 --- a/services/audio_engine/test/unittest/common/hpae_audio_service_callback_unit_test.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_AUDIO_AUDIO_SERVICE_CALLBACK_UNIT_TEST_H -#define HPAE_AUDIO_AUDIO_SERVICE_CALLBACK_UNIT_TEST_H -#include "audio_service_hpae_callback.h" - -namespace OHOS { -namespace AudioStandard { -class HpaeAudioServiceCallbackUnitTest : public AudioServiceHpaeCallback { -public: - ~HpaeAudioServiceCallbackUnitTest() override; - - void OnOpenAudioPortCb(int32_t portId) override; - - void OnCloseAudioPortCb(int32_t result) override; - - void OnSetSinkMuteCb(int32_t result) override; - - void OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) override; - - void OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) override; - - void OnGetAllSinksCb(int32_t result, std::vector &sinks) override; - - void OnMoveSinkInputByIndexOrNameCb(int32_t result) override; - - void OnMoveSourceOutputByIndexOrNameCb(int32_t result) override; - - void OnSetSourceOutputMuteCb(int32_t result) override; - - void OnGetAudioEffectPropertyCbV3(int32_t result) override; - - void OnGetAudioEffectPropertyCb(int32_t result) override; - - void OnGetAudioEnhancePropertyCbV3(int32_t result) override; - - void OnGetAudioEnhancePropertyCb(int32_t result) override; - - void HandleSourceAudioStreamRemoved(uint32_t sessionId) override; - - int32_t GetPortId() const noexcept; - - int32_t GetCloseAudioPortResult() const noexcept; - - int32_t GetSetSinkMuteResult() const noexcept; - - int32_t GetGetAllSinkInputsResult() const noexcept; - - int32_t GetGetAllSourceOutputsResult() const noexcept; - - int32_t GetGetAllSinksResult() const noexcept; - - int32_t GetMoveSinkInputByIndexOrNameResult() const noexcept; - - int32_t GetMoveSourceOutputByIndexOrNameResult() const noexcept; - - int32_t GetSetSourceOutputMuteResult() const noexcept; - - int32_t GetGetAudioEffectPropertyResult() const noexcept; - - int32_t GetGetAudioEnhancePropertyResult() const noexcept; - - std::vector GetSinkInputs() const noexcept; - - std::vector GetSourceOutputs() const noexcept; - - std::vector GetSinks() const noexcept; - -private: - int32_t portId_ = -1; - int32_t closeAudioPortResult_ = -1; - int32_t setSinkMuteResult_ = -1; - int32_t getAllSinkInputsResult_ = -1; - int32_t getAllSourceOutputsResult_ = -1; - int32_t getAllSinksResult_ = -1; - int32_t moveSinkInputByIndexOrNameResult_ = -1; - int32_t moveSourceOutputByIndexOrNameResult_ = -1; - int32_t setSourceOutputMuteResult_ = -1; - int32_t getAudioEffectPropertyResult_ = -1; - int32_t getAudioEnhancePropertyResult_ = -1; - std::vector sinkInputs_; - std::vector sourceOutputs_; - std::vector sinks_; -}; -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/test/unittest/common/hpae_manager_unit_test.h b/services/audio_engine/test/unittest/common/hpae_manager_unit_test.h deleted file mode 100644 index d4d23c4fee..0000000000 --- a/services/audio_engine/test/unittest/common/hpae_manager_unit_test.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_MANAGER_UNIT_TEST_H -#define HPAE_MANAGER_UNIT_TEST_H -#include "gtest/gtest.h" -#include "hpae_manager.h" -#include "hpae_info.h" -#include "hpae_audio_service_callback_unit_test.h" - -namespace OHOS { -namespace AudioStandard { -class HpaeManagerUnitTest : public testing::Test { -public: - void SetUp(); - void TearDown(); - -protected: - std::shared_ptr hpaeManager_; - -protected: - void WaitForMsgProcessing(); - AudioModuleInfo GetSinkAudioModeInfo(); - AudioModuleInfo GetSourceAudioModeInfo(); - HPAE::HpaeStreamInfo GetRenderStreamInfo(); - HPAE::HpaeStreamInfo GetCaptureStreamInfo(); -}; -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/test/unittest/common/test_case_common.cpp b/services/audio_engine/test/unittest/common/test_case_common.cpp deleted file mode 100644 index aa0ab3fbca..0000000000 --- a/services/audio_engine/test/unittest/common/test_case_common.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2025 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 "TestCaseCommon" -#endif - -#include "test_case_common.h" -#include "hpae_info.h" -#include "audio_engine_log.h" - -namespace OHOS { -namespace AudioStandard { - -int32_t WriteFixedDataCb::OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) -{ - size_t sampleSize = GET_SIZE_FROM_FORMAT(format_); - for (size_t i = 0; i < callBackStremInfo.requestDataLen / sampleSize; i++) { - switch (format_) { - case AudioSampleFormat::SAMPLE_U8: { - *(callBackStremInfo.inputData + i) = writeNum_; - break; - } - case SAMPLE_S16LE: { - *((int16_t*)callBackStremInfo.inputData + i) = writeNum_; - break; - } - case SAMPLE_S24LE: { - uint8_t *p = (uint8_t *)(callBackStremInfo.inputData + OFFSET_BIT_24 * i); - p[BIT_DEPTH_TWO] = (uint8_t) (writeNum_ >> BIT_16); - p[1] = (uint8_t) (writeNum_ >> BIT_8); - p[0] = (uint8_t) writeNum_; - break; - } - case SAMPLE_S32LE: { - *((int32_t*)callBackStremInfo.inputData + i) = writeNum_; - break; - } - case SAMPLE_F32LE: { - *((float*)callBackStremInfo.inputData + i) = writeNum_; - break; - } - default: - break; - } - } - writeNum_++; - return 0; -} - -int32_t WriteFixedValueCb::OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) -{ - size_t sampleSize = GET_SIZE_FROM_FORMAT(format_); - for (size_t i = 0; i < callBackStremInfo.requestDataLen / sampleSize; i++) { - switch (format_) { - case AudioSampleFormat::SAMPLE_U8: { - *(callBackStremInfo.inputData + i) = fixValue_; - break; - } - case SAMPLE_S16LE: { - *((int16_t*)callBackStremInfo.inputData + i) = fixValue_; - break; - } - case SAMPLE_S24LE: { - uint8_t *p = (uint8_t *)(callBackStremInfo.inputData + OFFSET_BIT_24 * i); - p[BIT_DEPTH_TWO] = (uint8_t) (fixValue_ >> BIT_16); - p[1] = (uint8_t) (fixValue_ >> BIT_8); - p[0] = (uint8_t) fixValue_; - break; - } - case SAMPLE_S32LE: { - *((int32_t*)callBackStremInfo.inputData + i) = fixValue_; - break; - } - case SAMPLE_F32LE: { - *((float*)callBackStremInfo.inputData + i) = fixValue_; - break; - } - default: - break; - } - } - return 0; -} - -int32_t WriteIncDataCb::OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) -{ - for (size_t i = 0; i < callBackStremInfo.requestDataLen / GET_SIZE_FROM_FORMAT(format_); i++) { - switch (format_) { - case AudioSampleFormat::SAMPLE_U8: { - *(callBackStremInfo.inputData + i) = i; - break; - } - case SAMPLE_S16LE: { - *((int16_t*)callBackStremInfo.inputData + i) = i; - break; - } - case SAMPLE_S24LE: { - uint8_t *p = (uint8_t *)(callBackStremInfo.inputData + OFFSET_BIT_24 * i); - p[BIT_DEPTH_TWO] = (uint8_t) (i >> BIT_16); - p[1] = (uint8_t) (i >> BIT_8); - p[0] = (uint8_t) i; - break; - } - case SAMPLE_S32LE: { - *((int32_t*)callBackStremInfo.inputData + i) = i; - break; - } - case SAMPLE_F32LE: { - *((float*)callBackStremInfo.inputData + i) = i; - break; - } - default: - break; - } - } - writeNum_++; - return 0; -} - -void StatusChangeCb::OnStatusUpdate(IOperation operation) -{ - switch (operation) { - case OPERATION_STARTED: - status_ = I_STATUS_STARTED; - break; - case OPERATION_PAUSED: - status_ = I_STATUS_PAUSED; - break; - case OPERATION_STOPPED: - status_ = I_STATUS_STOPPED; - break; - default: - status_ = I_STATUS_INVALID; - } -} - -IStatus StatusChangeCb::GetStatus() -{ - return status_; -} - -ReadDataCb::ReadDataCb(const std::string &fileName) -{ - testFile_ = fopen(fileName.c_str(), "ab"); - if (testFile_ == nullptr) { - AUDIO_ERR_LOG("Open file failed"); - } -} - -ReadDataCb::~ReadDataCb() -{ - if (testFile_) { - fclose(testFile_); - testFile_ = nullptr; - } -} - -int32_t ReadDataCb::OnReadData(size_t length) -{ - AUDIO_WARNING_LOG("ProAudio do not support!"); - return SUCCESS; -} - -int32_t ReadDataCb::OnReadData(std::vector& outputData, size_t requestDataLen) -{ - CHECK_AND_RETURN_RET_LOG(testFile_ != nullptr, ERROR, "testFile_ is nullptr"); - fwrite(outputData.data(), 1, requestDataLen, testFile_); - return SUCCESS; -} -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/common/test_case_common.h b/services/audio_engine/test/unittest/common/test_case_common.h deleted file mode 100644 index 237846f9ec..0000000000 --- a/services/audio_engine/test/unittest/common/test_case_common.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2025 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 TEST_CASE_COMMON_H -#define TEST_CASE_COMMON_H -#include -#include "i_renderer_stream.h" -#include "i_capturer_stream.h" -#include "audio_errors.h" -#include "hpae_info.h" - -namespace OHOS { -namespace AudioStandard { -constexpr int OFFSET_BIT_24 = 3; -constexpr int BIT_DEPTH_TWO = 2; -constexpr int BIT_16 = 16; -constexpr int BIT_8 = 8; -constexpr float TEST_VALUE_PRESION = 0.001; -constexpr int TEST_FREAME_LEN = 125; -constexpr int TEST_SUB_FREAME_LEN = 50; - -#define DEFAULT_TEST_SINK_NAME "hdi_output" -#define DEFAULT_TEST_AUDIO_DEVICE_NAME "Speaker" -#define DEFAULT_TEST_DEVICE_CLASS "file_io" -#define DEFAULT_TEST_DEVICE_NETWORKID "LocalDevice" - -class WriteFixedDataCb : public IStreamCallback, public std::enable_shared_from_this { -public: - int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) override; - - explicit WriteFixedDataCb(AudioSampleFormat format) : format_(format) - {} - virtual ~WriteFixedDataCb() - {} - -private: - int32_t writeNum_ = 0; - AudioSampleFormat format_ = SAMPLE_F32LE; -}; - -class WriteFixedValueCb : public IStreamCallback, public std::enable_shared_from_this { -public: - int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) override; - WriteFixedValueCb(AudioSampleFormat format, int32_t fixedValue) : format_(format), fixValue_(fixedValue) - {} - virtual ~WriteFixedValueCb() - {} - -private: - AudioSampleFormat format_ = SAMPLE_F32LE; - int32_t fixValue_ = 0; -}; - -class WriteIncDataCb : public IStreamCallback, public std::enable_shared_from_this { -public: - int32_t OnStreamData(AudioCallBackStreamInfo& callBackStremInfo) override; - explicit WriteIncDataCb(AudioSampleFormat format) : format_(format) - {} - virtual ~WriteIncDataCb() - {} - -private: - int32_t writeNum_ = 0; - AudioSampleFormat format_ = SAMPLE_F32LE; -}; - -class StatusChangeCb : public IStatusCallback, public std::enable_shared_from_this { -public: - void OnStatusUpdate(IOperation operation) override; - IStatus GetStatus(); - virtual ~StatusChangeCb() = default; -private: - IStatus status_; -}; - -class ReadDataCb : public IReadCallback, public std::enable_shared_from_this { -public: - explicit ReadDataCb(const std::string &fileName); - virtual ~ReadDataCb(); - int32_t OnReadData(size_t length) override; - int32_t OnReadData(std::vector& outputData, size_t requestDataLen) override; -private: - FILE *testFile_ = nullptr; -}; -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/test/unittest/dfx/hpae_dfx_tree_test.cpp b/services/audio_engine/test/unittest/dfx/hpae_dfx_tree_test.cpp deleted file mode 100644 index b9d4479fa2..0000000000 --- a/services/audio_engine/test/unittest/dfx/hpae_dfx_tree_test.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include -#include -#include -#include -#include -#include "hpae_dfx_tree.h" -#include - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -class HpaeDfxTreeTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeDfxTreeTest::SetUp() -{ - std::locale::global(std::locale("")); - std::wcout.imbue(std::locale()); -} - -void HpaeDfxTreeTest::TearDown() -{} - -TEST_F(HpaeDfxTreeTest, constructHpaeDfxTreeTest) -{ - HpaeDfxTree hpaeDfxTree; - HpaeNodeInfo info; - uint32_t nodeId = 123; - uint32_t sessionId = 12345; - size_t frameLen = 960; - uint32_t preNodeId = 0; - int32_t testNum = 10; - for (int32_t i = 0; i < testNum; i++) { - preNodeId = info.nodeId; - info.nodeId = nodeId + i; - info.sessionId = sessionId + i; - info.nodeName = "testNode1"; - info.frameLen = frameLen; - info.channels = STEREO; - info.samplingRate = SAMPLE_RATE_48000; - info.format = SAMPLE_F32LE; - info.sceneType = HPAE_SCENE_DEFAULT; - EXPECT_EQ(hpaeDfxTree.Insert(preNodeId, info), true); - } - std::vector> result = hpaeDfxTree.LevelOrderTraversal(); - std::string outStr; - hpaeDfxTree.PrintTree(outStr); - std::cout << outStr.c_str() << std::endl; - int32_t index = 0; - for (int32_t i = 0; i < result.size(); i++) { - for (int32_t j = 0; j < result[i].size(); j++) { - EXPECT_EQ(result[i][j].nodeId, index + nodeId); - EXPECT_EQ(result[i][j].sessionId, index + sessionId); - EXPECT_EQ(result[i][j].frameLen, frameLen); - EXPECT_EQ(result[i][j].samplingRate, SAMPLE_RATE_48000); - EXPECT_EQ(result[i][j].channels, STEREO); - EXPECT_EQ(result[i][j].format, SAMPLE_F32LE); - index++; - } - } -} - -TEST_F(HpaeDfxTreeTest, RemoveDfxTreeTest) -{ - HpaeDfxTree hpaeDfxTree; - HpaeNodeInfo info; - uint32_t nodeId = 123; - uint32_t sessionId = 12345; - size_t frameLen = 960; - uint32_t preNodeId = 0; - int32_t testNum = 10; - for (int32_t i = 0; i < testNum; i++) { - preNodeId = info.nodeId; - info.nodeId = nodeId + i; - info.sessionId = sessionId + i; - info.nodeName = "testNode2"; - info.frameLen = frameLen; - info.channels = MONO; - info.samplingRate = SAMPLE_RATE_16000; - info.format = SAMPLE_F32LE; - info.sceneType = HPAE_SCENE_MUSIC; - EXPECT_EQ(hpaeDfxTree.Insert(preNodeId, info), true); - } - std::vector> result = hpaeDfxTree.LevelOrderTraversal(); - EXPECT_EQ(result.size(), testNum); - uint32_t removeNodeIndex = 3; - EXPECT_EQ(hpaeDfxTree.Remove(nodeId + removeNodeIndex), true); - std::string outStr; - hpaeDfxTree.PrintTree(outStr); - std::cout << outStr.c_str() << std::endl; - result = hpaeDfxTree.LevelOrderTraversal(); - EXPECT_EQ(result.size(), removeNodeIndex); -} diff --git a/services/audio_engine/test/unittest/manager/hpae_audio_service_callback_unit_test.cpp b/services/audio_engine/test/unittest/manager/hpae_audio_service_callback_unit_test.cpp deleted file mode 100644 index 545fa94f7f..0000000000 --- a/services/audio_engine/test/unittest/manager/hpae_audio_service_callback_unit_test.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2025 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 "hpae_audio_service_callback_unit_test.h" -namespace OHOS { -namespace AudioStandard { -HpaeAudioServiceCallbackUnitTest::~HpaeAudioServiceCallbackUnitTest() -{} - -void HpaeAudioServiceCallbackUnitTest::OnOpenAudioPortCb(int32_t portId) -{ - portId_ = portId; -} - -void HpaeAudioServiceCallbackUnitTest::OnCloseAudioPortCb(int32_t result) -{ - closeAudioPortResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::OnSetSinkMuteCb(int32_t result) -{ - setSinkMuteResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) -{ - getAllSinkInputsResult_ = result; - sinkInputs_ = sinkInputs; -} - -void HpaeAudioServiceCallbackUnitTest::OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) -{ - getAllSourceOutputsResult_ = result; - sourceOutputs_ = sourceOutputs; -} - -void HpaeAudioServiceCallbackUnitTest::OnGetAllSinksCb(int32_t result, std::vector &sinks) -{ - getAllSinksResult_ = result; - sinks_ = sinks; -} - -void HpaeAudioServiceCallbackUnitTest::OnMoveSinkInputByIndexOrNameCb(int32_t result) -{ - moveSinkInputByIndexOrNameResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::OnMoveSourceOutputByIndexOrNameCb(int32_t result) -{ - moveSourceOutputByIndexOrNameResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::OnSetSourceOutputMuteCb(int32_t result) -{ - setSourceOutputMuteResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::OnGetAudioEffectPropertyCbV3(int32_t result) -{ - getAudioEffectPropertyResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::OnGetAudioEffectPropertyCb(int32_t result) -{ - getAudioEffectPropertyResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::OnGetAudioEnhancePropertyCbV3(int32_t result) -{ - getAudioEnhancePropertyResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::OnGetAudioEnhancePropertyCb(int32_t result) -{ - getAudioEnhancePropertyResult_ = result; -} - -void HpaeAudioServiceCallbackUnitTest::HandleSourceAudioStreamRemoved(uint32_t sessionId) -{} - -int32_t HpaeAudioServiceCallbackUnitTest::GetPortId() const noexcept -{ - return portId_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetCloseAudioPortResult() const noexcept -{ - return closeAudioPortResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetSetSinkMuteResult() const noexcept -{ - return setSinkMuteResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetGetAllSinkInputsResult() const noexcept -{ - return getAllSinkInputsResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetGetAllSourceOutputsResult() const noexcept -{ - return getAllSourceOutputsResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetGetAllSinksResult() const noexcept -{ - return getAllSinksResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetMoveSinkInputByIndexOrNameResult() const noexcept -{ - return moveSinkInputByIndexOrNameResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetMoveSourceOutputByIndexOrNameResult() const noexcept -{ - return moveSourceOutputByIndexOrNameResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetSetSourceOutputMuteResult() const noexcept -{ - return setSourceOutputMuteResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetGetAudioEffectPropertyResult() const noexcept -{ - return getAudioEffectPropertyResult_; -} - -int32_t HpaeAudioServiceCallbackUnitTest::GetGetAudioEnhancePropertyResult() const noexcept -{ - return getAudioEnhancePropertyResult_; -} - -std::vector HpaeAudioServiceCallbackUnitTest::GetSinkInputs() const noexcept -{ - return sinkInputs_; -} - -std::vector HpaeAudioServiceCallbackUnitTest::GetSourceOutputs() const noexcept -{ - return sourceOutputs_; -} - -std::vector HpaeAudioServiceCallbackUnitTest::GetSinks() const noexcept -{ - return sinks_; -} - -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/manager/hpae_capturer_manager_test.cpp b/services/audio_engine/test/unittest/manager/hpae_capturer_manager_test.cpp deleted file mode 100644 index 5fd90472b5..0000000000 --- a/services/audio_engine/test/unittest/manager/hpae_capturer_manager_test.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include -#include "test_case_common.h" -#include "audio_errors.h" -#include "hpae_capturer_manager.h" - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -std::string g_rootCapturerPath = "/data/data/.pulse_dir/"; -const uint32_t DEFAULT_FRAME_LENGTH = 960; -const uint32_t DEFAULT_SESSION_ID = 123456; - -class HpaeCapturerManagerTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeCapturerManagerTest::SetUp() -{} - -void HpaeCapturerManagerTest::TearDown() -{} - -static void TestCheckSourceOutputInfo(HpaeSourceOutputInfo& sourceOutputInfo, const HpaeStreamInfo& streamInfo) -{ - EXPECT_EQ(sourceOutputInfo.nodeInfo.channels == streamInfo.channels, true); - EXPECT_EQ(sourceOutputInfo.nodeInfo.format == streamInfo.format, true); - EXPECT_EQ(sourceOutputInfo.nodeInfo.frameLen == streamInfo.frameLen, true); - EXPECT_EQ(sourceOutputInfo.nodeInfo.sessionId == streamInfo.sessionId, true); - EXPECT_EQ(sourceOutputInfo.nodeInfo.samplingRate == streamInfo.samplingRate, true); - EXPECT_EQ(sourceOutputInfo.nodeInfo.streamType == streamInfo.streamType, true); -} - -static void WaitForMsgProcessing(std::shared_ptr &capturerManager) -{ - int waitCount = 0; - const int WAIT_COUNT_THD = 5; - while (capturerManager->IsMsgProcessing()) { - std::this_thread::sleep_for(std::chrono::milliseconds(20)); // 20 for sleep - waitCount++; - if (waitCount >= WAIT_COUNT_THD) { - break; - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(40)); // 40 for sleep - EXPECT_EQ(capturerManager->IsMsgProcessing(), false); - EXPECT_EQ(waitCount < WAIT_COUNT_THD, true); -} - -TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerConstructTest) -{ - HpaeSourceInfo sourceInfo; - sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sourceInfo.sourceType = SOURCE_TYPE_MIC; - sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; - - sourceInfo.samplingRate = SAMPLE_RATE_48000; - sourceInfo.channels = STEREO; - sourceInfo.format = SAMPLE_S16LE; - sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; - sourceInfo.ecType = HPAE_EC_TYPE_NONE; - sourceInfo.micRef = HPAE_REF_OFF; - - std::shared_ptr capturerManager = std::make_shared(sourceInfo); - HpaeSourceInfo dstSourceInfo = capturerManager->GetSourceInfo(); - EXPECT_EQ(dstSourceInfo.deviceNetId == sourceInfo.deviceNetId, true); - EXPECT_EQ(dstSourceInfo.deviceClass == sourceInfo.deviceClass, true); - EXPECT_EQ(dstSourceInfo.frameLen == sourceInfo.frameLen, true); - EXPECT_EQ(dstSourceInfo.samplingRate == sourceInfo.samplingRate, true); - EXPECT_EQ(dstSourceInfo.format == sourceInfo.format, true); - EXPECT_EQ(dstSourceInfo.channels == sourceInfo.channels, true); - EXPECT_EQ(dstSourceInfo.ecType == sourceInfo.ecType, true); - EXPECT_EQ(dstSourceInfo.micRef == sourceInfo.micRef, true); -} - -TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerInitTest) -{ - HpaeSourceInfo sourceInfo; - sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sourceInfo.sourceType = SOURCE_TYPE_MIC; - sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; - - sourceInfo.samplingRate = SAMPLE_RATE_48000; - sourceInfo.channels = STEREO; - sourceInfo.format = SAMPLE_S16LE; - sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; - sourceInfo.ecType = HPAE_EC_TYPE_NONE; - sourceInfo.micRef = HPAE_REF_OFF; - - std::shared_ptr capturerManager = std::make_shared(sourceInfo); - EXPECT_EQ(capturerManager->Init() == SUCCESS, true); -} - -TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerCreateDestoryStreamTest) -{ - HpaeSourceInfo sourceInfo; - sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sourceInfo.sourceType = SOURCE_TYPE_MIC; - sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; - - sourceInfo.samplingRate = SAMPLE_RATE_48000; - sourceInfo.channels = STEREO; - sourceInfo.format = SAMPLE_S16LE; - sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; - sourceInfo.ecType = HPAE_EC_TYPE_NONE; - sourceInfo.micRef = HPAE_REF_OFF; - - std::shared_ptr capturerManager = std::make_shared(sourceInfo); - EXPECT_EQ(capturerManager->Init() == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager->IsInit(), true); - HpaeStreamInfo streamInfo; - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_48000; - streamInfo.format = SAMPLE_S16LE; - streamInfo.frameLen = DEFAULT_FRAME_LENGTH; - streamInfo.sessionId = DEFAULT_SESSION_ID; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; - streamInfo.deviceName = "Built_in_mic"; - EXPECT_EQ(capturerManager->CreateStream(streamInfo) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager.use_count() == 1, true); - HpaeSourceOutputInfo sourceOutputInfo; - EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); - TestCheckSourceOutputInfo(sourceOutputInfo, streamInfo); - EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_NEW); - EXPECT_EQ(capturerManager->DestroyStream(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ( - capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == ERR_INVALID_OPERATION, true); -} - -static void StateControlTest(std::shared_ptr &capturerManager, HpaeStreamInfo &streamInfo, - HpaeSourceOutputInfo &sourceOutputInfo) -{ - EXPECT_EQ(capturerManager->Start(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); - EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_RUNNING); - EXPECT_EQ(capturerManager->IsRunning(), true); - - EXPECT_EQ(capturerManager->Pause(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); - EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_PAUSED); - EXPECT_EQ(capturerManager->IsRunning(), false); - - EXPECT_EQ(capturerManager->Start(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); - EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_RUNNING); - EXPECT_EQ(capturerManager->IsRunning(), true); - - EXPECT_EQ(capturerManager->Stop(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); - EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_STOPPED); - EXPECT_EQ(capturerManager->IsRunning(), false); - - EXPECT_EQ(capturerManager->DestroyStream(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ( - capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == ERR_INVALID_OPERATION, true); - EXPECT_EQ(capturerManager->IsRunning(), false); -} - -TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerStartStopTest) -{ - HpaeSourceInfo sourceInfo; - sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sourceInfo.sourceType = SOURCE_TYPE_MIC; - sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; - - sourceInfo.samplingRate = SAMPLE_RATE_48000; - sourceInfo.channels = STEREO; - sourceInfo.format = SAMPLE_S16LE; - sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; - sourceInfo.ecType = HPAE_EC_TYPE_NONE; - sourceInfo.micRef = HPAE_REF_OFF; - - std::shared_ptr capturerManager = std::make_shared(sourceInfo); - EXPECT_EQ(capturerManager->Init() == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager->IsInit(), true); - - HpaeStreamInfo streamInfo; - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_48000; - streamInfo.format = SAMPLE_S16LE; - streamInfo.frameLen = DEFAULT_FRAME_LENGTH; - streamInfo.sessionId = DEFAULT_SESSION_ID; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; - streamInfo.deviceName = "Built_in_mic"; - EXPECT_EQ(capturerManager->CreateStream(streamInfo) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager.use_count() == 1, true); - - HpaeSourceOutputInfo sourceOutputInfo; - EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); - TestCheckSourceOutputInfo(sourceOutputInfo, streamInfo); - EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_NEW); - EXPECT_EQ(capturerManager->IsRunning(), false); - - std::shared_ptr readDataCb = - std::make_shared(g_rootCapturerPath + "HpaeCapturerManagerTest.pcm"); - EXPECT_EQ(capturerManager->RegisterReadCallback(streamInfo.sessionId, readDataCb), SUCCESS); - EXPECT_EQ(readDataCb.use_count() == 1, true); - - StateControlTest(capturerManager, streamInfo, sourceOutputInfo); -} - -static void InitReloadSourceInfo(HpaeSourceInfo &sourceInfo, HpaeSourceInfo &newSourceInfo) -{ - sourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sourceInfo.sourceType = SOURCE_TYPE_MIC; - sourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; - - sourceInfo.samplingRate = SAMPLE_RATE_48000; - sourceInfo.channels = STEREO; - sourceInfo.format = SAMPLE_S16LE; - sourceInfo.frameLen = DEFAULT_FRAME_LENGTH; - sourceInfo.ecType = HPAE_EC_TYPE_NONE; - sourceInfo.micRef = HPAE_REF_OFF; - - newSourceInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - newSourceInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - newSourceInfo.sourceType = SOURCE_TYPE_VOICE_TRANSCRIPTION; - newSourceInfo.filePath = g_rootCapturerPath + "constructHpaeRendererManagerTest.pcm"; - - newSourceInfo.samplingRate = SAMPLE_RATE_48000; - newSourceInfo.channels = STEREO; - newSourceInfo.format = SAMPLE_S16LE; - newSourceInfo.frameLen = DEFAULT_FRAME_LENGTH; - newSourceInfo.ecType = HPAE_EC_TYPE_SAME_ADAPTER; - newSourceInfo.micRef = HPAE_REF_OFF; -} - -static void InitReloadStreamInfo(HpaeStreamInfo &streamInfo) -{ - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_48000; - streamInfo.format = SAMPLE_S16LE; - streamInfo.frameLen = DEFAULT_FRAME_LENGTH; - streamInfo.sessionId = DEFAULT_SESSION_ID; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; - streamInfo.deviceName = "Built_in_mic"; -} - -TEST_F(HpaeCapturerManagerTest, HpaeCapturerManagerReloadTest) -{ - HpaeSourceInfo sourceInfo; - HpaeSourceInfo newSourceInfo; - InitReloadSourceInfo(sourceInfo, newSourceInfo); - - std::shared_ptr capturerManager = std::make_shared(sourceInfo); - EXPECT_EQ(capturerManager->Init() == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager->IsInit(), true); - HpaeStreamInfo streamInfo; - InitReloadStreamInfo(streamInfo); - EXPECT_EQ(capturerManager->CreateStream(streamInfo) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager.use_count() == 1, true); - HpaeSourceOutputInfo sourceOutputInfo; - EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); - TestCheckSourceOutputInfo(sourceOutputInfo, streamInfo); - EXPECT_EQ(sourceOutputInfo.capturerSessionInfo.state, CAPTURER_NEW); - EXPECT_EQ(capturerManager->ReloadCaptureManager(newSourceInfo) == SUCCESS, true); - WaitForMsgProcessing(capturerManager); - EXPECT_EQ(capturerManager->GetSourceOutputInfo(streamInfo.sessionId, sourceOutputInfo) == SUCCESS, true); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/manager/hpae_inner_capturer_unit_test.cpp b/services/audio_engine/test/unittest/manager/hpae_inner_capturer_unit_test.cpp deleted file mode 100644 index db2e5f8032..0000000000 --- a/services/audio_engine/test/unittest/manager/hpae_inner_capturer_unit_test.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include "test_case_common.h" -#include "hpae_inner_capturer_manager.h" -#include -#include "audio_errors.h" -#include -#include - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -namespace OHOS { -namespace AudioStandard { -namespace HPAE{ -const uint32_t DEFAULT_SESSION_ID = 123456; -const float FRAME_LENGTH_IN_SECOND = 0.02; -std::string rootPath = "/data/data/.pulse_dir/"; - - -static HpaeSinkInfo GetInCapSinkInfo() -{ - HpaeSinkInfo sinkInfo; - sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.filePath = rootPath + "constructHpaeInnerCapturerManagerTest.pcm"; - sinkInfo.samplingRate = SAMPLE_RATE_48000; - sinkInfo.frameLen = SAMPLE_RATE_48000 * FRAME_LENGTH_IN_SECOND; - sinkInfo.format = SAMPLE_F32LE; - sinkInfo.channels = STEREO; - sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; - return sinkInfo; -} - -class HpaeInnerCapturerManagerUnitTest : public testing::Test { -public: - void SetUp(); - void TearDown(); - std::shared_ptr hpaeInnerCapturerManager_ = nullptr; -}; - -void HpaeInnerCapturerManagerUnitTest::SetUp(void) -{ - HpaeSinkInfo sinkInfo; - sinkInfo = GetInCapSinkInfo(); - hpaeInnerCapturerManager_ = std::make_shared(sinkInfo); -} - -void HpaeInnerCapturerManagerUnitTest::TearDown(void) -{ - hpaeInnerCapturerManager_->DeInit(); - hpaeInnerCapturerManager_ = nullptr; -} - -static HpaeStreamInfo GetInCapPlayStreamInfo() -{ - HpaeStreamInfo streamInfo; - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_44100; - streamInfo.frameLen = SAMPLE_RATE_44100 * FRAME_LENGTH_IN_SECOND; - streamInfo.format = SAMPLE_S16LE; - streamInfo.sessionId = DEFAULT_SESSION_ID + 1; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; - streamInfo.sourceType = SOURCE_TYPE_PLAYBACK_CAPTURE; - return streamInfo; -} - -static HpaeStreamInfo GetInCapRecordStreamInfo() -{ - HpaeStreamInfo streamInfo; - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_44100; - streamInfo.frameLen = SAMPLE_RATE_44100 * FRAME_LENGTH_IN_SECOND; - streamInfo.format = SAMPLE_S16LE; - streamInfo.sessionId = DEFAULT_SESSION_ID; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; - streamInfo.sourceType = SOURCE_TYPE_PLAYBACK_CAPTURE; - return streamInfo; -} - -static void WaitForMsgProcessing(std::shared_ptr& hpaeInnerCapturerManager) -{ - int waitCount = 0; - const int32_t WAIT_COUNT_THD = 5; - while(hpaeInnerCapturerManager->IsMsgProcessing()) { - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - waitCount++; - if (waitCount >= WAIT_COUNT_THD) { - break; - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(40)); - EXPECT_EQ(hpaeInnerCapturerManager->IsMsgProcessing(), false); - EXPECT_EQ(waitCount < WAIT_COUNT_THD, true); -} - -/** - * @tc.name : Test Construct - * @tc.type : FUNC - * @tc.number: Construct_001 - * @tc.desc : Test Construct when config in vaild. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, Construct_001) -{ - EXPECT_NE(hpaeInnerCapturerManager_, nullptr); - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSinkInfo sinkInfo; - sinkInfo = GetInCapSinkInfo(); - HpaeSinkInfo dstSinkInfo = hpaeInnerCapturerManager_->GetSinkInfo(); - EXPECT_EQ(dstSinkInfo.deviceNetId == sinkInfo.deviceNetId, true); - EXPECT_EQ(dstSinkInfo.deviceClass == sinkInfo.deviceClass, true); - EXPECT_EQ(dstSinkInfo.adapterName == sinkInfo.adapterName, true); - EXPECT_EQ(dstSinkInfo.frameLen == sinkInfo.frameLen, true); - EXPECT_EQ(dstSinkInfo.samplingRate == sinkInfo.samplingRate, true); - EXPECT_EQ(dstSinkInfo.format == sinkInfo.format, true); - EXPECT_EQ(dstSinkInfo.channels == sinkInfo.channels, true); - EXPECT_EQ(dstSinkInfo.deviceType == sinkInfo.deviceType, true); -} - -/** - * @tc.name : Test Init - * @tc.type : FUNC - * @tc.number: Init_001 - * @tc.desc : Test Init. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, Init_001) -{ - EXPECT_NE(hpaeInnerCapturerManager_, nullptr); - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), true); -} - -/** - * @tc.name : Test DeInit - * @tc.type : FUNC - * @tc.number: DeInit_001 - * @tc.desc : Test DeInit. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, DeInit_001) -{ - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->DeInit(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), false); -} - -/** - * @tc.name : Test CreateStream - * @tc.type : FUNC - * @tc.number: CreateStream_001 - * @tc.desc : Test CreateRendererStream when config in vaild. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, CreateStream_001) -{ - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), true); - HpaeStreamInfo streamInfo; - streamInfo = GetInCapPlayStreamInfo(); - EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(streamInfo), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSinkInputInfo sinkInputInfo; - EXPECT_EQ(hpaeInnerCapturerManager_->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo), SUCCESS); -} - -/** - * @tc.name : Test CreateStream - * @tc.type : FUNC - * @tc.number: CreateStream_002 - * @tc.desc : Test CreateCapturerStream when config in vaild. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, CreateStream_002) -{ - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), true); - HpaeStreamInfo streamInfo; - streamInfo = GetInCapRecordStreamInfo(); - EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(streamInfo), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSourceOutputInfo sourceOutoputInfo; - EXPECT_EQ(hpaeInnerCapturerManager_->GetSourceOutputInfo(streamInfo.sessionId, sourceOutoputInfo), SUCCESS); -} - -/** - * @tc.name : Test DestroyStream - * @tc.type : FUNC - * @tc.number: DestroyStream_001 - * @tc.desc : Test DestroyRendererStream when config in vaild. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, DestroyStream_001) -{ - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->IsInit(), true); - HpaeStreamInfo streamInfo; - streamInfo = GetInCapPlayStreamInfo(); - EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(streamInfo), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->Start(streamInfo.sessionId), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSinkInputInfo sinkInputInfo; - EXPECT_EQ(hpaeInnerCapturerManager_->GetSinkInputInfo(streamInfo.sessionId, - sinkInputInfo) == ERR_INVALID_OPERATION, true); -} - -/** - * @tc.name : Test DestroyStream - * @tc.type : FUNC - * @tc.number: DestroyStream_002 - * @tc.desc : Test DestroyCapturerStream when config in vaild. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, DestroyStream_002) -{ - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeStreamInfo streamInfo; - streamInfo = GetInCapRecordStreamInfo(); - EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(streamInfo), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSourceOutputInfo sourceOutoputInfo; - EXPECT_EQ(hpaeInnerCapturerManager_->GetSourceOutputInfo(streamInfo.sessionId, sourceOutoputInfo) - == ERR_INVALID_OPERATION, SUCCESS); -} - -/** - * @tc.name : Test StreamStartPauseChange_001 - * @tc.type : FUNC - * @tc.number: StreamStartPauseChange_001 - * @tc.desc : Test StartRendererStream when config in vaild. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, StreamStartPauseChange_001) -{ - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeStreamInfo recordStreamInfo; - recordStreamInfo = GetInCapRecordStreamInfo(); - EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(recordStreamInfo), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->Start(recordStreamInfo.sessionId), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSourceOutputInfo sourceOutoputInfo; - - HpaeStreamInfo playStreamInfo; - playStreamInfo = GetInCapPlayStreamInfo(); - EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(playStreamInfo), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - std::shared_ptr writeInPlayDataCb = std::make_shared(SAMPLE_S16LE); - EXPECT_EQ(hpaeInnerCapturerManager_->RegisterWriteCallback(playStreamInfo.sessionId, writeInPlayDataCb), SUCCESS); - EXPECT_EQ(hpaeInnerCapturerManager_->Start(playStreamInfo.sessionId), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSinkInputInfo sinkInputInfo; - - EXPECT_EQ(hpaeInnerCapturerManager_->Pause(recordStreamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->IsRunning(), true); - EXPECT_EQ(hpaeInnerCapturerManager_->Pause(playStreamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->IsRunning(), true); - EXPECT_EQ(hpaeInnerCapturerManager_->GetSinkInputInfo(playStreamInfo.sessionId, sinkInputInfo) == SUCCESS, true); - EXPECT_EQ(hpaeInnerCapturerManager_->GetSourceOutputInfo(recordStreamInfo.sessionId, sourceOutoputInfo), SUCCESS); - EXPECT_EQ(sourceOutoputInfo.capturerSessionInfo.state, CAPTURER_PAUSED); - EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_PAUSED); - EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(recordStreamInfo.sessionId) == SUCCESS, true); - EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(playStreamInfo.sessionId) == SUCCESS, true); -} - -/** - * @tc.name : Test StreamStartStopChange_001 - * @tc.type : FUNC - * @tc.number: StreamStartStopChange_001 - * @tc.desc : Test StartCapturerStream when config in vaild. - */ -TEST_F(HpaeInnerCapturerManagerUnitTest, StreamStartStopChange_001) -{ - EXPECT_EQ(hpaeInnerCapturerManager_->Init(), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeStreamInfo recordStreamInfo; - recordStreamInfo.channels = STEREO; - recordStreamInfo.samplingRate = SAMPLE_RATE_44100; - recordStreamInfo.frameLen = SAMPLE_RATE_44100 * FRAME_LENGTH_IN_SECOND; - recordStreamInfo.format = SAMPLE_S16LE; - recordStreamInfo.sessionId = DEFAULT_SESSION_ID; - recordStreamInfo.streamType = STREAM_MUSIC; - recordStreamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; - recordStreamInfo.sourceType = SOURCE_TYPE_PLAYBACK_CAPTURE; - EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(recordStreamInfo), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->Start(recordStreamInfo.sessionId), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSourceOutputInfo sourceOutoputInfo; - - HpaeStreamInfo playStreamInfo; - playStreamInfo = GetInCapPlayStreamInfo(); - EXPECT_EQ(hpaeInnerCapturerManager_->CreateStream(playStreamInfo), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - std::shared_ptr writeInPlayDataCb = std::make_shared(SAMPLE_S16LE); - EXPECT_EQ(hpaeInnerCapturerManager_->RegisterWriteCallback(playStreamInfo.sessionId, writeInPlayDataCb), SUCCESS); - EXPECT_EQ(hpaeInnerCapturerManager_->Start(playStreamInfo.sessionId), SUCCESS); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - HpaeSinkInputInfo sinkInputInfo; - - EXPECT_EQ(hpaeInnerCapturerManager_->Stop(recordStreamInfo.sessionId) == SUCCESS, true); - EXPECT_EQ(hpaeInnerCapturerManager_->Stop(playStreamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeInnerCapturerManager_); - EXPECT_EQ(hpaeInnerCapturerManager_->IsRunning(), true); - EXPECT_EQ(hpaeInnerCapturerManager_->GetSinkInputInfo(playStreamInfo.sessionId, sinkInputInfo) == SUCCESS, true); - EXPECT_EQ(hpaeInnerCapturerManager_->GetSourceOutputInfo(recordStreamInfo.sessionId, sourceOutoputInfo), SUCCESS); - EXPECT_EQ(sourceOutoputInfo.capturerSessionInfo.state, CAPTURER_STOPPED); - EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_STOPPED); - EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(recordStreamInfo.sessionId) == SUCCESS, true); - EXPECT_EQ(hpaeInnerCapturerManager_->DestroyStream(playStreamInfo.sessionId) == SUCCESS, true); -} -}; -} // namespace OHOS::AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/manager/hpae_manager_test.cpp b/services/audio_engine/test/unittest/manager/hpae_manager_test.cpp deleted file mode 100644 index 5c0ca34a6c..0000000000 --- a/services/audio_engine/test/unittest/manager/hpae_manager_test.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include -#include -#include -#include -#include -#include "test_case_common.h" -#include "audio_errors.h" -#include "hpae_manager_unit_test.h" - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; -namespace { -static std::string g_rootPath = "/data/data/.pulse_dir/"; -constexpr int32_t FRAME_LENGTH = 882; -constexpr int32_t TEST_STREAM_SESSION_ID = 123456; -constexpr int32_t TEST_SLEEP_TIME_20 = 20; -constexpr int32_t TEST_SLEEP_TIME_40 = 40; - -class HpaeManagerUnitTest : public testing::Test { -public: - void SetUp(); - void TearDown(); - std::shared_ptr hpaeManager_ = nullptr; -}; -void HpaeManagerUnitTest::SetUp() -{ - hpaeManager_ = std::make_shared(); -} - -void HpaeManagerUnitTest::TearDown() -{ - hpaeManager_->DeInit(); - hpaeManager_ = nullptr; -} - -void WaitForMsgProcessing(std::shared_ptr &hpaeManager) -{ - int waitCount = 0; - const int WAIT_COUNT_THD = 5; - while (hpaeManager->IsMsgProcessing()) { - std::this_thread::sleep_for(std::chrono::milliseconds(TEST_SLEEP_TIME_20)); - waitCount++; - if (waitCount >= WAIT_COUNT_THD) { - break; - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(TEST_SLEEP_TIME_40)); - EXPECT_EQ(hpaeManager->IsMsgProcessing(), false); - EXPECT_EQ(waitCount < WAIT_COUNT_THD, true); -} - -AudioModuleInfo GetSinkAudioModeInfo() -{ - AudioModuleInfo audioModuleInfo; - audioModuleInfo.lib = "libmodule-hdi-sink.z.so"; - audioModuleInfo.channels = "2"; - audioModuleInfo.rate = "48000"; - audioModuleInfo.name = "Speaker_File"; - audioModuleInfo.adapterName = "file_io"; - audioModuleInfo.className = "file_io"; - audioModuleInfo.bufferSize = "7680"; - audioModuleInfo.format = "s32le"; - audioModuleInfo.fixedLatency = "1"; - audioModuleInfo.offloadEnable = "0"; - audioModuleInfo.networkId = "LocalDevice"; - audioModuleInfo.fileName = g_rootPath + audioModuleInfo.adapterName + "_" + audioModuleInfo.rate + "_" + - audioModuleInfo.channels + "_" + audioModuleInfo.format + ".pcm"; - std::stringstream typeValue; - typeValue << static_cast(DEVICE_TYPE_SPEAKER); - audioModuleInfo.deviceType = typeValue.str(); - return audioModuleInfo; -} - -AudioModuleInfo GetSourceAudioModeInfo() -{ - AudioModuleInfo audioModuleInfo; - audioModuleInfo.lib = "libmodule-hdi-source.z.so"; - audioModuleInfo.channels = "2"; - audioModuleInfo.rate = "48000"; - audioModuleInfo.name = "mic"; - audioModuleInfo.adapterName = "file_io"; - audioModuleInfo.className = "file_io"; - audioModuleInfo.bufferSize = "3840"; - audioModuleInfo.format = "s16le"; - audioModuleInfo.fixedLatency = "1"; - audioModuleInfo.offloadEnable = "0"; - audioModuleInfo.networkId = "LocalDevice"; - audioModuleInfo.fileName = g_rootPath + "source_" + audioModuleInfo.adapterName + "_" + audioModuleInfo.rate + "_" + - audioModuleInfo.channels + "_" + audioModuleInfo.format + ".pcm"; - std::stringstream typeValue; - typeValue << static_cast(DEVICE_TYPE_FILE_SOURCE); - audioModuleInfo.deviceType = typeValue.str(); - return audioModuleInfo; -} - -HpaeStreamInfo GetRenderStreamInfo() -{ - HpaeStreamInfo streamInfo; - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_44100; - streamInfo.format = SAMPLE_S16LE; - streamInfo.frameLen = FRAME_LENGTH; - streamInfo.sessionId = TEST_STREAM_SESSION_ID; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; - return streamInfo; -} - -HpaeStreamInfo GetCaptureStreamInfo() -{ - HpaeStreamInfo streamInfo; - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_48000; - streamInfo.format = SAMPLE_S16LE; - streamInfo.frameLen = FRAME_LENGTH; - streamInfo.sessionId = TEST_STREAM_SESSION_ID; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; - return streamInfo; -} - -TEST_F(HpaeManagerUnitTest, constructHpaeManagerTest) -{ - EXPECT_NE(hpaeManager_, nullptr); - hpaeManager_->Init(); - EXPECT_EQ(hpaeManager_->IsInit(), true); - sleep(1); - EXPECT_EQ(hpaeManager_->IsRunning(), true); - hpaeManager_->DeInit(); - EXPECT_EQ(hpaeManager_->IsInit(), false); - sleep(1); - EXPECT_EQ(hpaeManager_->IsRunning(), false); -} - -TEST_F(HpaeManagerUnitTest, GetHpaeRenderManagerTest) -{ - EXPECT_NE(hpaeManager_, nullptr); - hpaeManager_->Init(); - EXPECT_EQ(hpaeManager_->IsInit(), true); - sleep(1); - EXPECT_EQ(hpaeManager_->IsRunning(), true); - - std::shared_ptr callback = std::make_shared(); - hpaeManager_->RegisterSerivceCallback(callback); - AudioModuleInfo audioModuleInfo = GetSinkAudioModeInfo(); - EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - int32_t portId = callback->GetPortId(); - - hpaeManager_->CloseAudioPort(portId); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(callback->GetCloseAudioPortResult(), SUCCESS); - - hpaeManager_->DeInit(); - EXPECT_EQ(hpaeManager_->IsInit(), false); - EXPECT_EQ(hpaeManager_->IsRunning(), false); -} - -TEST_F(HpaeManagerUnitTest, IHpaeRenderManagerTest) -{ - IHpaeManager::GetHpaeManager()->Init(); - EXPECT_EQ(IHpaeManager::GetHpaeManager()->IsInit(), true); - sleep(1); - EXPECT_EQ(IHpaeManager::GetHpaeManager()->IsRunning(), true); - - AudioModuleInfo audioModuleInfo = GetSinkAudioModeInfo(); - EXPECT_EQ(IHpaeManager::GetHpaeManager()->OpenAudioPort(audioModuleInfo), SUCCESS); - IHpaeManager::GetHpaeManager()->DeInit(); - EXPECT_EQ(IHpaeManager::GetHpaeManager()->IsInit(), false); - EXPECT_EQ(IHpaeManager::GetHpaeManager()->IsRunning(), false); -} - -TEST_F(HpaeManagerUnitTest, IHpaeRenderStreamManagerTest) -{ - EXPECT_NE(hpaeManager_, nullptr); - hpaeManager_->Init(); - EXPECT_EQ(hpaeManager_->IsInit(), true); - sleep(1); - AudioModuleInfo audioModuleInfo = GetSinkAudioModeInfo(); - std::shared_ptr callback = std::make_shared(); - int32_t result = hpaeManager_->RegisterSerivceCallback(callback); - EXPECT_EQ(result, SUCCESS); - EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); - hpaeManager_->SetDefaultSink(audioModuleInfo.name); - WaitForMsgProcessing(hpaeManager_); - HpaeStreamInfo streamInfo = GetRenderStreamInfo(); - hpaeManager_->CreateStream(streamInfo); - WaitForMsgProcessing(hpaeManager_); - - EXPECT_EQ(hpaeManager_->SetSinkMute(audioModuleInfo.name, true, true), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(callback->GetSetSinkMuteResult(), SUCCESS); - EXPECT_EQ(hpaeManager_->SetSinkMute(audioModuleInfo.name, false, true), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(callback->GetSetSinkMuteResult(), SUCCESS); - - EXPECT_EQ(hpaeManager_->SuspendAudioDevice(audioModuleInfo.name, true), SUCCESS); - EXPECT_EQ(hpaeManager_->SuspendAudioDevice(audioModuleInfo.name, false), SUCCESS); - - EXPECT_EQ(hpaeManager_->GetAllSinkInputs(), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(callback->GetGetAllSinkInputsResult(), SUCCESS); - std::vector sinkInputs = callback->GetSinkInputs(); - EXPECT_EQ(sinkInputs.size(), 1); - for (const auto &it : sinkInputs) { - std::cout << "sinkInputs.sinkName:" << it.sinkName << std::endl; - EXPECT_EQ(it.paStreamId, streamInfo.sessionId); - EXPECT_EQ(it.sinkName, audioModuleInfo.name); - } - hpaeManager_->Release(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - - EXPECT_EQ(hpaeManager_->GetAllSinkInputs(), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(callback->GetGetAllSinkInputsResult(), SUCCESS); - sinkInputs = callback->GetSinkInputs(); - EXPECT_EQ(sinkInputs.size(), 0); -} - -TEST_F(HpaeManagerUnitTest, IHpaeCaptureStreamManagerTest) -{ - EXPECT_NE(hpaeManager_, nullptr); - hpaeManager_->Init(); - EXPECT_EQ(hpaeManager_->IsInit(), true); - sleep(1); - std::shared_ptr callback = std::make_shared(); - int32_t result = hpaeManager_->RegisterSerivceCallback(callback); - EXPECT_EQ(result, SUCCESS); - - AudioModuleInfo audioModuleInfo = GetSourceAudioModeInfo(); - EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - hpaeManager_->SetDefaultSource(audioModuleInfo.name); - int32_t portId = callback->GetPortId(); - HpaeStreamInfo streamInfo = GetCaptureStreamInfo(); - hpaeManager_->CreateStream(streamInfo); - WaitForMsgProcessing(hpaeManager_); - - EXPECT_EQ(hpaeManager_->SetSourceOutputMute(portId, true), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(callback->GetSetSourceOutputMuteResult(), SUCCESS); - EXPECT_EQ(hpaeManager_->SetSourceOutputMute(portId, false), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(callback->GetSetSourceOutputMuteResult(), SUCCESS); - - EXPECT_EQ(hpaeManager_->GetAllSourceOutputs(), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(callback->GetGetAllSourceOutputsResult(), SUCCESS); - std::vector sourceOutputs = callback->GetSourceOutputs(); - EXPECT_EQ(sourceOutputs.size(), 1); - for (const auto &it : sourceOutputs) { - std::cout << "deviceSourceId:" << it.deviceSourceId << std::endl; - EXPECT_EQ(it.paStreamId, streamInfo.sessionId); - EXPECT_EQ(it.deviceSourceId, portId); - } - - hpaeManager_->Release(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); -} - -TEST_F(HpaeManagerUnitTest, IHpaeRenderStreamManagerTest002) -{ - EXPECT_NE(hpaeManager_, nullptr); - hpaeManager_->Init(); - EXPECT_EQ(hpaeManager_->IsInit(), true); - sleep(1); - AudioModuleInfo audioModuleInfo = GetSinkAudioModeInfo(); - EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); - hpaeManager_->SetDefaultSink(audioModuleInfo.name); - WaitForMsgProcessing(hpaeManager_); - HpaeStreamInfo streamInfo = GetRenderStreamInfo(); - hpaeManager_->CreateStream(streamInfo); - WaitForMsgProcessing(hpaeManager_); - int32_t fixedNum = 100; - std::shared_ptr writeFixedValueCb = std::make_shared(SAMPLE_S16LE, fixedNum); - hpaeManager_->RegisterWriteCallback(streamInfo.sessionId, writeFixedValueCb); - std::shared_ptr statusChangeCb = std::make_shared(); - hpaeManager_->RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_PLAY, streamInfo.sessionId, statusChangeCb); - WaitForMsgProcessing(hpaeManager_); - HpaeSessionInfo sessionInfo; - EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); - EXPECT_EQ(sessionInfo.streamInfo.sessionId, streamInfo.sessionId); - EXPECT_EQ(sessionInfo.streamInfo.streamType, streamInfo.streamType); - EXPECT_EQ(sessionInfo.streamInfo.frameLen, streamInfo.frameLen); - EXPECT_EQ(sessionInfo.streamInfo.format, streamInfo.format); - EXPECT_EQ(sessionInfo.streamInfo.samplingRate, streamInfo.samplingRate); - EXPECT_EQ(sessionInfo.streamInfo.channels, streamInfo.channels); - EXPECT_EQ(sessionInfo.streamInfo.streamClassType, streamInfo.streamClassType); - EXPECT_EQ(sessionInfo.state, I_STATUS_IDLE); - - hpaeManager_->Start(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo); - EXPECT_EQ(sessionInfo.state, I_STATUS_STARTING); - EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_STARTED); - - hpaeManager_->Pause(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); - EXPECT_EQ(sessionInfo.state, I_STATUS_PAUSING); - EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_PAUSED); - - hpaeManager_->Stop(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); - EXPECT_EQ(sessionInfo.state, I_STATUS_STOPPING); - EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_STOPPED); - - hpaeManager_->Release(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), ERROR); -} - -TEST_F(HpaeManagerUnitTest, IHpaeCaptureStreamManagerTest002) -{ - EXPECT_NE(hpaeManager_, nullptr); - hpaeManager_->Init(); - EXPECT_EQ(hpaeManager_->IsInit(), true); - sleep(1); - AudioModuleInfo audioModuleInfo = GetSourceAudioModeInfo(); - EXPECT_EQ(hpaeManager_->OpenAudioPort(audioModuleInfo), SUCCESS); - WaitForMsgProcessing(hpaeManager_); - hpaeManager_->SetDefaultSource(audioModuleInfo.name); - HpaeStreamInfo streamInfo = GetCaptureStreamInfo(); - hpaeManager_->CreateStream(streamInfo); - WaitForMsgProcessing(hpaeManager_); - int32_t fixedNum = 100; - std::shared_ptr writeFixedValueCb = std::make_shared(SAMPLE_S16LE, fixedNum); - hpaeManager_->RegisterWriteCallback(streamInfo.sessionId, writeFixedValueCb); - std::shared_ptr statusChangeCb = std::make_shared(); - hpaeManager_->RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_RECORD, streamInfo.sessionId, statusChangeCb); - WaitForMsgProcessing(hpaeManager_); - HpaeSessionInfo sessionInfo; - EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); - EXPECT_EQ(sessionInfo.streamInfo.sessionId, streamInfo.sessionId); - EXPECT_EQ(sessionInfo.streamInfo.streamType, streamInfo.streamType); - EXPECT_EQ(sessionInfo.streamInfo.frameLen, streamInfo.frameLen); - EXPECT_EQ(sessionInfo.streamInfo.streamClassType, streamInfo.streamClassType); - EXPECT_EQ(sessionInfo.state, I_STATUS_IDLE); - hpaeManager_->Start(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo); - EXPECT_EQ(sessionInfo.state, I_STATUS_STARTING); - EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_STARTED); - hpaeManager_->Pause(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); - EXPECT_EQ(sessionInfo.state, I_STATUS_PAUSING); - EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_PAUSED); - hpaeManager_->Stop(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), SUCCESS); - EXPECT_EQ(sessionInfo.state, I_STATUS_STOPPING); - EXPECT_EQ(statusChangeCb->GetStatus(), I_STATUS_STOPPED); - hpaeManager_->Release(streamInfo.streamClassType, streamInfo.sessionId); - WaitForMsgProcessing(hpaeManager_); - EXPECT_EQ(hpaeManager_->GetSessionInfo(streamInfo.streamClassType, streamInfo.sessionId, sessionInfo), ERROR); -} -} // namespace \ No newline at end of file diff --git a/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp b/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp deleted file mode 100644 index 7030997955..0000000000 --- a/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include "test_case_common.h" -#include "audio_errors.h" -#include "hpae_renderer_manager.h" -#include "hpae_offload_renderer_manager.h" -#include -#include -#include -#include -#include -#include - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; -namespace { -static std::string g_rootPath = "/data/data/.pulse_dir/"; -constexpr int32_t FRAME_LENGTH_882 = 882; -constexpr int32_t FRAME_LENGTH_960 = 960; -constexpr int32_t TEST_STREAM_SESSION_ID = 123456; -constexpr int32_t TEST_SLEEP_TIME_20 = 20; -constexpr int32_t TEST_SLEEP_TIME_40 = 40; -class HpaeRendererManagerTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeRendererManagerTest::SetUp() -{} - -void HpaeRendererManagerTest::TearDown() -{} - -static void TestCheckSinkInputInfo(HpaeSinkInputInfo &sinkInputInfo, const HpaeStreamInfo &streamInfo) -{ - EXPECT_EQ(sinkInputInfo.nodeInfo.channels == streamInfo.channels, true); - EXPECT_EQ(sinkInputInfo.nodeInfo.format == streamInfo.format, true); - EXPECT_EQ(sinkInputInfo.nodeInfo.frameLen == streamInfo.frameLen, true); - EXPECT_EQ(sinkInputInfo.nodeInfo.sessionId == streamInfo.sessionId, true); - EXPECT_EQ(sinkInputInfo.nodeInfo.samplingRate == streamInfo.samplingRate, true); - EXPECT_EQ(sinkInputInfo.nodeInfo.streamType == streamInfo.streamType, true); -} - -static void WaitForMsgProcessing(std::shared_ptr &hpaeRendererManager) -{ - int waitCount = 0; - const int WAIT_COUNT_THD = 5; - while (hpaeRendererManager->IsMsgProcessing()) { - std::this_thread::sleep_for(std::chrono::milliseconds(TEST_SLEEP_TIME_20)); - waitCount++; - if (waitCount >= WAIT_COUNT_THD) { - break; - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(TEST_SLEEP_TIME_40)); - EXPECT_EQ(hpaeRendererManager->IsMsgProcessing(), false); - EXPECT_EQ(waitCount < WAIT_COUNT_THD, true); -} - -template -void TestIRendererManagerConstruct() -{ - HpaeSinkInfo sinkInfo; - sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.filePath = g_rootPath + "constructHpaeRendererManagerTest.pcm"; - sinkInfo.frameLen = FRAME_LENGTH_960; - sinkInfo.samplingRate = SAMPLE_RATE_48000; - sinkInfo.format = SAMPLE_F32LE; - sinkInfo.channels = STEREO; - sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; - std::shared_ptr hpaeRendererManager = std::make_shared(sinkInfo); - HpaeSinkInfo dstSinkInfo = hpaeRendererManager->GetSinkInfo(); - EXPECT_EQ(dstSinkInfo.deviceNetId == sinkInfo.deviceNetId, true); - EXPECT_EQ(dstSinkInfo.deviceClass == sinkInfo.deviceClass, true); - EXPECT_EQ(dstSinkInfo.adapterName == sinkInfo.adapterName, true); - EXPECT_EQ(dstSinkInfo.frameLen == sinkInfo.frameLen, true); - EXPECT_EQ(dstSinkInfo.samplingRate == sinkInfo.samplingRate, true); - EXPECT_EQ(dstSinkInfo.format == sinkInfo.format, true); - EXPECT_EQ(dstSinkInfo.channels == sinkInfo.channels, true); - EXPECT_EQ(dstSinkInfo.deviceType == sinkInfo.deviceType, true); -} - -template -void TestIRendererManagerInit() -{ - HpaeSinkInfo sinkInfo; - sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.filePath = g_rootPath + "constructHpaeRendererManagerTest.pcm"; - sinkInfo.frameLen = FRAME_LENGTH_960; - sinkInfo.samplingRate = SAMPLE_RATE_48000; - sinkInfo.format = SAMPLE_F32LE; - sinkInfo.channels = STEREO; - sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; - std::shared_ptr hpaeRendererManager = std::make_shared(sinkInfo); - EXPECT_EQ(hpaeRendererManager->Init() == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager->IsInit(), true); - EXPECT_EQ(hpaeRendererManager->DeInit() == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager->IsInit(), false); -} - -void TestRendererManagerCrteateStream( - std::shared_ptr &hpaeRendererManager, HpaeStreamInfo &streamInfo) -{ - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_44100; - streamInfo.format = SAMPLE_S16LE; - streamInfo.frameLen = FRAME_LENGTH_882; - streamInfo.sessionId = TEST_STREAM_SESSION_ID; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; - EXPECT_EQ(hpaeRendererManager->CreateStream(streamInfo) == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager.use_count() == 1, true); - HpaeSinkInputInfo sinkInputInfo; - int32_t ret = hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo); - EXPECT_EQ(ret == SUCCESS, true); - TestCheckSinkInputInfo(sinkInputInfo, streamInfo); -} - -template -void TestIRendererManagerCreateDestoryStream() -{ - HpaeSinkInfo sinkInfo; - sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.filePath = g_rootPath + "constructHpaeRendererManagerTest.pcm"; - sinkInfo.frameLen = FRAME_LENGTH_960; - sinkInfo.samplingRate = SAMPLE_RATE_48000; - sinkInfo.format = SAMPLE_F32LE; - sinkInfo.channels = STEREO; - sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; - std::shared_ptr hpaeRendererManager = std::make_shared(sinkInfo); - EXPECT_EQ(hpaeRendererManager->Init() == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager->IsInit(), true); - HpaeStreamInfo streamInfo; - TestRendererManagerCrteateStream(hpaeRendererManager, streamInfo); - int32_t ret = hpaeRendererManager->DestroyStream(streamInfo.sessionId); - EXPECT_EQ(ret == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - HpaeSinkInputInfo sinkInputInfo; - ret = hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo); - EXPECT_EQ(ret == ERR_INVALID_OPERATION, true); - streamInfo.channels = STEREO; - streamInfo.samplingRate = SAMPLE_RATE_48000; - streamInfo.format = SAMPLE_F32LE; - streamInfo.frameLen = FRAME_LENGTH_960; - streamInfo.sessionId = TEST_STREAM_SESSION_ID; - streamInfo.streamType = STREAM_MUSIC; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; - EXPECT_EQ(hpaeRendererManager->CreateStream(streamInfo) == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager.use_count() == 1, true); - EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); - TestCheckSinkInputInfo(sinkInputInfo, streamInfo); - EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_NEW); - EXPECT_EQ(hpaeRendererManager->DestroyStream(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - ret = hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo); - EXPECT_EQ(ret == ERR_INVALID_OPERATION, true); -} - -template -static void TestIRendererManagerStartPuaseStream() -{ - HpaeSinkInfo sinkInfo; - sinkInfo.deviceNetId = DEFAULT_TEST_DEVICE_NETWORKID; - sinkInfo.deviceClass = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.adapterName = DEFAULT_TEST_DEVICE_CLASS; - sinkInfo.filePath = g_rootPath + "constructHpaeRendererManagerTest.pcm"; - sinkInfo.frameLen = FRAME_LENGTH_960; - sinkInfo.samplingRate = SAMPLE_RATE_48000; - sinkInfo.format = SAMPLE_F32LE; - sinkInfo.channels = STEREO; - sinkInfo.deviceType = DEVICE_TYPE_SPEAKER; - std::shared_ptr hpaeRendererManager = std::make_shared(sinkInfo); - EXPECT_EQ(hpaeRendererManager->Init() == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager->IsInit(), true); - HpaeStreamInfo streamInfo; - TestRendererManagerCrteateStream(hpaeRendererManager, streamInfo); - HpaeSinkInputInfo sinkInputInfo; - std::shared_ptr writeIncDataCb = std::make_shared(SAMPLE_S16LE); - EXPECT_EQ(hpaeRendererManager->RegisterWriteCallback(streamInfo.sessionId, writeIncDataCb), SUCCESS); - EXPECT_EQ(writeIncDataCb.use_count() == 1, true); - EXPECT_EQ(hpaeRendererManager->Start(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); - EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_RUNNING); - EXPECT_EQ(hpaeRendererManager->IsRunning(), true); - EXPECT_EQ(hpaeRendererManager->Pause(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); - EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_PAUSED); - EXPECT_EQ(hpaeRendererManager->Start(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); - EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_RUNNING); - EXPECT_EQ(hpaeRendererManager->IsRunning(), true); - EXPECT_EQ(hpaeRendererManager->Stop(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ(hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == SUCCESS, true); - EXPECT_EQ(sinkInputInfo.rendererSessionInfo.state, RENDERER_STOPPED); - EXPECT_EQ(hpaeRendererManager->DestroyStream(streamInfo.sessionId) == SUCCESS, true); - WaitForMsgProcessing(hpaeRendererManager); - EXPECT_EQ( - hpaeRendererManager->GetSinkInputInfo(streamInfo.sessionId, sinkInputInfo) == ERR_INVALID_OPERATION, true); -} - -TEST_F(HpaeRendererManagerTest, constructHpaeRendererManagerTest) -{ - TestIRendererManagerConstruct(); - std::cout << "test offload" << std::endl; - TestIRendererManagerConstruct(); -} - -TEST_F(HpaeRendererManagerTest, HpaeRendererManagerInitTest) -{ - TestIRendererManagerInit(); - std::cout << "test offload" << std::endl; - TestIRendererManagerInit(); -} - -TEST_F(HpaeRendererManagerTest, HpaeRendererManagerCreateDestoryStreamTest) -{ - TestIRendererManagerCreateDestoryStream(); - std::cout << "test offload" << std::endl; - TestIRendererManagerCreateDestoryStream(); -} - -TEST_F(HpaeRendererManagerTest, HpaeRendererManagerStartPuaseStreamTest) -{ - TestIRendererManagerStartPuaseStream(); - std::cout << "test offload" << std::endl; - TestIRendererManagerStartPuaseStream(); -} -} // namespace \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_gain_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_gain_node_test.cpp deleted file mode 100644 index 29bc6c6649..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_gain_node_test.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include "hpae_sink_input_node.h" -#include "hpae_sink_output_node.h" -#include "hpae_gain_node.h" -#include "test_case_common.h" -#include "audio_errors.h" - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -class HpaeGainNodeTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeGainNodeTest::SetUp() -{} - -void HpaeGainNodeTest::TearDown() -{} - -static int32_t g_testValue = 0; - -namespace { - -constexpr uint32_t DEFAULT_NODE_ID = 1234; -constexpr uint32_t DEFAULT_FRAME_LEN = 960; -constexpr uint32_t DEFAULT_NUM_TWO = 2; - -TEST_F(HpaeGainNodeTest, constructHpaeGainNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODE_ID; - nodeInfo.frameLen = DEFAULT_FRAME_LEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - nodeInfo.deviceClass = "primary"; - std::shared_ptr hpaeGainNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeGainNode->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeGainNode->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeGainNode->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeGainNode->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeGainNode->GetBitWidth(), nodeInfo.format); - std::cout << "HpaeGainNodeTest::GetNodeInfo" << std::endl; - HpaeNodeInfo &retNi = hpaeGainNode->GetNodeInfo(); - EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); - std::cout << "samplingRate: " << retNi.samplingRate << std::endl; - EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); - std::cout << "nodeId: " << retNi.nodeId << std::endl; - EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); - std::cout << "frameLen: " << retNi.frameLen << std::endl; - EXPECT_EQ(retNi.channels, nodeInfo.channels); - std::cout << "channels: " << retNi.channels << std::endl; - EXPECT_EQ(retNi.format, nodeInfo.format); - std::cout << "format: " << retNi.format << std::endl; - EXPECT_EQ(retNi.deviceClass, nodeInfo.deviceClass); - std::cout << "deviceClass: " << retNi.deviceClass << std::endl; - std::cout << "HpaeGainNodeTest::GetNodeInfo end" << std::endl; -} -static int32_t TestRendererRenderFrame(const char *data, uint64_t len) -{ - float curGain = 0.0f; - float targetGain = 1.0f; - float stepGain = targetGain - curGain; - uint64_t frameLen = len / (SAMPLE_F32LE * STEREO); - stepGain = stepGain / frameLen; - const float *tempData = reinterpret_cast(data); - for (int32_t i = 0; i < frameLen; i++) { - const float left = tempData[DEFAULT_NUM_TWO * i]; - const float right = tempData[DEFAULT_NUM_TWO * i + 1]; - const float expectedValue = g_testValue * (curGain + i * stepGain); - EXPECT_EQ(left, expectedValue); - EXPECT_EQ(right, expectedValue); - } - return 0; -} - -TEST_F(HpaeGainNodeTest, testHpaeGainTestNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODE_ID; - nodeInfo.frameLen = DEFAULT_FRAME_LEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - nodeInfo.streamType = STREAM_MUSIC; - std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); - std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); - std::shared_ptr hpaeGainNode = std::make_shared(nodeInfo); - hpaeGainNode->Connect(hpaeSinkInputNode); - hpaeSinkOutputNode->Connect(hpaeGainNode); - std::string deviceClass = "file_io"; - std::string deviceNetId = "LocalDevice"; - EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0); - EXPECT_EQ(hpaeSinkInputNode.use_count(), DEFAULT_NUM_TWO); - EXPECT_EQ(hpaeGainNode.use_count(), DEFAULT_NUM_TWO); - EXPECT_EQ(hpaeSinkOutputNode.use_count(), 1); - g_testValue = 0; - int32_t testValue = 100; - std::shared_ptr writeFixedValueCb0 = - std::make_shared(SAMPLE_F32LE, testValue); - g_testValue = testValue; - hpaeSinkInputNode->RegisterWriteCallback(writeFixedValueCb0); - hpaeSinkOutputNode->DoProcess(); - TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), - nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); - hpaeSinkOutputNode->DoProcess(); - TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), - nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); - hpaeSinkOutputNode->DisConnect(hpaeGainNode); - EXPECT_EQ(hpaeGainNode.use_count(), 1); - hpaeGainNode->DisConnect(hpaeSinkInputNode); - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); -} -} // namespace diff --git a/services/audio_engine/test/unittest/node/hpae_mixer_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_mixer_node_test.cpp deleted file mode 100644 index 16a543aaba..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_mixer_node_test.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include "hpae_sink_input_node.h" -#include "hpae_mixer_node.h" -#include "hpae_sink_output_node.h" -#include "test_case_common.h" -#include "audio_errors.h" - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; -namespace { -static constexpr int32_t TEST_VALUE1 = 100; -static constexpr int32_t TEST_VALUE2 = 200; -static constexpr uint32_t TEST_ID = 1243; -static constexpr uint32_t TEST_FRAMELEN = 960; -class HpaeMixerNodeTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeMixerNodeTest::SetUp() -{} - -void HpaeMixerNodeTest::TearDown() -{} - -static int32_t g_testValue = 0; - -TEST_F(HpaeMixerNodeTest, constructHpaeMixerNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = TEST_ID; - nodeInfo.frameLen = TEST_FRAMELEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeMixerNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeMixerNode->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeMixerNode->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeMixerNode->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeMixerNode->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeMixerNode->GetBitWidth(), nodeInfo.format); - HpaeNodeInfo &retNi = hpaeMixerNode->GetNodeInfo(); - EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); - EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); - EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); - EXPECT_EQ(retNi.channels, nodeInfo.channels); - EXPECT_EQ(retNi.format, nodeInfo.format); -} -static int32_t TestRendererRenderFrame(const char *data, uint64_t len) -{ - for (int32_t i = 0; i < len / SAMPLE_F32LE; i++) { - float diff = *((float*)data + i) - g_testValue; - EXPECT_EQ(fabs(diff) < TEST_VALUE_PRESION, true); - } - return 0; -} - -TEST_F(HpaeMixerNodeTest, testHpaePlayOutConnectNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = TEST_ID; - nodeInfo.frameLen = TEST_FRAMELEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); - std::shared_ptr hpaeSinkInputNode0 = std::make_shared(nodeInfo); - std::shared_ptr hpaeSinkInputNode1 = std::make_shared(nodeInfo); - std::shared_ptr hpaeMixerNode = std::make_shared(nodeInfo); - hpaeMixerNode->Connect(hpaeSinkInputNode0); - hpaeMixerNode->Connect(hpaeSinkInputNode1); - std::cout << "hpaeMixerNode->GetPreOutNum():" << hpaeMixerNode->GetPreOutNum() << std::endl; - EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); - hpaeSinkOutputNode->Connect(hpaeMixerNode); - std::string deviceClass = "file_io"; - std::string deviceNetId = "LocalDevice"; - EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 1); - EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0); - EXPECT_EQ(hpaeSinkInputNode0.use_count(), 1 + 1); - EXPECT_EQ(hpaeSinkInputNode1.use_count(), 1 + 1); - EXPECT_EQ(hpaeMixerNode.use_count(), 1 + 1); - g_testValue = 0; - int32_t testValue = TEST_VALUE1; - std::shared_ptr writeFixedValueCb0 = - std::make_shared(SAMPLE_F32LE, testValue); - g_testValue = g_testValue + testValue; - hpaeSinkInputNode0->RegisterWriteCallback(writeFixedValueCb0); - testValue = TEST_VALUE2; - std::shared_ptr writeFixedValueCb1 = - std::make_shared(SAMPLE_F32LE, testValue); - g_testValue = g_testValue + testValue; - hpaeSinkInputNode1->RegisterWriteCallback(writeFixedValueCb1); - hpaeSinkOutputNode->DoProcess(); - TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), nodeInfo.frameLen * nodeInfo.channels * - GET_SIZE_FROM_FORMAT(nodeInfo.format)); - hpaeSinkOutputNode->DisConnect(hpaeMixerNode); - EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); - EXPECT_EQ(hpaeMixerNode.use_count(), 1); - hpaeMixerNode->DisConnect(hpaeSinkInputNode0); - EXPECT_EQ(hpaeSinkInputNode0.use_count(), 1); - EXPECT_EQ(hpaeMixerNode->GetPreOutNum(), 1); - hpaeMixerNode->DisConnect(hpaeSinkInputNode1); - EXPECT_EQ(hpaeSinkInputNode1.use_count(), 1); - EXPECT_EQ(hpaeMixerNode->GetPreOutNum(), 0); -} - -} // namespace \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_output_cluster_test.cpp b/services/audio_engine/test/unittest/node/hpae_output_cluster_test.cpp deleted file mode 100644 index 4e52290b49..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_output_cluster_test.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include "hpae_process_cluster.h" -#include "test_case_common.h" -#include "audio_errors.h" -#include "hpae_sink_input_node.h" -#include "hpae_output_cluster.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr uint32_t NODE_ID = 1243; -constexpr uint32_t SESSION_ID_1 = 12345; -constexpr uint32_t SESSION_ID_2 = 12346; -constexpr uint32_t FRAME_LEN = 960; -constexpr uint32_t FRAME_LEN_2 = 820; -constexpr uint32_t NUM_TWO = 2; -constexpr int32_t TEST_VALUE_1 = 300; -constexpr int32_t TEST_VALUE_2 = 400; - -static std::string g_deviceClass = "file_io"; -static std::string g_deviceNetId = "LocalDevice"; - -static int32_t g_testValue1 = 0; -static int32_t g_testValue2 = 0; - -static int32_t TestRendererRenderFrame(const char *data, uint64_t len) -{ - float curGain = 0.0f; - float targetGain = 1.0f; - uint64_t frameLen = len / (SAMPLE_F32LE * STEREO); - float stepGain = (targetGain - curGain) / frameLen; - - const float *tempData = reinterpret_cast(data); - for (int32_t i = 0; i < frameLen; i++) { - const float left = tempData[NUM_TWO * i]; - const float right = tempData[NUM_TWO * i + 1]; - const float expectedValue = g_testValue1 * (curGain + i * stepGain) + g_testValue2 * (curGain + i * stepGain); - EXPECT_EQ(left, expectedValue); - EXPECT_EQ(right, expectedValue); - } - return 0; -} - -static void InitHpaeWriteDataOutSessionTest(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &dummySinkInfo) -{ - nodeInfo.nodeId = NODE_ID; - nodeInfo.frameLen = FRAME_LEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - - dummySinkInfo.frameLen = FRAME_LEN; - dummySinkInfo.samplingRate = SAMPLE_RATE_48000; - dummySinkInfo.channels = STEREO; - dummySinkInfo.format = SAMPLE_F32LE; - dummySinkInfo.deviceClass = g_deviceClass; - dummySinkInfo.deviceNetId = g_deviceNetId; -} - -class HpaeOutputClusterTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeOutputClusterTest::SetUp() -{} - -void HpaeOutputClusterTest::TearDown() -{} - -TEST_F(HpaeOutputClusterTest, constructHpaeOutputClusterNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = NODE_ID; - nodeInfo.frameLen = FRAME_LEN; - nodeInfo.sessionId = SESSION_ID_1; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - - std::shared_ptr hpaeoutputCluster = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeoutputCluster->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeoutputCluster->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeoutputCluster->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeoutputCluster->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeoutputCluster->GetBitWidth(), nodeInfo.format); - - std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); - hpaeoutputCluster->Connect(hpaeSinkInputNode); - EXPECT_EQ(hpaeSinkInputNode.use_count(), NUM_TWO); - EXPECT_EQ(hpaeoutputCluster->GetConverterNodeCount(), 1); - nodeInfo.frameLen = FRAME_LEN_2; - nodeInfo.sessionId = SESSION_ID_2; - nodeInfo.samplingRate = SAMPLE_RATE_44100; - std::shared_ptr hpaeSinkInputNode1 = std::make_shared(nodeInfo); - hpaeoutputCluster->Connect(hpaeSinkInputNode1); - EXPECT_EQ(hpaeSinkInputNode1.use_count(), NUM_TWO); - EXPECT_EQ(hpaeoutputCluster->GetConverterNodeCount(), 1); -} - -TEST_F(HpaeOutputClusterTest, testHpaeWriteDataOutSessionTest) -{ - HpaeNodeInfo nodeInfo; - HpaeSinkInfo dummySinkInfo; - InitHpaeWriteDataOutSessionTest(nodeInfo, dummySinkInfo); - std::shared_ptr hpaeOutputCluster = std::make_shared(nodeInfo); - nodeInfo.sessionId = SESSION_ID_1; - nodeInfo.streamType = STREAM_MUSIC; - std::shared_ptr musicSinkInputNode = std::make_shared(nodeInfo); - nodeInfo.sessionId = SESSION_ID_2; - nodeInfo.streamType = STREAM_RING; - std::shared_ptr ringSinkInputNode = std::make_shared(nodeInfo); - nodeInfo.sceneType = HPAE_SCENE_MUSIC; - std::shared_ptr muiscProcessCluster = - std::make_shared(nodeInfo, dummySinkInfo); - nodeInfo.sceneType = HPAE_SCENE_RING; - std::shared_ptr ringProcessCluster = - std::make_shared(nodeInfo, dummySinkInfo); - muiscProcessCluster->Connect(musicSinkInputNode); - ringProcessCluster->Connect(ringSinkInputNode); - hpaeOutputCluster->Connect(muiscProcessCluster); - hpaeOutputCluster->Connect(ringProcessCluster); - - EXPECT_EQ(ringProcessCluster->GetGainNodeCount(), 1); - EXPECT_EQ(muiscProcessCluster->GetGainNodeCount(), 1); - EXPECT_EQ(muiscProcessCluster->GetConverterNodeCount(), 1); - EXPECT_EQ(ringProcessCluster->GetConverterNodeCount(), 1); - EXPECT_EQ(hpaeOutputCluster->GetConverterNodeCount(), NUM_TWO); - EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), NUM_TWO); - - EXPECT_EQ(hpaeOutputCluster->GetInstance(g_deviceClass, g_deviceNetId), 0); - EXPECT_EQ(musicSinkInputNode.use_count(), NUM_TWO); - EXPECT_EQ(ringSinkInputNode.use_count(), NUM_TWO); - EXPECT_EQ(muiscProcessCluster.use_count(), 1); - g_testValue1 = TEST_VALUE_1; - std::shared_ptr writeFixedValueCb0 = - std::make_shared(SAMPLE_F32LE, g_testValue1); - musicSinkInputNode->RegisterWriteCallback(writeFixedValueCb0); - g_testValue2 = TEST_VALUE_2; - std::shared_ptr writeFixedValueCb1 = - std::make_shared(SAMPLE_F32LE, g_testValue2); - ringSinkInputNode->RegisterWriteCallback(writeFixedValueCb1); - hpaeOutputCluster->DoProcess(); - TestRendererRenderFrame(hpaeOutputCluster->GetFrameData(), - nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); - muiscProcessCluster->DisConnect(musicSinkInputNode); - EXPECT_EQ(musicSinkInputNode.use_count(), 1); - EXPECT_EQ(muiscProcessCluster->GetGainNodeCount(), 0); - ringProcessCluster->DisConnect(ringSinkInputNode); - EXPECT_EQ(ringSinkInputNode.use_count(), 1); - EXPECT_EQ(ringProcessCluster->GetGainNodeCount(), 0); - hpaeOutputCluster->DisConnect(muiscProcessCluster); - EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), 1); - hpaeOutputCluster->DisConnect(ringProcessCluster); - EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), 0); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_pcm_buffer_test.cpp b/services/audio_engine/test/unittest/node/hpae_pcm_buffer_test.cpp deleted file mode 100644 index 90be2886b1..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_pcm_buffer_test.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include "hpae_pcm_buffer.h" -#include "test_case_common.h" - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -class HpaePcmBufferTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaePcmBufferTest::SetUp() -{} - -void HpaePcmBufferTest::TearDown() -{} - -namespace { - -constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2; -constexpr uint32_t DEFAULT_FRAME_LEN = 480; -constexpr uint32_t DEFAULT_SAMPLE_RATE = 48000; -constexpr uint32_t DEFAULT_FRAME_NUM = 2; - - -TEST_F(HpaePcmBufferTest, constructHpaePcmBufferTest) -{ - PcmBufferInfo pcmBufferInfo; - pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT; - pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN; - pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE; - pcmBufferInfo.frames = DEFAULT_FRAME_NUM; - HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo); - EXPECT_EQ(reinterpret_cast(hpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); - EXPECT_EQ(hpaePcmBuffer.GetChannelCount(), pcmBufferInfo.ch); - EXPECT_EQ(hpaePcmBuffer.GetFrameLen(), pcmBufferInfo.frameLen); - EXPECT_EQ(hpaePcmBuffer.GetSampleRate(), pcmBufferInfo.rate); - EXPECT_EQ(hpaePcmBuffer.GetFrames(), pcmBufferInfo.frames); - EXPECT_EQ(hpaePcmBuffer.GetReadPos(), 0); - EXPECT_EQ(hpaePcmBuffer.GetWritePos(), 0); - EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), 0); - EXPECT_EQ(hpaePcmBuffer.IsMultiFrames(), false); - size_t addBytes = MEMORY_ALIGN_BYTE_NUM - - (pcmBufferInfo.frameLen * sizeof(float) * pcmBufferInfo.ch) % MEMORY_ALIGN_BYTE_NUM; - size_t frameByteSize = pcmBufferInfo.frameLen * sizeof(float) * pcmBufferInfo.ch + addBytes; - size_t bufferSize = frameByteSize * pcmBufferInfo.frames; - EXPECT_EQ(hpaePcmBuffer.Size(), bufferSize); -} - -TEST_F(HpaePcmBufferTest, assignHpaePcmBufferTest) -{ - PcmBufferInfo pcmBufferInfo; - pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT; - pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN; - pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE; - pcmBufferInfo.frames = DEFAULT_FRAME_NUM; - HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo); - EXPECT_EQ(reinterpret_cast(hpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); - size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch; - std::vector> testVec; - for (size_t i = 0; i < pcmBufferInfo.frames; i++) { - testVec.push_back(std::vector(tempFrameLen, 3.14f)); - } - hpaePcmBuffer = testVec; - for (size_t i = 0; i < pcmBufferInfo.frames; i++) { - for (size_t j = 0; j < tempFrameLen; j++) { - EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 3.14f) < TEST_VALUE_PRESION, true); - } - } -} - -TEST_F(HpaePcmBufferTest, calHpaePcmBufferTest) -{ - PcmBufferInfo pcmBufferInfo; - pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT; - pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN; - pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE; - pcmBufferInfo.frames = DEFAULT_FRAME_NUM; - HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo); - EXPECT_EQ(reinterpret_cast(hpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); - size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch; - for (size_t i = 0; i < pcmBufferInfo.frames; i++) { - for (size_t j = 0; j < tempFrameLen; j++) { - hpaePcmBuffer[i][j] = 3.14f; - } - } - std::vector> testVec; - for (size_t i = 0; i < pcmBufferInfo.frames; i++) { - testVec.push_back(std::vector(tempFrameLen, 3.14f)); - } - HpaePcmBuffer hpaePcmBuffer2(pcmBufferInfo); - EXPECT_EQ(reinterpret_cast(hpaePcmBuffer2.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); - hpaePcmBuffer2 = testVec; - hpaePcmBuffer += hpaePcmBuffer2; - for (size_t i = 0; i < pcmBufferInfo.frames; i++) { - for (size_t j = 0; j < tempFrameLen; j++) { - EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 6.28f) < TEST_VALUE_PRESION, true); - } - } - hpaePcmBuffer -= hpaePcmBuffer2; - for (size_t i = 0; i < pcmBufferInfo.frames; i++) { - for (size_t j = 0; j < tempFrameLen; j++) { - EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 3.14f) < TEST_VALUE_PRESION, true); - } - } - hpaePcmBuffer.Reset(); - for (size_t i = 0; i < pcmBufferInfo.frames; i++) { - for (size_t j = 0; j < tempFrameLen; j++) { - EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 0.0f) < TEST_VALUE_PRESION, true); - } - } -} - -TEST_F(HpaePcmBufferTest, calHpaePcmBufferMultiFrameTest) -{ - PcmBufferInfo pcmBufferInfo; - size_t inputFrames = 4; - pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT; - pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN; - pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE; - pcmBufferInfo.frames = inputFrames; - pcmBufferInfo.isMultiFrames = true; - HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo); - EXPECT_EQ(reinterpret_cast(hpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); - EXPECT_EQ(hpaePcmBuffer.IsMultiFrames(), true); - - size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch; - EXPECT_EQ(hpaePcmBuffer.GetFrameSample(), tempFrameLen); - for (size_t i = 0; i < inputFrames; i++) { - std::vector testVec(tempFrameLen, 3.14f); - hpaePcmBuffer = testVec; - } - std::cout << "tempFrameLen is: " << tempFrameLen << std::endl; - - EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), inputFrames); - EXPECT_EQ(hpaePcmBuffer.GetWritePos(), 0); - - std::vector testVec2(tempFrameLen, 0.0f); - EXPECT_EQ(hpaePcmBuffer.GetFrameSample(), tempFrameLen); - EXPECT_EQ(hpaePcmBuffer.PushFrameData(testVec2), false); - pcmBufferInfo.frames = 1; - pcmBufferInfo.isMultiFrames = false; - HpaePcmBuffer testHpaePcmBuffer(pcmBufferInfo); - EXPECT_EQ(reinterpret_cast(testHpaePcmBuffer.GetPcmDataBuffer()) % MEMORY_ALIGN_BYTE_NUM, 0); - EXPECT_EQ(hpaePcmBuffer.PushFrameData(testHpaePcmBuffer), false); - size_t curFrames = inputFrames; - std::cout << "inputFrames is: " << inputFrames << std::endl; - for (size_t i = 0; i < inputFrames; i++) { - EXPECT_EQ(hpaePcmBuffer.GetFrameData(testHpaePcmBuffer), true); - curFrames--; - EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), curFrames); - for (size_t j = 0; j < tempFrameLen; j++) { - EXPECT_EQ(testHpaePcmBuffer[0][j], 3.14f); - } - } - EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), 0); - EXPECT_EQ(hpaePcmBuffer.GetReadPos(), 0); - EXPECT_EQ(hpaePcmBuffer.GetFrameData(testHpaePcmBuffer), false); - EXPECT_EQ(hpaePcmBuffer.GetFrameData(testVec2), false); -} -} \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_pcm_process_test.cpp b/services/audio_engine/test/unittest/node/hpae_pcm_process_test.cpp deleted file mode 100644 index 609b189442..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_pcm_process_test.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include "hpae_pcm_process.h" -#include "test_case_common.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -constexpr uint32_t NUM_TWO = 2; - -class HpaePcmProcessTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaePcmProcessTest::SetUp() -{} - -void HpaePcmProcessTest::TearDown() -{} - -std::aligned_storage aligned_memory; - -TEST_F(HpaePcmProcessTest, constructHpaePcmProcess) -{ - std::vector testData(TEST_FREAME_LEN); - HpaePcmProcess hpaePcmProcess(testData.data(), TEST_FREAME_LEN); - EXPECT_EQ(hpaePcmProcess.Size(), TEST_FREAME_LEN); - for (int i = 0; i < TEST_FREAME_LEN; i++) { - testData[i] = i; - EXPECT_EQ(hpaePcmProcess[i], i); - const float testValue = hpaePcmProcess[i]; - EXPECT_EQ(hpaePcmProcess[i], testValue); - } - EXPECT_EQ(&testData[0], hpaePcmProcess.begin()); - EXPECT_EQ(&testData[TEST_FREAME_LEN - 1], hpaePcmProcess.end() - 1); -} - -TEST_F(HpaePcmProcessTest, assignHpaeProcessTest) -{ - std::vector testData(TEST_FREAME_LEN); - for (int i = 0; i < TEST_FREAME_LEN; i++) { - testData[i] = i; - } - std::vector testData2(TEST_SUB_FREAME_LEN); - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - testData2[i] = i; - } - std::vector tmpData(TEST_FREAME_LEN); - for (int i = 0; i < TEST_FREAME_LEN; i++) { - tmpData[i] = i; - } - HpaePcmProcess tmpPcmProcess(tmpData.data(), TEST_FREAME_LEN); - std::vector pcmData(TEST_SUB_FREAME_LEN); - std::vector pcmData2(TEST_FREAME_LEN); - HpaePcmProcess hpaePcmProcessTest(pcmData.data(), TEST_SUB_FREAME_LEN); - hpaePcmProcessTest = testData; - // errcase - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - EXPECT_EQ(hpaePcmProcessTest[i], 0); - } - hpaePcmProcessTest = testData2; - // normalcase - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - EXPECT_EQ(hpaePcmProcessTest[i], i); - } - HpaePcmProcess hpaePcmProcessTest2(pcmData2.data(), TEST_SUB_FREAME_LEN); - hpaePcmProcessTest2 = tmpPcmProcess; - // errcase - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - EXPECT_EQ(hpaePcmProcessTest2[i], 0); - } - hpaePcmProcessTest2 = hpaePcmProcessTest; - // normalcase - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - EXPECT_EQ(hpaePcmProcessTest2[i], i); - } -} - -TEST_F(HpaePcmProcessTest, calHpaeProcessTest) -{ - std::vector testData(TEST_SUB_FREAME_LEN); - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - testData[i] = i; - } - HpaePcmProcess hpaePcmProcessTest(testData.data(), TEST_SUB_FREAME_LEN); - std::vector testData2(TEST_SUB_FREAME_LEN, NUM_TWO); - HpaePcmProcess hpaePcmProcessTest2(testData2.data(), TEST_SUB_FREAME_LEN); - hpaePcmProcessTest2 += hpaePcmProcessTest; - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - EXPECT_EQ(hpaePcmProcessTest2[i], i + NUM_TWO); - } - hpaePcmProcessTest2 -= hpaePcmProcessTest; - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - EXPECT_EQ(hpaePcmProcessTest2[i], NUM_TWO); - } - hpaePcmProcessTest2 *= hpaePcmProcessTest; - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - EXPECT_EQ(hpaePcmProcessTest2[i], NUM_TWO * i); - } - hpaePcmProcessTest2.Reset(); - for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) { - EXPECT_EQ(hpaePcmProcessTest2[i], 0); - } -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_process_cluster_test.cpp b/services/audio_engine/test/unittest/node/hpae_process_cluster_test.cpp deleted file mode 100644 index ebaadaff0f..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_process_cluster_test.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include "hpae_process_cluster.h" -#include "test_case_common.h" -#include "audio_errors.h" -#include "hpae_sink_input_node.h" -#include "hpae_sink_output_node.h" - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -namespace OHOS { -namespace AudioStandard { - -const int32_t DEFAULT_VALUE_TWO = 2; -const uint32_t DEFAULT_SESSIONID_NUM_FIRST = 12345; -const uint32_t DEFAULT_SESSIONID_NUM_SECOND = 12346; -const uint32_t DEFAULT_NODEID_NUM_FIRST = 1243; -const size_t DEFAULT_FRAMELEN_FIRST = 820; -const size_t DEFAULT_FRAMELEN_SECOND = 960; -const int32_t DEFAULT_TEST_VALUE_FIRST = 100; -const int32_t DEFAULT_TEST_VALUE_SECOND = 200; - - -class HpaeProcessClusterTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeProcessClusterTest::SetUp() -{} - -void HpaeProcessClusterTest::TearDown() -{} - -TEST_F(HpaeProcessClusterTest, constructHpaeProcessClusterNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODEID_NUM_FIRST; - nodeInfo.frameLen = DEFAULT_FRAMELEN_SECOND; - nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_FIRST; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - - HpaeSinkInfo dummySinkInfo; - - std::shared_ptr hpaeProcessCluster = - std::make_shared(nodeInfo, dummySinkInfo); - EXPECT_EQ(hpaeProcessCluster->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeProcessCluster->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeProcessCluster->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeProcessCluster->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeProcessCluster->GetBitWidth(), nodeInfo.format); - HpaeNodeInfo &retNi = hpaeProcessCluster->GetNodeInfo(); - EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); - EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); - EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); - EXPECT_EQ(retNi.channels, nodeInfo.channels); - EXPECT_EQ(retNi.format, nodeInfo.format); - - std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); - hpaeProcessCluster->Connect(hpaeSinkInputNode); - EXPECT_EQ(hpaeSinkInputNode.use_count(), static_cast(DEFAULT_VALUE_TWO)); - EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 1); - EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), 1); - nodeInfo.frameLen = DEFAULT_FRAMELEN_FIRST; - nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_SECOND; - nodeInfo.samplingRate = SAMPLE_RATE_44100; - std::shared_ptr hpaeSinkInputNode1 = std::make_shared(nodeInfo); - hpaeProcessCluster->Connect(hpaeSinkInputNode1); - EXPECT_EQ(hpaeSinkInputNode1.use_count(), static_cast(DEFAULT_VALUE_TWO)); - EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), (DEFAULT_VALUE_TWO)); - EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), 2); -} -static int32_t g_testValue1 = 0; -static int32_t g_testValue2 = 0; -static int32_t TestRendererRenderFrame(const char *data, uint64_t len) -{ - float curGain = 0.0f; - float targetGain = 1.0f; - uint64_t frameLen = len / (SAMPLE_F32LE * STEREO); - float stepGain = (targetGain - curGain) / frameLen; - for (int32_t i = 0; i < frameLen; i++) { - EXPECT_EQ(*((float *)data + i * STEREO + 1), (g_testValue1 * (curGain + i * stepGain) + - g_testValue2 * (curGain + i * stepGain))); - EXPECT_EQ(*((float *)data + i * STEREO), (g_testValue1 * (curGain + i * stepGain) + - g_testValue2 * (curGain + i * stepGain))); - } - return 0; -} - -TEST_F(HpaeProcessClusterTest, testHpaeWriteDataProcessSessionTest) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODEID_NUM_FIRST; - nodeInfo.frameLen = DEFAULT_FRAMELEN_SECOND; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - HpaeSinkInfo dummySinkInfo; - dummySinkInfo.channels = STEREO; - dummySinkInfo.frameLen = DEFAULT_FRAMELEN_SECOND; - dummySinkInfo.format = SAMPLE_F32LE; - dummySinkInfo.samplingRate = SAMPLE_RATE_48000; - std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); - nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_FIRST; - std::shared_ptr hpaeSinkInputNode0 = std::make_shared(nodeInfo); - nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_SECOND; - std::shared_ptr hpaeSinkInputNode1 = std::make_shared(nodeInfo); - std::shared_ptr hpaeProcessCluster = - std::make_shared(nodeInfo, dummySinkInfo); - hpaeProcessCluster->Connect(hpaeSinkInputNode0); - hpaeProcessCluster->Connect(hpaeSinkInputNode1); - EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); - EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), DEFAULT_VALUE_TWO); - EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), DEFAULT_VALUE_TWO); - EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); - hpaeSinkOutputNode->Connect(hpaeProcessCluster); - std::string deviceClass = "file_io"; - std::string deviceNetId = "LocalDevice"; - EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 1); - EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0); - EXPECT_EQ(hpaeSinkInputNode0.use_count(), static_cast(DEFAULT_VALUE_TWO)); - EXPECT_EQ(hpaeSinkInputNode1.use_count(), static_cast(DEFAULT_VALUE_TWO)); - EXPECT_EQ(hpaeProcessCluster.use_count(), 1); - g_testValue1 = DEFAULT_TEST_VALUE_FIRST; - std::shared_ptr writeFixedValueCb0 = - std::make_shared(SAMPLE_F32LE, g_testValue1); - hpaeSinkInputNode0->RegisterWriteCallback(writeFixedValueCb0); - g_testValue2 = DEFAULT_TEST_VALUE_SECOND; - std::shared_ptr writeFixedValueCb1 = - std::make_shared(SAMPLE_F32LE, g_testValue2); - hpaeSinkInputNode1->RegisterWriteCallback(writeFixedValueCb1); - hpaeSinkOutputNode->DoProcess(); - TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), - nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); - hpaeSinkOutputNode->DisConnect(hpaeProcessCluster); - EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0); - EXPECT_EQ(hpaeProcessCluster.use_count(), 1); - hpaeProcessCluster->DisConnect(hpaeSinkInputNode0); - EXPECT_EQ(hpaeSinkInputNode0.use_count(), 1); - EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 1); - hpaeProcessCluster->DisConnect(hpaeSinkInputNode1); - EXPECT_EQ(hpaeSinkInputNode1.use_count(), 1); - EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 0); -} - -} //AudioStandard -} //OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_resample_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_resample_node_test.cpp deleted file mode 100644 index c5aec9a2b9..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_resample_node_test.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include -#include "hpae_sink_input_node.h" -#include "hpae_resample_node.h" -#include "hpae_sink_output_node.h" -#include -#include -#include -#include "test_case_common.h" -#include "audio_errors.h" - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -static constexpr uint32_t TEST_ID = 1243; -static constexpr uint32_t TEST_ID2 = 1246; -static constexpr uint32_t TEST_FRAMELEN1 = 960; -static constexpr uint32_t TEST_FRAMELEN2 = 640; -namespace { -class HpaeResampleNodeTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeResampleNodeTest::SetUp() -{} - -void HpaeResampleNodeTest::TearDown() -{} - -TEST_F(HpaeResampleNodeTest, constructHpaeResampleNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = TEST_ID; - nodeInfo.frameLen = TEST_FRAMELEN1; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - HpaeNodeInfo dstNodeInfo; - dstNodeInfo.nodeId = TEST_ID2; - dstNodeInfo.frameLen = TEST_FRAMELEN1; - dstNodeInfo.samplingRate = SAMPLE_RATE_44100; - dstNodeInfo.channels = CHANNEL_4; - dstNodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeResampleNode = std::make_shared(nodeInfo, dstNodeInfo); - EXPECT_EQ(hpaeResampleNode->GetSampleRate(), dstNodeInfo.samplingRate); - EXPECT_EQ(hpaeResampleNode->GetNodeId(), dstNodeInfo.nodeId); - EXPECT_EQ(hpaeResampleNode->GetFrameLen(), dstNodeInfo.frameLen); - EXPECT_EQ(hpaeResampleNode->GetChannelCount(), dstNodeInfo.channels); - EXPECT_EQ(hpaeResampleNode->GetBitWidth(), dstNodeInfo.format); - HpaeNodeInfo &retNi = hpaeResampleNode->GetNodeInfo(); - EXPECT_EQ(retNi.samplingRate, dstNodeInfo.samplingRate); - EXPECT_EQ(retNi.nodeId, dstNodeInfo.nodeId); - EXPECT_EQ(retNi.frameLen, dstNodeInfo.frameLen); - EXPECT_EQ(retNi.channels, dstNodeInfo.channels); - EXPECT_EQ(retNi.format, dstNodeInfo.format); -} - -TEST_F(HpaeResampleNodeTest, testHpaeReampleNodeProcess) -{ - HpaeNodeInfo srcNodeInfo; - srcNodeInfo.nodeId = TEST_ID; - srcNodeInfo.frameLen = TEST_FRAMELEN1; - srcNodeInfo.samplingRate = SAMPLE_RATE_48000; - srcNodeInfo.channels = STEREO; - srcNodeInfo.format = SAMPLE_S32LE; - std::shared_ptr hpaeSinkInputNode = std::make_shared(srcNodeInfo); - HpaeNodeInfo dstNodeInfo; - dstNodeInfo.nodeId = TEST_ID; - dstNodeInfo.frameLen = TEST_FRAMELEN2; - dstNodeInfo.samplingRate = SAMPLE_RATE_32000; - dstNodeInfo.channels = CHANNEL_4; - dstNodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeResampleNode = std::make_shared(srcNodeInfo, dstNodeInfo); -} -} // namespace diff --git a/services/audio_engine/test/unittest/node/hpae_sink_input_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_sink_input_node_test.cpp deleted file mode 100644 index 5338027799..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_sink_input_node_test.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include "hpae_sink_input_node.h" -#include "hpae_sink_output_node.h" -#include "test_case_common.h" -#include "audio_errors.h" -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -class HpaeSinkInputNodeTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeSinkInputNodeTest::SetUp() -{} - -void HpaeSinkInputNodeTest::TearDown() -{} - -namespace { -constexpr int32_t NORMAL_FRAME_LEN = 960; -constexpr int32_t NORMAL_ID = 1243; -TEST_F(HpaeSinkInputNodeTest, constructHpaeSinkInputNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = NORMAL_ID; - nodeInfo.frameLen = NORMAL_FRAME_LEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::unique_ptr hpaeSinkInputNode = std::make_unique(nodeInfo); - EXPECT_EQ(hpaeSinkInputNode->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeSinkInputNode->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeSinkInputNode->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeSinkInputNode->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeSinkInputNode->GetBitWidth(), nodeInfo.format); - HpaeNodeInfo &retNi = hpaeSinkInputNode->GetNodeInfo(); - EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); - EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); - EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); - EXPECT_EQ(retNi.channels, nodeInfo.channels); - EXPECT_EQ(retNi.format, nodeInfo.format); -} - -TEST_F(HpaeSinkInputNodeTest, testSinkInputOutputCase) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = NORMAL_ID; - nodeInfo.frameLen = NORMAL_FRAME_LEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); - { - std::shared_ptr> outputNode = hpaeSinkInputNode; - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1 + 1); // add 1 count because outputNode - std::shared_ptr hpaeNode = outputNode->GetSharedInstance(); - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1 + 1 + 1); // add 1 count because hpaeNode - EXPECT_EQ(hpaeNode->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeNode->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeNode->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeNode->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeNode->GetBitWidth(), nodeInfo.format); - } - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); - std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeSinkOutputNode.use_count(), 1); - hpaeSinkOutputNode->Connect(hpaeSinkInputNode); - EXPECT_EQ(hpaeSinkOutputNode.use_count(), 1); - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1 + 1); - OutputPort *outputPort = hpaeSinkInputNode->GetOutputPort(); - EXPECT_EQ(outputPort->GetInputNum(), 1); - hpaeSinkOutputNode->DisConnect(hpaeSinkInputNode); - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); - outputPort = hpaeSinkInputNode->GetOutputPort(); - EXPECT_EQ(outputPort->GetInputNum(), 0); -} - -TEST_F(HpaeSinkInputNodeTest, testWriteDataToSinkInputDataCase) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = NORMAL_ID; - nodeInfo.frameLen = NORMAL_FRAME_LEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - int32_t testNum = 10; - std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); - std::shared_ptr writeFixedDataCb = std::make_shared(SAMPLE_F32LE); - hpaeSinkInputNode->RegisterWriteCallback(writeFixedDataCb); - for (int32_t i = 0; i < testNum; i++) { - OutputPort *outputPort = hpaeSinkInputNode->GetOutputPort(); - HpaePcmBuffer* outPcmBuffer = outputPort->PullOutputData(); - float* outputPcmData = outPcmBuffer->GetPcmDataBuffer(); - for (int32_t j = 0; j < nodeInfo.frameLen; j++) { - for (int32_t k = 0; k < nodeInfo.channels; k++) { - float diff = outputPcmData[j * nodeInfo.channels + k] - i; - EXPECT_EQ(fabs(diff) < TEST_VALUE_PRESION, true); - } - } - } -} - -TEST_F(HpaeSinkInputNodeTest, testWriteDataToSinkInputAndSinkOutputDataCase) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = NORMAL_ID; - nodeInfo.frameLen = NORMAL_FRAME_LEN; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - int32_t testNum = 10; - std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); - std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); - std::shared_ptr writeFixedDataCb = std::make_shared(SAMPLE_F32LE); - hpaeSinkInputNode->RegisterWriteCallback(writeFixedDataCb); - hpaeSinkOutputNode->Connect(hpaeSinkInputNode); - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1 + 1); - for (int32_t i = 0; i < testNum; i++) { - OutputPort *outputPort = hpaeSinkInputNode->GetOutputPort(); - HpaePcmBuffer* outPcmBuffer = outputPort->PullOutputData(); - float* outputPcmData = outPcmBuffer->GetPcmDataBuffer(); - for (int32_t j = 0; j < nodeInfo.frameLen; j++) { - for (int32_t k = 0; k < nodeInfo.channels; k++) { - float diff = outputPcmData[j * nodeInfo.channels + k] - i; - EXPECT_EQ(fabs(diff) < TEST_VALUE_PRESION, true); - } - } - } - - hpaeSinkOutputNode->DisConnect(hpaeSinkInputNode); - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); -} -} \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_sink_output_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_sink_output_node_test.cpp deleted file mode 100644 index ceb968287f..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_sink_output_node_test.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include "hpae_sink_input_node.h" -#include "hpae_sink_output_node.h" -#include "test_case_common.h" -#include "audio_errors.h" -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; -namespace { -class HpaeSinkOutputNodeTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeSinkOutputNodeTest::SetUp() -{} - -void HpaeSinkOutputNodeTest::TearDown() -{} - -TEST_F(HpaeSinkOutputNodeTest, constructHpaeSinkOutputNode) -{ - size_t frameLen = 960; - uint32_t nodeId = 1243; - uint32_t sessionId = 10001; - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = nodeId; - nodeInfo.frameLen = frameLen; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - nodeInfo.sessionId = sessionId; - std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeSinkOutputNode->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeSinkOutputNode->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeSinkOutputNode->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeSinkOutputNode->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeSinkOutputNode->GetBitWidth(), nodeInfo.format); - EXPECT_EQ(hpaeSinkOutputNode->GetSessionId(), nodeInfo.sessionId); - - HpaeNodeInfo &retNi = hpaeSinkOutputNode->GetNodeInfo(); - EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); - EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); - EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); - EXPECT_EQ(retNi.channels, nodeInfo.channels); - EXPECT_EQ(retNi.format, nodeInfo.format); - EXPECT_EQ(retNi.sessionId, nodeInfo.sessionId); -} -static int32_t TestRendererRenderFrame(const char *data, uint64_t len) -{ - for (int32_t i = 0; i < len / SAMPLE_F32LE; i++) { - float diff = *((float *)data + i) - i; - EXPECT_EQ(diff, 0); - } - return 0; -} - -TEST_F(HpaeSinkOutputNodeTest, testHpaeSinkOutConnectNode) -{ - size_t frameLen = 960; - uint32_t nodeId = 1243; - size_t usedCount = 2; - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = nodeId; - nodeInfo.frameLen = frameLen; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeSinkOutputNode = std::make_shared(nodeInfo); - std::shared_ptr hpaeSinkInputNode = std::make_shared(nodeInfo); - hpaeSinkOutputNode->Connect(hpaeSinkInputNode); - std::shared_ptr writeIncDataCb = std::make_shared(SAMPLE_F32LE); - hpaeSinkInputNode->RegisterWriteCallback(writeIncDataCb); - std::string deviceClass = "file_io"; - std::string deviceNetId = "LocalDevice"; - EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0); - EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_NEW, true); - IAudioSinkAttr attr; - attr.adapterName = "file_io"; - attr.openMicSpeaker = 0; - attr.format = nodeInfo.format; - attr.sampleRate = nodeInfo.samplingRate; - attr.channel = nodeInfo.channels; - attr.volume = 0.0f; - attr.filePath = nullptr; - attr.deviceNetworkId = deviceNetId.c_str(); - attr.deviceType = 0; - attr.channelLayout = 0; - attr.audioStreamFlag = 0; - - EXPECT_EQ(hpaeSinkOutputNode->RenderSinkInit(attr), ERROR); - EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_PREPARED, true); - EXPECT_EQ(hpaeSinkOutputNode->RenderSinkStart(), ERROR); - EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_RUNNING, false); - EXPECT_EQ(hpaeSinkOutputNode->RenderSinkPause(), SUCCESS); - EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_PAUSED, true); - EXPECT_EQ(hpaeSinkOutputNode->RenderSinkStop(), SUCCESS); - EXPECT_EQ(hpaeSinkOutputNode->GetSinkState() == RENDERER_STOPPED, true); - hpaeSinkOutputNode->DoProcess(); - TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(), - nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format)); - EXPECT_EQ(hpaeSinkInputNode.use_count(), usedCount); - hpaeSinkOutputNode->DisConnect(hpaeSinkInputNode); - EXPECT_EQ(hpaeSinkInputNode.use_count(), 1); -} -} // namespace \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_source_input_cluster_test.cpp b/services/audio_engine/test/unittest/node/hpae_source_input_cluster_test.cpp deleted file mode 100644 index a9cc960284..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_source_input_cluster_test.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include "hpae_process_cluster.h" -#include "test_case_common.h" -#include "audio_errors.h" -#include "hpae_source_input_node.h" -#include "hpae_source_input_cluster.h" -#include "hpae_source_output_node.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -const uint32_t DEFAULT_FRAME_LENGTH = 960; - -class TestStatusCallback : public INodeCallback, public std::enable_shared_from_this { -public: - std::weak_ptr GetWeakPtr(); - virtual ~TestStatusCallback() = default; -}; - -std::weak_ptr TestStatusCallback::GetWeakPtr() -{ - return weak_from_this(); -} - - -class HpaeSourceInputClusterTest : public ::testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeSourceInputClusterTest::SetUp() -{} - -void HpaeSourceInputClusterTest::TearDown() -{} - -TEST_F(HpaeSourceInputClusterTest, constructHpaeSourceInputClusterNode) -{ - std::shared_ptr g_testStatuscallback = std::make_shared(); - HpaeNodeInfo nodeInfo; - nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - nodeInfo.statusCallback = g_testStatuscallback->GetWeakPtr(); - - std::shared_ptr hpaeSourceInputCluster = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeSourceInputCluster->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeSourceInputCluster->GetNodeId(), 0); - EXPECT_EQ(hpaeSourceInputCluster->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeSourceInputCluster->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeSourceInputCluster->GetBitWidth(), nodeInfo.format); - EXPECT_EQ(hpaeSourceInputCluster->GetSourceInputNodeUseCount(), 1); - std::shared_ptr hpaeSourceOutputNode = std::make_shared(nodeInfo); - hpaeSourceOutputNode->Connect(hpaeSourceInputCluster); - EXPECT_EQ(hpaeSourceInputCluster->GetSourceInputNodeUseCount(), 1 + 1); - EXPECT_EQ(hpaeSourceInputCluster->GetConverterNodeCount(), 0); - - nodeInfo.samplingRate = SAMPLE_RATE_16000; - std::shared_ptr hpaeSourceOutputNode1 = std::make_shared(nodeInfo); - hpaeSourceOutputNode1->ConnectWithInfo(hpaeSourceInputCluster, nodeInfo); - EXPECT_EQ(hpaeSourceInputCluster->GetSourceInputNodeUseCount(), 1 + 1 + 1); - EXPECT_EQ(hpaeSourceInputCluster->GetConverterNodeCount(), 1); -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_source_input_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_source_input_node_test.cpp deleted file mode 100644 index f91eec8b18..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_source_input_node_test.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include -#include "hpae_source_input_node.h" -#include "hpae_source_output_node.h" -#include "test_case_common.h" -#include "audio_errors.h" - -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -const uint32_t DEFAULT_FRAME_LENGTH = 960; -const uint32_t DEFAULT_NODE_ID = 1243; - -class HpaeSourceInputNodeTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeSourceInputNodeTest::SetUp() -{} - -void HpaeSourceInputNodeTest::TearDown() -{} - -TEST_F(HpaeSourceInputNodeTest, constructHpaeSourceInputNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODE_ID; - nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeSoruceInputNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeSoruceInputNode->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeSoruceInputNode->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeSoruceInputNode->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeSoruceInputNode->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeSoruceInputNode->GetBitWidth(), nodeInfo.format); - HpaeNodeInfo &retNi = hpaeSoruceInputNode->GetNodeInfo(); - EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); - EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); - EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); - EXPECT_EQ(retNi.channels, nodeInfo.channels); - EXPECT_EQ(retNi.format, nodeInfo.format); -} - -TEST_F(HpaeSourceInputNodeTest, testSourceInputOutputCase) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODE_ID; - nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeSoruceInputNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeSoruceInputNode.use_count(), 1); - { - std::shared_ptr> ouputNode = hpaeSoruceInputNode; - EXPECT_EQ(hpaeSoruceInputNode.use_count(), 2); // 2 for test - std::shared_ptr hpaeNode = ouputNode->GetSharedInstance(); - EXPECT_EQ(hpaeSoruceInputNode.use_count(), 3); // 3 for test - EXPECT_EQ(hpaeNode->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeNode->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeNode->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeNode->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeNode->GetBitWidth(), nodeInfo.format); - } - EXPECT_EQ(hpaeSoruceInputNode.use_count(), 1); - std::shared_ptr hpaeSourceOutputNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeSourceOutputNode.use_count(), 1); - hpaeSourceOutputNode->Connect(hpaeSoruceInputNode); - EXPECT_EQ(hpaeSourceOutputNode.use_count(), 1); - EXPECT_EQ(hpaeSoruceInputNode.use_count(), 2); // 2 for test - OutputPort *outputPort = hpaeSoruceInputNode->GetOutputPort(); - EXPECT_EQ(outputPort->GetInputNum(), 1); - hpaeSourceOutputNode->DisConnect(hpaeSoruceInputNode); - EXPECT_EQ(hpaeSoruceInputNode.use_count(), 1); - outputPort = hpaeSoruceInputNode->GetOutputPort(); - EXPECT_EQ(outputPort->GetInputNum(), 0); -} - -static int32_t TestCapturerSourceFrame(char *frame, uint64_t requestBytes, uint64_t *replyBytes) -{ - for (int32_t i = 0; i < requestBytes / SAMPLE_F32LE; i++) { - *(float *)(frame + i * sizeof(float)) = i; - } - *replyBytes = requestBytes; - return 0; -} - -TEST_F(HpaeSourceInputNodeTest, testWriteDataToSourceInputDataCase) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODE_ID; - nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeSoruceInputNode = std::make_shared(nodeInfo); - uint64_t requestBytes = nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format); - std::vector testData(requestBytes); - uint64_t replyBytes = 0; - std::string deviceClass = "file_io"; - std::string deviceNetId = "LocalDevice"; - SourceType sourceType = SOURCE_TYPE_MIC; - std::string sourceName = "mic"; - EXPECT_EQ(hpaeSoruceInputNode->GetCapturerSourceInstance(deviceClass, deviceNetId, sourceType, sourceName), 0); - IAudioSourceAttr attr; - attr.adapterName = NULL; - attr.openMicSpeaker = 0; - attr.format = AudioSampleFormat::INVALID_WIDTH; - attr.sampleRate = nodeInfo.samplingRate; - attr.channel = nodeInfo.channels; - attr.volume = 0.0f; - attr.bufferSize = 0; - attr.isBigEndian = false; - attr.filePath = NULL; - attr.deviceNetworkId = NULL; - attr.deviceType = 0; - attr.sourceType = 0; - attr.channelLayout = 0; - attr.audioStreamFlag = 0; - EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceInit(attr), ERROR); - EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceStart(), SUCCESS); - EXPECT_EQ(hpaeSoruceInputNode->GetSourceState() == CAPTURER_RUNNING, true); - EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceStop(), SUCCESS); - EXPECT_EQ(hpaeSoruceInputNode->GetSourceState() == CAPTURER_STOPPED, true); - TestCapturerSourceFrame(testData.data(), requestBytes, &replyBytes); - hpaeSoruceInputNode->WriteCapturerData(testData.data(), requestBytes); - OutputPort *outputPort = hpaeSoruceInputNode->GetOutputPort(); - HpaePcmBuffer* outPcmBuffer = outputPort->PullOutputData(); - float* outputPcmData = outPcmBuffer->GetPcmDataBuffer(); - for (int32_t j = 0; j < nodeInfo.frameLen; j++) { - for (int32_t k = 0; k < nodeInfo.channels; k++) { - float diff = outputPcmData[(j * nodeInfo.channels + k)] - (j * nodeInfo.channels + k); - EXPECT_EQ(fabs(diff) < TEST_VALUE_PRESION, true); - } - } -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/node/hpae_source_output_node_test.cpp b/services/audio_engine/test/unittest/node/hpae_source_output_node_test.cpp deleted file mode 100644 index 86b25a3dca..0000000000 --- a/services/audio_engine/test/unittest/node/hpae_source_output_node_test.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include -#include "hpae_source_input_node.h" -#include "hpae_source_output_node.h" -#include "test_case_common.h" -#include "audio_errors.h" -using namespace OHOS; -using namespace AudioStandard; -using namespace HPAE; - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -const uint32_t DEFAULT_FRAME_LENGTH = 960; -const uint32_t DEFAULT_NODE_ID = 1243; - -class HpaeSourceOutputNodeTest : public testing::Test { -public: - void SetUp(); - void TearDown(); -}; - -void HpaeSourceOutputNodeTest::SetUp() -{} - -void HpaeSourceOutputNodeTest::TearDown() -{} - -class TestReadDataCb : public IReadCallback, public std::enable_shared_from_this { -public: - int32_t OnReadData(std::vector &inputData, size_t requestDataLen) override; - int32_t OnReadData(size_t length) override - { - return SUCCESS; - } - TestReadDataCb() - {} - virtual ~TestReadDataCb() - {} -}; - -int32_t TestReadDataCb::OnReadData(std::vector &inputData, size_t requestDataLen) -{ - for (int32_t i = 0; i < requestDataLen / SAMPLE_F32LE; i++) { - EXPECT_EQ(*(float *)(inputData.data() + i * sizeof(float)), i); - } - return 0; -} - -static int32_t TestCapturerSourceFrame(char *frame, uint64_t requestBytes, uint64_t *replyBytes) -{ - for (int32_t i = 0; i < requestBytes / SAMPLE_F32LE; i++) { - *(float *)(frame + i * sizeof(float)) = i; - } - *replyBytes = requestBytes; - return 0; -} - -TEST_F(HpaeSourceOutputNodeTest, constructHpaeSourceOutputNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODE_ID; - nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeSoruceOutputNode = std::make_shared(nodeInfo); - EXPECT_EQ(hpaeSoruceOutputNode->GetSampleRate(), nodeInfo.samplingRate); - EXPECT_EQ(hpaeSoruceOutputNode->GetNodeId(), nodeInfo.nodeId); - EXPECT_EQ(hpaeSoruceOutputNode->GetFrameLen(), nodeInfo.frameLen); - EXPECT_EQ(hpaeSoruceOutputNode->GetChannelCount(), nodeInfo.channels); - EXPECT_EQ(hpaeSoruceOutputNode->GetBitWidth(), nodeInfo.format); - HpaeNodeInfo &retNi = hpaeSoruceOutputNode->GetNodeInfo(); - EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate); - EXPECT_EQ(retNi.nodeId, nodeInfo.nodeId); - EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen); - EXPECT_EQ(retNi.channels, nodeInfo.channels); - EXPECT_EQ(retNi.format, nodeInfo.format); -} - -TEST_F(HpaeSourceOutputNodeTest, connectHpaeSourceInputAndOutputNode) -{ - HpaeNodeInfo nodeInfo; - nodeInfo.nodeId = DEFAULT_NODE_ID; - nodeInfo.frameLen = DEFAULT_FRAME_LENGTH; - nodeInfo.samplingRate = SAMPLE_RATE_48000; - nodeInfo.channels = STEREO; - nodeInfo.format = SAMPLE_F32LE; - std::shared_ptr hpaeSoruceInputNode = std::make_shared(nodeInfo); - uint64_t requestBytes = nodeInfo.frameLen * nodeInfo.channels * GET_SIZE_FROM_FORMAT(nodeInfo.format); - std::vector testData(requestBytes); - uint64_t replyBytes = 0; - std::string deviceClass = "file_io"; - std::string deviceNetId = "LocalDevice"; - SourceType sourceType = SOURCE_TYPE_MIC; - std::string sourceName = "mic"; - EXPECT_EQ(hpaeSoruceInputNode->GetCapturerSourceInstance(deviceClass, deviceNetId, sourceType, sourceName), 0); - IAudioSourceAttr attr; - attr.adapterName = NULL; - attr.openMicSpeaker = 0; - attr.format = AudioSampleFormat::INVALID_WIDTH; - attr.sampleRate = nodeInfo.samplingRate; - attr.channel = nodeInfo.channels; - attr.volume = 0.0f; - attr.bufferSize = 0; - attr.isBigEndian = false; - attr.filePath = NULL; - attr.deviceNetworkId = NULL; - attr.deviceType = 0; - attr.sourceType = 0; - attr.channelLayout = 0; - attr.audioStreamFlag = 0; - EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceInit(attr), ERROR); - EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceStart(), 0); - EXPECT_EQ(hpaeSoruceInputNode->GetSourceState() == CAPTURER_RUNNING, true); - EXPECT_EQ(hpaeSoruceInputNode->CapturerSourceStop(), 0); - EXPECT_EQ(hpaeSoruceInputNode->GetSourceState() == CAPTURER_STOPPED, true); - TestCapturerSourceFrame(testData.data(), requestBytes, &replyBytes); - hpaeSoruceInputNode->WriteCapturerData(testData.data(), requestBytes); - std::shared_ptr hpaeSoruceOutputNode = std::make_shared(nodeInfo); - std::shared_ptr testReadDataCb = std::make_shared(); - hpaeSoruceOutputNode->RegisterReadCallback(testReadDataCb); - hpaeSoruceOutputNode->Connect(hpaeSoruceInputNode); - EXPECT_EQ(hpaeSoruceInputNode.use_count(), 2); // 2 for test - hpaeSoruceOutputNode->DoProcess(); - hpaeSoruceOutputNode->DisConnect(hpaeSoruceInputNode); - EXPECT_EQ(hpaeSoruceInputNode.use_count(), 1); -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_engine/test/unittest/resource/ohos_test.xml b/services/audio_engine/test/unittest/resource/ohos_test.xml deleted file mode 100644 index 21512912b0..0000000000 --- a/services/audio_engine/test/unittest/resource/ohos_test.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/services/audio_engine/utils/high_resolution_timer.h b/services/audio_engine/utils/high_resolution_timer.h deleted file mode 100644 index e7f55c0e58..0000000000 --- a/services/audio_engine/utils/high_resolution_timer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2025 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 HIGH_RRSOLUTION_TIMER_H -#define HIGH_RRSOLUTION_TIMER_H -#include -#include -#include -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -typedef std::chrono::high_resolution_clock::time_point TimePoint; -class HighResolutionTimer { -public: - HighResolutionTimer() : startTime_(), endTime_() - {} - - void Start() - { - startTime_ = std::chrono::high_resolution_clock::now(); - } - - void Stop() - { - endTime_ = std::chrono::high_resolution_clock::now(); - } - - template - auto Elapsed() const - { - return std::chrono::duration_cast(endTime_ - startTime_).count(); - } - -private: - std::chrono::high_resolution_clock::time_point startTime_; - std::chrono::high_resolution_clock::time_point endTime_; -}; - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS - -#endif // __HIGH_RRSOLUTION_TIMER_H__ \ No newline at end of file diff --git a/services/audio_engine/utils/hpae_format_convert.cpp b/services/audio_engine/utils/hpae_format_convert.cpp deleted file mode 100644 index 9ddcde6c03..0000000000 --- a/services/audio_engine/utils/hpae_format_convert.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2025 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 "securec.h" -#include "hpae_format_convert.h" - - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr float FLOAT_EPS = 1e-9f; -constexpr int OFFSET_BIT_24 = 3; -constexpr int BIT_DEPTH_TWO = 2; -constexpr int BIT_8 = 8; -constexpr int BIT_16 = 16; -constexpr int BIT_32 = 32; - -static uint32_t Read24Bit(const uint8_t *p) -{ - return ((uint32_t) p[BIT_DEPTH_TWO] << BIT_16) | ((uint32_t) p[1] << BIT_8) | ((uint32_t) p[0]); -} - -static void Write24Bit(uint8_t *p, uint32_t u) -{ - p[BIT_DEPTH_TWO] = (uint8_t) (u >> BIT_16); - p[1] = (uint8_t) (u >> BIT_8); - p[0] = (uint8_t) u; -} - -static void ConvertFrom16BitToFloat(unsigned n, const int16_t *a, float *b) -{ - for (; n > 0; n--) { - *(b++) = *(a++) * (1.0f / (1 << (BIT_16 - 1))); - } -} - -static void ConvertFrom24BitToFloat(unsigned n, const uint8_t *a, float *b) -{ - for (; n > 0; n--) { - int32_t s = Read24Bit(a) << BIT_8; - *b = s * (1.0f / (1U << (BIT_32 - 1))); - a += OFFSET_BIT_24; - b++; - } -} - -static void ConvertFrom32BitToFloat(unsigned n, const int32_t *a, float *b) -{ - for (; n > 0; n--) { - *(b++) = *(a++) * (1.0f / (1U << (BIT_32 - 1))); - } -} - -static float CapMax(float v) -{ - float value = v; - if (v > 1.0f) { - value = 1.0f - FLOAT_EPS; - } else if (v < -1.0f) { - value = -1.0f + FLOAT_EPS; - } - return value; -} - -static void ConvertFromFloatTo16Bit(unsigned n, const float *a, int16_t *b) -{ - for (; n > 0; n--) { - float tmp = *a++; - float v = CapMax(tmp) * (1 << (BIT_16 - 1)); - *(b++) = (int16_t) v; - } -} - -static void ConvertFromFloatTo24Bit(unsigned n, const float *a, uint8_t *b) -{ - for (; n > 0; n--) { - float tmp = *a++; - float v = CapMax(tmp) * (1U << (BIT_32 - 1)); - Write24Bit(b, ((int32_t) v) >> BIT_8); - b += OFFSET_BIT_24; - } -} - -static void ConvertFromFloatTo32Bit(unsigned n, const float *a, int32_t *b) -{ - for (; n > 0; n--) { - float tmp = *a++; - float v = CapMax(tmp) * (1U << (BIT_32 - 1)); - *(b++) = (int32_t) v; - } -} - -void ConvertToFloat(AudioSampleFormat format, unsigned n, void *src, float *dst) -{ - int32_t ret; - switch (format) { - case SAMPLE_S16LE: - ConvertFrom16BitToFloat(n, (const int16_t *)src, dst); - break; - case SAMPLE_S24LE: - ConvertFrom24BitToFloat(n, (const uint8_t *)src, dst); - break; - case SAMPLE_S32LE: - ConvertFrom32BitToFloat(n, (const int32_t *)src, dst); - break; - default: - ret = memcpy_s(dst, n * sizeof(float), (const float *)src, n * sizeof(float)); - if (ret != 0) { - float *srcFloat = (float *)src; - for (uint32_t i = 0; i < n; i++) { - dst[i] = srcFloat[i]; - } - } - break; - } -} - -void ConvertFromFloat(AudioSampleFormat format, unsigned n, float *src, void *dst) -{ - int32_t ret; - switch (format) { - case SAMPLE_S16LE: - ConvertFromFloatTo16Bit(n, src, (int16_t *)dst); - break; - case SAMPLE_S24LE: - ConvertFromFloatTo24Bit(n, src, (uint8_t *)dst); - break; - case SAMPLE_S32LE: - ConvertFromFloatTo32Bit(n, src, (int32_t *)dst); - break; - default: - ret = memcpy_s(dst, n * sizeof(float), src, n * sizeof(float)); - if (ret != 0) { - float *dstFloat = (float *)dst; - for (uint32_t i = 0; i < n; i++) { - dstFloat[i] = src[i]; - } - } - break; - } -} -}}} \ No newline at end of file diff --git a/services/audio_engine/utils/hpae_format_convert.h b/services/audio_engine/utils/hpae_format_convert.h deleted file mode 100644 index 3f9ad18fd9..0000000000 --- a/services/audio_engine/utils/hpae_format_convert.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_FORMAT_CONVERT_H -#define HPAE_FORMAT_CONVERT_H -#include "audio_stream_info.h" -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -void ConvertToFloat(AudioSampleFormat format, unsigned n, void *src, float *dst); - -void ConvertFromFloat(AudioSampleFormat format, unsigned n, float *src, void *dst); -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/audio_engine/utils/hpae_no_lock_queue.cpp b/services/audio_engine/utils/hpae_no_lock_queue.cpp deleted file mode 100644 index 4128a6b4ed..0000000000 --- a/services/audio_engine/utils/hpae_no_lock_queue.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include "audio_engine_log.h" -#include - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -constexpr uint32_t MAX_REQUEST_COUNT = std::numeric_limits::max() - 1; -constexpr uint32_t INVALID_REQUEST_ID = std::numeric_limits::max(); -constexpr uint64_t SHIFT_32_OFFSET = 32; -HpaeNoLockQueue::HpaeNoLockQueue(size_t maxRequestCount) -{ - if (maxRequestCount > MAX_REQUEST_COUNT) { - AUDIO_WARNING_LOG("[HpaeNoLockQueue] maxRequestCount %{public}zu is beyound Max Count", maxRequestCount); - maxRequestCount = MAX_REQUEST_COUNT; - } - if (maxRequestCount <= 0) { - AUDIO_WARNING_LOG("[HpaeNoLockQueue] maxRequestCount can not be zero"); - return; - } - InitQueue(maxRequestCount); -} - -HpaeNoLockQueue::~HpaeNoLockQueue() -{ - AUDIO_INFO_LOG("HpaeNoLockQueue destroyed"); -} -void HpaeNoLockQueue::InitQueue(size_t maxRequestCount) -{ - requestQueue_.resize(maxRequestCount); - tempRequestQueue_.reserve(maxRequestCount); - - freeRequestHeadIndex_ = 0; - for (size_t i = 0; i < maxRequestCount - 1; ++i) { - requestQueue_[i].nextRequestIndex = i + 1; - } - requestQueue_[maxRequestCount - 1].nextRequestIndex = INVALID_REQUEST_ID; - requestHeadIndex_ = INVALID_REQUEST_ID; - AUDIO_INFO_LOG("Init Queue size is %{public}zu", maxRequestCount); -} -void HpaeNoLockQueue::PushRequest(Request &&request) -{ - const uint64_t freeRequestIndex = GetRequestNode(&freeRequestHeadIndex_); - if (GetRequsetIndex(freeRequestIndex) == INVALID_REQUEST_ID) { - AUDIO_WARNING_LOG("reached Queue Capacity: drop this request"); - return; - } - requestQueue_[GetRequsetIndex(freeRequestIndex)].request = std::move(request); - PushRequestNode(&requestHeadIndex_, freeRequestIndex); -} - -void HpaeNoLockQueue::HandleRequests() -{ - const uint64_t oldRequestFlag = (GetRequsetFlag(requestHeadIndex_) << 32) + INVALID_REQUEST_ID; - const uint64_t oldRequestHeadindex = requestHeadIndex_.exchange(oldRequestFlag); - ProcessRequests(oldRequestHeadindex, true); -} - -void HpaeNoLockQueue::Reset() -{ - const uint64_t oldRequestFlag = (GetRequsetFlag(requestHeadIndex_) << 32) + INVALID_REQUEST_ID; - const uint64_t oldRequestHeadindex = requestHeadIndex_.exchange(oldRequestFlag); - ProcessRequests(oldRequestHeadindex, false); -} - -uint64_t HpaeNoLockQueue::IncRequsetIndex(uint64_t requestIndex) -{ - return requestIndex + (static_cast(1) << SHIFT_32_OFFSET); -} - -uint64_t HpaeNoLockQueue::GetRequsetIndex(uint64_t requestIndex) -{ - return requestIndex & std::numeric_limits::max(); -} - -uint64_t HpaeNoLockQueue::GetRequsetFlag(uint64_t requestFlag) -{ - return requestFlag >> SHIFT_32_OFFSET; -} - -void HpaeNoLockQueue::PushRequestNode(std::atomic *pRequestHeadIndex, uint64_t index) -{ - if (pRequestHeadIndex == nullptr) { - return; - } - uint64_t requestHeadIndex; - do { - requestHeadIndex = pRequestHeadIndex->load(); - requestQueue_[GetRequsetIndex(index)].nextRequestIndex = requestHeadIndex; - } while (!std::atomic_compare_exchange_strong(pRequestHeadIndex, &requestHeadIndex, index)); -} - -uint64_t HpaeNoLockQueue::GetRequestNode(std::atomic *pRequestHeadIndex) -{ - if (pRequestHeadIndex == nullptr) { - return std::numeric_limits::max(); - } - uint64_t requestHeadIndex; - uint64_t nextRequestIndex; - do { - requestHeadIndex = pRequestHeadIndex->load(); - if (GetRequsetIndex(requestHeadIndex) == INVALID_REQUEST_ID) { - return INVALID_REQUEST_ID; - } - nextRequestIndex = requestQueue_[GetRequsetIndex(requestHeadIndex)].nextRequestIndex; - } while (!std::atomic_compare_exchange_strong(pRequestHeadIndex, &requestHeadIndex, nextRequestIndex)); - return IncRequsetIndex(requestHeadIndex); -} - -void HpaeNoLockQueue::ProcessRequests(uint64_t requestHeadIndex, bool isProcess) -{ - uint64_t tempIndex = requestHeadIndex; - while (GetRequsetIndex(tempIndex) != INVALID_REQUEST_ID) { - RequestNode *tempRequest = &requestQueue_[GetRequsetIndex(tempIndex)]; - uint64_t nextRequest = tempRequest->nextRequestIndex; - tempRequestQueue_.emplace_back(std::move(tempRequest->request)); - tempRequest->request = nullptr; - PushRequestNode(&freeRequestHeadIndex_, tempIndex); - tempIndex = nextRequest; - } - - if (isProcess) { - for (std::vector::reverse_iterator requestIter = tempRequestQueue_.rbegin(); - requestIter != tempRequestQueue_.rend(); - ++requestIter) { - if (*requestIter != nullptr) { - (*requestIter)(); - } - } - } - tempRequestQueue_.clear(); -} - -bool HpaeNoLockQueue::IsFinishProcess() -{ - if (GetRequsetIndex(requestHeadIndex_) == INVALID_REQUEST_ID) { - return true; - } else { - return false; - } -} -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/utils/hpae_no_lock_queue.h b/services/audio_engine/utils/hpae_no_lock_queue.h deleted file mode 100644 index 47d45b86dc..0000000000 --- a/services/audio_engine/utils/hpae_no_lock_queue.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2025 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 NOLOCK_REQUEST_QUEUE_H -#define NOLOCK_REQUEST_QUEUE_H -#include -#include -#include -#include - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -const size_t CURRENT_REQUEST_COUNT = 1000; -using Request = std::function; -struct RequestNode { - RequestNode() = default; - RequestNode(const RequestNode &requestNode) : nextRequestIndex() - {} - RequestNode& operator=(const RequestNode& requestNode) = delete; - Request request; - std::atomic nextRequestIndex; -}; -class HpaeNoLockQueue { -public: - explicit HpaeNoLockQueue(size_t maxRequestCount); - ~HpaeNoLockQueue(); - - void PushRequest(Request &&request); - void HandleRequests(); - void Reset(); - bool IsFinishProcess(); - -private: - void InitQueue(size_t maxRequestCount); - uint64_t IncRequsetIndex(uint64_t requestIndex); - uint64_t GetRequsetIndex(uint64_t requestIndex); - uint64_t GetRequsetFlag(uint64_t requestFlag); - - void PushRequestNode(std::atomic *pRequestHeadIndex, uint64_t index); - uint64_t GetRequestNode(std::atomic *pRequestHeadIndex); - void ProcessRequests(uint64_t requestHeadIndex, bool isProcess); - -private: - std::atomic freeRequestHeadIndex_; - std::atomic requestHeadIndex_; - std::vector requestQueue_; - std::vector tempRequestQueue_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif diff --git a/services/audio_engine/utils/hpae_pcm_dumper.cpp b/services/audio_engine/utils/hpae_pcm_dumper.cpp deleted file mode 100644 index 04080e56a7..0000000000 --- a/services/audio_engine/utils/hpae_pcm_dumper.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include "hpae_pcm_dumper.h" -#include "audio_errors.h" -#include "audio_engine_log.h" -#include "audio_utils.h" -#include "securec.h" - -namespace OHOS { -namespace AudioStandard { -namespace HPAE { - -HpaePcmDumper::HpaePcmDumper(const std::string &filename) -{ - DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, filename, &dumpFile_); - filename_ = filename; -} - -HpaePcmDumper::~HpaePcmDumper() -{ - DumpFileUtil::CloseDumpFile(&dumpFile_); -} - -int32_t HpaePcmDumper::Dump(const int8_t *buffer, int32_t length) -{ - DumpFileUtil::WriteDumpFile(dumpFile_, (void *)(buffer), length); - return SUCCESS; -} - -bool HpaePcmDumper::CheckAndReopenHandlde() -{ - if (dumpFile_ != nullptr) { - return true; - } else { - DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, filename_, &dumpFile_); - AUDIO_DEBUG_LOG("Reopen dump file: %{public}s", filename_.c_str()); - } - return false; -} - -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_engine/utils/hpae_pcm_dumper.h b/services/audio_engine/utils/hpae_pcm_dumper.h deleted file mode 100644 index ca7d5e3732..0000000000 --- a/services/audio_engine/utils/hpae_pcm_dumper.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2025 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 HPAE_PCM_DUMPER_H -#define HPAE_PCM_DUMPER_H -#include -namespace OHOS { -namespace AudioStandard { -namespace HPAE { -class HpaePcmDumper { -public: - explicit HpaePcmDumper(const std::string &filename); - ~HpaePcmDumper(); - int32_t Dump(const int8_t *buffer, int32_t length); - bool CheckAndReopenHandlde(); -private: - FILE *dumpFile_ = nullptr; - std::string filename_; -}; -} // namespace HPAE -} // namespace AudioStandard -} // namespace OHOS -#endif \ No newline at end of file -- Gitee From 25175de77245445defb5acdd301451cd96c011d6 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 20:28:10 +0800 Subject: [PATCH 20/40] sync1 Signed-off-by: c00657214 --- .../include/pro_audio_service_adapter_impl.h | 20 +------------------ .../src/pro_audio_service_adapter_impl.cpp | 19 ------------------ .../pro_audio_service_adapter_unit_test.cpp | 4 ++-- .../native/audioutils/src/audio_utils.cpp | 2 +- .../sink/primary/audio_renderer_sink.cpp | 2 +- .../bluetooth/bluetooth_capturer_source.cpp | 2 +- .../source/primary/audio_capturer_source.cpp | 2 +- services/audio_policy/etc/audio_config.para | 2 +- 8 files changed, 8 insertions(+), 45 deletions(-) diff --git a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h index 486df97b7e..0f3d1b9963 100644 --- a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h +++ b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h @@ -20,12 +20,11 @@ #include #include "audio_service_adapter.h" #include "audio_module_info.h" -#include "audio_service_hpae_callback.h" namespace OHOS { namespace AudioStandard { -class ProAudioServiceAdapterImpl : public AudioServiceAdapter, public AudioServiceHpaeCallback, public std::enable_shared_from_this { +class ProAudioServiceAdapterImpl : public AudioServiceAdapter, public std::enable_shared_from_this { public: explicit ProAudioServiceAdapterImpl(std::unique_ptr &cb); ~ProAudioServiceAdapterImpl(); @@ -56,23 +55,6 @@ public: int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override; // callback Member functions - virtual void OnOpenAudioPortCb(int32_t portId) override; - virtual void OnCloseAudioPortCb(int32_t result) override; - virtual void OnSetSinkMuteCb(int32_t result) override; - virtual void OnSetSourceOutputMuteCb(int32_t result) override; - - virtual void OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) override; - virtual void OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) override; - virtual void OnGetAllSinksCb(int32_t result, std::vector &sinks) override; - - virtual void OnMoveSinkInputByIndexOrNameCb(int32_t result) override; - virtual void OnMoveSourceOutputByIndexOrNameCb(int32_t result) override; - - virtual void OnGetAudioEffectPropertyCbV3(int32_t result) override; - virtual void OnGetAudioEffectPropertyCb(int32_t result) override; - virtual void OnGetAudioEnhancePropertyCbV3(int32_t result) override; - virtual void OnGetAudioEnhancePropertyCb(int32_t result) override; - virtual void HandleSourceAudioStreamRemoved(uint32_t sessionId) override; private: std::mutex lock_; diff --git a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp index ce16d2dc30..abd631fa8e 100644 --- a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp +++ b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp @@ -32,10 +32,8 @@ #include "audio_utils.h" #include #include -#include "i_hpae_manager.h" using namespace std; -using namespace OHOS::AudioStandard::HPAE; namespace OHOS { namespace AudioStandard { static unique_ptr g_audioServiceAdapterCallback; @@ -51,7 +49,6 @@ ProAudioServiceAdapterImpl::ProAudioServiceAdapterImpl(unique_ptrRegisterSerivceCallback(shared_from_this()); return true; } @@ -66,7 +63,6 @@ int32_t ProAudioServiceAdapterImpl::OpenAudioPort(string audioPortName, const Au AUDIO_PRERELEASE_LOGI("OpenAudioPort enter."); Trace trace("OpenAudioPort"); lock_guard lock(lock_); - IHpaeManager::GetHpaeManager()->OpenAudioPort(audioModuleInfo); isFinishOpenAudioPort_ = false; std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { @@ -85,7 +81,6 @@ int32_t ProAudioServiceAdapterImpl::CloseAudioPort(int32_t audioHandleIndex, boo AUDIO_INFO_LOG("try to close module:%{public}d", audioHandleIndex); Trace trace("CloseAudioPort"); lock_guard lock(lock_); - IHpaeManager::GetHpaeManager()->CloseAudioPort(audioHandleIndex); AUDIO_INFO_LOG("CloseAudioPort: audioHandleIndex: [%{public}d] isSync [%{public}d]", audioHandleIndex, isSync); if (isSync) { isFinishCloseAudioPort_ = false; @@ -107,7 +102,6 @@ int32_t ProAudioServiceAdapterImpl::SuspendAudioDevice(string &audioPortName, bo lock_guard lock(lock_); Trace trace("SuspendAudioDevice"); AUDIO_INFO_LOG("SuspendAudioDevice [%{public}s] : [%{public}d]", audioPortName.c_str(), isSuspend); - IHpaeManager::GetHpaeManager()->SuspendAudioDevice(audioPortName, isSuspend); return SUCCESS; } @@ -116,7 +110,6 @@ bool ProAudioServiceAdapterImpl::SetSinkMute(const std::string &sinkName, bool i AUDIO_INFO_LOG("SetSinkMute: [%{public}s] : [%{public}d] isSync [%{public}d]", sinkName.c_str(), isMute, isSync); lock_guard lock(lock_); Trace trace("SetSinkMute:" + sinkName + "isMute:" + std::to_string(isMute)); - IHpaeManager::GetHpaeManager()->SetSinkMute(sinkName, isMute, isSync); if (isSync) { isFinishSetSinkMute_ = false; std::unique_lock waitLock(callbackMutex_); @@ -136,7 +129,6 @@ int32_t ProAudioServiceAdapterImpl::SetDefaultSink(string name) { lock_guard lock(lock_); Trace trace("SetDefaultSink:" + name); - IHpaeManager::GetHpaeManager()->SetDefaultSink(name); AUDIO_INFO_LOG("SetDefaultSink: [%{public}s]", name.c_str()); return SUCCESS; } @@ -145,7 +137,6 @@ int32_t ProAudioServiceAdapterImpl::SetDefaultSource(string name) { lock_guard lock(lock_); Trace trace("SetDefaultSource:" + name); - IHpaeManager::GetHpaeManager()->SetDefaultSource(name); AUDIO_INFO_LOG("SetDefaultSink: [%{public}s]", name.c_str()); return SUCCESS; } @@ -156,7 +147,6 @@ std::vector ProAudioServiceAdapterImpl::GetAllSinks() lock_guard lock(lock_); Trace trace("GetAllSinks"); isFinishGetAllSinks_ = false; - IHpaeManager::GetHpaeManager()->GetAllSinks(); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishGetAllSinks_; // will be true when got notified. @@ -200,7 +190,6 @@ int32_t ProAudioServiceAdapterImpl::MoveSinkInputByIndexOrName( Trace trace("MoveSinkInputByIndexOrName: " + std::to_string(sinkInputId) + " index:" + std::to_string(sinkIndex) + " sink:" + sinkName); isFinishMoveSinkInputByIndexOrName_ = false; - IHpaeManager::GetHpaeManager()->MoveSinkInputByIndexOrName(sinkInputId, sinkIndex, sinkName); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishMoveSinkInputByIndexOrName_; // will be true when got notified. @@ -225,7 +214,6 @@ int32_t ProAudioServiceAdapterImpl::MoveSourceOutputByIndexOrName( Trace trace("MoveSourceOutputByIndexOrName: " + std::to_string(sourceOutputId) + " index:" + std::to_string(sourceIndex) + " source:" + sourceName); isFinishMoveSourceOutputByIndexOrName_ = false; - IHpaeManager::GetHpaeManager()->MoveSourceOutputByIndexOrName(sourceOutputId, sourceIndex, sourceName); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishMoveSourceOutputByIndexOrName_; // will be true when got notified. @@ -244,7 +232,6 @@ int32_t ProAudioServiceAdapterImpl::SetSourceOutputMute(int32_t uid, bool setMut lock_guard lock(lock_); isFinishSetSourceOutputMute_ = false; SourceOutputMuteStreamSet_ = 0; - IHpaeManager::GetHpaeManager()->SetSourceOutputMute(uid, setMute); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishSetSourceOutputMute_; // will be true when got notified. @@ -262,7 +249,6 @@ std::vector ProAudioServiceAdapterImpl::GetAllSinkInputs() AUDIO_INFO_LOG("GetAllSinkInputs Enter"); lock_guard lock(lock_); isFinishGetAllSinkInputs_ = false; - IHpaeManager::GetHpaeManager()->GetAllSinkInputs(); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishGetAllSinkInputs_; // will be true when got notified. @@ -280,7 +266,6 @@ std::vector ProAudioServiceAdapterImpl::GetAllSourceOutputs() AUDIO_INFO_LOG("GetAllSourceOutputs"); lock_guard lock(lock_); isFinishGetAllSourceOutputs_ = false; - IHpaeManager::GetHpaeManager()->GetAllSourceOutputs(); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishGetAllSourceOutputs_; // will be true when got notified. @@ -303,7 +288,6 @@ int32_t ProAudioServiceAdapterImpl::GetAudioEffectProperty(AudioEffectPropertyAr AUDIO_INFO_LOG("GetAudioEffectProperty"); lock_guard lock(lock_); isFinishGetAudioEffectPropertyV3_ = false; - IHpaeManager::GetHpaeManager()->GetAudioEffectProperty(propertyArray); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishGetAudioEffectPropertyV3_; @@ -319,7 +303,6 @@ int32_t ProAudioServiceAdapterImpl::GetAudioEffectProperty(AudioEffectPropertyAr AUDIO_INFO_LOG("GetAudioEffectProperty"); lock_guard lock(lock_); isFinishGetAudioEffectProperty_ = false; - IHpaeManager::GetHpaeManager()->GetAudioEffectProperty(propertyArray); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishGetAudioEffectProperty_; @@ -336,7 +319,6 @@ int32_t ProAudioServiceAdapterImpl::GetAudioEnhanceProperty(AudioEffectPropertyA AUDIO_INFO_LOG("GetAudioEnhancePropertyV3"); lock_guard lock(lock_); isFinishGetAudioEnhancePropertyV3_ = false; - IHpaeManager::GetHpaeManager()->GetAudioEnhanceProperty(propertyArray); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishGetAudioEnhancePropertyV3_; @@ -353,7 +335,6 @@ int32_t ProAudioServiceAdapterImpl::GetAudioEnhanceProperty(AudioEnhanceProperty AUDIO_INFO_LOG("GetAudioEnhanceProperty"); lock_guard lock(lock_); isFinishGetAudioEnhanceProperty_ = false; - IHpaeManager::GetHpaeManager()->GetAudioEnhanceProperty(propertyArray); std::unique_lock waitLock(callbackMutex_); bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { return isFinishGetAudioEnhanceProperty_; diff --git a/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp b/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp index 9cfa538225..0d28dcd3a2 100644 --- a/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp +++ b/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp @@ -39,7 +39,7 @@ void ProAudioServiceAdapterUnitTest::TearDown(void) { impl_ = nullptr; if (engineFlag_ != 1) { - const char *key = "sys.audio.engine.proaudio.enable"; + const char *key = "const.multimedia.audio.proaudioEnable"; SetSysPara(key, engineFlag_); } } @@ -49,7 +49,7 @@ ProAudioServiceAdapterUnitTest::ProAudioServiceAdapterUnitTest() engineFlag_ = GetEngineFlag(); std::cout<<"engine flag:"<SetInputDevice(captureId, inputDevice, deviceName); diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 2f9bb95065..89bbb8e920 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -1771,7 +1771,7 @@ int32_t AudioCapturerSourceInner::SetAudioRouteInfoForEnhanceChain(const DeviceT AUDIO_WARNING_LOG("GetCaptureId failed"); } int32_t engineFlag = GetEngineFlag(); - if (engineFlag == 0) { + if (engineFlag != 1) { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); if (halName_ == "usb") { diff --git a/services/audio_policy/etc/audio_config.para b/services/audio_policy/etc/audio_config.para index 6a2342883c..998c038b05 100644 --- a/services/audio_policy/etc/audio_config.para +++ b/services/audio_policy/etc/audio_config.para @@ -16,4 +16,4 @@ const.multimedia.audio.volumestep = 1 persist.multimedia.audio.safevolume = 15 persist.multimedia.audio.safevolume.timeout = 1140 persist.multimedia.audio.firstboot = 1 -sys.audio.engine.proaudio.enable = 1 +const.multimedia.audio.proaudioEnable = 0 -- Gitee From c283d5f3087576cdcaf3b398b0dac4bb837f3e3e Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 20:29:22 +0800 Subject: [PATCH 21/40] sync2 Signed-off-by: c00657214 --- .../src/pro_audio_service_adapter_impl.cpp | 112 ------------------ 1 file changed, 112 deletions(-) diff --git a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp index abd631fa8e..68c0a45487 100644 --- a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp +++ b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp @@ -345,118 +345,6 @@ int32_t ProAudioServiceAdapterImpl::GetAudioEnhanceProperty(AudioEnhanceProperty return SUCCESS; } -void ProAudioServiceAdapterImpl::OnOpenAudioPortCb(int32_t portId) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnOpenAudioPortCb portId: %{public}d", portId); - isFinishOpenAudioPort_ = true; - AudioPortIndex_ = portId; - callbackCV_.notify_all(); -} -void ProAudioServiceAdapterImpl::OnCloseAudioPortCb(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnCloseAudioPortCb result: %{public}d", result); - isFinishCloseAudioPort_ = true; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnSetSinkMuteCb(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnSetSinkMuteCb result: %{public}d", result); - isFinishSetSinkMute_ = true; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnGetAllSinkInputsCb(int32_t result, std::vector &sinkInputs) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnGetAllSinkInputsCb result: %{public}d", result); - isFinishGetAllSinkInputs_ = true; - sinkInputs_ = sinkInputs; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnSetSourceOutputMuteCb(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnSetSourceOutputMuteCb result: %{public}d", result); - isFinishSetSourceOutputMute_ = true; - SourceOutputMuteStreamSet_ = result; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnGetAllSourceOutputsCb(int32_t result, std::vector &sourceOutputs) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnGetAllSourceOutputsCb result: %{public}d", result); - isFinishGetAllSourceOutputs_ = true; - sourceOutputs_ = sourceOutputs; - callbackCV_.notify_all(); -} -void ProAudioServiceAdapterImpl::OnGetAllSinksCb(int32_t result, std::vector &sinks) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnGetAllSinksCb result: %{public}d", result); - isFinishGetAllSinks_ = true; - sinks_ = sinks; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnMoveSinkInputByIndexOrNameCb(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnMoveSinkInputByIndexOrNameCb result: %{public}d", result); - isFinishMoveSinkInputByIndexOrName_ = true; - callbackCV_.notify_all(); -} -void ProAudioServiceAdapterImpl::OnMoveSourceOutputByIndexOrNameCb(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnMoveSourceOutputByIndexOrNameCb result: %{public}d", result); - isFinishMoveSourceOutputByIndexOrName_ = true; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnGetAudioEffectPropertyCbV3(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnGetAudioEffectPropertyCbV3 result: %{public}d", result); - isFinishGetAudioEffectPropertyV3_ = true; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnGetAudioEffectPropertyCb(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnGetAudioEffectPropertyCb result: %{public}d", result); - isFinishGetAudioEffectProperty_ = true; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnGetAudioEnhancePropertyCbV3(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnGetAudioEnhancePropertyCbV3 result: %{public}d", result); - isFinishGetAudioEnhancePropertyV3_ = true; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::OnGetAudioEnhancePropertyCb(int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - AUDIO_INFO_LOG("OnGetAudioEnhancePropertyCb result: %{public}d", result); - isFinishGetAudioEnhanceProperty_ = true; - callbackCV_.notify_all(); -} - -void ProAudioServiceAdapterImpl::HandleSourceAudioStreamRemoved(uint32_t sessionId) -{ - // todo: code check - CHECK_AND_RETURN_LOG(g_audioServiceAdapterCallback != nullptr, "g_audioServiceAdapterCallback is nullptr"); - g_audioServiceAdapterCallback->OnAudioStreamRemoved(sessionId); -} } // namespace AudioStandard } // namespace OHOS -- Gitee From 41acdfe86bb286b2aa96b2d35476f323115c1148 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 20:37:38 +0800 Subject: [PATCH 22/40] sync3 Signed-off-by: c00657214 --- frameworks/native/audioadapter/BUILD.gn | 2 - .../audioadapter/test/unittest/BUILD.gn | 68 ---- .../pro_audio_service_adapter_unit_test.h | 54 --- .../pro_audio_service_adapter_unit_test.cpp | 329 ------------------ services/audio_service/BUILD.gn | 24 -- test/BUILD.gn | 2 - 6 files changed, 479 deletions(-) delete mode 100644 frameworks/native/audioadapter/test/unittest/BUILD.gn delete mode 100644 frameworks/native/audioadapter/test/unittest/include/pro_audio_service_adapter_unit_test.h delete mode 100644 frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp diff --git a/frameworks/native/audioadapter/BUILD.gn b/frameworks/native/audioadapter/BUILD.gn index eeb477f9d2..1ee3cd2440 100644 --- a/frameworks/native/audioadapter/BUILD.gn +++ b/frameworks/native/audioadapter/BUILD.gn @@ -45,12 +45,10 @@ ohos_shared_library("pulse_audio_service_adapter") { "../hdiadapter/sink/common", "../hdiadapter/source/common", "../../../services/audio_policy/server/include/service/common", - "../../../services/audio_engine/manager/include", "../../../services/audio_service/common/include", ] deps = [ "../audioutils:audio_utils", - "../../../services/audio_engine:audio_engine_manager", "../../../services/audio_service:audio_common", ] diff --git a/frameworks/native/audioadapter/test/unittest/BUILD.gn b/frameworks/native/audioadapter/test/unittest/BUILD.gn deleted file mode 100644 index 1052901e77..0000000000 --- a/frameworks/native/audioadapter/test/unittest/BUILD.gn +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2025 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("//build/test.gni") -import("../../../../../config.gni") - -module_output_path = "multimedia_audio_framework/audio_engine" - -config("audio_engine_private_config") { - visibility = [ ":*" ] - - include_dirs = [ - "../../../audioutils/include", - "../../../../../interfaces/inner_api/native/audiocommon/include", - "../../../../../services/audio_service/server/include", - "../../../hdiadapter/common/include", - "../../../hdiadapter/sink/common", - "../../../hdiadapter/source/common", - "../../../../../services/audio_policy/server/include/service/common", - "../../../../../services/audio_engine/manager/include", - "../../../../../services/audio_service/common/include", - "./include", - "../../include" - ] -} - -############################################################################################# -ohos_unittest("pro_audio_service_adapter_unit_test") { - module_out_path = module_output_path - testonly = true - cflags = [ - "-Wall", - "-Werror", - "-fno-access-control", - ] - sources = [ - "src/pro_audio_service_adapter_unit_test.cpp", - ] - - configs = [ ":audio_engine_private_config" ] - - deps = [ - "../../../audioutils:audio_utils", - "../../../../../services/audio_engine:audio_engine_manager", - "../../:pulse_audio_service_adapter", - ] - - external_deps = [ - "c_utils:utils", - "googletest:gtest", - "hilog:libhilog", - "hisysevent:libhisysevent", - "ipc:ipc_single", - "safwk:system_ability_fwk", - "samgr:samgr_proxy", - ] -} \ No newline at end of file diff --git a/frameworks/native/audioadapter/test/unittest/include/pro_audio_service_adapter_unit_test.h b/frameworks/native/audioadapter/test/unittest/include/pro_audio_service_adapter_unit_test.h deleted file mode 100644 index 9570b10bce..0000000000 --- a/frameworks/native/audioadapter/test/unittest/include/pro_audio_service_adapter_unit_test.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2025 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 PRO_AUDIO_SERVICE_ADAPTER_UNIT_TEST_H -#define PRO_AUDIO_SERVICE_ADAPTER_UNIT_TEST_H -#include -#include "gtest/gtest.h" -#include "pro_audio_service_adapter_impl.h" -#include "audio_service_adapter.h" -namespace OHOS { -namespace AudioStandard { -class ProAudioServiceCallbackTest : public AudioServiceAdapterCallback { -public: - ProAudioServiceCallbackTest() {} - ~ProAudioServiceCallbackTest() { - AUDIO_WARNING_LOG("Destructor ProAudioServiceCallbackTest"); - } - void OnAudioStreamRemoved(const uint64_t sessionId) - {} - void OnSetVolumeDbCb() - {} -}; - -class ProAudioServiceAdapterUnitTest : public testing::Test { -public: - ProAudioServiceAdapterUnitTest(); - ~ProAudioServiceAdapterUnitTest(); - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(void); - void TearDown(void); - AudioModuleInfo InitSinkAudioModeInfo(); - AudioModuleInfo InitSourceAudioModeInfo(); -private: - void Init(); -protected: - std::shared_ptr impl_; - int32_t engineFlag_; -}; -} // namespace AudioStandard -} // namespace OHOS - -#endif \ No newline at end of file diff --git a/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp b/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp deleted file mode 100644 index 0d28dcd3a2..0000000000 --- a/frameworks/native/audioadapter/test/unittest/src/pro_audio_service_adapter_unit_test.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2025 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 -#include -#include "gtest/gtest.h" -#include "audio_errors.h" -#include "audio_utils.h" -#include "i_hpae_manager.h" -#include "pro_audio_service_adapter_unit_test.h" -using namespace testing::ext; -namespace OHOS { -namespace AudioStandard { -static std::string g_rootPath = "/data/data/.pulse_dir/"; - -void ProAudioServiceAdapterUnitTest::SetUpTestCase(void) -{} -void ProAudioServiceAdapterUnitTest::TearDownTestCase(void) -{} -void ProAudioServiceAdapterUnitTest::SetUp(void) -{ - std::unique_ptr cb = std::make_unique(); - impl_ = AudioServiceAdapter::CreateAudioAdapter(std::move(cb)); - impl_->Connect(); - HPAE::IHpaeManager::GetHpaeManager()->Init(); -} -void ProAudioServiceAdapterUnitTest::TearDown(void) -{ - impl_ = nullptr; - if (engineFlag_ != 1) { - const char *key = "const.multimedia.audio.proaudioEnable"; - SetSysPara(key, engineFlag_); - } -} - -ProAudioServiceAdapterUnitTest::ProAudioServiceAdapterUnitTest() -{ - engineFlag_ = GetEngineFlag(); - std::cout<<"engine flag:"<(DEVICE_TYPE_SPEAKER); - audioModuleInfo.deviceType = typeValue.str(); - return audioModuleInfo; -} - -AudioModuleInfo ProAudioServiceAdapterUnitTest::InitSourceAudioModeInfo() -{ - AudioModuleInfo audioModuleInfo; - audioModuleInfo.lib = "libmodule-hdi-source.z.so"; - audioModuleInfo.channels = "2"; - audioModuleInfo.rate = "48000"; - audioModuleInfo.name = "mic"; - audioModuleInfo.adapterName = "file_io"; - audioModuleInfo.className = "file_io"; - audioModuleInfo.bufferSize = "3840"; - audioModuleInfo.format = "s16le"; - audioModuleInfo.fixedLatency = "1"; - audioModuleInfo.offloadEnable = "0"; - audioModuleInfo.networkId = "LocalDevice"; - audioModuleInfo.fileName = g_rootPath + audioModuleInfo.adapterName + "_" + audioModuleInfo.rate + "_" + - audioModuleInfo.channels + "_" + audioModuleInfo.format + ".pcm"; - std::stringstream typeValue; - typeValue << static_cast(DEVICE_TYPE_SPEAKER); - audioModuleInfo.deviceType = typeValue.str(); - return audioModuleInfo; -} - -/** - * @tc.name: Pro_Audio_OpenAudioPort_001 - * @tc.desc: test open audio port sink - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_OpenAudioPort_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); -} - -/** - * @tc.name: Pro_Audio_OpenAudioPort_002 - * @tc.desc: test open audio port source - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_OpenAudioPort_002, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); -} - -/** - * @tc.name: Pro_Audio_CloseAudioPort_001 - * @tc.desc: test close audio port - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_CloseAudioPort_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->CloseAudioPort(portId); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_CloseAudioPort_002 - * @tc.desc: test close audio port source - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_CloseAudioPort_002, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->CloseAudioPort(portId); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SetDefaultSink_001 - * @tc.desc: test set default sink - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetDefaultSink_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SetDefaultSink(moduleInfo.name); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SetDefaultSource_001 - * @tc.desc: test set default source - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetDefaultSource_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SetDefaultSource(moduleInfo.name); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SetSinkMute_001 - * @tc.desc: test set sink mute - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetSinkMute_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SetSinkMute(moduleInfo.name, true); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SetSinkMute_002 - * @tc.desc: test set sink unmute - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetSinkMute_002, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SetSinkMute(moduleInfo.name, false); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SetSourceMute_001 - * @tc.desc: test set source mute - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetSourceMute_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SetSourceOutputMute(portId, true); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SetSourceMute_002 - * @tc.desc: test set source unmute - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SetSourceMute_002, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SetSourceOutputMute(portId, false); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SuspendedSink_001 - * @tc.desc: test suspended sink - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SuspendedSink_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SuspendAudioDevice(moduleInfo.name, true); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SuspendedSink_002 - * @tc.desc: test suspended sink - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SuspendedSink_002, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SuspendAudioDevice(moduleInfo.name, false); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SuspendedSource_001 - * @tc.desc: test suspended source - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SuspendedSource_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SuspendAudioDevice(moduleInfo.name, true); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_SuspendedSource_002 - * @tc.desc: test suspended source - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_SuspendedSource_002, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - int32_t ret = impl_->SuspendAudioDevice(moduleInfo.name, false); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: Pro_Audio_GetAllSinks_001 - * @tc.desc: test get all sinks - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_GetAllSinks_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSinkAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - std::vector sinkInputs = impl_->GetAllSinkInputs(); - EXPECT_EQ(0, sinkInputs.size()); -} - -/** - * @tc.name: Pro_Audio_GetAllSources_001 - * @tc.desc: test get all sources - * @tc.type: FUNC - */ -HWTEST_F(ProAudioServiceAdapterUnitTest, Pro_Audio_GetAllSources_001, TestSize.Level1) -{ - AudioModuleInfo moduleInfo = InitSourceAudioModeInfo(); - int32_t portId = impl_->OpenAudioPort(moduleInfo.lib, moduleInfo); - EXPECT_GE(0, portId); - std::vector sourceOutputs = impl_->GetAllSourceOutputs(); - EXPECT_EQ(0, sourceOutputs.size()); -} -} // namespace AudioStandard -} // namespace OHOS \ No newline at end of file diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index fdc17946c7..b6fb94d042 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -308,7 +308,6 @@ config("audio_service_config") { "client/include", "server/include", "server/include/config", - "../audio_engine/manager/include", "../audio_policy/server/include/service/common", "../audio_policy/common/definitions/include", "../audio_policy/server/include/service/common", @@ -325,21 +324,6 @@ config("audio_service_config") { "../../frameworks/native/playbackcapturer/include", "../../frameworks/native/hdiadapter_new/include", "../../frameworks/native/hdiadapter_new/include/common", - "../../frameworks/native/hdiadapter/common/include", - "../../frameworks/native/hdiadapter/sink/bluetooth", - "../../frameworks/native/hdiadapter/sink/common", - "../../frameworks/native/hdiadapter/sink/file", - "../../frameworks/native/hdiadapter/sink/fast", - "../../frameworks/native/hdiadapter/sink/remote", - "../../frameworks/native/hdiadapter/sink/remote_fast", - "../../frameworks/native/hdiadapter/sink/primary", - "../../frameworks/native/hdiadapter/sink/offload", - "../../frameworks/native/hdiadapter/source/bluetooth", - "../../frameworks/native/hdiadapter/source/common", - "../../frameworks/native/hdiadapter/source/fast", - "../../frameworks/native/hdiadapter/source/primary", - "../../frameworks/native/hdiadapter/source/remote", - "../../frameworks/native/hdiadapter/source/remote_fast", "../../interfaces/inner_api/native/audiocommon/include", "../../interfaces/inner_api/native/audiomanager/include", ] @@ -412,20 +396,12 @@ audio_ohos_library("audio_process_service") { deps = [ ":audio_common", - "../audio_engine:audio_engine_manager", "../../frameworks/native/audioeffect:audio_effect", "../../frameworks/native/audioqosmanager:audio_qosmanager", "../../frameworks/native/audioschedule:audio_schedule", "../../frameworks/native/audioutils:audio_utils", "../../frameworks/native/hdiadapter_new:hdiadapter_new", "../audio_policy:audio_foundation", - "../../frameworks/native/hdiadapter/sink:audio_renderer_sink", - "../../frameworks/native/hdiadapter/sink:bluetooth_renderer_sink", - "../../frameworks/native/hdiadapter/sink:fast_audio_renderer_sink", - "../../frameworks/native/hdiadapter/sink:renderer_sink_adapter", - "../../frameworks/native/hdiadapter/source:audio_capturer_source", - "../../frameworks/native/hdiadapter/source:capturer_source_adapter", - "../../frameworks/native/hdiadapter/source:fast_audio_capturer_source", ] external_deps = [ diff --git a/test/BUILD.gn b/test/BUILD.gn index 8a5fcb82af..c6f234560c 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -71,8 +71,6 @@ group("audio_unit_test") { "../frameworks/native/ohaudio/test/unittest/oh_audio_routing_manager_test:audio_oh_routing_manager_unit_test", "../frameworks/native/ohaudio/test/unittest/oh_audio_stream_builder_test:audio_oh_builder_unit_test", "../frameworks/native/toneplayer/test/unittest:audio_toneplayer_unit_test", - "../frameworks/native/audioadapter/test/unittest:pro_audio_service_adapter_unit_test", - "../services/audio_engine/test/unittest:audio_engine_unit_test", "../services/audio_policy/test:audio_policy_unittest_packages", "../services/audio_service/test/unittest:audio_balance_unit_test", "../services/audio_service/test/unittest:audio_dump_pcm_unit_test", -- Gitee From df0b06be0708035f47619b45ee205fbde74ecf68 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 20:42:42 +0800 Subject: [PATCH 23/40] sync4 Signed-off-by: c00657214 --- services/audio_service/BUILD.gn | 2 - .../server/include/audio_server.h | 2 - .../server/include/audio_server_hpae_dump.h | 66 ------ .../audio_service/server/src/audio_server.cpp | 9 +- .../server/src/audio_server_hpae_dump.cpp | 196 ------------------ .../server/src/renderer_in_server.cpp | 4 +- 6 files changed, 4 insertions(+), 275 deletions(-) delete mode 100644 services/audio_service/server/include/audio_server_hpae_dump.h delete mode 100644 services/audio_service/server/src/audio_server_hpae_dump.cpp diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index b6fb94d042..d2db3a8b8d 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -475,7 +475,6 @@ audio_ohos_library("audio_service") { "server/src/audio_server.cpp", "server/src/audio_server_asr.cpp", "server/src/audio_server_dump.cpp", - "server/src/audio_server_hpae_dump.cpp", "server/src/audio_server_effect.cpp", "server/src/config/audio_param_parser.cpp", ] @@ -485,7 +484,6 @@ audio_ohos_library("audio_service") { deps = [ ":audio_common", ":audio_process_service", - "../audio_engine:audio_engine_manager", "../../frameworks/native/audioeffect:audio_effect", "../../frameworks/native/audioinnercall:audio_inner_call", "../../frameworks/native/audioschedule:audio_schedule", diff --git a/services/audio_service/server/include/audio_server.h b/services/audio_service/server/include/audio_server.h index 7070b01be3..3c12e7d72e 100644 --- a/services/audio_service/server/include/audio_server.h +++ b/services/audio_service/server/include/audio_server.h @@ -29,7 +29,6 @@ #include "audio_manager_base.h" #include "audio_server_death_recipient.h" #include "audio_server_dump.h" -#include "audio_server_hpae_dump.h" #include "audio_system_manager.h" #include "audio_inner_call.h" #include "common/hdi_adapter_info.h" @@ -328,7 +327,6 @@ private: std::condition_variable isAudioPolicyReadyCv_; int32_t waitCreateStreamInServerCount_ = 0; - AudioServerHpaeDump hpaeDumpObj_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/include/audio_server_hpae_dump.h b/services/audio_service/server/include/audio_server_hpae_dump.h deleted file mode 100644 index 63d2854f72..0000000000 --- a/services/audio_service/server/include/audio_server_hpae_dump.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2025 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 AUDIO_SERVER_HPAE_DUMP_H -#define AUDIO_SERVER_HPAE_DUMP_H - -#include -#include -#include -#include -#include -#include "securec.h" -#include "nocopyable.h" -#include "audio_service_hpae_dump_callback.h" -#include "audio_service_log.h" -#include "audio_timer.h" -#include "audio_errors.h" - -namespace OHOS { -namespace AudioStandard { - -class AudioServerHpaeDump : public AudioTimer, public AudioServiceHpaeDumpCallback { -public: - DISALLOW_COPY_AND_MOVE(AudioServerHpaeDump); - - AudioServerHpaeDump(); - ~AudioServerHpaeDump(); - int32_t Initialize(); - void AudioDataDump(std::string &dumpString, std::queue &argQue); - void OnDumpSinkInfoCb(std::string &dumpStr, int32_t result) override; - void OnDumpSourceInfoCb(std::string &dumpStr, int32_t result) override; -private: - void InitDumpFuncMap(); - void HelpInfoDump(std::string &dumpString); - void ArgDataDump(std::string &dumpString, std::queue &argQue); - void ServerDataDump(std::string &dumpString); - void PlaybackSinkDump(std::string &dumpString); - void GetDeviceSinkInfo(std::string &dumpString, std::string deviceName); - void RecordSourceDump(std::string &dumpString); - void GetDeviceSourceInfo(std::string &dumpString, std::string deviceName); - - using DumpFunc = void(AudioServerHpaeDump::*)(std::string &dumpString); - std::map dumpFuncMap; - std::string dumpHpaeSinkInfo_; - std::string dumpHpaeSourceInfo_; - std::mutex lock_; - // for status operation wait and notify - std::mutex callbackMutex_; - std::condition_variable callbackCV_; - bool isFinishGetSinkInfo_ = false; - bool isFinishGetSourceInfo_ = false; -}; -} // namespace AudioStandard -} // namespace OHOS -#endif // AUDIO_SERVER_DUMP_H diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index af7735dbca..8806d54b94 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -57,7 +57,6 @@ #include "offline_stream_in_server.h" #include "audio_dump_pcm.h" #include "audio_info.h" -#include "i_hpae_manager.h" #define PA #ifdef PA @@ -311,10 +310,7 @@ int32_t AudioServer::Dump(int32_t fd, const std::vector &args) std::string dumpString; int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - int32_t res = hpaeDumpObj_.Initialize(); - CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR, - "Audio Service Hpae Dump Not Initialed"); - hpaeDumpObj_.AudioDataDump(dumpString, argQue); + AUDIO_DEBUG_LOG("HPAE dump"); } else { AudioServerDump dumpObj; int32_t res = dumpObj.Initialize(); @@ -358,8 +354,7 @@ void AudioServer::OnStart() AddSystemAbilityListener(RES_SCHED_SYS_ABILITY_ID); int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->Init(); - AUDIO_INFO_LOG("IHpaeManager Init\n"); + AUDIO_INFO_LOG("HPAE IHpaeManager Init\n"); } else { #ifdef PA int32_t ret = pthread_create(&m_paDaemonThread, nullptr, AudioServer::paDaemonThread, nullptr); diff --git a/services/audio_service/server/src/audio_server_hpae_dump.cpp b/services/audio_service/server/src/audio_server_hpae_dump.cpp deleted file mode 100644 index 3ada17b7e6..0000000000 --- a/services/audio_service/server/src/audio_server_hpae_dump.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2025 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 "AudioServerHpaeDump" -#endif - -#include "audio_server_hpae_dump.h" -#include "audio_utils.h" -#include "audio_errors.h" -#include "i_hpae_manager.h" - -using namespace std; -using namespace OHOS::AudioStandard::HPAE; -namespace OHOS { -namespace AudioStandard { -static const int32_t OPERATION_TIMEOUT_IN_MS = 1000; // 1000ms -static const std::string BT_SINK_NAME = "Bt_Speaker"; -static const std::string MCH_SINK_NAME = "MCH_Speaker"; -static const std::string OFFLOAD_SINK_NAME = "Offload_Speaker"; -static const std::string DP_SINK_NAME = "DP_speaker"; -static const std::string DEFAULT_SINK_NAME = "Speaker"; -static const std::string PRIMARY_SOURCE_NAME = "Built_in_mic"; -static const std::string BT_SOURCE_NAME = "Bt_Mic"; -static const std::string USB_SOURCE_NAME = "Usb_arm_mic"; -static const std::string PRIMARY_WAKEUP_SOURCE_NAME = "Built_in_wakeup"; - -AudioServerHpaeDump::AudioServerHpaeDump() -{ - AUDIO_DEBUG_LOG("AudioServerHpaeDump construct"); - InitDumpFuncMap(); -} - -AudioServerHpaeDump::~AudioServerHpaeDump() -{} - -void AudioServerHpaeDump::InitDumpFuncMap() -{ - dumpFuncMap[u"-h"] = &AudioServerHpaeDump::HelpInfoDump; - dumpFuncMap[u"-p"] = &AudioServerHpaeDump::PlaybackSinkDump; -} - -void AudioServerHpaeDump::AudioDataDump(std::string &dumpString, std::queue &argQue) -{ - ArgDataDump(dumpString, argQue); -} - -void AudioServerHpaeDump::ServerDataDump(string &dumpString) -{ - PlaybackSinkDump(dumpString); - RecordSourceDump(dumpString); -} - -void AudioServerHpaeDump::GetDeviceSinkInfo(std::string &dumpString, std::string deviceName) -{ - lock_guard lock(lock_); - AUDIO_INFO_LOG("GetDeviceSinkInfo %{public}s start", deviceName.c_str()); - isFinishGetSinkInfo_ = false; - IHpaeManager::GetHpaeManager()->DumpSinkInfo(deviceName); - std::unique_lock waitLock(callbackMutex_); - dumpHpaeSinkInfo_.clear(); - bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { - return isFinishGetSinkInfo_; // will be true when got notified. - }); - if (!stopWaiting) { - AUDIO_ERR_LOG("GetDeviceSinkInfo timeout"); - return; - } - AUDIO_INFO_LOG("GetDeviceSinkInfo %{public}s end", deviceName.c_str()); - dumpString += dumpHpaeSinkInfo_; -} - -void AudioServerHpaeDump::PlaybackSinkDump(std::string &dumpString) -{ - dumpString += "Hpae AudioServer Playback sink Dump:\n\n"; - dumpString += DEFAULT_SINK_NAME + ":\n"; - GetDeviceSinkInfo(dumpString, DEFAULT_SINK_NAME); - dumpString += OFFLOAD_SINK_NAME + ":\n"; - GetDeviceSinkInfo(dumpString, OFFLOAD_SINK_NAME); - dumpString += MCH_SINK_NAME + ":\n"; - GetDeviceSinkInfo(dumpString, MCH_SINK_NAME); - dumpString += BT_SINK_NAME + ":\n"; - GetDeviceSinkInfo(dumpString, BT_SINK_NAME); - dumpString += DP_SINK_NAME + ":\n"; - GetDeviceSinkInfo(dumpString, DP_SINK_NAME); -} - -void AudioServerHpaeDump::OnDumpSinkInfoCb(std::string &dumpStr, int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - dumpHpaeSinkInfo_ = dumpStr; - isFinishGetSinkInfo_ = true; - AUDIO_INFO_LOG( - "AudioServerHpaeDump OnDumpSinkInfoCb %{public}s, result %{public}d", dumpHpaeSinkInfo_.c_str(), result); - callbackCV_.notify_all(); -} - -void AudioServerHpaeDump::GetDeviceSourceInfo(std::string &dumpString, std::string deviceName) -{ - lock_guard lock(lock_); - AUDIO_INFO_LOG("GetDeviceSourceInfo %{public}s start", deviceName.c_str()); - isFinishGetSourceInfo_ = false; - IHpaeManager::GetHpaeManager()->DumpSourceInfo(deviceName); - std::unique_lock waitLock(callbackMutex_); - dumpHpaeSourceInfo_.clear(); - bool stopWaiting = callbackCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { - return isFinishGetSourceInfo_; // will be true when got notified. - }); - if (!stopWaiting) { - AUDIO_ERR_LOG("GetDeviceSourceInfo timeout"); - return; - } - AUDIO_INFO_LOG("GetDeviceSourceInfo %{public}s end", deviceName.c_str()); - dumpString += dumpHpaeSourceInfo_; -} - -void AudioServerHpaeDump::RecordSourceDump(std::string &dumpString) -{ - dumpString += "\nHpae AudioServer Record source Dump:\n\n"; - dumpString += PRIMARY_SOURCE_NAME + ":\n"; - GetDeviceSourceInfo(dumpString, PRIMARY_SOURCE_NAME); - dumpString += BT_SOURCE_NAME + ":\n"; - GetDeviceSourceInfo(dumpString, BT_SOURCE_NAME); - dumpString += USB_SOURCE_NAME + ":\n"; - GetDeviceSourceInfo(dumpString, USB_SOURCE_NAME); - dumpString += PRIMARY_WAKEUP_SOURCE_NAME + ":\n"; - GetDeviceSourceInfo(dumpString, PRIMARY_WAKEUP_SOURCE_NAME); -} - -void AudioServerHpaeDump::OnDumpSourceInfoCb(std::string &dumpStr, int32_t result) -{ - std::unique_lock waitLock(callbackMutex_); - dumpHpaeSourceInfo_ = dumpStr; - isFinishGetSourceInfo_ = true; - AUDIO_INFO_LOG( - "AudioServerHpaeDump OnDumpSourceInfoCb %{public}s, result %{public}d", dumpHpaeSourceInfo_.c_str(), result); - callbackCV_.notify_all(); -} - -void AudioServerHpaeDump::ArgDataDump(std::string &dumpString, std::queue &argQue) -{ - dumpString += "Hpae AudioServer Data Dump:\n\n"; - if (argQue.empty()) { - ServerDataDump(dumpString); - return; - } - while (!argQue.empty()) { - std::u16string para = argQue.front(); - if (para == u"-h") { - dumpString.clear(); - (this->*dumpFuncMap[para])(dumpString); - return; - } else if (para == u"-p") { - dumpString.clear(); - (this->*dumpFuncMap[para])(dumpString); - return; - } else if (dumpFuncMap.count(para) == 0) { - dumpString.clear(); - AppendFormat(dumpString, "Please input correct param:\n"); - HelpInfoDump(dumpString); - return; - } else { - (this->*dumpFuncMap[para])(dumpString); - } - argQue.pop(); - } -} - -void AudioServerHpaeDump::HelpInfoDump(string &dumpString) -{ - AppendFormat(dumpString, "usage:\n"); - AppendFormat(dumpString, " -h\t\t\t|help text for hidumper audio\n"); - AppendFormat(dumpString, " -p\t\t\t|dump hpae playback streams\n"); - AppendFormat(dumpString, " -r\t\t\t|dump hpae record streams\n"); -} - -int32_t AudioServerHpaeDump::Initialize() -{ - AUDIO_INFO_LOG("AudioServerHpaeDump Initialize"); - IHpaeManager::GetHpaeManager()->RegisterHpaeDumpCallback(this); - return SUCCESS; -} - -} // namespace AudioStandard -} // namespace OHOS diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index 819fe72a01..9ac847260d 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -39,7 +39,6 @@ #include "audio_volume_c.h" #include "core_service_handler.h" #include "audio_service_enum.h" -#include "i_hpae_manager.h" namespace OHOS { namespace AudioStandard { @@ -1645,7 +1644,8 @@ int32_t RendererInServer::SetStreamVolumeInfoForEnhanceChain() float streamVolume = audioServerBuffer_->GetStreamVolume(); int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->SetStreamVolumeInfo(sessionId, streamVolume); + AUDIO_DEBUG_LOG("HPAE SetStreamVolumeInfoForEnhanceChain"); + return SUCCESS; } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); -- Gitee From 826e880af7aa51acba82589277c2536ddc9c67d5 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 20:49:40 +0800 Subject: [PATCH 24/40] sync5 Signed-off-by: c00657214 --- .../server/src/audio_server_effect.cpp | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/services/audio_service/server/src/audio_server_effect.cpp b/services/audio_service/server/src/audio_server_effect.cpp index c621161734..98ad753b9a 100644 --- a/services/audio_service/server/src/audio_server_effect.cpp +++ b/services/audio_service/server/src/audio_server_effect.cpp @@ -22,7 +22,6 @@ #include "audio_enhance_chain_manager.h" #include "common/hdi_adapter_info.h" #include "manager/hdi_adapter_manager.h" -#include "i_hpae_manager.h" #include "audio_utils.h" namespace OHOS { @@ -34,7 +33,7 @@ void AudioServer::RecognizeAudioEffectType(const std::string &mainkey, const std { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->UpdateParamExtra(mainkey, subkey, extraSceneType); + AUDIO_DEBUG_LOG("HPAE RecognizeAudioEffectType"); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); if (audioEffectChainManager == nullptr) { @@ -42,11 +41,7 @@ void AudioServer::RecognizeAudioEffectType(const std::string &mainkey, const std return; } audioEffectChainManager->UpdateParamExtra(mainkey, subkey, extraSceneType); - } - - if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->UpdateExtraSceneType(mainkey, subkey, extraSceneType); - } else { + AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_LOG(audioEnhanceChainManager != nullptr, "audioEnhanceChainManager is nullptr"); return audioEnhanceChainManager->UpdateExtraSceneType(mainkey, subkey, extraSceneType); @@ -62,11 +57,7 @@ bool AudioServer::CreateEffectChainManager(std::vector &effectChain } int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->InitAudioEffectChainManager(effectChains, effectParam, - audioEffectServer_->GetEffectEntries()); - HPAE::IHpaeManager::GetHpaeManager()->InitAudioEnhanceChainManager(effectChains, enhanceParam, - audioEffectServer_->GetEffectEntries()); - AUDIO_INFO_LOG("AudioEffectChainManager Init"); + AUDIO_INFO_LOG("HPAE AudioEffectChainManager Init"); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); audioEffectChainManager->InitAudioEffectChainManager(effectChains, effectParam, @@ -88,7 +79,7 @@ void AudioServer::SetOutputDeviceSink(int32_t deviceType, std::string &sinkName) int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->SetOutputDeviceSink(deviceType, sinkName); + AUDIO_DEBUG_LOG("HPAE SetOutputDeviceSink"); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); audioEffectChainManager->SetOutputDeviceSink(deviceType, sinkName); @@ -103,7 +94,8 @@ int32_t AudioServer::UpdateSpatializationState(AudioSpatializationState spatiali int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->UpdateSpatializationState(spatializationState); + AUDIO_DEBUG_LOG("HPAE UpdateSpatializationState"); + return SUCCESS; } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); if (audioEffectChainManager == nullptr) { @@ -121,7 +113,8 @@ int32_t AudioServer::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDevic int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->UpdateSpatialDeviceType(spatialDeviceType); + AUDIO_DEBUG_LOG("HPAE UpdateSpatialDeviceType"); + return SUCCESS; } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -136,7 +129,7 @@ int32_t AudioServer::SetSystemVolumeToEffect(const AudioStreamType streamType, f int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->SetEffectSystemVolume(systemVolumeType, volume); + AUDIO_DEBUG_LOG("HPAE SetSystemVolumeToEffect"); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -157,7 +150,7 @@ int32_t AudioServer::SetSpatializationSceneType(AudioSpatializationSceneType spa int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->SetSpatializationSceneType(spatializationSceneType); + AUDIO_DEBUG_LOG("HPAE SetSpatializationSceneType"); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -189,7 +182,7 @@ void AudioServer::LoadHdiEffectModel() int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->InitHdiState(); + AUDIO_DEBUG_LOG("HPAE LoadHdiEffectModel"); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); @@ -248,7 +241,8 @@ int32_t AudioServer::SetAudioEffectProperty(const AudioEffectPropertyArray &prop int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEffectProperty(propertyArray); + AUDIO_DEBUG_LOG("HPAE SetAudioEffectProperty"); + return SUCCESS; } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -274,7 +268,8 @@ int32_t AudioServer::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &pr "Set Audio Enhance Property refused for %{public}d", callingUid); int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); + AUDIO_DEBUG_LOG("HPAE SetAudioEnhanceProperty"); + return SUCCESS; } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); @@ -297,7 +292,8 @@ int32_t AudioServer::SetAudioEffectChainProperty(const AudioEffectPropertyArrayV { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEffectProperty(propertyArray); + AUDIO_DEBUG_LOG("HPAE SetAudioEffectProperty"); + return SUCCESS; } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); @@ -310,7 +306,8 @@ int32_t AudioServer::SetAudioEnhanceChainProperty(const AudioEffectPropertyArray { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->SetAudioEnhanceProperty(propertyArray, deviceType); + AUDIO_DEBUG_LOG("HPAE SetAudioEnhanceProperty"); + return SUCCESS; } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); @@ -340,7 +337,7 @@ void AudioServer::UpdateEffectBtOffloadSupported(const bool &isSupported) int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->UpdateEffectBtOffloadSupported(isSupported); + AUDIO_DEBUG_LOG("HPAE UpdateEffectBtOffloadSupported"); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); @@ -355,7 +352,7 @@ void AudioServer::SetRotationToEffect(const uint32_t rotate) int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - HPAE::IHpaeManager::GetHpaeManager()->EffectRotationUpdate(rotate); + AUDIO_DEBUG_LOG("HPAE EffectRotationUpdate"); } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "audioEffectChainManager is nullptr"); @@ -383,7 +380,8 @@ int32_t AudioServer::SetVolumeInfoForEnhanceChain(const AudioStreamType &streamT int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->SetVolumeInfo(volumeType, systemVol); + AUDIO_DEBUG_LOG("HPAE SetVolumeInfo"); + return SUCCESS; } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); @@ -395,7 +393,8 @@ int32_t AudioServer::SetMicrophoneMuteForEnhanceChain(const bool &isMute) { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - return HPAE::IHpaeManager::GetHpaeManager()->SetMicrophoneMuteInfo(isMute); + AUDIO_DEBUG_LOG("HPAE SetMicrophoneMuteInfo"); + return SUCCESS; } else { AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr"); -- Gitee From 7d2ca33feb6592d845787c61415d35d2c3fd9037 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 20:54:20 +0800 Subject: [PATCH 25/40] sync6 Signed-off-by: c00657214 --- .../server/src/audio_server_effect.cpp | 5 ++- .../server/src/hpae_capturer_stream_impl.cpp | 34 ++----------------- 2 files changed, 5 insertions(+), 34 deletions(-) diff --git a/services/audio_service/server/src/audio_server_effect.cpp b/services/audio_service/server/src/audio_server_effect.cpp index 98ad753b9a..2e5f5592b4 100644 --- a/services/audio_service/server/src/audio_server_effect.cpp +++ b/services/audio_service/server/src/audio_server_effect.cpp @@ -136,9 +136,7 @@ int32_t AudioServer::SetSystemVolumeToEffect(const AudioStreamType streamType, f AUDIO_INFO_LOG("streamType: %{public}d, systemVolume: %{public}f", streamType, volume); audioEffectChainManager->SetEffectSystemVolume(systemVolumeType, volume); - std::shared_ptr audioEffectVolume = AudioEffectVolume::GetInstance(); - CHECK_AND_RETURN_RET_LOG(audioEffectVolume != nullptr, ERROR, "null audioEffectVolume"); - audioEffectChainManager->EffectVolumeUpdate(audioEffectVolume); + audioEffectChainManager->EffectVolumeUpdate(); } return SUCCESS; } @@ -151,6 +149,7 @@ int32_t AudioServer::SetSpatializationSceneType(AudioSpatializationSceneType spa int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { AUDIO_DEBUG_LOG("HPAE SetSpatializationSceneType"); + return SUCCESS; } else { AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERROR, "audioEffectChainManager is nullptr"); diff --git a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp index cf5504dd9b..c9105c26d2 100644 --- a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp @@ -24,14 +24,15 @@ #include "policy_handler.h" #include #include -#include "i_hpae_manager.h" -using namespace OHOS::AudioStandard::HPAE; + namespace OHOS { namespace AudioStandard { static SafeMap> paCapturerMap_; const int32_t MIN_BUFFER_SIZE = 2; const int32_t FRAME_LEN_10MS = 2; +#define GET_SIZE_FROM_FORMAT(format) ((format) != SAMPLE_F32LE ? ((format) + 1) : (4)) + HpaeCapturerStreamImpl::HpaeCapturerStreamImpl(AudioProcessConfig processConfig) { processConfig_ = processConfig; @@ -54,28 +55,12 @@ int32_t HpaeCapturerStreamImpl::InitParams(const std::string &deviceName) { paCapturerMap_.Insert(this, weak_from_this()); - HpaeStreamInfo streamInfo; - streamInfo.channels = processConfig_.streamInfo.channels; - streamInfo.samplingRate = processConfig_.streamInfo.samplingRate; - streamInfo.format = processConfig_.streamInfo.format; - streamInfo.frameLen = spanSizeInFrame_; - streamInfo.sessionId = processConfig_.originalSessionId; - streamInfo.streamType = processConfig_.streamType; - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_RECORD; - streamInfo.sourceType = processConfig_.capturerInfo.sourceType; - streamInfo.uid = processConfig_.appInfo.appUid; - streamInfo.pid = processConfig_.appInfo.appPid; - streamInfo.deviceName = deviceName; - int32_t ret = IHpaeManager::GetHpaeManager()->CreateStream(streamInfo); - CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR_INVALID_PARAM, "CreateStream is error"); return SUCCESS; } int32_t HpaeCapturerStreamImpl::Start() { AUDIO_INFO_LOG("Start"); - int32_t ret = IHpaeManager::GetHpaeManager()->Start(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); - CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_INVALID_PARAM, "Start failed"); state_ = RUNNING; return SUCCESS; } @@ -83,8 +68,6 @@ int32_t HpaeCapturerStreamImpl::Start() int32_t HpaeCapturerStreamImpl::Pause(bool isStandby) { AUDIO_INFO_LOG("Pause"); - int32_t ret = IHpaeManager::GetHpaeManager()->Pause(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "Pause error"); return SUCCESS; } @@ -111,16 +94,12 @@ int32_t HpaeCapturerStreamImpl::GetLatency(uint64_t &latency) int32_t HpaeCapturerStreamImpl::Flush() { AUDIO_INFO_LOG("Flush"); - int32_t ret = IHpaeManager::GetHpaeManager()->Flush(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "Flush error"); return SUCCESS; } int32_t HpaeCapturerStreamImpl::Stop() { AUDIO_INFO_LOG("Stop"); - int32_t ret = IHpaeManager::GetHpaeManager()->Stop(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "Stop failed"); state_ = STOPPING; return SUCCESS; } @@ -129,12 +108,8 @@ int32_t HpaeCapturerStreamImpl::Release() { if (state_ == RUNNING) { AUDIO_ERR_LOG("%{public}u Release state_ is RUNNING", processConfig_.originalSessionId); - IHpaeManager::GetHpaeManager()->Stop(HPAE_STREAM_CLASS_TYPE_RECORD, processConfig_.originalSessionId); } AUDIO_INFO_LOG("Release Enter"); - int32_t ret = IHpaeManager::GetHpaeManager()->Release(HPAE_STREAM_CLASS_TYPE_RECORD, - processConfig_.originalSessionId); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "Release is error"); state_ = RELEASED; // to do check closeaudioport if (processConfig_.capturerInfo.sourceType == SOURCE_TYPE_WAKEUP) { @@ -146,15 +121,12 @@ int32_t HpaeCapturerStreamImpl::Release() // to do callback data report void HpaeCapturerStreamImpl::RegisterStatusCallback(const std::weak_ptr &callback) { - IHpaeManager::GetHpaeManager()->RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_RECORD, - processConfig_.originalSessionId, callback); statusCallback_ = callback; } void HpaeCapturerStreamImpl::RegisterReadCallback(const std::weak_ptr &callback) { AUDIO_INFO_LOG("RegisterReadCallback start"); - IHpaeManager::GetHpaeManager()->RegisterReadCallback(processConfig_.originalSessionId, callback); readCallback_ = callback; } -- Gitee From 9cd8216bfba195ac6a10a4bba63fb7f80e7bb53a Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 21:00:21 +0800 Subject: [PATCH 26/40] sync7 Signed-off-by: c00657214 --- .../server/src/hpae_renderer_stream_impl.cpp | 106 +++--------------- 1 file changed, 16 insertions(+), 90 deletions(-) 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 53a0835aa3..c8c6e9f7e8 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -21,23 +21,35 @@ #endif #include "hpae_renderer_stream_impl.h" -#include "i_audio_renderer_sink.h" +#include "sink/i_audio_renderer_sink.h" +#include "manager/hdi_adapter_manager.h" #include #include "safe_map.h" #include "audio_errors.h" #include "audio_service_log.h" #include "audio_utils.h" -#include "i_hpae_manager.h" #include "audio_stream_info.h" #include "audio_effect_map.h" -using namespace OHOS::AudioStandard::HPAE; namespace OHOS { namespace AudioStandard { const int32_t MIN_BUFFER_SIZE = 2; const int32_t FRAME_LEN_10MS = 2; -static AudioChannelLayout SetDefaultChannelLayout(AudioChannel channels); + +#define GET_SIZE_FROM_FORMAT(format) ((format) != SAMPLE_F32LE ? ((format) + 1) : (4)) + +static std::shared_ptr GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId) +{ + uint32_t renderId = HDI_INVALID_ID; + if (deviceNetId.empty()) { + renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, HDI_ID_INFO_DEFAULT, false); + } else { + renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, deviceNetId, false); + } + return HdiAdapterManager::GetInstance().GetRenderSink(renderId, true); +} + HpaeRendererStreamImpl::HpaeRendererStreamImpl(AudioProcessConfig processConfig) { processConfig_ = processConfig; @@ -52,98 +64,36 @@ HpaeRendererStreamImpl::~HpaeRendererStreamImpl() int32_t HpaeRendererStreamImpl::InitParams(const std::string &deviceName) { - HpaeStreamInfo streamInfo; - 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.frameLen = spanSizeInFrame_; - streamInfo.sessionId = processConfig_.originalSessionId; - streamInfo.streamType = processConfig_.streamType; - streamInfo.fadeType = FadeType::DEFAULT_FADE; // to be passed from processConfig - streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY; - streamInfo.uid = processConfig_.appInfo.appUid; - streamInfo.pid = processConfig_.appInfo.appPid; - streamInfo.effectInfo.effectMode = (effectMode_ != EFFECT_DEFAULT && effectMode_ != EFFECT_NONE) ? EFFECT_DEFAULT : - static_cast(effectMode_); - const std::unordered_map &audioSupportedSceneTypes = GetSupportedSceneType(); - streamInfo.effectInfo.effectScene = static_cast(GetKeyFromValue( - audioSupportedSceneTypes, processConfig_.rendererInfo.sceneType)); - streamInfo.effectInfo.volumeType = STREAM_MUSIC; - streamInfo.effectInfo.streamUsage = processConfig_.rendererInfo.streamUsage; - streamInfo.sourceType = processConfig_.isInnerCapturer == true ? SOURCE_TYPE_PLAYBACK_CAPTURE : SOURCE_TYPE_INVALID; - streamInfo.deviceName = deviceName; - AUDIO_INFO_LOG("InitParams channels %{public}u end", streamInfo.channels); - AUDIO_INFO_LOG("InitParams channelLayout %{public}" PRIu64 " end", streamInfo.channelLayout); - AUDIO_INFO_LOG("InitParams samplingRate %{public}u end", streamInfo.samplingRate); - AUDIO_INFO_LOG("InitParams format %{public}u end", streamInfo.format); - AUDIO_INFO_LOG("InitParams frameLen %{public}zu end", streamInfo.frameLen); - AUDIO_INFO_LOG("InitParams streamType %{public}u end", streamInfo.streamType); - AUDIO_INFO_LOG("InitParams sessionId %{public}u end", streamInfo.sessionId); - AUDIO_INFO_LOG("InitParams streamClassType %{public}u end", streamInfo.streamClassType); - AUDIO_INFO_LOG("InitParams sourceType %{public}d end", streamInfo.sourceType); - int32_t ret = IHpaeManager::GetHpaeManager()->CreateStream(streamInfo); - if (ret != 0) { - AUDIO_ERR_LOG("CreateStream is error"); - return ERR_INVALID_PARAM; - } return SUCCESS; } int32_t HpaeRendererStreamImpl::Start() { AUDIO_INFO_LOG("Start"); - int32_t ret = IHpaeManager::GetHpaeManager()->Start(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); - if (ret != 0) { - AUDIO_ERR_LOG("Start is error"); - return ERR_INVALID_PARAM; - } return SUCCESS; } int32_t HpaeRendererStreamImpl::Pause(bool isStandby) { AUDIO_INFO_LOG("Pause"); - int32_t ret = IHpaeManager::GetHpaeManager()->Pause(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); - if (ret != 0) { - AUDIO_ERR_LOG("Pause is error"); - return ERR_INVALID_PARAM; - } return SUCCESS; } int32_t HpaeRendererStreamImpl::Flush() { AUDIO_PRERELEASE_LOGI("Flush Enter"); - int32_t ret = IHpaeManager::GetHpaeManager()->Flush(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); - if (ret != 0) { - AUDIO_ERR_LOG("Flush is error"); - return ERR_INVALID_PARAM; - } return SUCCESS; } int32_t HpaeRendererStreamImpl::Drain(bool stopFlag) { AUDIO_INFO_LOG("Drain Enter %{public}d", stopFlag); - int32_t ret = IHpaeManager::GetHpaeManager()->Drain(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); - if (ret != 0) { - AUDIO_ERR_LOG("Drain is error"); - return ERR_INVALID_PARAM; - } return SUCCESS; } int32_t HpaeRendererStreamImpl::Stop() { AUDIO_INFO_LOG("Stop Enter"); - int32_t ret = IHpaeManager::GetHpaeManager()->Stop(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); - if (ret != 0) { - AUDIO_ERR_LOG("Stop is error"); - return ERR_INVALID_PARAM; - } state_ = STOPPING; return SUCCESS; } @@ -152,14 +102,8 @@ int32_t HpaeRendererStreamImpl::Release() { if (state_ == RUNNING) { AUDIO_ERR_LOG("%{public}u Release state_ is RUNNING", processConfig_.originalSessionId); - IHpaeManager::GetHpaeManager()->Stop(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); } AUDIO_INFO_LOG("Release Enter"); - int32_t ret = IHpaeManager::GetHpaeManager()->DestroyStream(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId); - if (ret != 0) { - AUDIO_ERR_LOG("Release is error"); - return ERR_INVALID_PARAM; - } state_ = RELEASED; return SUCCESS; } @@ -246,22 +190,12 @@ int32_t HpaeRendererStreamImpl::GetPrivacyType(int32_t &privacyType) void HpaeRendererStreamImpl::RegisterStatusCallback(const std::weak_ptr &callback) { AUDIO_DEBUG_LOG("RegisterStatusCallback in"); - int32_t ret = IHpaeManager::GetHpaeManager()->RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId, callback); - if (ret != 0) { - AUDIO_ERR_LOG("RegisterStatusCallback is error"); - return; - } statusCallback_ = callback; } void HpaeRendererStreamImpl::RegisterWriteCallback(const std::weak_ptr &callback) { AUDIO_DEBUG_LOG("RegisterWriteCallback in"); - int32_t ret = IHpaeManager::GetHpaeManager()->RegisterWriteCallback(processConfig_.originalSessionId, shared_from_this()); - if (ret != 0) { - AUDIO_ERR_LOG("RegisterStatusCallback is error"); - return; - } writeCallback_ = callback; } @@ -385,9 +319,6 @@ int32_t HpaeRendererStreamImpl::SetOffloadMode(int32_t state, bool isAppBack) offloadEnable_ = true; SyncOffloadMode(); - auto ret = IHpaeManager::GetHpaeManager()->SetOffloadPolicy(processConfig_.originalSessionId, statePolicy); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, - "SetOffloadPolicy failed, errcode is %{public}d", ret); offloadStatePolicy_.store(statePolicy); #else AUDIO_INFO_LOG("SetStreamOffloadMode not available, FEATURE_POWER_MANAGER no define"); @@ -432,11 +363,6 @@ int32_t HpaeRendererStreamImpl::SetClientVolume(float clientVolume) { AUDIO_PRERELEASE_LOGI("set client volume success"); - int32_t ret = IHpaeManager::GetHpaeManager()->SetClientVolume(processConfig_.originalSessionId, clientVolume); - if (ret != 0) { - AUDIO_ERR_LOG("SetClientVolume is error"); - return ERR_INVALID_PARAM; - } clientVolume_ = clientVolume; return SUCCESS; } -- Gitee From ec6e2d7904750acfd6cb302e95ed27dfee7429c3 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 21:02:33 +0800 Subject: [PATCH 27/40] sync8 Signed-off-by: c00657214 --- .../server/src/hpae_renderer_stream_impl.cpp | 43 ++----------------- 1 file changed, 4 insertions(+), 39 deletions(-) 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 c8c6e9f7e8..37f48ab3b6 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -21,7 +21,7 @@ #endif #include "hpae_renderer_stream_impl.h" -#include "sink/i_audio_renderer_sink.h" +#include "sink/i_audio_render_sink.h" #include "manager/hdi_adapter_manager.h" #include #include "safe_map.h" @@ -136,9 +136,9 @@ int32_t HpaeRendererStreamImpl::GetLatency(uint64_t &latency) std::shared_lock lock(latencyMutex_); if (deviceClass_ != "offload") { uint32_t SinkLatency = 0; - IAudioRendererSink* audioRendererSink = IAudioRendererSink::GetInstance(deviceClass_.c_str(), deviceNetId_.c_str()); + std::shared_ptr audioRendererSink = GetRenderSinkInstance(deviceClass_, deviceNetId_); if (audioRendererSink) { - audioRendererSink->GetLatency(&SinkLatency); + audioRendererSink->GetLatency(SinkLatency); } latency = SinkLatency + latency_; return SUCCESS; @@ -268,7 +268,7 @@ size_t HpaeRendererStreamImpl::GetWritableSize() int32_t HpaeRendererStreamImpl::OffloadSetVolume(float volume) { - IAudioRendererSink *audioRendererSinkInstance = IAudioRendererSink::GetInstance("offload", ""); + std::shared_ptr audioRendererSink = GetRenderSinkInstance("offload", ""); if (audioRendererSinkInstance == nullptr) { AUDIO_ERR_LOG("Renderer is null."); return ERROR; @@ -367,40 +367,5 @@ 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; - } -} - } // namespace AudioStandard } // namespace OHOS -- Gitee From d4b2ab7ac5dfae4b079bff5cb6e6e3ece5557ede Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 21:03:34 +0800 Subject: [PATCH 28/40] sync9 Signed-off-by: c00657214 --- services/audio_service/server/src/hpae_renderer_stream_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 37f48ab3b6..b69b650847 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -268,7 +268,7 @@ size_t HpaeRendererStreamImpl::GetWritableSize() int32_t HpaeRendererStreamImpl::OffloadSetVolume(float volume) { - std::shared_ptr audioRendererSink = GetRenderSinkInstance("offload", ""); + std::shared_ptr audioRendererSinkInstance = GetRenderSinkInstance("offload", ""); if (audioRendererSinkInstance == nullptr) { AUDIO_ERR_LOG("Renderer is null."); return ERROR; -- Gitee From 64c6251f421659f2e32381115c071f6fe2e224ac Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 21:19:57 +0800 Subject: [PATCH 29/40] sync10 Signed-off-by: c00657214 --- .../offload/offload_audio_renderer_sink.cpp | 4 ++-- .../native/audiocommon/include/audio_effect.h | 8 +++---- .../audio_service/common/src/audio_volume.cpp | 2 +- .../server/src/capturer_in_server.cpp | 5 +++++ .../server/src/renderer_in_server.cpp | 21 ++++++++++++++----- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/frameworks/native/hdiadapter/sink/offload/offload_audio_renderer_sink.cpp b/frameworks/native/hdiadapter/sink/offload/offload_audio_renderer_sink.cpp index 7a4d53a5eb..873d98726b 100644 --- a/frameworks/native/hdiadapter/sink/offload/offload_audio_renderer_sink.cpp +++ b/frameworks/native/hdiadapter/sink/offload/offload_audio_renderer_sink.cpp @@ -1044,7 +1044,6 @@ int32_t OffloadAudioRendererSinkInner::OffloadRunningLockInit(void) int32_t OffloadAudioRendererSinkInner::OffloadRunningLockLock(void) { #ifdef FEATURE_POWER_MANAGER - CHECK_AND_RETURN_RET(!runninglocked, SUCCESS); AUDIO_INFO_LOG("keepRunningLock Lock"); std::shared_ptr keepRunningLock; if (offloadRunningLockManager_ == nullptr) { @@ -1059,6 +1058,7 @@ int32_t OffloadAudioRendererSinkInner::OffloadRunningLockLock(void) } CHECK_AND_RETURN_RET_LOG(offloadRunningLockManager_ != nullptr, ERR_OPERATION_FAILED, "offloadRunningLockManager_ is null, playback can not work well!"); + CHECK_AND_RETURN_RET(!runninglocked, SUCCESS); runninglocked = true; offloadRunningLockManager_->Lock(RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING); // -1 for lasting. #endif @@ -1069,10 +1069,10 @@ int32_t OffloadAudioRendererSinkInner::OffloadRunningLockLock(void) int32_t OffloadAudioRendererSinkInner::OffloadRunningLockUnlock(void) { #ifdef FEATURE_POWER_MANAGER - CHECK_AND_RETURN_RET(runninglocked, SUCCESS); AUDIO_INFO_LOG("keepRunningLock UnLock"); CHECK_AND_RETURN_RET_LOG(offloadRunningLockManager_ != nullptr, ERR_OPERATION_FAILED, "OffloadKeepRunningLock is null, playback can not work well!"); + CHECK_AND_RETURN_RET(runninglocked, SUCCESS); runninglocked = false; offloadRunningLockManager_->UnLock(); #endif diff --git a/interfaces/inner_api/native/audiocommon/include/audio_effect.h b/interfaces/inner_api/native/audiocommon/include/audio_effect.h index 8dcd7b8b33..d5c92769fd 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_effect.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_effect.h @@ -191,12 +191,12 @@ enum AudioEffectScene { * Enumerates the audio enhance scene effect type. */ enum AudioEnhanceScene { - SCENE_NONE = 0, - SCENE_VOIP_UP = 1, - SCENE_RECORD = 2, - SCENE_PRE_ENHANCE = 3, + SCENE_VOIP_UP = 0, + SCENE_RECORD = 1, + SCENE_PRE_ENHANCE = 2, SCENE_ASR = 4, SCENE_VOICE_MESSAGE = 5, + SCENE_NONE = 6, }; /** diff --git a/services/audio_service/common/src/audio_volume.cpp b/services/audio_service/common/src/audio_volume.cpp index 1cf0ec7e94..9cc8bf1986 100644 --- a/services/audio_service/common/src/audio_volume.cpp +++ b/services/audio_service/common/src/audio_volume.cpp @@ -202,7 +202,7 @@ float AudioVolume::GetHistoryVolume(uint32_t sessionId) void AudioVolume::SetHistoryVolume(uint32_t sessionId, float volume) { - AUDIO_DEBUG_LOG("history volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume); + AUDIO_INFO_LOG("history volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume); Trace trace("AudioVolume::SetHistoryVolume sessionId:" + std::to_string(sessionId)); std::shared_lock lock(volumeMutex_); auto it = historyVolume_.find(sessionId); diff --git a/services/audio_service/server/src/capturer_in_server.cpp b/services/audio_service/server/src/capturer_in_server.cpp index 0da852f27f..1b8ccf4ef9 100644 --- a/services/audio_service/server/src/capturer_in_server.cpp +++ b/services/audio_service/server/src/capturer_in_server.cpp @@ -229,6 +229,11 @@ bool CapturerInServer::IsReadDataOverFlow(size_t length, uint64_t currentWriteFr overFlowLogFlag_ = 0; } overFlowLogFlag_++; + int32_t engineFlag = GetEngineFlag(); + if (engineFlag != 1) { + BufferDesc dstBuffer = stream_->DequeueBuffer(length); + stream_->EnqueueBuffer(dstBuffer); + } stateListener->OnOperationHandled(UPDATE_STREAM, currentWriteFrame); return true; } diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index 9ac847260d..b121a3638f 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -89,7 +89,12 @@ int32_t RendererInServer::ConfigServerBuffer() return SUCCESS; } stream_->GetSpanSizePerFrame(spanSizeInFrame_); - totalSizeInFrame_ = spanSizeInFrame_ * 2; // 4 frames + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + totalSizeInFrame_ = spanSizeInFrame_ * 2; // 2 * 2 = 4 frames + } else { + totalSizeInFrame_ = spanSizeInFrame_ * DEFAULT_SPAN_SIZE; + } stream_->GetByteSizePerFrame(byteSizePerFrame_); if (totalSizeInFrame_ == 0 || spanSizeInFrame_ == 0 || totalSizeInFrame_ % spanSizeInFrame_ != 0) { AUDIO_ERR_LOG("ConfigProcessBuffer: ERR_INVALID_PARAM"); @@ -1294,7 +1299,7 @@ int32_t RendererInServer::InitDupStream(int32_t innerCapId) CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Config dup buffer failed"); } // todo check index - dupStreamCallback_ = std::make_shared(streamIndex_); + dupStreamCallback_ = std::make_shared(dupStreamIndex); capInfo.dupStream->RegisterStatusCallback(dupStreamCallback_); capInfo.dupStream->RegisterWriteCallback(dupStreamCallback_); @@ -1396,13 +1401,19 @@ int32_t RendererInServer::InitDualToneStream() StreamCallbacks::StreamCallbacks(uint32_t streamIndex) : streamIndex_(streamIndex) { AUDIO_INFO_LOG("DupStream %{public}u create StreamCallbacks", streamIndex_); - dumpDupOutFileName_ = std::to_string(streamIndex_) + "_dup_out_" + ".pcm"; - DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupOutFileName_, &dumpDupOut_); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + dumpDupOutFileName_ = std::to_string(streamIndex_) + "_dup_out_" + ".pcm"; + DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupOutFileName_, &dumpDupOut_); + } } StreamCallbacks::~StreamCallbacks() { - DumpFileUtil::CloseDumpFile(&dumpDupOut_); + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1) { + DumpFileUtil::CloseDumpFile(&dumpDupOut_); + } } void StreamCallbacks::OnStatusUpdate(IOperation operation) -- Gitee From 8bd6de36d796ac6acd3a090c2c5afce8e9f3df05 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 21:22:42 +0800 Subject: [PATCH 30/40] sync11 Signed-off-by: c00657214 --- services/audio_service/common/include/audio_volume_c.h | 2 -- services/audio_service/common/src/audio_volume.cpp | 8 -------- 2 files changed, 10 deletions(-) diff --git a/services/audio_service/common/include/audio_volume_c.h b/services/audio_service/common/include/audio_volume_c.h index 014db3ea69..c498bbb720 100644 --- a/services/audio_service/common/include/audio_volume_c.h +++ b/services/audio_service/common/include/audio_volume_c.h @@ -49,8 +49,6 @@ float GetCurVolume(uint32_t sessionId, const char *streamType, const char *devic float GetStreamVolume(uint32_t sessionId); -float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char *deviceClass); - float GetPreVolume(uint32_t sessionId); void SetPreVolume(uint32_t sessionId, float volume); diff --git a/services/audio_service/common/src/audio_volume.cpp b/services/audio_service/common/src/audio_volume.cpp index 9cc8bf1986..20eeb4939f 100644 --- a/services/audio_service/common/src/audio_volume.cpp +++ b/services/audio_service/common/src/audio_volume.cpp @@ -662,14 +662,6 @@ float GetCurVolume(uint32_t sessionId, const char *streamType, const char *devic return AudioVolume::GetInstance()->GetVolume(sessionId, stream, deviceClass, volumes); } -float GetCurVolumeByStreamType(uint32_t sessionId, int32_t streamType, const char *deviceClass) -{ - struct VolumeValues volumes; - CHECK_AND_RETURN_RET_LOG(deviceClass != nullptr, 1.0f, "deviceClass is nullptr"); - AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(static_cast(streamType)); - return AudioVolume::GetInstance()->GetVolume(sessionId, volumeType, deviceClass, &volumes); -} - float GetStreamVolume(uint32_t sessionId) { return AudioVolume::GetInstance()->GetStreamVolume(sessionId); -- Gitee From cbccb5e6ebac20227ff4324d487dc5055199a08c Mon Sep 17 00:00:00 2001 From: c00657214 Date: Wed, 16 Apr 2025 21:32:08 +0800 Subject: [PATCH 31/40] sync12 Signed-off-by: c00657214 --- frameworks/native/audioutils/src/audio_utils.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frameworks/native/audioutils/src/audio_utils.cpp b/frameworks/native/audioutils/src/audio_utils.cpp index 9f21046b23..a2b229620e 100644 --- a/frameworks/native/audioutils/src/audio_utils.cpp +++ b/frameworks/native/audioutils/src/audio_utils.cpp @@ -1100,9 +1100,11 @@ template bool GetSysPara(const char *key, std::string &value); int32_t GetEngineFlag() { std::string para = "const.multimedia.audio.proaudioEnable"; - int32_t engineFlag = -1; - bool res = GetSysPara(para.c_str(), engineFlag); - AUDIO_DEBUG_LOG("get %{public}s = %{public}d", para.c_str(), engineFlag); + static int32_t engineFlag = -1; + if (engineFlag == -1) { + bool res = GetSysPara(para.c_str(), engineFlag); + AUDIO_DEBUG_LOG("get %{public}s = %{public}d", para.c_str(), engineFlag); + } if (!res || engineFlag == -1) { AUDIO_ERR_LOG("get %{public}s fail", para.c_str()); } -- Gitee From b1d15dcaf38fecda2d7ad340ec2a8cf6392a9e8a Mon Sep 17 00:00:00 2001 From: c00657214 Date: Thu, 17 Apr 2025 10:27:25 +0800 Subject: [PATCH 32/40] sync13 Signed-off-by: c00657214 --- frameworks/native/audioutils/src/audio_utils.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frameworks/native/audioutils/src/audio_utils.cpp b/frameworks/native/audioutils/src/audio_utils.cpp index a2b229620e..05e8e30060 100644 --- a/frameworks/native/audioutils/src/audio_utils.cpp +++ b/frameworks/native/audioutils/src/audio_utils.cpp @@ -1104,9 +1104,7 @@ int32_t GetEngineFlag() if (engineFlag == -1) { bool res = GetSysPara(para.c_str(), engineFlag); AUDIO_DEBUG_LOG("get %{public}s = %{public}d", para.c_str(), engineFlag); - } - if (!res || engineFlag == -1) { - AUDIO_ERR_LOG("get %{public}s fail", para.c_str()); + CHECK_AND_RETURN_RET_LOG(res, engineFlag, "get %{public}s fail", para.c_str()); } return engineFlag; } -- Gitee From c20e2d4f503a9504c9ba7eaa2a841eb59dbd0e81 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Thu, 17 Apr 2025 10:38:06 +0800 Subject: [PATCH 33/40] sync14 Signed-off-by: c00657214 --- .../audioadapter/include/pro_audio_service_adapter_impl.h | 3 ++- frameworks/native/audioadapter/src/audio_service_adapter.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h index 0f3d1b9963..cdac8b3f0f 100644 --- a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h +++ b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h @@ -24,7 +24,8 @@ namespace OHOS { namespace AudioStandard { -class ProAudioServiceAdapterImpl : public AudioServiceAdapter, public std::enable_shared_from_this { +class ProAudioServiceAdapterImpl : public AudioServiceAdapter, + public std::enable_shared_from_this { public: explicit ProAudioServiceAdapterImpl(std::unique_ptr &cb); ~ProAudioServiceAdapterImpl(); diff --git a/frameworks/native/audioadapter/src/audio_service_adapter.cpp b/frameworks/native/audioadapter/src/audio_service_adapter.cpp index 930a7ece1b..0452aa1013 100644 --- a/frameworks/native/audioadapter/src/audio_service_adapter.cpp +++ b/frameworks/native/audioadapter/src/audio_service_adapter.cpp @@ -41,7 +41,8 @@ namespace AudioStandard { AudioServiceAdapter::~AudioServiceAdapter() = default; -std::shared_ptr AudioServiceAdapter::CreateAudioAdapter(std::unique_ptr cb) +std::shared_ptr AudioServiceAdapter::CreateAudioAdapter( + std::unique_ptr cb) { CHECK_AND_RETURN_RET_LOG(cb != nullptr, nullptr, "CreateAudioAdapter cb is nullptr!"); AUDIO_INFO_LOG("CreateAudioAdapter"); -- Gitee From 1574f04b680aa93f703f227351a3539351c8e962 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Thu, 17 Apr 2025 10:50:02 +0800 Subject: [PATCH 34/40] sync15 Signed-off-by: c00657214 --- .../include/hpae_capturer_stream_impl.h | 4 +- .../include/hpae_renderer_stream_impl.h | 8 +-- .../server/include/renderer_in_server.h | 1 + .../server/src/hpae_capturer_stream_impl.cpp | 16 +++--- .../server/src/hpae_renderer_stream_impl.cpp | 30 ++++++----- .../server/src/pro_adapter_manager.cpp | 3 +- .../server/src/renderer_in_server.cpp | 50 +++++++++++-------- 7 files changed, 65 insertions(+), 47 deletions(-) diff --git a/services/audio_service/server/include/hpae_capturer_stream_impl.h b/services/audio_service/server/include/hpae_capturer_stream_impl.h index 1fb97b5e56..c4576cca38 100644 --- a/services/audio_service/server/include/hpae_capturer_stream_impl.h +++ b/services/audio_service/server/include/hpae_capturer_stream_impl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef hpae_capturer_stream_impl_H -#define hpae_capturer_stream_impl_H +#ifndef HPAE_CAPTURER_STREAM_IMPL_H +#define HPAE_CAPTURER_STREAM_IMPL_H #include "i_capturer_stream.h" diff --git a/services/audio_service/server/include/hpae_renderer_stream_impl.h b/services/audio_service/server/include/hpae_renderer_stream_impl.h index 6166ce23dc..da7d13b806 100644 --- a/services/audio_service/server/include/hpae_renderer_stream_impl.h +++ b/services/audio_service/server/include/hpae_renderer_stream_impl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef pro_renderer_stream_impl_H -#define pro_renderer_stream_impl_H +#ifndef HPAE_RENDERER_STREAM_IMPL_H +#define HPAE_RENDERER_STREAM_IMPL_H #include #include @@ -23,7 +23,9 @@ namespace OHOS { namespace AudioStandard { -class HpaeRendererStreamImpl : public std::enable_shared_from_this, public IStreamCallback, public IRendererStream { +class HpaeRendererStreamImpl : public std::enable_shared_from_this, + public IStreamCallback, + public IRendererStream { public: HpaeRendererStreamImpl(AudioProcessConfig processConfig); ~HpaeRendererStreamImpl(); diff --git a/services/audio_service/server/include/renderer_in_server.h b/services/audio_service/server/include/renderer_in_server.h index 4bdc9957cc..53d2cfc2dc 100644 --- a/services/audio_service/server/include/renderer_in_server.h +++ b/services/audio_service/server/include/renderer_in_server.h @@ -134,6 +134,7 @@ private: bool ShouldEnableStandBy(); int32_t OffloadSetVolumeInner(); void InnerCaptureOtherStream(const BufferDesc &bufferDesc, CaptureInfo &captureInfo); + void InnerCaptureEnqueueBuffer(const BufferDesc &bufferDesc, CaptureInfo &captureInfo); int32_t StartInner(); int64_t GetLastAudioDuration(); int32_t CreateDupBufferInner(int32_t innerCapId); diff --git a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp index c9105c26d2..02103470b2 100644 --- a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp @@ -23,21 +23,25 @@ #include "audio_utils.h" #include "policy_handler.h" #include -#include +#include namespace OHOS { namespace AudioStandard { static SafeMap> paCapturerMap_; -const int32_t MIN_BUFFER_SIZE = 2; -const int32_t FRAME_LEN_10MS = 2; +const int32_t FRAME_LEN_ON_MS = 20; +const int32_t MSEC_PER_SEC = 1000; -#define GET_SIZE_FROM_FORMAT(format) ((format) != SAMPLE_F32LE ? ((format) + 1) : (4)) +static inline int32_t GetSizeFromFormat(int32_t format) +{ + return format != SAMPLE_F32LE ? ((format) + 1) : (4); +} HpaeCapturerStreamImpl::HpaeCapturerStreamImpl(AudioProcessConfig processConfig) { processConfig_ = processConfig; - spanSizeInFrame_ = FRAME_LEN_10MS * (processConfig.streamInfo.samplingRate / 100); - byteSizePerFrame_ = (processConfig.streamInfo.channels * GET_SIZE_FROM_FORMAT(processConfig.streamInfo.format)); + spanSizeInFrame_ = static_cast(FRAME_LEN_ON_MS * + (static_cast(streamInfo.samplingRate) / MSEC_PER_SEC)); + byteSizePerFrame_ = (processConfig.streamInfo.channels * GetSizeFromFormat(processConfig.streamInfo.format)); minBufferSize_ = MIN_BUFFER_SIZE * byteSizePerFrame_ * spanSizeInFrame_; } 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 b69b650847..0820072bb0 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -35,26 +35,20 @@ namespace OHOS { namespace AudioStandard { const int32_t MIN_BUFFER_SIZE = 2; -const int32_t FRAME_LEN_10MS = 2; +const int32_t FRAME_LEN_ON_MS = 20; +const int32_t MSEC_PER_SEC = 1000; -#define GET_SIZE_FROM_FORMAT(format) ((format) != SAMPLE_F32LE ? ((format) + 1) : (4)) - -static std::shared_ptr GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId) +static inline int32_t GetSizeFromFormat(int32_t format) { - uint32_t renderId = HDI_INVALID_ID; - if (deviceNetId.empty()) { - renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, HDI_ID_INFO_DEFAULT, false); - } else { - renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, deviceNetId, false); - } - return HdiAdapterManager::GetInstance().GetRenderSink(renderId, true); + return format != SAMPLE_F32LE ? ((format) + 1) : (4); } HpaeRendererStreamImpl::HpaeRendererStreamImpl(AudioProcessConfig processConfig) { processConfig_ = processConfig; - spanSizeInFrame_ = FRAME_LEN_10MS * (processConfig.streamInfo.samplingRate / 100); - byteSizePerFrame_ = (processConfig.streamInfo.channels * GET_SIZE_FROM_FORMAT(processConfig.streamInfo.format)); + spanSizeInFrame_ = static_cast(FRAME_LEN_ON_MS * + (static_cast(streamInfo.samplingRate) / MSEC_PER_SEC)); + byteSizePerFrame_ = (processConfig.streamInfo.channels * GetSizeFromFormat(processConfig.streamInfo.format)); minBufferSize_ = MIN_BUFFER_SIZE * byteSizePerFrame_ * spanSizeInFrame_; } HpaeRendererStreamImpl::~HpaeRendererStreamImpl() @@ -130,6 +124,16 @@ int32_t HpaeRendererStreamImpl::GetCurrentPosition(uint64_t &framePosition, uint return SUCCESS; } +static std::shared_ptr GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId) +{ + uint32_t renderId = HDI_INVALID_ID; + if (deviceNetId.empty()) { + renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, HDI_ID_INFO_DEFAULT, false); + } else { + renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, deviceNetId, false); + } + return HdiAdapterManager::GetInstance().GetRenderSink(renderId, true); +} int32_t HpaeRendererStreamImpl::GetLatency(uint64_t &latency) { diff --git a/services/audio_service/server/src/pro_adapter_manager.cpp b/services/audio_service/server/src/pro_adapter_manager.cpp index 20b9938224..d90ca8bf16 100644 --- a/services/audio_service/server/src/pro_adapter_manager.cpp +++ b/services/audio_service/server/src/pro_adapter_manager.cpp @@ -47,7 +47,8 @@ int32_t ProAdapterManager::CreateRender(AudioProcessConfig processConfig, std::s if (managerType_ == DUP_PLAYBACK || processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_STREAMID) { sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid); - AUDIO_ERR_LOG("Create [%{public}d] type renderer:[%{public}u] error", managerType_, processConfig.originalSessionId); + AUDIO_ERR_LOG("Create [%{public}d] type renderer:[%{public}u] error", + managerType_, processConfig.originalSessionId); } AUDIO_INFO_LOG("Create [%{public}d] type renderer:[%{public}u]", managerType_, sessionId); diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index b121a3638f..fffbb6df98 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -694,31 +694,36 @@ void RendererInServer::OtherStreamEnqueue(const BufferDesc &bufferDesc) } } +void RendererInServer::InnerCaptureEnqueueBuffer(const BufferDesc &bufferDesc, CaptureInfo &captureInfo) +{ + int32_t engineFlag = GetEngineFlag(); + if (renderEmptyCountForInnerCap_ > 0) { + size_t emptyBufferSize = static_cast(renderEmptyCountForInnerCap_) * spanSizeInByte_; + auto buffer = std::make_unique(emptyBufferSize); + BufferDesc emptyBufferDesc = {buffer.get(), emptyBufferSize, emptyBufferSize}; + memset_s(emptyBufferDesc.buffer, emptyBufferDesc.bufLength, 0, emptyBufferDesc.bufLength); + if (engineFlag == 1) { + WriteDupBufferInner(emptyBufferDesc); + } else { + captureInfo.dupStream->EnqueueBuffer(emptyBufferDesc); + } + renderEmptyCountForInnerCap_ = 0; + } + if (engineFlag == 1) { + AUDIO_INFO_LOG("OtherStreamEnqueue running"); + WriteDupBufferInner(bufferDesc); + } else { + captureInfo.dupStream->EnqueueBuffer(bufferDesc); // what if enqueue fail? + } +} + void RendererInServer::InnerCaptureOtherStream(const BufferDesc &bufferDesc, CaptureInfo &captureInfo) { if (captureInfo.isInnerCapEnabled) { Trace traceDup("RendererInServer::WriteData DupSteam write"); std::lock_guard lock(dupMutex_); if (captureInfo.dupStream != nullptr) { - int32_t engineFlag = GetEngineFlag(); - if (renderEmptyCountForInnerCap_ > 0) { - size_t emptyBufferSize = static_cast(renderEmptyCountForInnerCap_) * spanSizeInByte_; - auto buffer = std::make_unique(emptyBufferSize); - BufferDesc emptyBufferDesc = {buffer.get(), emptyBufferSize, emptyBufferSize}; - memset_s(emptyBufferDesc.buffer, emptyBufferDesc.bufLength, 0, emptyBufferDesc.bufLength); - if (engineFlag == 1) { - WriteDupBufferInner(emptyBufferDesc); - } else { - captureInfo.dupStream->EnqueueBuffer(emptyBufferDesc); - } - renderEmptyCountForInnerCap_ = 0; - } - if (engineFlag == 1) { - AUDIO_INFO_LOG("OtherStreamEnqueue running"); - WriteDupBufferInner(bufferDesc); - } else { - captureInfo.dupStream->EnqueueBuffer(bufferDesc); // what if enqueue fail? - } + InnerCaptureEnqueueBuffer(bufferDesc, captureInfo); } } } @@ -1068,7 +1073,6 @@ int32_t RendererInServer::Stop() AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING"); fadeoutFlag_ = NO_FADING; } - stopedTime_ = ClockTime::GetCurNano(); int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ? IStreamManager::GetPlaybackManager(managerType_).StopRender(streamIndex_) : stream_->Stop(); @@ -1441,7 +1445,8 @@ int32_t StreamCallbacks::OnWriteData(int8_t *inputData, size_t requestDataLen) CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "dupBuffer get readable size failed, size is:%{public}zu", result.size); CHECK_AND_RETURN_RET_LOG((result.size != 0) && (result.size >= requestDataLen), ERROR, - "Readable size is invaild, result.size:%{public}zu, requstDataLen:%{public}zu", result.size, requestDataLen); + "Readable size is invaild, result.size:%{public}zu, requstDataLen:%{public}zu", + result.size, requestDataLen); AUDIO_DEBUG_LOG("requstDataLen is:%{public}zu readSize is:%{public}zu", requestDataLen, result.size); result = dupBuffer->Dequeue({reinterpret_cast(inputData), requestDataLen}); CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "dupBuffer dequeue failed");\ @@ -1820,7 +1825,8 @@ int32_t RendererInServer::SetSourceDuration(int64_t duration) return SUCCESS; } -std::unique_ptr& RendererInServer::GetDupRingBuffer() { +std::unique_ptr& RendererInServer::GetDupRingBuffer() +{ return dupRingBuffer_; } -- Gitee From 2853dd4817185a49605a93ab13212a23f35685d5 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Thu, 17 Apr 2025 11:18:04 +0800 Subject: [PATCH 35/40] sync16 Signed-off-by: c00657214 --- frameworks/native/audioadapter/BUILD.gn | 3 ++- .../server/src/hpae_capturer_stream_impl.cpp | 3 ++- .../server/src/hpae_renderer_stream_impl.cpp | 8 ++++---- services/audio_service/server/src/pro_adapter_manager.cpp | 3 +-- services/audio_service/server/src/renderer_in_server.cpp | 6 +++--- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/frameworks/native/audioadapter/BUILD.gn b/frameworks/native/audioadapter/BUILD.gn index 1ee3cd2440..e728a0aa3e 100644 --- a/frameworks/native/audioadapter/BUILD.gn +++ b/frameworks/native/audioadapter/BUILD.gn @@ -48,8 +48,9 @@ ohos_shared_library("pulse_audio_service_adapter") { "../../../services/audio_service/common/include", ] - deps = [ "../audioutils:audio_utils", + deps = [ "../../../services/audio_service:audio_common", + "../audioutils:audio_utils", ] external_deps = [ diff --git a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp index 02103470b2..2ba0237123 100644 --- a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp @@ -28,6 +28,7 @@ namespace OHOS { namespace AudioStandard { static SafeMap> paCapturerMap_; +const int32_t MIN_BUFFER_SIZE = 2; const int32_t FRAME_LEN_ON_MS = 20; const int32_t MSEC_PER_SEC = 1000; @@ -40,7 +41,7 @@ HpaeCapturerStreamImpl::HpaeCapturerStreamImpl(AudioProcessConfig processConfig) { processConfig_ = processConfig; spanSizeInFrame_ = static_cast(FRAME_LEN_ON_MS * - (static_cast(streamInfo.samplingRate) / MSEC_PER_SEC)); + (static_cast(processConfig.streamInfo.samplingRate) / MSEC_PER_SEC)); byteSizePerFrame_ = (processConfig.streamInfo.channels * GetSizeFromFormat(processConfig.streamInfo.format)); minBufferSize_ = MIN_BUFFER_SIZE * byteSizePerFrame_ * spanSizeInFrame_; } 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 0820072bb0..4d0f1320d9 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -47,7 +47,7 @@ HpaeRendererStreamImpl::HpaeRendererStreamImpl(AudioProcessConfig processConfig) { processConfig_ = processConfig; spanSizeInFrame_ = static_cast(FRAME_LEN_ON_MS * - (static_cast(streamInfo.samplingRate) / MSEC_PER_SEC)); + (static_cast(processConfig.streamInfo.samplingRate) / MSEC_PER_SEC)); byteSizePerFrame_ = (processConfig.streamInfo.channels * GetSizeFromFormat(processConfig.streamInfo.format)); minBufferSize_ = MIN_BUFFER_SIZE * byteSizePerFrame_ * spanSizeInFrame_; } @@ -152,7 +152,8 @@ int32_t HpaeRendererStreamImpl::GetLatency(uint64_t &latency) auto timestamp = static_cast(tm.tv_sec) * 1000000000ll + static_cast(tm.tv_nsec); auto interval = (timestamp - timestamp_) / 1000; latency = latency_ > interval ? latency_ - interval : 0; - AUDIO_DEBUG_LOG("HpaeRendererStreamImpl::GetLatency latency_ %{public}" PRIu64 ", interval %{public}llu latency %{public}" PRIu64, latency_, interval, latency); + AUDIO_DEBUG_LOG("HpaeRendererStreamImpl::GetLatency latency_ %{public}" PRIu64 "," + "interval %{public}llu latency %{public}" PRIu64, latency_, interval, latency); return SUCCESS; } @@ -267,7 +268,7 @@ void HpaeRendererStreamImpl::AbortCallback(int32_t abortTimes) size_t HpaeRendererStreamImpl::GetWritableSize() { - return 0; + return 0; } int32_t HpaeRendererStreamImpl::OffloadSetVolume(float volume) @@ -365,7 +366,6 @@ void HpaeRendererStreamImpl::BlockStream() noexcept int32_t HpaeRendererStreamImpl::SetClientVolume(float clientVolume) { - AUDIO_PRERELEASE_LOGI("set client volume success"); clientVolume_ = clientVolume; return SUCCESS; diff --git a/services/audio_service/server/src/pro_adapter_manager.cpp b/services/audio_service/server/src/pro_adapter_manager.cpp index d90ca8bf16..9678d33c61 100644 --- a/services/audio_service/server/src/pro_adapter_manager.cpp +++ b/services/audio_service/server/src/pro_adapter_manager.cpp @@ -49,8 +49,7 @@ int32_t ProAdapterManager::CreateRender(AudioProcessConfig processConfig, std::s sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid); AUDIO_ERR_LOG("Create [%{public}d] type renderer:[%{public}u] error", managerType_, processConfig.originalSessionId); - - } + } AUDIO_INFO_LOG("Create [%{public}d] type renderer:[%{public}u]", managerType_, sessionId); std::string deviceName; int32_t ret = GetDeviceNameForConnect(processConfig, processConfig.originalSessionId, deviceName); diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index fffbb6df98..8eb8048b9d 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -1827,7 +1827,7 @@ int32_t RendererInServer::SetSourceDuration(int64_t duration) std::unique_ptr& RendererInServer::GetDupRingBuffer() { - return dupRingBuffer_; + return dupRingBuffer_; } int32_t RendererInServer::CreateDupBufferInner(int32_t innerCapId) @@ -1850,8 +1850,8 @@ int32_t RendererInServer::CreateDupBufferInner(int32_t innerCapId) dupSpanSizeInByte_ = dupSpanSizeInFrame_ * dupByteSizePerFrame_; CHECK_AND_RETURN_RET_LOG(dupSpanSizeInByte_ != 0, ERR_OPERATION_FAILED, "Config dup buffer failed"); AUDIO_INFO_LOG("dupTotalSizeInFrame_: %{public}zu, dupSpanSizeInFrame_: %{public}zu," - "dupByteSizePerFrame_:%{public}zu dupSpanSizeInByte_: %{public}zu,", - dupTotalSizeInFrame_, dupSpanSizeInFrame_, dupByteSizePerFrame_, dupSpanSizeInByte_); + "dupByteSizePerFrame_:%{public}zu dupSpanSizeInByte_: %{public}zu,", + dupTotalSizeInFrame_, dupSpanSizeInFrame_, dupByteSizePerFrame_, dupSpanSizeInByte_); // create dupBuffer in server dupRingBuffer_ = AudioRingCache::Create(dupTotalSizeInFrame_ * dupByteSizePerFrame_); -- Gitee From e4e373f4cee286f8ad2510161bc0e60802e11223 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Thu, 17 Apr 2025 11:20:30 +0800 Subject: [PATCH 36/40] sync17 Signed-off-by: c00657214 --- services/audio_service/server/src/hpae_capturer_stream_impl.cpp | 2 +- services/audio_service/server/src/hpae_renderer_stream_impl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp index 2ba0237123..d767cfcde5 100644 --- a/services/audio_service/server/src/hpae_capturer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_capturer_stream_impl.cpp @@ -34,7 +34,7 @@ const int32_t MSEC_PER_SEC = 1000; static inline int32_t GetSizeFromFormat(int32_t format) { - return format != SAMPLE_F32LE ? ((format) + 1) : (4); + return format != SAMPLE_F32LE ? ((format) + 1) : (4); // float 4 } HpaeCapturerStreamImpl::HpaeCapturerStreamImpl(AudioProcessConfig processConfig) 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 4d0f1320d9..f700dfdb35 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -40,7 +40,7 @@ const int32_t MSEC_PER_SEC = 1000; static inline int32_t GetSizeFromFormat(int32_t format) { - return format != SAMPLE_F32LE ? ((format) + 1) : (4); + return format != SAMPLE_F32LE ? ((format) + 1) : (4); // float 4 } HpaeRendererStreamImpl::HpaeRendererStreamImpl(AudioProcessConfig processConfig) -- Gitee From 4795bef9c606d53c7e579b8fbff49f5c636ddc6d Mon Sep 17 00:00:00 2001 From: c00657214 Date: Thu, 17 Apr 2025 12:42:21 +0800 Subject: [PATCH 37/40] sync18 Signed-off-by: c00657214 --- .../audio_effect_chain_manager_unit_test.cpp | 1 - services/audio_service/BUILD.gn | 8 ++-- ...apter_manager.h => hpae_adapter_manager.h} | 10 ++--- ...r_manager.cpp => hpae_adapter_manager.cpp} | 40 +++++++++---------- .../server/src/i_stream_manager.cpp | 10 ++--- 5 files changed, 34 insertions(+), 35 deletions(-) rename services/audio_service/server/include/{pro_adapter_manager.h => hpae_adapter_manager.h} (92%) rename services/audio_service/server/src/{pro_adapter_manager.cpp => hpae_adapter_manager.cpp} (86%) diff --git a/frameworks/native/audioeffect/test/unittest/effect_unit_test/src/audio_effect_chain_manager_unit_test.cpp b/frameworks/native/audioeffect/test/unittest/effect_unit_test/src/audio_effect_chain_manager_unit_test.cpp index a7c389f826..c1415b03ee 100644 --- a/frameworks/native/audioeffect/test/unittest/effect_unit_test/src/audio_effect_chain_manager_unit_test.cpp +++ b/frameworks/native/audioeffect/test/unittest/effect_unit_test/src/audio_effect_chain_manager_unit_test.cpp @@ -167,7 +167,6 @@ HWTEST(AudioEffectChainManagerUnitTest, CreateAudioEffectChainDynamic_005, TestS "SCENE_MOVIE", INFOCHANNELS, INFOCHANNELLAYOUT, - "0", 10, }; diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index d2db3a8b8d..40b56ef8bb 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -294,9 +294,9 @@ ohos_prebuilt_etc("audio_server_init") { config("audio_service_config") { visibility = [ ":*" ] visibility += [ + "../../services/audio_service/test/unittest:audio_process_in_client_unit_test", "../../services/audio_service/test/unittest/audio_endpoint_unit_test", "../../services/audio_service/test/unittest/audio_server_unit_test", - "../../services/audio_service/test/unittest:audio_process_in_client_unit_test", "../../services/audio_service/test/unittest/pro_renderer_stream_impl_unit_test", "../../test/fuzztest/*", ] @@ -363,6 +363,9 @@ audio_ohos_library("audio_process_service") { "server/src/capturer_in_server.cpp", "server/src/core_service_handler.cpp", "server/src/core_service_provider_proxy.cpp", + "server/src/hpae_adapter_manager.cpp", + "server/src/hpae_capturer_stream_impl.cpp", + "server/src/hpae_renderer_stream_impl.cpp", "server/src/i_stream_manager.cpp", "server/src/ipc_offline_stream_stub.cpp", "server/src/ipc_stream_in_server.cpp", @@ -373,9 +376,6 @@ audio_ohos_library("audio_process_service") { "server/src/pa_adapter_manager.cpp", "server/src/pa_capturer_stream_impl.cpp", "server/src/pa_renderer_stream_impl.cpp", - "server/src/pro_adapter_manager.cpp", - "server/src/hpae_capturer_stream_impl.cpp", - "server/src/hpae_renderer_stream_impl.cpp", "server/src/policy_handler.cpp", "server/src/policy_provider_proxy.cpp", "server/src/pro_audio_stream_manager.cpp", diff --git a/services/audio_service/server/include/pro_adapter_manager.h b/services/audio_service/server/include/hpae_adapter_manager.h similarity index 92% rename from services/audio_service/server/include/pro_adapter_manager.h rename to services/audio_service/server/include/hpae_adapter_manager.h index c9572f2021..ce86f15490 100644 --- a/services/audio_service/server/include/pro_adapter_manager.h +++ b/services/audio_service/server/include/hpae_adapter_manager.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PRO_ADAPTER_MANAGER_H -#define PRO_ADAPTER_MANAGER_H +#ifndef HPAE_ADAPTER_MANAGER_H +#define HPAE_ADAPTER_MANAGER_H #include #include @@ -26,9 +26,9 @@ namespace OHOS { namespace AudioStandard { -class ProAdapterManager : public IStreamManager { +class HpaeAdapterManager : public IStreamManager { public: - ProAdapterManager(ManagerType type); + HpaeAdapterManager(ManagerType type); int32_t CreateRender(AudioProcessConfig processConfig, std::shared_ptr &stream) override; int32_t ReleaseRender(uint32_t streamIndex_) override; @@ -60,4 +60,4 @@ private: }; } // namespace AudioStandard } // namespace OHOS -#endif // pro_adapter_manager_H +#endif // HPAE_ADAPTER_MANAGER_H diff --git a/services/audio_service/server/src/pro_adapter_manager.cpp b/services/audio_service/server/src/hpae_adapter_manager.cpp similarity index 86% rename from services/audio_service/server/src/pro_adapter_manager.cpp rename to services/audio_service/server/src/hpae_adapter_manager.cpp index 9678d33c61..b4b4d62832 100644 --- a/services/audio_service/server/src/pro_adapter_manager.cpp +++ b/services/audio_service/server/src/hpae_adapter_manager.cpp @@ -13,10 +13,10 @@ * limitations under the License. */ #ifndef LOG_TAG -#define LOG_TAG "ProAdapterManager" +#define LOG_TAG "HpaeAdapterManager" #endif -#include "pro_adapter_manager.h" +#include "hpae_adapter_manager.h" #include #include #include "audio_common_log.h" @@ -33,13 +33,13 @@ const char* PRO_INNER_CAPTURER_SOURCE = "Speaker.monitor"; const char* PRO_NEW_INNER_CAPTURER_SOURCE = "InnerCapturerSink.monitor"; const char* PRO_MONITOR_SOURCE_SUFFIX = ".monitor"; -ProAdapterManager::ProAdapterManager(ManagerType type) +HpaeAdapterManager::HpaeAdapterManager(ManagerType type) { AUDIO_INFO_LOG("Constructor with type:%{public}d", type); managerType_ = type; } -int32_t ProAdapterManager::CreateRender(AudioProcessConfig processConfig, std::shared_ptr &stream) +int32_t HpaeAdapterManager::CreateRender(AudioProcessConfig processConfig, std::shared_ptr &stream) { AUDIO_DEBUG_LOG("Create renderer start"); uint32_t sessionId = 0; @@ -56,7 +56,7 @@ int32_t ProAdapterManager::CreateRender(AudioProcessConfig processConfig, std::s CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR_INVALID_PARAM, "getdevicename err: %{public}d", ret); processConfig.originalSessionId = sessionId; - // ProAdapterManager is solely responsible for creating paStream objects + // HpaeAdapterManager is solely responsible for creating paStream objects std::shared_ptr rendererStream = CreateRendererStream(processConfig, deviceName); CHECK_AND_RETURN_RET_LOG(rendererStream != nullptr, ERR_DEVICE_INIT, "Failed to init pa stream"); rendererStream->SetStreamIndex(sessionId); @@ -75,7 +75,7 @@ int32_t ProAdapterManager::CreateRender(AudioProcessConfig processConfig, std::s return SUCCESS; } -int32_t ProAdapterManager::ReleaseRender(uint32_t streamIndex) +int32_t HpaeAdapterManager::ReleaseRender(uint32_t streamIndex) { AUDIO_DEBUG_LOG("Release [%{public}d] type render:[%{public}u]", managerType_, streamIndex); std::unique_lock lock(streamMapMutex_); @@ -108,7 +108,7 @@ int32_t ProAdapterManager::ReleaseRender(uint32_t streamIndex) return SUCCESS; } -int32_t ProAdapterManager::StartRender(uint32_t streamIndex) +int32_t HpaeAdapterManager::StartRender(uint32_t streamIndex) { AUDIO_DEBUG_LOG("Enter StartRender"); std::lock_guard lock(streamMapMutex_); @@ -120,7 +120,7 @@ int32_t ProAdapterManager::StartRender(uint32_t streamIndex) return rendererStreamMap_[streamIndex]->Start(); } -int32_t ProAdapterManager::StopRender(uint32_t streamIndex) +int32_t HpaeAdapterManager::StopRender(uint32_t streamIndex) { AUDIO_DEBUG_LOG("Enter StopRender"); std::lock_guard lock(streamMapMutex_); @@ -132,7 +132,7 @@ int32_t ProAdapterManager::StopRender(uint32_t streamIndex) return rendererStreamMap_[streamIndex]->Stop(); } -int32_t ProAdapterManager::PauseRender(uint32_t streamIndex) +int32_t HpaeAdapterManager::PauseRender(uint32_t streamIndex) { AUDIO_DEBUG_LOG("Enter PauseRender"); std::lock_guard lock(streamMapMutex_); @@ -145,12 +145,12 @@ int32_t ProAdapterManager::PauseRender(uint32_t streamIndex) return SUCCESS; } -int32_t ProAdapterManager::TriggerStartIfNecessary() +int32_t HpaeAdapterManager::TriggerStartIfNecessary() { return SUCCESS; } -int32_t ProAdapterManager::GetStreamCount() const noexcept +int32_t HpaeAdapterManager::GetStreamCount() const noexcept { if (managerType_ == RECORDER) { return capturerStreamMap_.size(); @@ -159,7 +159,7 @@ int32_t ProAdapterManager::GetStreamCount() const noexcept } } -int32_t ProAdapterManager::GetDeviceNameForConnect(AudioProcessConfig processConfig, uint32_t sessionId, +int32_t HpaeAdapterManager::GetDeviceNameForConnect(AudioProcessConfig processConfig, uint32_t sessionId, std::string &deviceName) { deviceName = ""; @@ -189,7 +189,7 @@ int32_t ProAdapterManager::GetDeviceNameForConnect(AudioProcessConfig processCon return SUCCESS; } -int32_t ProAdapterManager::CreateCapturer(AudioProcessConfig processConfig, std::shared_ptr &stream) +int32_t HpaeAdapterManager::CreateCapturer(AudioProcessConfig processConfig, std::shared_ptr &stream) { AUDIO_DEBUG_LOG("Create capturer start"); CHECK_AND_RETURN_RET_LOG(managerType_ == RECORDER, ERROR, "Invalid managerType:%{public}d", managerType_); @@ -205,7 +205,7 @@ int32_t ProAdapterManager::CreateCapturer(AudioProcessConfig processConfig, std: int32_t ret = GetDeviceNameForConnect(processConfig, processConfig.originalSessionId, deviceName); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR_INVALID_PARAM, "getdevicename err: %{public}d", ret); - // ProAdapterManager is solely responsible for creating paStream objects + // HpaeAdapterManager is solely responsible for creating paStream objects std::shared_ptr capturerStream = CreateCapturerStream(processConfig, deviceName); CHECK_AND_RETURN_RET_LOG(capturerStream != nullptr, ERR_DEVICE_INIT, "Failed to init pa stream"); capturerStream->SetStreamIndex(sessionId); @@ -215,12 +215,12 @@ int32_t ProAdapterManager::CreateCapturer(AudioProcessConfig processConfig, std: return SUCCESS; } -int32_t ProAdapterManager::AddUnprocessStream(int32_t appUid) +int32_t HpaeAdapterManager::AddUnprocessStream(int32_t appUid) { return SUCCESS; } -int32_t ProAdapterManager::ReleaseCapturer(uint32_t streamIndex) +int32_t HpaeAdapterManager::ReleaseCapturer(uint32_t streamIndex) { AUDIO_DEBUG_LOG("Enter ReleaseCapturer"); std::lock_guard lock(streamMapMutex_); @@ -243,7 +243,7 @@ int32_t ProAdapterManager::ReleaseCapturer(uint32_t streamIndex) return SUCCESS; } -std::shared_ptr ProAdapterManager::CreateRendererStream(AudioProcessConfig processConfig, +std::shared_ptr HpaeAdapterManager::CreateRendererStream(AudioProcessConfig processConfig, const std::string &deviceName) { std::lock_guard lock(paElementsMutex_); @@ -261,7 +261,7 @@ std::shared_ptr ProAdapterManager::CreateRendererStream(AudioPr return rendererStream; } -std::shared_ptr ProAdapterManager::CreateCapturerStream(AudioProcessConfig processConfig, +std::shared_ptr HpaeAdapterManager::CreateCapturerStream(AudioProcessConfig processConfig, const std::string &deviceName) { std::lock_guard lock(paElementsMutex_); @@ -274,12 +274,12 @@ std::shared_ptr ProAdapterManager::CreateCapturerStream(AudioPr return capturerStream; } -uint64_t ProAdapterManager::GetLatency() noexcept +uint64_t HpaeAdapterManager::GetLatency() noexcept { return 0; } -void ProAdapterManager::GetAllSinkInputs(std::vector &sinkInputs) +void HpaeAdapterManager::GetAllSinkInputs(std::vector &sinkInputs) { std::lock_guard lock(paElementsMutex_); sinkInputs = sinkInputs_; diff --git a/services/audio_service/server/src/i_stream_manager.cpp b/services/audio_service/server/src/i_stream_manager.cpp index c278f14a50..fc5e8ec44a 100644 --- a/services/audio_service/server/src/i_stream_manager.cpp +++ b/services/audio_service/server/src/i_stream_manager.cpp @@ -16,7 +16,7 @@ #include "audio_utils.h" #include "audio_engine_log.h" #include "pa_adapter_manager.h" -#include "pro_adapter_manager.h" +#include "hpae_adapter_manager.h" #include "pro_audio_stream_manager.h" namespace OHOS { @@ -34,7 +34,7 @@ IStreamManager &IStreamManager::GetPlaybackManager(ManagerType managerType) default: int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - static ProAdapterManager adapterManager(PLAYBACK); + static HpaeAdapterManager adapterManager(PLAYBACK); return adapterManager; } else { static PaAdapterManager adapterManager(PLAYBACK); @@ -47,7 +47,7 @@ IStreamManager &IStreamManager::GetDupPlaybackManager() { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - static ProAdapterManager adapterManager(DUP_PLAYBACK); + static HpaeAdapterManager adapterManager(DUP_PLAYBACK); return adapterManager; } else { static PaAdapterManager adapterManager(DUP_PLAYBACK); @@ -59,7 +59,7 @@ IStreamManager &IStreamManager::GetDualPlaybackManager() { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - static ProAdapterManager adapterManager(DUAL_PLAYBACK); + static HpaeAdapterManager adapterManager(DUAL_PLAYBACK); return adapterManager; } else { static PaAdapterManager adapterManager(DUAL_PLAYBACK); @@ -71,7 +71,7 @@ IStreamManager &IStreamManager::GetRecorderManager() { int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { - static ProAdapterManager adapterManager(RECORDER); + static HpaeAdapterManager adapterManager(RECORDER); return adapterManager; } else { static PaAdapterManager adapterManager(RECORDER); -- Gitee From 0bd80e981fb777c65e68e9f7e9cc410505db5cf9 Mon Sep 17 00:00:00 2001 From: c00657214 Date: Thu, 17 Apr 2025 14:21:46 +0800 Subject: [PATCH 38/40] fix fuzz problem Signed-off-by: c00657214 --- .../audioeffectchain_fuzzer/audio_effect_chain_fuzzer.cpp | 2 ++ .../audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/fuzztest/audioeffectchain_fuzzer/audio_effect_chain_fuzzer.cpp b/test/fuzztest/audioeffectchain_fuzzer/audio_effect_chain_fuzzer.cpp index 9496ee0459..e952d55324 100644 --- a/test/fuzztest/audioeffectchain_fuzzer/audio_effect_chain_fuzzer.cpp +++ b/test/fuzztest/audioeffectchain_fuzzer/audio_effect_chain_fuzzer.cpp @@ -15,6 +15,8 @@ #include #include +#include "securec.h" + #include "audio_effect.h" #include "audio_effect_chain.h" #include "audio_effect_log.h" diff --git a/test/fuzztest/audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp b/test/fuzztest/audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp index 3985a5d9de..522c5b325b 100644 --- a/test/fuzztest/audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp +++ b/test/fuzztest/audioeffectenhance_fuzzer/audio_effect_enhance_fuzzer.cpp @@ -17,6 +17,8 @@ #include #include #include +#include "securec.h" + #include "audio_effect_log.h" #include "audio_effect_chain.h" #include "audio_effect_chain_adapter.h" -- Gitee From f3db6778064d5b59369c7294e11dd884016e21c0 Mon Sep 17 00:00:00 2001 From: hejunjieru Date: Thu, 17 Apr 2025 15:32:07 +0800 Subject: [PATCH 39/40] fix innercap bug Signed-off-by: hejunjieru --- .../server/include/renderer_in_server.h | 3 ++ .../server/src/renderer_in_server.cpp | 30 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/services/audio_service/server/include/renderer_in_server.h b/services/audio_service/server/include/renderer_in_server.h index 53d2cfc2dc..63ceb315d8 100644 --- a/services/audio_service/server/include/renderer_in_server.h +++ b/services/audio_service/server/include/renderer_in_server.h @@ -35,10 +35,12 @@ public: void OnStatusUpdate(IOperation operation) override; int32_t OnWriteData(size_t length) override; int32_t OnWriteData(int8_t *inputData, size_t requestDataLen) override; + std::unique_ptr& GetDupRingBuffer(); private: uint32_t streamIndex_ = 0; FILE *dumpDupOut_ = nullptr; std::string dumpDupOutFileName_ = ""; + std::unique_ptr dupRingBuffer_ = nullptr; }; class RendererInServer : public IStatusCallback, public IWriteCallback, @@ -118,6 +120,7 @@ public: void SetNonInterruptMute(const bool muteFlag); RestoreStatus RestoreSession(RestoreInfo restoreInfo); void dualToneStreamInStart(); + std::shared_ptr& GetDupStreamCallback(); public: const AudioProcessConfig processConfig_; diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index 8eb8048b9d..670aa1e59c 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -339,9 +339,11 @@ void RendererInServer::OnStatusUpdateSub(IOperation operation) case OPERATION_SET_OFFLOAD_ENABLE: case OPERATION_UNSET_OFFLOAD_ENABLE: offloadEnable_ = operation == OPERATION_SET_OFFLOAD_ENABLE ? true : false; - if (offloadEnable_ == true && dupRingBuffer_ != nullptr) { + int32_t engineFlag = GetEngineFlag(); + if (engineFlag == 1 && offloadEnable_ == true && dupStreamCallback_ != nullptr && + dupStreamCallback_->GetDupRingBuffer() != nullptr) { dupTotalSizeInFrame_ = dupSpanSizeInFrame_ * (DUP_OFFLOAD_LEN / DUP_DEFAULT_LEN); - dupRingBuffer_->ReConfig(dupTotalSizeInFrame_ * dupByteSizePerFrame_, false); + dupStreamCallback_->GetDupRingBuffer()->ReConfig(dupTotalSizeInFrame_ * dupByteSizePerFrame_, false); } stateListener->OnOperationHandled(SET_OFFLOAD_ENABLE, operation == OPERATION_SET_OFFLOAD_ENABLE ? 1 : 0); break; @@ -1295,10 +1297,11 @@ int32_t RendererInServer::InitDupStream(int32_t innerCapId) processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid, isSystemApp, processConfig_.rendererInfo.volumeMode); + dupStreamCallback_ = std::make_shared(dupStreamIndex); int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1) { ret = CreateDupBufferInner(innerCapId); - dumpDupInFileName_ = std::to_string(streamIndex_) + "_dup_in_" + ".pcm"; + dumpDupInFileName_ = std::to_string(dupStreamIndex) + "_dup_in_" + ".pcm"; DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupInFileName_, &dumpDupIn_); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Config dup buffer failed"); } @@ -1455,6 +1458,16 @@ int32_t StreamCallbacks::OnWriteData(int8_t *inputData, size_t requestDataLen) return SUCCESS; } +std::unique_ptr& StreamCallbacks::GetDupRingBuffer() +{ + return dupRingBuffer_; +} + +std::shared_ptr& RendererInServer::GetDupStreamCallback() +{ + return dupStreamCallback_; +} + int32_t RendererInServer::SetOffloadMode(int32_t state, bool isAppBack) { int32_t ret = stream_->SetOffloadMode(state, isAppBack); @@ -1833,7 +1846,7 @@ std::unique_ptr& RendererInServer::GetDupRingBuffer() int32_t RendererInServer::CreateDupBufferInner(int32_t innerCapId) { // todo dynamic - if (dupRingBuffer_ != nullptr) { + if (dupStreamCallback_->GetDupRingBuffer() != nullptr) { AUDIO_INFO_LOG("dup buffer already configed!"); return SUCCESS; } @@ -1854,15 +1867,16 @@ int32_t RendererInServer::CreateDupBufferInner(int32_t innerCapId) dupTotalSizeInFrame_, dupSpanSizeInFrame_, dupByteSizePerFrame_, dupSpanSizeInByte_); // create dupBuffer in server - dupRingBuffer_ = AudioRingCache::Create(dupTotalSizeInFrame_ * dupByteSizePerFrame_); - CHECK_AND_RETURN_RET_LOG(dupRingBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create dup buffer failed"); + dupStreamCallback_->GetDupRingBuffer() = AudioRingCache::Create(dupTotalSizeInFrame_ * dupByteSizePerFrame_); + CHECK_AND_RETURN_RET_LOG(dupStreamCallback_->GetDupRingBuffer() != nullptr, ERR_OPERATION_FAILED, + "Create dup buffer failed"); return SUCCESS; } int32_t RendererInServer::WriteDupBufferInner(const BufferDesc &bufferDesc) { size_t targetSize = bufferDesc.bufLength; - OptResult result = dupRingBuffer_->GetWritableSize(); + OptResult result = dupStreamCallback_->GetDupRingBuffer()->GetWritableSize(); // todo get writeable size failed CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "DupRingBuffer write invalid size is:%{public}zu", result.size); @@ -1871,7 +1885,7 @@ int32_t RendererInServer::WriteDupBufferInner(const BufferDesc &bufferDesc) size_t writeSize = std::min(writableSize, targetSize); BufferWrap bufferWrap = {bufferDesc.buffer, writeSize}; if (writeSize > 0) { - result = dupRingBuffer_->Enqueue(bufferWrap); + result = dupStreamCallback_->GetDupRingBuffer()->Enqueue(bufferWrap); if (result.ret != OPERATION_SUCCESS) { AUDIO_ERR_LOG("RingCache Enqueue failed ret:%{public}d size:%{public}zu", result.ret, result.size); } -- Gitee From 142897d68a7dec803074cc58b8eb4c5023032d43 Mon Sep 17 00:00:00 2001 From: hejunjieru Date: Thu, 17 Apr 2025 17:07:45 +0800 Subject: [PATCH 40/40] fix innercap bug_patch Signed-off-by: hejunjieru --- services/audio_service/server/include/renderer_in_server.h | 1 - services/audio_service/server/src/renderer_in_server.cpp | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/services/audio_service/server/include/renderer_in_server.h b/services/audio_service/server/include/renderer_in_server.h index 63ceb315d8..261fcf41b6 100644 --- a/services/audio_service/server/include/renderer_in_server.h +++ b/services/audio_service/server/include/renderer_in_server.h @@ -120,7 +120,6 @@ public: void SetNonInterruptMute(const bool muteFlag); RestoreStatus RestoreSession(RestoreInfo restoreInfo); void dualToneStreamInStart(); - std::shared_ptr& GetDupStreamCallback(); public: const AudioProcessConfig processConfig_; diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index 670aa1e59c..8290af5605 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -312,6 +312,7 @@ void RendererInServer::OnStatusUpdateSub(IOperation operation) { std::shared_ptr stateListener = streamListener_.lock(); CHECK_AND_RETURN_LOG(stateListener != nullptr, "StreamListener is nullptr"); + int32_t engineFlag = GetEngineFlag(); switch (operation) { case OPERATION_RELEASED: stateListener->OnOperationHandled(RELEASE_STREAM, 0); @@ -339,7 +340,6 @@ void RendererInServer::OnStatusUpdateSub(IOperation operation) case OPERATION_SET_OFFLOAD_ENABLE: case OPERATION_UNSET_OFFLOAD_ENABLE: offloadEnable_ = operation == OPERATION_SET_OFFLOAD_ENABLE ? true : false; - int32_t engineFlag = GetEngineFlag(); if (engineFlag == 1 && offloadEnable_ == true && dupStreamCallback_ != nullptr && dupStreamCallback_->GetDupRingBuffer() != nullptr) { dupTotalSizeInFrame_ = dupSpanSizeInFrame_ * (DUP_OFFLOAD_LEN / DUP_DEFAULT_LEN); @@ -1463,11 +1463,6 @@ std::unique_ptr& StreamCallbacks::GetDupRingBuffer() return dupRingBuffer_; } -std::shared_ptr& RendererInServer::GetDupStreamCallback() -{ - return dupStreamCallback_; -} - int32_t RendererInServer::SetOffloadMode(int32_t state, bool isAppBack) { int32_t ret = stream_->SetOffloadMode(state, isAppBack); -- Gitee