From: Jaechul Lee Date: Wed, 10 May 2023 08:20:56 +0000 (+0900) Subject: Use libaudio-effect module X-Git-Tag: accepted/tizen/unified/20230620.022501^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ba829f18171f3f229edfb7b30d533216684be9db;p=platform%2Fcore%2Fmultimedia%2Fpulseaudio-modules-tizen.git Use libaudio-effect module * Moved every plugin to libaudio-effect * Added a dependency on libaudio-effect [Version] 15.0.42 [Issue Type] New feature Change-Id: Ib32588d6138258647af5df5ce0f622289003ad49 Signed-off-by: Jaechul Lee --- diff --git a/Makefile.am b/Makefile.am index 91d448d..01e5190 100644 --- a/Makefile.am +++ b/Makefile.am @@ -82,7 +82,7 @@ libtizenaudio_util_la_SOURCES = \ src/tizenaudio-source2.h \ src/tizenaudio-util.c \ src/tizenaudio-util.h \ - src/preprocessor/preprocessor-def.h + src/preprocessor/processor-def.h libtizenaudio_util_la_LDFLAGS = $(AM_LDFLAGS) $(PA_LDFLAGS) -avoid-version libtizenaudio_util_la_LIBADD = $(AM_LIBADD) $(PA_LIBS) libhal-interface.la libprocessor.la libtizenaudio_util_la_CFLAGS = $(MODULE_CFLAGS) @@ -98,13 +98,10 @@ module_tizenaudio_source2_la_LIBADD = $(MODULE_LIBADD) libtizenaudio-util.la module_tizenaudio_source2_la_CFLAGS = $(MODULE_CFLAGS) -DPA_MODULE_NAME=module_tizenaudio_source2 libprocessor_la_SOURCES = \ - src/preprocessor/method_speex.c \ - src/preprocessor/method_rnnoise.c \ - src/preprocessor/method_reference_copy.c \ - src/preprocessor/method_webrtc.cpp \ src/preprocessor/reference_method_filesrc.c \ src/preprocessor/processor.c \ src/preprocessor/processor.h \ + src/preprocessor/processor-def.h \ src/preprocessor/method_factory.c \ src/preprocessor/method_factory.h \ src/preprocessor/processor_reference.c \ @@ -112,8 +109,8 @@ libprocessor_la_SOURCES = \ src/preprocessor/processor_holder.c \ src/preprocessor/processor_holder.h libprocessor_la_LDFLAGS = $(AM_LDFLAGS) $(PA_LDFLAGS) -avoid-version -libprocessor_la_LIBADD = $(AM_LIBADD) $(LIBSPEEX_LIBS) $(RNNOISE_LIBS) $(WEBRTC_LIBS) -libprocessor_la_CFLAGS = $(AM_CFLAGS) $(PA_CFLAGS) $(LIBSPEEX_CFLAGS) $(RNNOISE_CFLAGS) +libprocessor_la_LIBADD = $(AM_LIBADD) $(AUDIOEFFECT_LIBS) +libprocessor_la_CFLAGS = $(AM_CFLAGS) $(PA_CFLAGS) $(AUDIOEFFECT_CFLAGS) libprocessor_la_CPPFLAGS = $(AM_CFLAGS) $(PA_CFLAGS) $(WEBRTC_CFLAGS) -DSUPPORT_METHOD_WEBRTC -std=c++17 module_tizenaudio_preprocessor_la_SOURCES = src/preprocessor/module-tizenaudio-preprocessor.c diff --git a/configure.ac b/configure.ac index 6c3637f..6f2ebe6 100644 --- a/configure.ac +++ b/configure.ac @@ -369,17 +369,10 @@ PKG_CHECK_MODULES(HALAPIAUDIO, hal-api-audio) AC_SUBST(HALAPIAUDIO_CFLAGS) AC_SUBST(HALAPIAUDIO_LIBS) -PKG_CHECK_MODULES(SPEEX, speexdsp) -AC_SUBST(SPEEX_CFLAGS) -AC_SUBST(SPEEX_LIBS) +PKG_CHECK_MODULES(AUDIOEFFECT, libaudio-effect) +AC_SUBST(AUDIOEFFECT_CFLAGS) +AC_SUBST(AUDIOEFFECT_LIBS) -PKG_CHECK_MODULES(WEBRTC, webrtc-audio-processing) -AC_SUBST(WEBRTC_CFLAGS) -AC_SUBST(WEBRTC_LIBS) - -PKG_CHECK_MODULES(RNNOISE, rnnoise) -AC_SUBST(RNNOISE_CFLAGS) -AC_SUBST(RNNOISE_LIBS) dnl use hal tc ------------------------------------------------------------ AC_ARG_ENABLE(haltc, AC_HELP_STRING([--enable-haltc], [using haltc]), diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index ee30edf..ba66270 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -2,7 +2,7 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 15.0.41 +Version: 15.0.42 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ @@ -26,6 +26,7 @@ BuildRequires: pkgconfig(hal-api-audio) BuildRequires: pkgconfig(speexdsp) BuildRequires: pkgconfig(rnnoise) BuildRequires: pkgconfig(webrtc-audio-processing) +BuildRequires: pkgconfig(libaudio-effect) BuildRequires: pulseaudio BuildRequires: m4 Requires(post): /sbin/ldconfig diff --git a/src/preprocessor/method_factory.c b/src/preprocessor/method_factory.c index 902f7fd..695eb43 100644 --- a/src/preprocessor/method_factory.c +++ b/src/preprocessor/method_factory.c @@ -25,62 +25,10 @@ #include "processor.h" -extern void *speex_create(size_t nframes, pa_sample_spec *ss); -extern int32_t speex_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out); -extern int32_t speex_destroy(void *priv); - -extern void *webrtc_audio_create(size_t nframes, pa_sample_spec *ss); -extern int32_t webrtc_audio_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out); -extern int32_t webrtc_audio_destroy(void *priv); - -extern void *reference_copy_create(size_t nframes, pa_sample_spec *ss); -extern int32_t reference_copy_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out); -extern int32_t reference_copy_destroy(void *priv); - -extern void *rnnoise_ns_create(size_t nframes, pa_sample_spec *ss); -extern int32_t rnnoise_ns_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out); -extern int32_t rnnoise_ns_destroy(void *priv); - extern void *processor_reference_filesrc_create(pa_sample_spec *ss); extern size_t processor_reference_filesec_read(void *priv, void *ref, size_t length); extern void processor_reference_filesrc_destroy(void *priv); -pa_processor_method *pa_processor_method_create(pa_processor_method_t type) { - pa_processor_method *m = pa_xnew0(pa_processor_method, 1); - - switch (type) { - case PROCESSOR_METHOD_SPEEX: - m->name = "speex"; - m->create = speex_create; - m->process = speex_process; - m->destroy = speex_destroy; - break; - case PROCESSOR_METHOD_WEBRTC: - m->name = "webrtc"; - m->create = webrtc_audio_create; - m->process = webrtc_audio_process; - m->destroy = webrtc_audio_destroy; - break; - case PROCESSOR_METHOD_REFERENCE_COPY: - m->name = "reference_copy"; - m->create = reference_copy_create; - m->process = reference_copy_process; - m->destroy = reference_copy_destroy; - break; - case PROCESSOR_METHOD_RNNOISE: - m->name = "rnnoise"; - m->create = rnnoise_ns_create; - m->process = rnnoise_ns_process; - m->destroy = rnnoise_ns_destroy; - break; - default: - pa_assert_not_reached(); - break; - } - - return m; -} - pa_processor_reference_method *pa_processor_reference_method_create(pa_processor_reference_method_t type) { pa_processor_reference_method *m = pa_xnew0(pa_processor_reference_method, 1); diff --git a/src/preprocessor/method_factory.h b/src/preprocessor/method_factory.h index 110d150..96bd030 100644 --- a/src/preprocessor/method_factory.h +++ b/src/preprocessor/method_factory.h @@ -31,6 +31,7 @@ typedef enum { PROCESSOR_METHOD_WEBRTC, PROCESSOR_METHOD_REFERENCE_COPY, PROCESSOR_METHOD_RNNOISE, + PROCESSOR_METHOD_NONE_PSE, PROCESSOR_METHOD_MAX, } pa_processor_method_t; @@ -41,13 +42,6 @@ typedef enum { PROCESSOR_REFERENCE_METHOD_MAX, } pa_processor_reference_method_t; -typedef struct pa_processor_method { - const char *name; - void *(*create)(size_t nframes, pa_sample_spec *ss); - int32_t (*process)(void *priv, int8_t *rec, int8_t *ref, int8_t *out); - int32_t (*destroy)(void *priv); -} pa_processor_method; - typedef struct pa_processor_reference_method { const char *name; void *(*create)(pa_sample_spec *ss); @@ -55,7 +49,6 @@ typedef struct pa_processor_reference_method { void (*destroy)(void *priv); } pa_processor_reference_method; -pa_processor_method *pa_processor_method_create(pa_processor_method_t type); pa_processor_reference_method *pa_processor_reference_method_create(pa_processor_reference_method_t type); #endif diff --git a/src/preprocessor/method_reference_copy.c b/src/preprocessor/method_reference_copy.c deleted file mode 100644 index b3da526..0000000 --- a/src/preprocessor/method_reference_copy.c +++ /dev/null @@ -1,86 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2022 Jaechul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include - -struct reference_copy { - size_t nframes; - pa_sample_spec ss; - int reference_channels; -}; - -void *reference_copy_create(size_t nframes, pa_sample_spec *ss) { - struct reference_copy *rc; - - pa_assert(ss); - - rc = pa_xnew0(struct reference_copy, 1); - rc->nframes = nframes; - rc->ss = *ss; - - return rc; -} - -int32_t reference_copy_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out) { - struct reference_copy *rc = priv; - size_t rec_bytes, ref_bytes, actual_bytes, total_bytes; - int8_t *dst = out; - - pa_assert(rc); - pa_assert(rec); - pa_assert(ref); - pa_assert(out); - - rec_bytes = pa_frame_size(&rc->ss); - ref_bytes = pa_sample_size(&rc->ss); /* reference must be 1 channel */ - actual_bytes = rec_bytes - ref_bytes; - total_bytes = rec_bytes * rc->nframes; - - while ((dst - out) < total_bytes) { - memcpy(dst, rec, actual_bytes); - memcpy(dst + actual_bytes, ref, ref_bytes); - dst += rec_bytes; - rec += rec_bytes; - ref += ref_bytes; - } - - return 0; -} - -int32_t reference_copy_destroy(void *priv) { - struct reference_copy *rc = priv; - - pa_assert(rc); - - pa_xfree(rc); - - return 0; -} - diff --git a/src/preprocessor/method_rnnoise.c b/src/preprocessor/method_rnnoise.c deleted file mode 100644 index ca4de9f..0000000 --- a/src/preprocessor/method_rnnoise.c +++ /dev/null @@ -1,102 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2023 Jaechul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include - -#include - -struct method_rnnoise { - DenoiseState *st; - pa_sample_spec ss; - size_t frames; - float *buffer; -}; - -void *rnnoise_ns_create(size_t nframes, pa_sample_spec *ss) { - struct method_rnnoise *rnnoise = NULL; - - pa_assert(ss); - - if (ss->channels >= 2 || ss->format != PA_SAMPLE_S16LE || ss->rate != 48000) { - pa_log_error("rnnoise limitation. not support rate(%d) ch(%d) format(%d)", - ss->rate, ss->channels, ss->format); - return NULL; - } - - rnnoise = pa_xnew0(struct method_rnnoise, 1); - rnnoise->st = rnnoise_create(NULL); - rnnoise->ss = *ss; - rnnoise->frames = nframes; - rnnoise->buffer = pa_xnew(float, nframes * ss->channels); - - pa_log_info("rnnoise initialized. frame(%zu), rate(%d) channels(%d)", - nframes, ss->rate, ss->channels); - - return rnnoise; -} - -int32_t rnnoise_ns_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out) { - struct method_rnnoise *rnnoise = priv; - int16_t *ptr; - int i; - - assert(rec); - assert(out); - - ptr = (int16_t *)rec; - for (i=0; iframes; i++) { - rnnoise->buffer[i] = 0; - rnnoise->buffer[i] = ptr[i]; - } - - rnnoise_process_frame(rnnoise->st, rnnoise->buffer, rnnoise->buffer); - - ptr = (int16_t *)out; - for (i=0; iframes; i++) { - ptr[i] = 0; - ptr[i] = rnnoise->buffer[i]; - } - - return 0; -} - -int32_t rnnoise_ns_destroy(void *priv) { - struct method_rnnoise *rnnoise = priv; - - pa_assert(rnnoise); - - rnnoise_destroy(rnnoise->st); - - pa_xfree(rnnoise->buffer); - pa_xfree(rnnoise); - - return 0; -} diff --git a/src/preprocessor/method_speex.c b/src/preprocessor/method_speex.c deleted file mode 100644 index 5dd0b5f..0000000 --- a/src/preprocessor/method_speex.c +++ /dev/null @@ -1,138 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2021 Jaechul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -struct method_speex { - SpeexEchoState *echo_state; - SpeexPreprocessState *preprocess; -}; - -void *speex_create(size_t nframes, pa_sample_spec *ss) { - struct method_speex *speex = NULL; - spx_int32_t value = 1; - int rate; - - pa_assert(ss); - - if (ss->channels > 2 || ss->format != PA_SAMPLE_S16LE) { - pa_log_error("Invalid channels(%d) or format(%d)", ss->channels, ss->format); - return NULL; - } - - speex = pa_xnew0(struct method_speex, 1); - - /* TODO: need to check. weird behavior */ - if (ss->channels == 2) - nframes *= 2; - - speex->echo_state = speex_echo_state_init(nframes, nframes * 10); - - if (!speex->echo_state) { - pa_log_error("_echo_state_init_mc failed"); - goto fail; - } - - rate = ss->rate; - if (!(speex->preprocess = speex_preprocess_state_init(nframes, rate))) { - pa_log_error("_preprocess_state_init failed"); - goto fail; - } - - if (speex_echo_ctl(speex->echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate)) { - pa_log_error("_echo_ctl SET_SAMPLING_RATE failed"); - goto fail; - } - - if (speex_preprocess_ctl(speex->preprocess, SPEEX_PREPROCESS_SET_AGC, &value)) { - pa_log_error("_echo_ctl SPEEX_PREPROCESS_SET_AGC failed"); - goto fail; - } - - if (speex_preprocess_ctl(speex->preprocess, SPEEX_PREPROCESS_SET_DENOISE, &value)) { - pa_log_error("_echo_ctl SPEEX_PREPROCESS_SET_DENOISE failed"); - goto fail; - } - - if (speex_preprocess_ctl(speex->preprocess, SPEEX_PREPROCESS_SET_DEREVERB, &value)) { - pa_log_error("_echo_ctl SPEEX_PREPROCESS_SET_DEREVERB failed"); - goto fail; - } - - if (speex_preprocess_ctl(speex->preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, speex->echo_state)) { - pa_log_error("_echo_ctl SET_ECHO_STATE failed"); - goto fail; - } - - pa_log_info("speex echo-canceller initialized. frame(%zu), rate(%d) channels(%d)", - nframes, ss->rate, ss->channels); - - return speex; - -fail: - pa_xfree(speex); - - return NULL; -} - -int32_t speex_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out) { - struct method_speex *speex = priv; - - assert(rec); - assert(ref); - assert(out); - - speex_echo_cancellation(speex->echo_state, - (const spx_int16_t *)rec, - (const spx_int16_t *)ref, - (spx_int16_t *)out); - - speex_preprocess_run(speex->preprocess, (spx_int16_t *)out); - - return 0; -} - -int32_t speex_destroy(void *priv) { - struct method_speex *speex = priv; - - if (speex->echo_state) - speex_echo_state_destroy(speex->echo_state); - if (speex->preprocess) - speex_preprocess_state_destroy(speex->preprocess); - - pa_xfree(speex); - - return 0; -} diff --git a/src/preprocessor/method_webrtc.cpp b/src/preprocessor/method_webrtc.cpp deleted file mode 100644 index 0572d66..0000000 --- a/src/preprocessor/method_webrtc.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2021 Jaechul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#define DEFAULT_PROCESS_SIZE_MS 10 - -using namespace webrtc; - -PA_C_DECL_BEGIN -#include -#include -#include -#include -#include -#include -#include -#include - -static void allocate_stream_buffer(struct method_webrtc *webrtc, size_t nframes); -static void deallocate_stream_buffer(struct method_webrtc *webrtc); -static void convert_s16_to_float(float *dst, int16_t *src, size_t n); -static void convert_float_to_s16(int16_t *dst, float *src, size_t n); - -void *webrtc_audio_create(size_t nframes, pa_sample_spec *ss); -int32_t webrtc_audio_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out); -int32_t webrtc_audio_destroy(void *priv); -PA_C_DECL_END - -struct method_webrtc { - AudioProcessing *ap; - Config config; - StreamConfig *sconfig; - - float *rec_fbuf; - float *rec_dbuf[PA_CHANNELS_MAX]; - - float *ref_fbuf; - float *ref_dbuf[PA_CHANNELS_MAX]; - - float *out_fbuf; - float *out_dbuf[PA_CHANNELS_MAX]; - - pa_sample_spec ss; - size_t frames; - - /* Currently, webrtc uses fixed size(10ms) buffer */ - int loops; - size_t fixed_bytes; - size_t fixed_frames; -}; - -void *webrtc_audio_create(size_t nframes, pa_sample_spec *ss) { - struct method_webrtc *webrtc = NULL; - size_t fixed_bytes, request_bytes; - Config config; - - pa_assert(ss); - - if (ss->channels > 2 || ss->format != PA_SAMPLE_S16LE) { - pa_log_error("Invalid channels (%d) or format (%d)", ss->channels, ss->format); - return NULL; - } - - fixed_bytes = pa_usec_to_bytes(DEFAULT_PROCESS_SIZE_MS * PA_USEC_PER_MSEC, ss); - request_bytes = nframes * pa_frame_size(ss); - - if (fixed_bytes > request_bytes) { - pa_log_error("nframes should be bigger than %dms. nframes(%zu) request_bytes(%zu)", - DEFAULT_PROCESS_SIZE_MS, nframes, request_bytes); - return NULL; - } - - if (request_bytes % fixed_bytes) { - pa_log_error("request_bytes(%zu) should be multiples of fixed_bytes(%zu)", - nframes, request_bytes); - return NULL; - } - - webrtc = pa_xnew0(struct method_webrtc, 1); - webrtc->ss = *ss; - webrtc->fixed_bytes = fixed_bytes; - webrtc->fixed_frames = fixed_bytes / pa_frame_size(ss); - webrtc->loops = request_bytes / fixed_bytes; - - config.Set(new ExperimentalNs(false)); - config.Set(new Intelligibility(false)); - config.Set(new ExperimentalAgc(false)); - - webrtc->ap = AudioProcessing::Create(config); - if (!webrtc->ap) { - pa_log_error("Failed to create audio processing"); - goto fail; - } - - webrtc->ap->echo_cancellation()->Enable(true); - - webrtc->ap->gain_control()->set_mode(GainControl::kAdaptiveDigital); - //webrtc->ap->gain_control()->set_target_level_dbfs(30); - //webrtc->ap->gain_control()->set_stream_analog_level(30); - webrtc->ap->echo_cancellation()->set_suppression_level(static_cast(1)); - - webrtc->sconfig = new StreamConfig(ss->rate, ss->channels, false); - if (!webrtc->sconfig) { - pa_log_error("Failed to create stream config"); - goto fail; - } - - webrtc->sconfig->set_sample_rate_hz(ss->rate); - webrtc->sconfig->set_num_channels(ss->channels); - - /* webrtc supports 10ms by default */ - webrtc->frames = webrtc->sconfig->num_frames(); - if (webrtc->frames != webrtc->fixed_frames) { - pa_log_error("Failed to set frames. frames(%zu), fixed_frames(%zu)", - webrtc->frames, webrtc->fixed_frames); - goto fail; - } - - allocate_stream_buffer(webrtc, webrtc->fixed_frames); - - pa_log_info("webrtc processes request block(%llumsec) block(%llumsec) n(%d)\n", - pa_bytes_to_usec(request_bytes, ss) / PA_USEC_PER_MSEC, - pa_bytes_to_usec(fixed_bytes, ss) / PA_USEC_PER_MSEC, - webrtc->loops); - - return webrtc; - -fail: - if (webrtc->ap) - delete webrtc->ap; - if (webrtc->sconfig) - delete webrtc->sconfig; - - pa_xfree(webrtc); - - return NULL; -} - -int32_t webrtc_audio_process(void *priv, int8_t *rec, int8_t *ref, int8_t *out) { - struct method_webrtc *webrtc = (struct method_webrtc *)priv; - pa_sample_spec ss; - size_t frames; - - pa_assert(webrtc); - pa_assert(rec); - pa_assert(ref); - pa_assert(out); - - ss.format = PA_SAMPLE_FLOAT32LE; - ss.rate = webrtc->ss.rate; - ss.channels = webrtc->ss.channels; - - frames = webrtc->fixed_frames; - - for (int i = 0; i < webrtc->loops; i++) { - int ret; - - convert_s16_to_float(webrtc->ref_fbuf, (int16_t *)ref, frames * ss.channels); - pa_deinterleave(webrtc->ref_fbuf, (void **)webrtc->ref_dbuf, ss.channels, - pa_sample_size(&ss), frames); - - /* reference */ - ret = webrtc->ap->ProcessReverseStream(webrtc->ref_dbuf, - *webrtc->sconfig, - *webrtc->sconfig, - webrtc->ref_dbuf); - if (ret != AudioProcessing::kNoError) { - pa_log_error("Failed to process reverse stream"); - return -1; - } - - webrtc->ap->set_stream_delay_ms(0); - - /* capture */ - convert_s16_to_float(webrtc->rec_fbuf, (int16_t *)rec, frames * ss.channels); - pa_deinterleave(webrtc->rec_fbuf, (void **)webrtc->rec_dbuf, ss.channels, - pa_sample_size(&ss), frames); - - ret = webrtc->ap->ProcessStream(webrtc->rec_dbuf, - *webrtc->sconfig, - *webrtc->sconfig, - webrtc->out_dbuf); - if (ret != AudioProcessing::kNoError) { - pa_log_error("Failed to process stream"); - return -1; - } - - pa_interleave((const void **)webrtc->out_dbuf, ss.channels, webrtc->out_fbuf, - pa_sample_size(&ss), frames); - convert_float_to_s16((int16_t *)out, webrtc->out_fbuf, frames * ss.channels); - - rec += webrtc->fixed_bytes; - ref += webrtc->fixed_bytes; - out += webrtc->fixed_bytes; - } - - return 0; -} - -int32_t webrtc_audio_destroy(void *priv) { - struct method_webrtc *webrtc = (struct method_webrtc *)priv; - - pa_assert(webrtc); - - delete webrtc->sconfig; - delete webrtc->ap; - - deallocate_stream_buffer(webrtc); - pa_xfree(webrtc); - - return 0; -} - -static void deallocate_stream_buffer(struct method_webrtc *webrtc) { - pa_assert(webrtc); - - for (int i = 0; i < webrtc->ss.channels; i++) { - pa_xfree(webrtc->rec_dbuf[i]); - pa_xfree(webrtc->ref_dbuf[i]); - pa_xfree(webrtc->out_dbuf[i]); - } - - pa_xfree(webrtc->rec_fbuf); - pa_xfree(webrtc->ref_fbuf); - pa_xfree(webrtc->out_fbuf); -} - -static void allocate_stream_buffer(struct method_webrtc *webrtc, size_t nframes) { - int channels; - - pa_assert(webrtc); - - channels = webrtc->ss.channels; - - webrtc->rec_fbuf = pa_xnew(float, nframes * channels); - webrtc->ref_fbuf = pa_xnew(float, nframes * channels); - webrtc->out_fbuf = pa_xnew(float, nframes * channels); - - for (int i = 0; i < channels; i++) { - webrtc->rec_dbuf[i] = pa_xnew(float, nframes); - webrtc->ref_dbuf[i] = pa_xnew(float, nframes); - webrtc->out_dbuf[i] = pa_xnew(float, nframes); - } -} - -static void convert_s16_to_float(float *dst, int16_t *src, size_t n) { - pa_assert(dst); - pa_assert(src); - - ((pa_convert_func_t)pa_get_convert_to_float32ne_function(PA_SAMPLE_S16LE))(n, src, dst); -} - -static void convert_float_to_s16(int16_t *dst, float *src, size_t n) { - pa_assert(dst); - pa_assert(src); - - ((pa_convert_func_t)pa_get_convert_to_s16ne_function(PA_SAMPLE_FLOAT32LE))(n, src, dst); -} - diff --git a/src/preprocessor/module-tizenaudio-preprocessor.c b/src/preprocessor/module-tizenaudio-preprocessor.c index bc2fb9b..37f93ff 100644 --- a/src/preprocessor/module-tizenaudio-preprocessor.c +++ b/src/preprocessor/module-tizenaudio-preprocessor.c @@ -38,7 +38,6 @@ #include #include -#include "preprocessor-def.h" #include "processor.h" #include "processor_holder.h" @@ -250,7 +249,7 @@ static pa_usec_t get_round_trip_latency(pa_source *source, pa_sink *sink) { static pa_processor_holder *build_processor_holder(pa_core *core, pa_source_output_new_data *data) { const char *state = NULL; const char *processors_list; - char *processor_str; + char *processor_str = NULL; pa_processor_holder *holder; pa_usec_t process_usec; @@ -258,7 +257,7 @@ static pa_processor_holder *build_processor_holder(pa_core *core, pa_source_outp pa_assert(core); pa_assert(data); - holder = pa_processor_holder_new(&data->sample_spec); + holder = pa_processor_holder_new(core, &data->sample_spec); if (!holder) { pa_log_error("Failed to allocate pa_processor_holder"); return NULL; @@ -275,23 +274,38 @@ static pa_processor_holder *build_processor_holder(pa_core *core, pa_source_outp while ((processor_str = pa_split(processors_list, ",", &state))) { pa_processor *processor; - pa_processor_method_t method = pa_processor_method_enum(processor_str); + pa_processor_method_t method; + + if (pa_processor_method_enum(processor_str, &method) < 0) { + pa_log_error("Failed to get method. processor_str(%s)", processor_str); + goto fail; + } processor = pa_processor_new(core, process_usec / PA_USEC_PER_MSEC, &data->sample_spec, method); if (!processor) { pa_log_error("Failed to create pa_processor. preprocessor(aec) will be disabled"); - continue; + goto fail; } /* reference */ if (pa_processor_method_need_reference_structure(method)) { pa_sample_spec request_ss; pa_processor_reference *reference; - pa_sink *sink = convert_reference_str_to_sink(core, - pa_proplist_gets(data->proplist, PA_PROP_MEDIA_ECHO_CANCEL_REFERENCE_SINK)); + const char *ref_sink; + pa_sink *sink; - pa_assert(sink); + ref_sink = pa_proplist_gets(data->proplist, PA_PROP_MEDIA_ECHO_CANCEL_REFERENCE_SINK); + if (!ref_sink) { + pa_log_error("Failed to get ref sink"); + goto fail; + } + + sink = convert_reference_str_to_sink(core, ref_sink); + if (!sink) { + pa_log_error("Failed to convert sink"); + goto fail; + } request_ss = data->sample_spec; if (method == PROCESSOR_METHOD_REFERENCE_COPY) { @@ -305,7 +319,7 @@ static pa_processor_holder *build_processor_holder(pa_core *core, pa_source_outp if (!reference) { pa_processor_free(processor); pa_log_error("Failed to create reference custom. processor_str(%s)", processor_str); - continue; + goto fail; } /* holder -> reference -> processor */ @@ -314,7 +328,7 @@ static pa_processor_holder *build_processor_holder(pa_core *core, pa_source_outp pa_processor_reference_free(reference); pa_processor_free(processor); pa_log_error("Failed to connect holder to reference"); - continue; + goto fail; } } @@ -327,6 +341,14 @@ static pa_processor_holder *build_processor_holder(pa_core *core, pa_source_outp } return holder; + +fail: + if (holder) + pa_processor_holder_free(holder); + if (processor_str) + pa_xfree(processor_str); + + return NULL; } static void destroy_source_output_preprocessor(pa_source_output *o) { @@ -343,6 +365,7 @@ static void destroy_source_output_preprocessor(pa_source_output *o) { static int preprocess(pa_source_output *o, pa_memchunk *chunk, pa_memchunk *ochunk) { pa_processor_holder *holder; + int ret; pa_assert(o); pa_assert(chunk); @@ -353,12 +376,14 @@ static int preprocess(pa_source_output *o, pa_memchunk *chunk, pa_memchunk *ochu /* chunk must contain resampled sound pcm */ pa_processor_holder_push_data(holder, chunk); - if (pa_processor_holder_pump(holder) < 0) { - pa_log_warn("Failed to pump holder"); - return -1; + ret = pa_processor_holder_pump(holder); + if (ret != PROCESSOR_OK) { + if (ret != -PROCESSOR_ERR_BUFFERING) + pa_log_warn("Failed to pump holder. ret(%x)", ret); + + return ret; } - /* TODO: need to check return value for pse */ pa_processor_holder_pull_data(holder, ochunk); return 0; @@ -505,7 +530,7 @@ static pa_hook_result_t source_output_fixate_cb(pa_core *c, pa_source_output_new holder = build_processor_holder(c, data); if (!holder) { pa_log_error("Failed to build holder"); - return PA_HOOK_OK; + return PA_HOOK_CANCEL; } data->processor_holder = (void *)holder; @@ -577,8 +602,10 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); +#if 0 // FIXME: RT disabled due to segfault when invoking tflite if (u->core->realtime_scheduling) pa_thread_make_realtime(u->core->realtime_priority); +#endif pa_thread_mq_install(&u->thread_mq); diff --git a/src/preprocessor/preprocessor-def.h b/src/preprocessor/preprocessor-def.h deleted file mode 100644 index 7e5a856..0000000 --- a/src/preprocessor/preprocessor-def.h +++ /dev/null @@ -1,43 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2021 Jaechul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifndef __PREPROCESSOR_DEF_H__ -#define __PREPROCESSOR_DEF_H__ - -#ifdef HAVE_CONFIG_H -#include -#endif - -enum { - PA_SOURCE_MESSAGE_PREPROCESSOR_ADD_OUTPUT = PA_SOURCE_MESSAGE_MAX + 1, /* 21 */ - PA_SOURCE_MESSAGE_PREPROCESSOR_REMOVE_OUTPUT, - PA_SOURCE_MESSAGE_PREPROCESSOR_PUSH_DATA, - PA_SOURCE_MESSAGE_PREPROCESSOR_PUSH_REFERENCE, - PA_SOURCE_MESSAGE_PREPROCESSOR_RESET_REFERENCE, - PA_SOURCE_MESSAGE_PREPROCESSOR_DESTROY, - PA_SOURCE_MESSAGE_PREPROCESSOR_TERMINATE, -}; - -enum { - PA_SINK_MESSAGE_PREPROCESSOR_REBUILD_RTPOLL = PA_SINK_MESSAGE_MAX, -}; - -#endif diff --git a/src/preprocessor/processor-def.h b/src/preprocessor/processor-def.h new file mode 100644 index 0000000..5f897f9 --- /dev/null +++ b/src/preprocessor/processor-def.h @@ -0,0 +1,52 @@ +/*** + This file is part of PulseAudio. + + Copyright 2021 Jaechul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifndef __PREPROCESSOR_DEF_H__ +#define __PREPROCESSOR_DEF_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +typedef enum processor_error_code { + PROCESSOR_OK, + PROCESSOR_ERR_INVALID, + PROCESSOR_ERR_BUFFERING, +} processor_error_code_t; + +enum { + PA_SOURCE_MESSAGE_PREPROCESSOR_ADD_OUTPUT = PA_SOURCE_MESSAGE_MAX + 1, /* 21 */ + PA_SOURCE_MESSAGE_PREPROCESSOR_REMOVE_OUTPUT, + PA_SOURCE_MESSAGE_PREPROCESSOR_PUSH_DATA, + PA_SOURCE_MESSAGE_PREPROCESSOR_PUSH_REFERENCE, + PA_SOURCE_MESSAGE_PREPROCESSOR_RESET_REFERENCE, + PA_SOURCE_MESSAGE_PREPROCESSOR_DESTROY, + PA_SOURCE_MESSAGE_PREPROCESSOR_TERMINATE, +}; + +enum { + PA_SINK_MESSAGE_PREPROCESSOR_REBUILD_RTPOLL = PA_SINK_MESSAGE_MAX, +}; + +#endif diff --git a/src/preprocessor/processor.c b/src/preprocessor/processor.c index 510987a..7e96446 100644 --- a/src/preprocessor/processor.c +++ b/src/preprocessor/processor.c @@ -63,12 +63,74 @@ static size_t pa_processor_usec_to_frame(pa_usec_t usec, pa_sample_spec *spec) { return pa_usec_to_bytes(usec, spec) / pa_frame_size(spec); } +static pa_usec_t pa_processor_frame_to_usec(size_t frame, pa_sample_spec *spec) { + return pa_bytes_to_usec(pa_frame_size(spec) * frame, spec); +} + +static int pa_processor_convert_method(pa_processor_method_t method, audio_effect_type_e *type) { + int ret = 0; + + switch (method) { + case PROCESSOR_METHOD_SPEEX: + *type = AUDIO_EFFECT_TYPE_AEC_SPEEX; + break; + case PROCESSOR_METHOD_WEBRTC: + *type = AUDIO_EFFECT_TYPE_AEC_WEBRTC; + break; + case PROCESSOR_METHOD_REFERENCE_COPY: + *type = AUDIO_EFFECT_TYPE_AEC_REFCOPY; + break; + case PROCESSOR_METHOD_RNNOISE: + *type = AUDIO_EFFECT_TYPE_NS_RNNOISE; + break; + case PROCESSOR_METHOD_NONE_PSE: + *type = AUDIO_EFFECT_TYPE_NS_PSE; + break; + default: + ret = -1; + break; + } + + return ret; +} + +static int pa_processor_convert_format(pa_sample_format_t f, audio_effect_format_e *format) { + int ret = 0; + + switch(f) { + case PA_SAMPLE_U8: + *format = AUDIO_EFFECT_FORMAT_S8; + break; + case PA_SAMPLE_S16LE: + *format = AUDIO_EFFECT_FORMAT_S16; + break; + case PA_SAMPLE_S24LE: + *format = AUDIO_EFFECT_FORMAT_S24; + break; + case PA_SAMPLE_S32LE: + *format = AUDIO_EFFECT_FORMAT_S32; + break; + case PA_SAMPLE_FLOAT32LE: + *format = AUDIO_EFFECT_FORMAT_FLOAT; + break; + default: + ret = -1; + break; + } + + return ret; +} + pa_processor *pa_processor_new(pa_core *core, uint32_t process_msec, pa_sample_spec *ss, pa_processor_method_t method) { pa_processor *processor; pa_memchunk silence; + size_t process_framesize; + + audio_effect_type_e type; + audio_effect_format_e format; pa_assert(core); pa_assert(ss); @@ -76,23 +138,39 @@ pa_processor *pa_processor_new(pa_core *core, processor = pa_xnew0(pa_processor, 1); processor->core = core; - processor->interface = pa_processor_method_create(method); processor->process_usec = process_msec * PA_USEC_PER_MSEC; processor->ss = *ss; processor->method = method; processor->process_frames = pa_processor_usec_to_frame(processor->process_usec, &processor->ss); processor->process_bytes = pa_usec_to_bytes(processor->process_usec, &processor->ss); - pa_assert(processor->interface->create); - pa_assert(processor->interface->process); - pa_assert(processor->interface->destroy); + if (pa_processor_convert_method(method, &type) < 0) { + pa_log_error("Failed to convert audio-effect type. method(%d), type(%d)", method, type); + return NULL; + } + + if (pa_processor_convert_format(ss->format, &format) < 0) { + pa_log_error("Failed to convert audio-effect format. format(%d), audio_effect_format(%d)", ss->format, format); + return NULL; + } - if (!(processor->priv = processor->interface->create(processor->process_frames, &processor->ss))) { - pa_log_error("Failed to create processor. rate(%d), channels(%d).", processor->ss.rate, processor->ss.channels); - pa_xfree(processor); + processor->audio_effect = audio_effect_create(type, ss->rate, ss->channels, format, processor->process_frames); + if (!processor->audio_effect) { + pa_log_error("Failed to create audio effect. type(%d), rate(%d), ch(%d), format(%d), frames(%zu)", + type, ss->rate, ss->channels, format, processor->process_frames); return NULL; } + process_framesize = audio_effect_get_process_framesize(processor->audio_effect); + + if (process_framesize > 0) { + processor->process_frames = process_framesize; + processor->process_usec = pa_processor_frame_to_usec(processor->process_frames, ss); + processor->process_bytes = pa_usec_to_bytes(processor->process_usec, ss); + + pa_log_info("Changed process_frame. constraint process_frame(%zu)", processor->process_frames); + } + pa_silence_memchunk_get(&core->silence_cache, core->mempool, &silence, &processor->ss, 0); processor->result_memblockq = pa_memblockq_new("source-output memblockq", 0, @@ -118,13 +196,10 @@ pa_processor *pa_processor_new(pa_core *core, } void pa_processor_free(pa_processor *processor) { - pa_assert(processor); - pa_assert(processor->priv); - pa_assert(processor->interface); + pa_assert(processor->audio_effect); - if (processor->interface->destroy(processor->priv) < 0) - pa_log_error("Failed to destroy processor"); + audio_effect_destroy(processor->audio_effect); if (processor->result_memblockq) pa_memblockq_free(processor->result_memblockq); @@ -132,8 +207,6 @@ void pa_processor_free(pa_processor *processor) { if (processor->reference) pa_processor_reference_free(processor->reference); - pa_xfree(processor->interface); - debug_close_file(processor); pa_xfree(processor); @@ -156,7 +229,6 @@ int pa_processor_process(pa_processor *processor, pa_memchunk *chunk) { pa_assert(processor); pa_assert(processor->result_memblockq); - pa_assert(processor->interface); pa_assert(processor->process_bytes > 0ULL); pa_assert(chunk); @@ -176,7 +248,7 @@ int pa_processor_process(pa_processor *processor, pa_memchunk *chunk) { debug_timestamp_begin(processor); - r = processor->interface->process(processor->priv, recording, reference, output); + r = audio_effect_process_reference(processor->audio_effect, recording, reference, output); if (r < 0) { pa_log_warn("Failed to process memchunk"); goto fail; @@ -233,7 +305,7 @@ fail: pa_memblock_unref(ochunk.memblock); - return -1; + return r; } pa_memblockq *pa_processor_get_result_memblockq(pa_processor *processor) { @@ -251,21 +323,24 @@ const char *pa_processor_method_str(pa_processor_method_t method) { return method_table[method]; } -pa_processor_method_t pa_processor_method_enum(const char *method) { - pa_processor_method_t m; +int pa_processor_method_enum(const char *method, pa_processor_method_t *m) { + pa_assert(method); + pa_assert(m); if (pa_streq(method, "speex")) - m = PROCESSOR_METHOD_SPEEX; + *m = PROCESSOR_METHOD_SPEEX; else if (pa_streq(method, "webrtc")) - m = PROCESSOR_METHOD_WEBRTC; + *m = PROCESSOR_METHOD_WEBRTC; else if (pa_streq(method, "reference_copy")) - m = PROCESSOR_METHOD_REFERENCE_COPY; + *m = PROCESSOR_METHOD_REFERENCE_COPY; else if (pa_streq(method, "rnnoise")) - m = PROCESSOR_METHOD_RNNOISE; + *m = PROCESSOR_METHOD_RNNOISE; + else if (pa_streq(method, "pse")) + *m = PROCESSOR_METHOD_NONE_PSE; else - pa_assert(0); + return -1; - return m; + return 0; } bool pa_processor_method_need_reference_structure(pa_processor_method_t m) { diff --git a/src/preprocessor/processor.h b/src/preprocessor/processor.h index ef999c2..599d27b 100644 --- a/src/preprocessor/processor.h +++ b/src/preprocessor/processor.h @@ -31,6 +31,7 @@ #include #include +#include #include "processor_reference.h" #include "method_factory.h" @@ -45,8 +46,7 @@ typedef struct pa_processor { pa_sample_spec ss; pa_memblockq *result_memblockq; - void *priv; - pa_processor_method *interface; + audio_effect_s *audio_effect; pa_processor_method_t method; pa_processor_reference *reference; @@ -71,7 +71,7 @@ size_t pa_processor_get_process_bytes(pa_processor *p); void pa_processor_attach_reference(pa_processor *processor, pa_processor_reference *reference); pa_processor_reference *pa_processor_get_reference(pa_processor *processor); -pa_processor_method_t pa_processor_method_enum(const char *method); +int pa_processor_method_enum(const char *method, pa_processor_method_t *m); const char *pa_processor_method_str(pa_processor_method_t method); bool pa_processor_method_need_reference_structure(pa_processor_method_t m); diff --git a/src/preprocessor/processor_holder.c b/src/preprocessor/processor_holder.c index a466411..046c81f 100644 --- a/src/preprocessor/processor_holder.c +++ b/src/preprocessor/processor_holder.c @@ -35,14 +35,16 @@ #define MEMBLOCKQ_MAXLENGTH (16*1024*1024) -pa_processor_holder *pa_processor_holder_new(pa_sample_spec *ss) { +pa_processor_holder *pa_processor_holder_new(pa_core *core, pa_sample_spec *ss) { pa_processor_holder *holder; + pa_memchunk silence; pa_assert(ss); holder = pa_xnew0(pa_processor_holder, 1); holder->processors = pa_idxset_new(NULL, NULL); + pa_silence_memchunk_get(&core->silence_cache, core->mempool, &silence, ss, 0); holder->input= pa_memblockq_new("holder input memblockq", 0, MEMBLOCKQ_MAXLENGTH, @@ -51,7 +53,7 @@ pa_processor_holder *pa_processor_holder_new(pa_sample_spec *ss) { 0, 0, 0, - NULL); + &silence); holder->output = pa_memblockq_new("holder output memblockq", 0, @@ -61,7 +63,9 @@ pa_processor_holder *pa_processor_holder_new(pa_sample_spec *ss) { 0, 0, 0, - NULL); + &silence); + + pa_memblock_unref(silence.memblock); return holder; } @@ -125,52 +129,48 @@ int pa_processor_holder_pump(pa_processor_holder *holder) { pa_memchunk chunk; pa_processor *p; int ret; - size_t size; uint32_t idx; + size_t length; + size_t process_size; + pa_assert(holder); pull_queue = holder->input; PA_IDXSET_FOREACH(p, holder->processors, idx) { - if (pa_memblockq_peek(pull_queue, &chunk)) { - pa_log_info("Failed to peek data. processor(%s)", pa_processor_method_str(p->method)); - return -1; - } + process_size = pa_processor_get_process_bytes(p); + length = pa_memblockq_get_length(pull_queue); - size = pa_processor_get_process_bytes(p); - if (chunk.length < size) { - pa_log_info("Not enough buffer. need to wait more buffer"); - pa_memblock_unref(chunk.memblock); - return -1; - } + if (length < process_size) + return -PROCESSOR_ERR_BUFFERING; - /* chunk will be copied */ - /* TODO : ERROR BUFFERING */ - if ((ret = pa_processor_process(p, &chunk))) { - if (ret == -2) { - pa_log_info("Tried to process but processor has a latency"); - return 0; - } else { - pa_log_info("Failed to process"); - return 0; + while (length >= process_size) { + ret = pa_memblockq_peek_fixed_size(pull_queue, process_size, &chunk); + pa_assert(!ret); + + if ((ret = pa_processor_process(p, &chunk)) < 0) { + pa_memblock_unref(chunk.memblock); + pa_memblockq_drop(pull_queue, chunk.length); + return ret; } - } - pa_memblock_unref(chunk.memblock); - pa_memblockq_drop(pull_queue, chunk.length); + pa_memblock_unref(chunk.memblock); + pa_memblockq_drop(pull_queue, chunk.length); + + length = pa_memblockq_get_length(pull_queue); + } pull_queue = pa_processor_get_result_memblockq(p); } - /* in case of only pass though */ - if (pull_queue == holder->input) - return -1; - - pa_memblockq_peek(pull_queue, &chunk); - pa_memblockq_push(holder->output, &chunk); - pa_memblock_unref(chunk.memblock); - pa_memblockq_drop(pull_queue, chunk.length); + length = pa_memblockq_get_length(pull_queue); + if (length > 0) { + pa_memblockq_peek_fixed_size(pull_queue, length, &chunk); + pa_memblockq_push(holder->output, &chunk); + pa_memblock_unref(chunk.memblock); + pa_memblockq_drop(pull_queue, chunk.length); + } return 0; } diff --git a/src/preprocessor/processor_holder.h b/src/preprocessor/processor_holder.h index f756514..7ba0275 100644 --- a/src/preprocessor/processor_holder.h +++ b/src/preprocessor/processor_holder.h @@ -28,6 +28,7 @@ #include #include +#include "processor-def.h" #include "processor.h" typedef struct pa_processor_holder { @@ -42,7 +43,7 @@ typedef struct pa_processor_holder { void *data2; } pa_processor_holder; -pa_processor_holder *pa_processor_holder_new(pa_sample_spec *ss); +pa_processor_holder *pa_processor_holder_new(pa_core *core, pa_sample_spec *ss); void pa_processor_holder_register_processor_sequencial(pa_processor_holder *holder, pa_processor *processor); int pa_processor_holder_connect_reference(pa_processor_holder *holder, pa_processor_reference *reference); int pa_processor_holder_push_data(pa_processor_holder *holder, pa_memchunk *chunk); diff --git a/src/tizenaudio-sink2.c b/src/tizenaudio-sink2.c index 4b3f888..1178799 100644 --- a/src/tizenaudio-sink2.c +++ b/src/tizenaudio-sink2.c @@ -47,7 +47,7 @@ #include "hal-interface.h" #include "tizenaudio-util.h" -#include "preprocessor/preprocessor-def.h" +#include "preprocessor/processor-def.h" #include "preprocessor/processor_holder.h" #include "preprocessor/processor_reference.h" diff --git a/src/tizenaudio-source2.c b/src/tizenaudio-source2.c index 0718eb6..f808cf2 100644 --- a/src/tizenaudio-source2.c +++ b/src/tizenaudio-source2.c @@ -47,7 +47,7 @@ #include "hal-interface.h" #include "tizenaudio-util.h" -#include "preprocessor/preprocessor-def.h" +#include "preprocessor/processor-def.h" #include "preprocessor/processor_holder.h" #define DEFAULT_SOURCE_NAME "tizenaudio-source2"