summaryrefslogtreecommitdiffstats
path: root/src/modules/echo-cancel/module-echo-cancel.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2010-09-09 16:20:20 +0200
committerColin Guthrie <cguthrie@mandriva.org>2010-09-09 17:03:46 +0100
commit26dfacf20b34642ccc4aefa2eb01fb67c38b9fc2 (patch)
tree5c5980c5ae23028b1d0538833477e476997e72ec /src/modules/echo-cancel/module-echo-cancel.c
parent7b873785ca40c7d1d3109f8cc8202b996ebe1522 (diff)
echo-cancel: pause timer when echo canceling is off
While the sink or source is in the suspended state, disable the timer callback because we are not doing any echo canceling then.
Diffstat (limited to 'src/modules/echo-cancel/module-echo-cancel.c')
-rw-r--r--src/modules/echo-cancel/module-echo-cancel.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index 467e2160..8ae45a5c 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -172,7 +172,6 @@ struct userdata {
pa_bool_t source_auto_desc;
pa_source_output *source_output;
pa_memblockq *source_memblockq; /* echo canceler needs fixed sized chunks */
- pa_atomic_t source_active;
size_t source_skip;
pa_sink *sink;
@@ -181,11 +180,11 @@ struct userdata {
pa_memblockq *sink_memblockq;
int64_t send_counter; /* updated in sink IO thread */
int64_t recv_counter;
- pa_atomic_t sink_active;
size_t sink_skip;
pa_atomic_t request_resync;
+ int active_mask;
pa_time_event *time_event;
pa_usec_t adjust_time;
@@ -272,8 +271,8 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
pa_assert(u->time_event == e);
pa_assert_ctl_context();
- if (pa_atomic_load (&u->sink_active) == 0 || pa_atomic_load (&u->source_active) == 0)
- goto done;
+ if (u->active_mask != 3)
+ return;
/* update our snapshots */
pa_asyncmsgq_send(u->source_output->source->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT, &latency_snapshot, 0, NULL);
@@ -318,7 +317,6 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
pa_sink_input_set_rate(u->sink_input, new_rate);
}
-done:
pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
}
@@ -398,14 +396,18 @@ static int source_set_state_cb(pa_source *s, pa_source_state_t state) {
!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
return 0;
- pa_log_debug("Source state %d", state);
+ pa_log_debug("Source state %d %d", state, u->active_mask);
if (state == PA_SOURCE_RUNNING) {
- pa_atomic_store (&u->source_active, 1);
+ /* restart timer when both sink and source are active */
+ u->active_mask |= 1;
+ if (u->active_mask == 3)
+ pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
+
pa_atomic_store (&u->request_resync, 1);
pa_source_output_cork(u->source_output, FALSE);
} else if (state == PA_SOURCE_SUSPENDED) {
- pa_atomic_store (&u->source_active, 0);
+ u->active_mask &= ~1;
pa_source_output_cork(u->source_output, TRUE);
}
return 0;
@@ -422,14 +424,18 @@ static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
return 0;
- pa_log_debug("Sink state %d", state);
+ pa_log_debug("Sink state %d %d", state, u->active_mask);
if (state == PA_SINK_RUNNING) {
- pa_atomic_store (&u->sink_active, 1);
+ /* restart timer when both sink and source are active */
+ u->active_mask |= 2;
+ if (u->active_mask == 3)
+ pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
+
pa_atomic_store (&u->request_resync, 1);
pa_sink_input_cork(u->sink_input, FALSE);
} else if (state == PA_SINK_SUSPENDED) {
- pa_atomic_store (&u->sink_active, 0);
+ u->active_mask &= ~2;
pa_sink_input_cork(u->sink_input, TRUE);
}
return 0;
@@ -598,7 +604,7 @@ static void apply_diff_time(struct userdata *u, int64_t diff_time) {
* timings */
diff += 10 * pa_frame_size (&u->source_output->sample_spec);
- pa_log_info("Playback after capture (%lld), drop sink %lld", (long long) diff_time, (long long) diff);
+ pa_log("Playback after capture (%lld), drop sink %lld", (long long) diff_time, (long long) diff);
u->sink_skip = diff;
u->source_skip = 0;
@@ -607,7 +613,7 @@ static void apply_diff_time(struct userdata *u, int64_t diff_time) {
diff = pa_usec_to_bytes (diff_time, &u->source_output->sample_spec);
if (diff > 0) {
- pa_log_info("playback too far ahead (%lld), drop source %lld", (long long) diff_time, (long long) diff);
+ pa_log("playback too far ahead (%lld), drop source %lld", (long long) diff_time, (long long) diff);
u->source_skip = diff;
u->sink_skip = 0;
@@ -1574,6 +1580,9 @@ int pa__init(pa_module*m) {
goto fail;
}
+ /* our source and sink are not suspended when we create them */
+ u->active_mask = 3;
+
if (u->adjust_time > 0)
u->time_event = pa_core_rttime_new(m->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
@@ -1629,6 +1638,9 @@ void pa__done(pa_module*m) {
/* See comments in source_output_kill_cb() above regarding
* destruction order! */
+ if (u->time_event)
+ u->core->mainloop->time_free(u->time_event);
+
if (u->source_output)
pa_source_output_unlink(u->source_output);
if (u->sink_input)
@@ -1649,9 +1661,6 @@ void pa__done(pa_module*m) {
if (u->sink)
pa_sink_unref(u->sink);
- if (u->time_event)
- u->core->mainloop->time_free(u->time_event);
-
if (u->source_memblockq)
pa_memblockq_free(u->source_memblockq);
if (u->sink_memblockq)