How to properly switch between multiple audio sources while playing
OPENSOURCE Manuel Huber
manuel.huber at opensource.tttech.com
Thu Apr 4 13:04:27 UTC 2019
Hello,
I would like to switch between playing sine tones of specific duration
and playback files - both with low latency. There seem to be different
ways possible to potentially achieve this, and I already tried most of
them. However, I'm unsure which approach is cleanest and should be
followed in that case and would kindly ask for guidance...
I would of course be happy to report back how the final solution
looked like, which might be helpful for others.
There are multiple things important here:
- I would like to prevent that gstreamer has to spawns threads
whenever a tone or file is played. I would rather like to keep the
threads idle, which should be achieved if kept in PAUSED state as I
understand it.
- Fast switching between playing files and tones. It doesn't have to
be gap-less, but I think it would be good to avoid having to
reassemble the pipeline every time. I'd rather have one pipeline and
just replace / switch the current source.
To simplify the use-case, I tried to only switch between two sine
tones (just to get a basic understanding).
1. Using input-selector and valve
audiotestsrc1 -> valve1 -+
+-> input-selector -> alsasink
audiotestsrc2 -> valve2 -+
I heard some click's and pop's when switching...
2. Dynamically changing the pipeline using probes:
<source> -> [queue ->] alsasink
The idea would be to replace the source using blocking probes similar to this:
- https://gstreamer.freedesktop.org/documentation/application-development/advanced/pipeline-manipulation.html#changing-elements-in-a-pipeline
I'm not sure whether it's possible to apply the same idea when
replacing the source. Would this work:
- block on source.src pad, install a new probe and send EOS
- wait for EOS on alsasink.sink (or on the queue.src?)
- in the callback for EOS remove the source, add a new source, set
the state, ...
3. Using playbin directly
I'm unsure whether it's possible to replace the source while playing
or there is some other way to start playing sine tones mixed with
actual files. Maybe also a combination with input-selector is
possible?
A second problem is how to play the sine tone only for the requested
time. I see two approaches:
- audiotestsrc seems to be quite capable on the second look, as
adjusting the parameters (lower buffer size, smaller blocks,
live-source, etc) can lower the latency during starting and also
allows to set the playback time (more or less) exactly to the
requested duration. The only problem I had with that approach is
how to "rewind" and re-configure the element (or do I have to
recreate the element and replace it (for example using option 2)
every time a new tone will be played?
- appsrc gives me (more or less) full control over the playback, seems
to work fine for me. However, if not necessary, I would of course
prefer to stick with a standard source like audiotestsrc.
If anybody has suggestions regarding the topic, I would be happy to
hear about it ;)
Best regards,
Manuel
More information about the gstreamer-devel
mailing list