From c912da02593762322b6a14f8d1f56595ba006738 Mon Sep 17 00:00:00 2001 From: Jaechul Lee Date: Wed, 5 Jul 2023 15:12:01 +0900 Subject: [PATCH] Add effect methods information to AudioInfo [Version] 0.5.58 [Issue Type] Update Change-Id: I9c685f9b724583e1afa616a6f387aa6dd34ca981 Signed-off-by: Jaechul Lee --- CMakeLists.txt | 1 + include/CAudioInfo.h | 18 ++++--- packaging/capi-media-audio-io.spec | 2 +- src/cpp/CAudioIO.cpp | 19 +++----- src/cpp/CAudioInfo.cpp | 67 +++++++++++++++----------- src/cpp/CPulseAudioClient.cpp | 17 ++++--- test/audio_io_process_test.c | 97 ++++++++++++++++++++++---------------- 7 files changed, 125 insertions(+), 96 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c72833..af1abcb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ SET(fw_name "capi-media-audio-io") PROJECT(${fw_name}) +SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_INSTALL_PREFIX /usr) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) diff --git a/include/CAudioInfo.h b/include/CAudioInfo.h index 1b1163b..5ee60e1 100644 --- a/include/CAudioInfo.h +++ b/include/CAudioInfo.h @@ -142,10 +142,12 @@ namespace tizen_media_audio { int getAudioIndex() noexcept; void setAudioIndex(int audioIndex) noexcept; int getSampleSize() noexcept; - void bindEchoCancelReferenceDeviceId(int id, sound_acoustic_echo_cancel_type_e type); - int getEchoCancelReferenceDeviceId() noexcept; - void setNoiseSuppression(bool enable, sound_noise_suppression_type_e type); - std::string& getProcessorProperty() noexcept; + + void setEffectMethod(int method) noexcept; + std::string getEffectMethod() noexcept; + + void setEffectMethodWithReference(sound_effect_method_with_reference_e method, int id) noexcept; + std::pair getEffectMethodWithReference() noexcept; /* Setter & Getter Utilities */ const char* getConvertedStreamType(); @@ -201,9 +203,11 @@ namespace tizen_media_audio { ESampleType __mSampleType; EAudioType __mAudioType; int __mAudioIndex; - int __mReferenceDeviceId; - bool __mNoiseSuppression; - std::string __mProcessorProperty; + + sound_effect_method_with_reference_e __mEffectMethodWithReference; + int __mEffectMethodReferenceDeviceId; + int __mEffectMethod; + }; diff --git a/packaging/capi-media-audio-io.spec b/packaging/capi-media-audio-io.spec index f809753..ee9e64c 100644 --- a/packaging/capi-media-audio-io.spec +++ b/packaging/capi-media-audio-io.spec @@ -1,6 +1,6 @@ Name: capi-media-audio-io Summary: An Audio Input & Audio Output library in Tizen Native API -Version: 0.5.57 +Version: 0.5.58 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/cpp/CAudioIO.cpp b/src/cpp/CAudioIO.cpp index e337973..e6149ec 100644 --- a/src/cpp/CAudioIO.cpp +++ b/src/cpp/CAudioIO.cpp @@ -226,20 +226,13 @@ void CAudioIO::setStreamInfo(sound_stream_info_h stream_info) { if (mDirection == CAudioInfo::EAudioDirection::AUDIO_DIRECTION_IN) { int device_id; - bool noise_suppression_enabled; - sound_acoustic_echo_cancel_type_e aec_type; - sound_noise_suppression_type_e ns_type; + int method; + sound_effect_method_with_reference_e method_reference; - if ((errorCode = sound_manager_get_echo_cancel_reference_device(stream_info, &device_id, &aec_type)) != SOUND_MANAGER_ERROR_NONE) - THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Can't get reference device [ret:%d]", errorCode); //LCOV_EXCL_LINE + if (sound_manager_get_effect_method(stream_info, &method) == SOUND_MANAGER_ERROR_NONE) + getAudioInfo().setEffectMethod(method); - if (device_id != SOUND_MANAGER_STREAM_NO_REFERENCE_DEVICE) - getAudioInfo().bindEchoCancelReferenceDeviceId(device_id, aec_type); - - if ((errorCode = sound_manager_get_noise_suppression(stream_info, &noise_suppression_enabled, &ns_type)) != SOUND_MANAGER_ERROR_NONE) - THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Can't get noise suppression status [ret:%d]", errorCode); //LCOV_EXCL_LINE - - if (noise_suppression_enabled) - getAudioInfo().setNoiseSuppression(noise_suppression_enabled, ns_type); + if (sound_manager_get_effect_method_with_reference(stream_info, &method_reference, &device_id) == SOUND_MANAGER_ERROR_NONE) + getAudioInfo().setEffectMethodWithReference(method_reference, device_id); } } diff --git a/src/cpp/CAudioInfo.cpp b/src/cpp/CAudioInfo.cpp index f5d2666..367fd4f 100644 --- a/src/cpp/CAudioInfo.cpp +++ b/src/cpp/CAudioInfo.cpp @@ -19,6 +19,8 @@ #include #include "CAudioIODef.h" +#include +#include using namespace std; using namespace tizen_media_audio; @@ -33,8 +35,9 @@ CAudioInfo::CAudioInfo() : __mSampleType(ESampleType::SAMPLE_TYPE_U8), __mAudioType(EAudioType::AUDIO_IN_TYPE_MEDIA), __mAudioIndex(-1), - __mReferenceDeviceId(0), - __mNoiseSuppression(false) { + __mEffectMethodWithReference((sound_effect_method_with_reference_e)0), + __mEffectMethodReferenceDeviceId(0), + __mEffectMethod(0) { } CAudioInfo::CAudioInfo(unsigned int sampleRate, EChannel channel, ESampleType sampleType, EAudioType audioType, int audioIndex) : @@ -43,8 +46,9 @@ CAudioInfo::CAudioInfo(unsigned int sampleRate, EChannel channel, ESampleType sa __mSampleType(sampleType), __mAudioType(audioType), __mAudioIndex(audioIndex), - __mReferenceDeviceId(0), - __mNoiseSuppression(false) { + __mEffectMethodWithReference((sound_effect_method_with_reference_e)0), + __mEffectMethodReferenceDeviceId(0), + __mEffectMethod(0) { // Check to invalid AudioInfo if (sampleRate < CAudioInfo::MIN_SYSTEM_SAMPLERATE || sampleRate > CAudioInfo::MAX_SYSTEM_SAMPLERATE) @@ -125,37 +129,44 @@ int CAudioInfo::getSampleSize() noexcept { return bytes_in_sample * static_cast(__mChannel); } -void CAudioInfo::bindEchoCancelReferenceDeviceId(int id, sound_acoustic_echo_cancel_type_e type) { - if (type == SOUND_ACOUSTIC_ECHO_CANCEL_VOICE_CALL) - __mProcessorProperty += "webrtc,"; - else if (type == SOUND_ACOUSTIC_ECHO_CANCEL_REFERENCE_COPY) - __mProcessorProperty += "reference_copy,"; - else - THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, - "The echo cancel is not supported [type:%d]", type); +void CAudioInfo::setEffectMethod(int method) noexcept { + __mEffectMethod = method; +} + +std::string CAudioInfo::getEffectMethod() noexcept { + std::string method; + + if (__mEffectMethod & SOUND_EFFECT_NOISE_SUPPRESSION_VOIP) + method += "ns-rnnoise,"; + + if (__mEffectMethod & SOUND_EFFECT_NOISE_SUPPRESSION_VOICE_RECOGNITION) + method += "ns-pse,"; - __mReferenceDeviceId = id; + if (__mEffectMethod & SOUND_EFFECT_NOISE_SUPPRESSION_DOORBELL) + method += "ns-srid,"; + + if (__mEffectMethod & SOUND_EFFECT_AUTOMATIC_GAIN_CONTROL_CAPTURE) + method += "agc-speex,"; + + return method; } -int CAudioInfo::getEchoCancelReferenceDeviceId() noexcept { - return __mReferenceDeviceId; +void CAudioInfo::setEffectMethodWithReference(sound_effect_method_with_reference_e method, int id) noexcept { + __mEffectMethodWithReference = method; + __mEffectMethodReferenceDeviceId = id; } -void CAudioInfo::setNoiseSuppression(bool enable, sound_noise_suppression_type_e type) { - if (type == SOUND_NOISE_SUPPRESSION_VOICE_CALL) { - __mProcessorProperty += "rnnoise,"; - } else if (type == SOUND_NOISE_SUPPRESSION_VOICE_RECOGNITION) { - __mProcessorProperty += "pse,"; - } else { - THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, - "The noise suppression type is not supported [type:%d]", type); - } +std::pair CAudioInfo::getEffectMethodWithReference() noexcept { + std::string method; - __mNoiseSuppression = enable; -} + if (__mEffectMethodWithReference == SOUND_EFFECT_REFERENCE_COPY) + method += "reference_copy,"; + else if (__mEffectMethodWithReference == SOUND_EFFECT_ACOUSTIC_ECHO_CANCEL_SPEEX) + method += "aec-speex,"; + else if (__mEffectMethodWithReference == SOUND_EFFECT_ACOUSTIC_ECHO_CANCEL_WEBRTC) + method += "aec-webrtc,"; -std::string& CAudioInfo::getProcessorProperty() noexcept { - return __mProcessorProperty; + return make_pair(method, __mEffectMethodReferenceDeviceId); } const char* CAudioInfo::getConvertedStreamType() { diff --git a/src/cpp/CPulseAudioClient.cpp b/src/cpp/CPulseAudioClient.cpp index 34f769a..c47a4ac 100644 --- a/src/cpp/CPulseAudioClient.cpp +++ b/src/cpp/CPulseAudioClient.cpp @@ -412,14 +412,17 @@ void CPulseAudioClient::initialize() { pa_proplist_setf(__mpPropList, PA_PROP_MEDIA_PARENT_ID, "%u", (unsigned int) index); if (__mDirection == EStreamDirection::STREAM_DIRECTION_RECORD) { - int reference_id = __mSpec.getAudioInfo().getEchoCancelReferenceDeviceId(); - if (reference_id > 0) { - pa_proplist_setf(__mpPropList, PA_PROP_MEDIA_ECHO_CANCEL_REFERENCE_DEVICE, "%d", reference_id); - } + /* Noise-suppression effect should be set first. */ + std::string method = __mSpec.getAudioInfo().getEffectMethod(); + auto [ method_reference, device_id ] = __mSpec.getAudioInfo().getEffectMethodWithReference(); + std::string method_all = method + method_reference; + + if (!method_all.empty()) { + pa_proplist_setf(__mpPropList, PA_PROP_MEDIA_PREPROCESSOR_METHOD, "%s", method_all.c_str()); + pa_proplist_setf(__mpPropList, PA_PROP_MEDIA_ECHO_CANCEL_REFERENCE_DEVICE, "%d", device_id); - if (!__mSpec.getAudioInfo().getProcessorProperty().empty()) - pa_proplist_setf(__mpPropList, PA_PROP_MEDIA_PREPROCESSOR_METHOD, "%s", - __mSpec.getAudioInfo().getProcessorProperty().c_str()); + AUDIO_IO_LOGD("preprocess will be set. method[%s], device_id[%d]", method_all.c_str(), device_id); + } } // Adds latency on proplist for delivery to PULSEAUDIO diff --git a/test/audio_io_process_test.c b/test/audio_io_process_test.c index 5cf4c6b..4276fb7 100644 --- a/test/audio_io_process_test.c +++ b/test/audio_io_process_test.c @@ -19,20 +19,21 @@ #include #include #include -#include #include -static bool arg_aec_is_set; -static int arg_aec_ref; -static sound_acoustic_echo_cancel_type_e arg_aec_type; - -static bool arg_ns_is_set; -static sound_noise_suppression_type_e arg_ns_type; +#define DEFAULT_CHANNELS 1 static int arg_samplerate; static audio_channel_e arg_channels; static audio_sample_type_e arg_format; +static bool arg_ref_dev_is_set; +static int arg_ref_dev; +static bool arg_method_is_set; +static int arg_method; +static bool arg_reference_method_is_set; +static int arg_reference_method; + static char arg_filename[256]; static int ch_table[] = { 0, AUDIO_CHANNEL_MONO, AUDIO_CHANNEL_STEREO, @@ -66,7 +67,7 @@ static void record() goto out; } - if (arg_aec_is_set) { + if (arg_reference_method_is_set) { if (sound_manager_get_device_list(SOUND_DEVICE_ALL_MASK, &device_list) != SOUND_MANAGER_ERROR_NONE) { printf("fail to get device list"); goto out; @@ -76,7 +77,7 @@ static void record() if (sound_manager_get_device_id(device, &id) != SOUND_MANAGER_ERROR_NONE) goto out; - if (arg_aec_ref == id) { + if (arg_ref_dev == id) { found = true; break; } @@ -87,9 +88,9 @@ static void record() goto out; } - ret = sound_manager_set_echo_cancel_reference_device(stream_info, device, arg_aec_type); + ret = sound_manager_set_effect_method_with_reference(stream_info, arg_reference_method, device); if (ret != SOUND_MANAGER_ERROR_NONE) { - printf("fail to sound_manager_set_echo_cancel_reference_device(), ret(0x%x)\n", ret); + printf("fail to sound_manager_set_audio_effect_reference_device(), ret(0x%x)\n", ret); goto out; } @@ -97,11 +98,11 @@ static void record() { int device_id; int id; - sound_acoustic_echo_cancel_type_e aec_type; + sound_effect_method_with_reference_e method; - ret = sound_manager_get_echo_cancel_reference_device(stream_info, &device_id, &aec_type); + ret = sound_manager_get_effect_method_with_reference(stream_info, &method, &device_id); if (ret != SOUND_MANAGER_ERROR_NONE) { - printf("fail to sound_manager_get_echo_cancel_reference_device(), ret(0x%x)\n", ret); + printf("fail to sound_manager_get_audio_effect_reference_device(), ret(0x%x)\n", ret); goto out; } @@ -110,33 +111,32 @@ static void record() goto out; } - if (device_id != id || arg_aec_type != aec_type) { + if (device_id != id || method != arg_reference_method) { printf("fail to verify aec args\n"); goto out; } } } - if (arg_ns_is_set) { - ret = sound_manager_set_noise_suppression(stream_info, arg_ns_is_set, arg_ns_type); + if (arg_method_is_set) { + ret = sound_manager_set_effect_method(stream_info, arg_method); if (ret != SOUND_MANAGER_ERROR_NONE) { - printf("failed to sound_manager_set_noise_suppression(), ret(0x%x)\n", ret); + printf("failed to sound_manager_set_audio_effect_method(), ret(0x%x)\n", ret); goto out; } /* verify */ { - bool ns_enabled; - sound_noise_suppression_type_e ns_type; + int method; - ret = sound_manager_get_noise_suppression(stream_info, &ns_enabled, &ns_type); + ret = sound_manager_get_effect_method(stream_info, &method); if (ret != SOUND_MANAGER_ERROR_NONE) { - printf("fail to sound_manager_get_echo_cancel_reference_device(), ret(0x%x)\n", ret); + printf("fail to sound_manager_get_audio_effect_reference_device(), ret(0x%x)\n", ret); goto out; } - if (arg_ns_is_set != ns_enabled || arg_ns_type != ns_type) { - printf("fail to verify ns args\n"); + if (method != arg_method) { + printf("fail to verify method args\n"); goto out; } } @@ -196,17 +196,27 @@ out: static void print_usage() { - printf("audio_io_process_test -r [samplerate] -c [channels] -d [reference_device_id] -a [AEC type] -n [NS type] -o [output filename]\n"); - printf("e.g) audio_io_process_test -r 16000 -d 1 -a 0 -n 0 -o filename\n"); + printf("Usage\n\n"); + printf("audio_io_process_test -r [samplerate] -c [channels] -a [reference_method] -d [reference_device_id] -m [methods] -o [output filename]\n"); + printf("e.g) audio_io_process_test -r 48000 -d 1 -m 0x0001 -a 0x0004 -d 1 -o filename (method:webrtc and voicecall)\n"); + + printf("\n"); + printf("Please refer to the optional arguments as following.\n\n"); + printf("Options\n"); + printf("-a\t\taudio-effects with reference device_id like AEC\n"); + printf("\t\te.g) refcopy:0x0001, aec-speex:0x0002, aec-webrtc:0x0004\n"); + + printf("-m\t\taudio-effects like noise-suppression\n"); + printf("\t\te.g) rnnoise:0x0001, agc-speex:0x0002, pse:0x0200, doorbel:0x0100\n"); } int main(int argc, char **argv) { setbuf(stdout, NULL); - const char *optstring = "r:c:f:a:n:o:d:"; + const char *optstring = "r:c:f:m:o:d:a:"; int option; - arg_channels = AUDIO_CHANNEL_MONO; + arg_channels = DEFAULT_CHANNELS; arg_format = AUDIO_SAMPLE_TYPE_S16_LE; if (argc == 1) { @@ -221,20 +231,21 @@ int main(int argc, char **argv) arg_samplerate = atoi(optarg); printf("Samplerate : %d\n", arg_samplerate); break; - case 'd': /* reference device */ - arg_aec_ref = atoi(optarg); - arg_aec_is_set = true; - printf("AEC reference device : %d\n", arg_aec_ref); + case 'a': /* sound_effect_method_with_reference_e */ + arg_reference_method_is_set = true; + arg_reference_method = (int)strtol(optarg, NULL, 16); + printf("reference method : 0x%x, optarg(%s)\n", + arg_reference_method, optarg); break; - case 'a': /* AEC method */ - arg_aec_type = atoi(optarg); - arg_aec_is_set = true; - printf("AEC reference type: %d\n", arg_aec_type); + case 'd': /* reference device */ + arg_ref_dev_is_set = true; + arg_ref_dev = atoi(optarg); + printf("reference device : %d\n", arg_ref_dev); break; - case 'n': /* Noise suppression method */ - arg_ns_type = atoi(optarg); - arg_ns_is_set = true; - printf("Noise Suppression Type : %d\n", arg_ns_type); + case 'm': /* method */ + arg_method_is_set = true; + arg_method = (int)strtol(optarg, NULL, 16); + printf("method : 0x%x, optarg(%s)\n", arg_method, optarg); break; case 'o': /* output file */ snprintf(arg_filename, sizeof(arg_filename), "%s", optarg); @@ -256,6 +267,12 @@ int main(int argc, char **argv) } printf("=================================\n"); + if ((arg_reference_method_is_set && !arg_ref_dev_is_set) || + (!arg_reference_method_is_set && arg_ref_dev_is_set)) { + printf("need to set reference devices and method both\n"); + return 0; + } + record(); printf("END\n"); -- 2.7.4