aec-manager: Add audio AEC manager
[platform/core/multimedia/pulseaudio-modules-tizen.git] / src / module-tizenaudio-source.c
index c0337e0..4ec1330 100644 (file)
 
 #include "hal-interface.h"
 
+#ifdef SUPPORT_AEC
+#include "aec-manager.h"
+#endif
+
 PA_MODULE_AUTHOR("Tizen");
 PA_MODULE_DESCRIPTION("Tizen Audio Source");
 PA_MODULE_VERSION(PACKAGE_VERSION);
@@ -70,6 +74,13 @@ PA_MODULE_USAGE(
 
 #define DEVICE_NAME_MAX                     30
 
+#ifdef SUPPORT_AEC
+enum {
+    PA_SOURCE_MESSAGE_SET_AEC_STATE = PA_SOURCE_MESSAGE_MAX,
+    PA_SOURCE_MESSAGE_GET_AEC_PARAMS,
+};
+#endif
+
 struct userdata {
     pa_core *core;
     pa_module *module;
@@ -95,6 +106,11 @@ struct userdata {
     uint64_t read_count;
     pa_usec_t latency_time;
     pa_hal_interface *hal_interface;
+
+#ifdef SUPPORT_AEC
+    bool aec_enable;
+    pa_sample_spec ss;
+#endif
 };
 
 static const char* const valid_modargs[] = {
@@ -152,7 +168,7 @@ static int suspend(struct userdata *u) {
         u->rtpoll_item = NULL;
     }
 
-    pa_log_info("Device suspended...[%s,%s]", u->card, u->device);
+    pa_log_info("Device suspended...");
 
     return 0;
 }
@@ -163,6 +179,9 @@ static int unsuspend(struct userdata *u) {
     int32_t ret;
     size_t frame_size;
 
+    char *card = u->card;
+    char *device = u->device;
+
     pa_assert(u);
     pa_assert(!u->pcm_handle);
 
@@ -175,9 +194,16 @@ static int unsuspend(struct userdata *u) {
         goto fail;
     }
 
+#ifdef SUPPORT_AEC
+    if (u->aec_enable) {
+        card = "Loopback";
+        device = "1,1";
+    }
+#endif
+
     ret = pa_hal_interface_pcm_open(u->hal_interface,
-              u->card,
-              u->device,
+              card,
+              device,
               DIRECTION_IN,
               &sample_spec,
               u->frag_size / frame_size,
@@ -194,7 +220,7 @@ static int unsuspend(struct userdata *u) {
     u->read_count = 0;
     u->first = true;
 
-    pa_log_info("Resumed successfully...");
+    pa_log_info("Resumed successfully...device(%s:%s)", card, device);
 
     return 0;
 
@@ -265,6 +291,36 @@ static int source_process_msg(
             *((pa_usec_t*)data) = u->timestamp > now ? 0ULL : now - u->timestamp;
             return 0;
         }
+#ifdef SUPPORT_AEC
+        case PA_SOURCE_MESSAGE_SET_AEC_STATE: {
+            pa_source *s = PA_SOURCE(o);
+            bool enable = (bool)data;
+
+            if (u->aec_enable == enable)
+                return 0;
+
+            pa_log_info("AEC enable(%d)", enable);
+
+            u->aec_enable = enable;
+            if (s->thread_info.state == PA_SOURCE_RUNNING) {
+                suspend(u);
+                unsuspend(u);
+            }
+
+            return 0;
+        }
+        case PA_SOURCE_MESSAGE_GET_AEC_PARAMS: {
+            aec_params_t *params = (aec_params_t *)data;
+            params->rate = u->ss.rate;
+            params->channels = u->ss.channels;
+            params->format = u->ss.format;
+            params->frag_size = u->frag_size;
+            params->nfrags = u->nfrags;
+            snprintf(params->card, DEVICE_NAME_MAX, "%s", u->card);
+            snprintf(params->device, DEVICE_NAME_MAX, "%s", u->device);
+            return 0;
+        }
+#endif
     }
 
     return pa_source_process_msg(o, code, data, offset, chunk);
@@ -463,6 +519,7 @@ int pa__init(pa_module*m) {
     const char *modarg_device;
     char card[DEVICE_NAME_MAX];
     char device[DEVICE_NAME_MAX];
+    size_t frame_size, buffer_size, period_frames, buffer_frames;
 
     pa_assert(m);
 
@@ -490,6 +547,9 @@ int pa__init(pa_module*m) {
     u->first = true;
     u->hal_interface = pa_hal_interface_get(u->core);
     u->rtpoll = pa_rtpoll_new();
+#ifdef SUPPORT_AEC
+    u->ss = ss;
+#endif
     pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
 
     if (!(modarg_device = pa_modargs_get_value(ma, "device", NULL))) {
@@ -526,6 +586,13 @@ int pa__init(pa_module*m) {
     pa_proplist_sets(data.proplist, "tizen.device", u->device);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "tizen");
 
+    frame_size = pa_frame_size(&ss);
+    buffer_size = u->frag_size * u->nfrags;
+    buffer_frames = buffer_size / frame_size;
+    period_frames = u->frag_size / frame_size;
+    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%zu", buffer_frames * frame_size);
+    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%zu", period_frames * frame_size);
+
     if (pa_modargs_get_proplist(ma, "source_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
         pa_log_error("Invalid properties.");
         pa_source_new_data_done(&data);