#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);
#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;
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[] = {
u->rtpoll_item = NULL;
}
- pa_log_info("Device suspended...[%s,%s]", u->card, u->device);
+ pa_log_info("Device suspended...");
return 0;
}
int32_t ret;
size_t frame_size;
+ char *card = u->card;
+ char *device = u->device;
+
pa_assert(u);
pa_assert(!u->pcm_handle);
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,
u->read_count = 0;
u->first = true;
- pa_log_info("Resumed successfully...");
+ pa_log_info("Resumed successfully...device(%s:%s)", card, device);
return 0;
*((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);
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);
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))) {
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);