Use libaudio-effect module 72/292672/11 accepted/tizen/unified/20230620.022501
authorJaechul Lee <jcsing.lee@samsung.com>
Wed, 10 May 2023 08:20:56 +0000 (17:20 +0900)
committerJaechul Lee <jcsing.lee@samsung.com>
Thu, 15 Jun 2023 08:22:07 +0000 (17:22 +0900)
* 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 <jcsing.lee@samsung.com>
17 files changed:
Makefile.am
configure.ac
packaging/pulseaudio-modules-tizen.spec
src/preprocessor/method_factory.c
src/preprocessor/method_factory.h
src/preprocessor/method_reference_copy.c [deleted file]
src/preprocessor/method_rnnoise.c [deleted file]
src/preprocessor/method_speex.c [deleted file]
src/preprocessor/method_webrtc.cpp [deleted file]
src/preprocessor/module-tizenaudio-preprocessor.c
src/preprocessor/processor-def.h [moved from src/preprocessor/preprocessor-def.h with 87% similarity]
src/preprocessor/processor.c
src/preprocessor/processor.h
src/preprocessor/processor_holder.c
src/preprocessor/processor_holder.h
src/tizenaudio-sink2.c
src/tizenaudio-source2.c

index 91d448d..01e5190 100644 (file)
@@ -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
index 6c3637f..6f2ebe6 100644 (file)
@@ -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]),
index ee30edf..ba66270 100644 (file)
@@ -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
index 902f7fd..695eb43 100644 (file)
 
 #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);
 
index 110d150..96bd030 100644 (file)
@@ -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 (file)
index b3da526..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2022 Jaechul Lee <jcsing.lee@samsung.com>
-
-  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 <config.h>
-#endif
-
-#include <stdint.h>
-#include <pulse/xmalloc.h>
-#include <pulse/sample.h>
-#include <pulse/channelmap.h>
-#include <pulsecore/log.h>
-#include <pulsecore/macro.h>
-
-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 (file)
index ca4de9f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2023 Jaechul Lee <jcsing.lee@samsung.com>
-
-  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 <config.h>
-#endif
-
-#include <stdint.h>
-#include <pulse/xmalloc.h>
-#include <pulse/sample.h>
-#include <pulsecore/log.h>
-#include <pulsecore/macro.h>
-
-#include <rnnoise.h>
-
-#include <assert.h>
-
-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; i<rnnoise->frames; 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; i<rnnoise->frames; 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 (file)
index 5dd0b5f..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2021 Jaechul Lee <jcsing.lee@samsung.com>
-
-  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 <config.h>
-#endif
-
-#include <stdint.h>
-#include <pulse/xmalloc.h>
-#include <pulse/sample.h>
-#include <pulsecore/log.h>
-#include <pulsecore/macro.h>
-
-#include <speex/speex.h>
-#include <speex/speex_preprocess.h>
-#include <speex/speex_echo.h>
-
-#include <assert.h>
-
-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 (file)
index 0572d66..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2021 Jaechul Lee <jcsing.lee@samsung.com>
-
-  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 <config.h>
-#endif
-
-#include <pulse/cdecl.h>
-
-#include <webrtc/modules/audio_processing/include/audio_processing.h>
-
-#define DEFAULT_PROCESS_SIZE_MS 10
-
-using namespace webrtc;
-
-PA_C_DECL_BEGIN
-#include <pulsecore/log.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/sconv.h>
-#include <pulsecore/sample-util.h>
-#include <pulse/xmalloc.h>
-#include <pulse/sample.h>
-#include <pulse/timeval.h>
-#include <stdint.h>
-
-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<ExperimentalNs>(new ExperimentalNs(false));
-    config.Set<Intelligibility>(new Intelligibility(false));
-    config.Set<ExperimentalAgc>(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<EchoCancellation::SuppressionLevel>(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);
-}
-
index bc2fb9b..37f93ff 100644 (file)
@@ -38,7 +38,6 @@
 #include <pulse/util.h>
 #include <pulse/timeval.h>
 
-#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);
 
similarity index 87%
rename from src/preprocessor/preprocessor-def.h
rename to src/preprocessor/processor-def.h
index 7e5a856..5f897f9 100644 (file)
 #include <config.h>
 #endif
 
+#include <pulsecore/source.h>
+#include <pulsecore/sink.h>
+
+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,
index 510987a..7e96446 100644 (file)
@@ -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) {
index ef999c2..599d27b 100644 (file)
@@ -31,6 +31,7 @@
 #include <pulse/channelmap.h>
 #include <pulse/sample.h>
 
+#include <audio_effect.h>
 #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);
 
index a466411..046c81f 100644 (file)
 
 #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;
 }
index f756514..7ba0275 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <pulsecore/memblock.h>
 #include <pulsecore/memchunk.h>
+#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);
index 4b3f888..1178799 100644 (file)
@@ -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"
 
index 0718eb6..f808cf2 100644 (file)
@@ -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"