From d5298eee2cf6adb90bc6f9a692086dd3ad341848 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 1 Aug 2024 17:17:05 +0200 Subject: [PATCH] module-ffado: implement freewheeling When freewheeling starts, pause the streaming and resume when freewheeling stops. Also make sure we don't try to do any IO or timeouts. --- src/modules/module-ffado-driver.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/modules/module-ffado-driver.c b/src/modules/module-ffado-driver.c index 974081f55..6c714a16a 100644 --- a/src/modules/module-ffado-driver.c +++ b/src/modules/module-ffado-driver.c @@ -252,6 +252,7 @@ struct impl { unsigned int do_disconnect:1; unsigned int fix_midi:1; unsigned int started:1; + unsigned int freewheel:1; pthread_t thread; @@ -674,10 +675,28 @@ static void stream_io_changed(void *data, void *port_data, uint32_t id, void *ar { struct stream *s = data; struct impl *impl = s->impl; + bool freewheel; + if (port_data == NULL) { switch (id) { case SPA_IO_Position: impl->position = area; + freewheel = impl->position != NULL && + SPA_FLAG_IS_SET(impl->position->clock.flags, SPA_IO_CLOCK_FLAG_FREEWHEEL); + if (impl->freewheel != freewheel) { + pw_log_info("freewheel: %d -> %d", impl->freewheel, freewheel); + impl->freewheel = freewheel; + if (impl->started) { + if (freewheel) { + set_timeout(impl, 0); + ffado_streaming_stop(impl->dev); + } else { + ffado_streaming_start(impl->dev); + impl->rt.done = true; + set_timeout(impl, get_time_ns(impl)); + } + } + } break; default: break; @@ -982,6 +1001,9 @@ static void on_ffado_timeout(void *data, uint64_t expirations) pw_log_trace_fp("wakeup %d", impl->rt.done); + if (impl->freewheel) + return; + if (!impl->rt.done) { impl->rt.pw_xrun++; impl->rt.new_xrun = true;