## How to build
* local : meson build --reconfigure [-Dtestsuite=enabled] && ninja -C build clean && ninja -C build/
- e.g) meson build --reconfigure -Db_sanitize=address -Db_coverage=true -Dtestsuite=enabled -Damplify=enabled -Dspeex-agc=enabled -Dns-rnnoise=enabled -Daec-refcopy=enabled -Daec-speex=enabled -Daec-webrtc=enabled && ninja -C build clean && ninja -C build/
+ e.g) meson build --reconfigure -Db_sanitize=address -Db_coverage=true -Dtestsuite=enabled -Damplify=enabled -Dspeex-agc=enabled -Dns-rnnoise=enabled -Dns-versatile=enabled -Daec-refcopy=enabled -Daec-speex=enabled -Daec-webrtc=enabled && ninja -C build clean && ninja -C build/
* GBS : gbs build -A aarch64 --include-all
## How to test
/* Noise Suppression */
AUDIO_EFFECT_METHOD_NS_PSE, /* SAIC NS solution */
AUDIO_EFFECT_METHOD_NS_RNNOISE, /* RNNoise */
+ AUDIO_EFFECT_METHOD_NS_VERSATILE, /* SRID solution */
/* Template */
AUDIO_EFFECT_METHOD_AMPLIFY,
#undef LOG_TAG
#endif
#define LOG_TAG "AUDIO_EFFECT"
-#define LOG_ERROR(...) SLOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)
-#define LOG_WARN(...) SLOG(LOG_WARN, LOG_TAG, __VA_ARGS__)
-#define LOG_INFO(...) SLOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
-#define LOG_DEBUG(...) SLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#define LOG_VERBOSE(...) SLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+#define LOG_ERROR(...) SLOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)
+#define LOG_WARN(...) SLOG(LOG_WARN, LOG_TAG, __VA_ARGS__)
+#define LOG_INFO(...) SLOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define LOG_DEBUG(...) SLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+#define LOG_VERBOSE(...) SLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#else
#include <stdio.h>
-#define LOG_ERROR(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
-#define LOG_WARN(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
-#define LOG_INFO(...) { fprintf(stdout, __VA_ARGS__); fprintf(stderr, "\n"); }
-#define LOG_DEBUG(...) { fprintf(stdout, __VA_ARGS__); fprintf(stderr, "\n"); }
-#define LOG_VERBOSE(...) { fprintf(stdout, __VA_ARGS__); fprintf(stderr, "\n"); }
+#define LOG_ERROR(...) { printf(__VA_ARGS__); printf("\n"); }
+#define LOG_WARN(...) { printf(__VA_ARGS__); printf("\n"); }
+#define LOG_INFO(...) { printf(__VA_ARGS__); printf("\n"); }
+#define LOG_DEBUG(...) { printf(__VA_ARGS__); printf("\n"); }
+#define LOG_VERBOSE(...) { printf(__VA_ARGS__); printf("\n"); }
#endif
#endif
)
endif
+# --- srid plugin ---
+if get_option('ns-versatile').enabled()
+shared_library('audio-effect-ns-versatile',
+ sources: [ 'src/plugin_ns_versatile.c' ],
+ dependencies: [ dependency('noise-suppression'), platform_dep ],
+ include_directories: audio_effect_include_dir,
+ link_with: [audio_effect_shared],
+ install: true,
+ install_dir: audio_effect_plugins_install_dir,
+)
+endif
+
# --- aec-refcopy plugin ---
if get_option('aec-refcopy').enabled()
shared_library('audio-effect-aec-refcopy',
option('tizen', type : 'feature', value : 'disabled', description : 'Tizen feature enable')
option('testsuite', type : 'feature', value : 'disabled', description : 'Testsuite')
option('ns-rnnoise', type : 'feature', value : 'disabled', description : 'rnnoise noise suppression')
+option('ns-versatile', type : 'feature', value : 'disabled', description : 'versatile noise suppression')
option('aec-refcopy', type : 'feature', value : 'disabled', description : 'reference copy')
option('aec-speex', type : 'feature', value : 'disabled', description : 'speex aec')
option('aec-webrtc', type : 'feature', value : 'disabled', description : 'webrtc aec')
Name: libaudio-effect
Summary: audio effect library
-Version: 0.0.4
+Version: 0.0.5
Release: 0
Group: System/Libraries
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
+BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(speexdsp)
+BuildRequires: pkgconfig(noise-suppression)
+%if "%{tizen_profile_name}" != "tv"
BuildRequires: pkgconfig(rnnoise)
BuildRequires: pkgconfig(webrtc-audio-processing)
-BuildRequires: pkgconfig(dlog)
+%endif
BuildRequires: meson >= 0.53.0
%description
%setup -q
%build
-%{meson} -Dtizen=enabled -Dns-rnnoise=enabled -Daec-refcopy=enabled -Daec-speex=enabled -Daec-webrtc=enabled
+%{meson} -Dtizen=enabled \
+%if "%{tizen_profile_name}" != "tv"
+ -Dns-rnnoise=enabled \
+ -Daec-webrtc=enabled \
+%endif
+ -Daec-refcopy=enabled \
+ -Daec-speex=enabled \
+ -Dns-versatile=enabled
%{meson_build}
* ISO C forbids conversion of object pointer to function pointer type
* when I convert void pointer to function pointer */
#include <stdint.h>
+#include <string.h>
#include <audio_effect_interface.h>
#include <audio_effect_util.h>
[AUDIO_EFFECT_METHOD_AEC_REFCOPY] = DL_PLUGIN_PATH "libaudio-effect-aec-refcopy.so",
[AUDIO_EFFECT_METHOD_NS_PSE] = DL_PLUGIN_PATH "libaudio-effect-ns-pse.so",
[AUDIO_EFFECT_METHOD_NS_RNNOISE] = DL_PLUGIN_PATH "libaudio-effect-ns-rnnoise.so",
+ [AUDIO_EFFECT_METHOD_NS_VERSATILE] = DL_PLUGIN_PATH "libaudio-effect-ns-versatile.so",
[AUDIO_EFFECT_METHOD_AMPLIFY] = DL_PLUGIN_PATH "libaudio-effect-amplify.so",
[AUDIO_EFFECT_METHOD_AGC_SPEEX] = DL_PLUGIN_PATH "libaudio-effect-agc-speex.so",
};
if (!plugin_list[method].plugin_info && plugin_list[method].refcnt == 0) {
handle = dlopen(effect_path_list[method], RTLD_LAZY);
if (!handle) {
- LOG_INFO("Failed to open handle. path(%s) dlerror(%s)", get_plugin_name(effect_path_list[method]), dlerror());
+ LOG_ERROR("Failed to open handle. path(%s) dlerror(%s)", get_plugin_name(effect_path_list[method]), dlerror());
return NULL;
}
}
--- /dev/null
+/*
+* Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <audio_effect_interface.h>
+#include <audio_effect_log.h>
+
+#include <noise-suppression.h>
+
+#define MAX_DELAY_MSEC 20
+
+struct userdata {
+ noise_suppression_h handle;
+ float *buffer;
+ size_t frames;
+};
+
+void init_noise_suppression_versatile(void) __attribute__ ((constructor));
+void fini_noise_suppression_versatile(void) __attribute__ ((destructor));
+static audio_effect_plugin_info_s noise_suppression_versatile;
+
+void *noise_suppression_versatile_create(int rate, int channels, audio_effect_format_e format, size_t frames)
+{
+ struct userdata *u;
+ noise_suppression_h handle;
+ unsigned int frame_size = frames;
+
+ if (rate != 48000 && rate != 16000) {
+ LOG_ERROR("Not support rate %d", rate);
+ return NULL;
+ }
+
+ if (noise_suppression_initialize(NULL, rate, MAX_DELAY_MSEC, &handle, &frame_size) != NOISE_SUPPRESSION_ERROR_NONE) {
+ LOG_ERROR("Failed to init noise-suppression versatile");
+ return NULL;
+ }
+
+ if ((size_t)frame_size != frames) {
+ LOG_INFO("frames_size(%d) is not same with frame(%zu)", frame_size, frames);
+ noise_suppression_versatile.constraint.frames = frame_size;
+ }
+
+ u = (struct userdata *)malloc(sizeof(struct userdata));
+ u->handle = handle;
+ u->frames = frames;
+ u->buffer = (float *)malloc(sizeof(float) * frames);
+
+ noise_suppression_set_level(u->handle, NOISE_SUPPRESSION_LEVEL_MID);
+
+ LOG_INFO("plugin noise-suppression versatile init. rate(%d), channels(%d), format(%d), frames(%zu), frame_size(%d)",
+ rate, channels, format, frames, frame_size);
+
+ return u;
+}
+
+int noise_suppression_versatile_process(void *priv, char *in, char *out)
+{
+ struct userdata *u = (struct userdata *)priv;
+ int16_t *rec = (int16_t *)in;
+ int16_t *result = (int16_t *)out;
+ int i;
+
+ assert(u);
+ assert(u->handle);
+ assert(u->buffer);
+ assert(rec);
+ assert(result);
+
+ for (i = 0; i < u->frames; i++)
+ u->buffer[i] = rec[i];
+
+ if (NOISE_SUPPRESSION_ERROR_NONE !=
+ noise_suppression_process_audio(u->handle, u->buffer, u->buffer)) {
+ LOG_ERROR("Failed to process noise suppression");
+ return -1;
+ }
+
+ for (i = 0; i < u->frames; i++)
+ result[i] = u->buffer[i];
+
+ return 0;
+}
+
+void noise_suppression_versatile_destroy(void *priv)
+{
+ struct userdata *u = (struct userdata *)priv;
+
+ if (u->buffer)
+ free(u->buffer);
+
+ if (u->handle)
+ noise_suppression_deinitialize(u->handle);
+
+ free(u);
+}
+
+static audio_effect_plugin_info_s noise_suppression_versatile = {
+ .name = "noise-suppression-versatile",
+ .interface = {
+ .method = AUDIO_EFFECT_METHOD_NS_VERSATILE,
+ .create = noise_suppression_versatile_create,
+ .process = noise_suppression_versatile_process,
+ .destroy = noise_suppression_versatile_destroy,
+ },
+ .constraint = {
+ .frames = 480,
+ .min_rate = 16000,
+ .max_rate = 48000,
+ .min_channels = 1,
+ .max_channels = 1,
+ .min_format = AUDIO_EFFECT_FORMAT_S16,
+ .max_format = AUDIO_EFFECT_FORMAT_S16,
+ },
+};
+
+void init_noise_suppression_versatile(void)
+{
+ audio_effect_register_module(&noise_suppression_versatile);
+}
+
+void fini_noise_suppression_versatile(void)
+{
+ audio_effect_unregister_module(&noise_suppression_versatile);
+}
+
int i=0;
- printf("--- Hello test start ---\n");
+ printf("--- amplify start ---\n");
fin = fopen("obama.raw", "r");
if (!fin) {
}
fout = fopen("amplify_out.raw", "wb");
- if (!fin) {
+ if (!fout) {
printf("failed to open raw\n");
exit(-1);
}
ae = audio_effect_create(AUDIO_EFFECT_METHOD_AMPLIFY, 16000, 1, AUDIO_EFFECT_FORMAT_S16, FRAME_SIZE);
while (!feof(fin)) {
- printf("#%d frame. \n", i++);
+ printf("#%d frame. ", i++);
ret = fread(in, FRAME_SIZE*sizeof(short), 1, fin);
if (audio_effect_process(ae, in, out) < 0) {
printf("(failed!)\n");
test_list += [[ 'ns_rnnoise_test', 'ns_rnnoise_test.c' ]]
endif
+if get_option('ns-versatile').enabled()
+ test_list += [[ 'ns_versatile_test', 'ns_versatile_test.c' ]]
+endif
+
if get_option('aec-refcopy').enabled()
test_list += [[ 'aec_refcopy_test', 'aec_refcopy_test.c' ]]
endif
#include "audio_effect.h"
-#define FRAME_SIZE 480
+#define FRAME_SIZE (480)
int main(void)
{
FILE *fout;
short in[FRAME_SIZE];
short out[FRAME_SIZE];
- size_t ret;
size_t framesize = FRAME_SIZE;
int i=0;
}
fout = fopen("rnnoise_out.raw", "wb");
- if (!fin) {
+ if (!fout) {
printf("failed to open raw\n");
exit(-1);
}
printf("frame size %zu\n", framesize);
while (!feof(fin)) {
- printf("#%d frame. \n", i++);
- ret = fread(in, sizeof(in), 1, fin);
+ if (fread(in, sizeof(short), FRAME_SIZE, fin) < 0)
+ break;
+
+ printf("#%d frame. ", i++);
+
if (audio_effect_process(ae, in, out) < 0) {
printf("(failed!)\n");
} else {
- printf("(success!), ret(%zu)\n", ret);
- fwrite(out, framesize*sizeof(short), 1, fout);
+ printf("(success!)\n");
+ fwrite(out, sizeof(short), FRAME_SIZE, fout);
}
}
+ audio_effect_destroy(ae);
+
fclose(fin);
fclose(fout);
- audio_effect_destroy(ae);
-
printf("--- Hello test end ---\n");
return 0;
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "audio_effect.h"
+
+#define FRAME_SIZE (1024) /* 48KHz:960, 16KHz:320 */
+
+int main(void)
+{
+ audio_effect_s *ae;
+ FILE *fin;
+ FILE *fout;
+ short in[FRAME_SIZE];
+ short out[FRAME_SIZE];
+ size_t framesize = FRAME_SIZE;
+
+ int i, n = 0;
+
+ const char *source_file[] = { "airport_48k.raw", "obama.raw" };
+ const char *output_file[] = { "versatile_out_48k.raw", "versatile_out_16k.raw" };
+
+ int loop = sizeof(source_file) / sizeof(char *);
+ int rate[] = { 48000, 16000 };
+
+ for (i = 0; i < loop; i++) {
+ printf("--- versatile start ---\n");
+ printf("source file : %s\n", source_file[i]);
+ printf("output file : %s\n", output_file[i]);
+ printf("samplerate : %d\n", rate[i]);
+
+ fin = fopen(source_file[i], "r");
+ if (!fin) {
+ printf("failed to find airport_48k.raw\n");
+ exit(-1);
+ }
+
+ fout = fopen(output_file[i], "wb");
+ if (!fout) {
+ printf("failed to open raw\n");
+ exit(-1);
+ }
+
+ ae = audio_effect_create(AUDIO_EFFECT_METHOD_NS_VERSATILE, rate[i], 1, AUDIO_EFFECT_FORMAT_S16, framesize);
+ assert(ae);
+
+ framesize = audio_effect_get_process_framesize(ae);
+ printf("setting frame size %zu\n", framesize);
+
+ while (!feof(fin)) {
+ if (fread(in, sizeof(short), framesize, fin) < 0)
+ break;
+
+ printf("#%d frame. ", n++);
+
+ if (audio_effect_process(ae, in, out) < 0) {
+ printf("(failed!)\n");
+ } else {
+ printf("(success!)\n");
+ fwrite(out, sizeof(short), framesize, fout);
+ }
+ }
+
+ audio_effect_destroy(ae);
+
+ fclose(fin);
+ fclose(fout);
+
+ }
+
+ printf("--- test end ---\n");
+
+ return 0;
+}