Subject: [ecasound] JACK transport control (fwd)
From: Kai Vehmanen (kai.vehmanen_AT_wakkanet.fi)
Date: Mon Jun 24 2002 - 06:41:36 EEST
To try this out you need the latest JACK and ecasound CVS-versions.
---------- Forwarded message ----------
Date: Mon, 24 Jun 2002 06:40:36 +0300 (EEST)
From: Kai Vehmanen <kai.vehmanen_AT_wakkanet.fi>
Subject: transport control (was: Re: 0.33.1, aka 0.34.0-rc1)
On Fri, 24 May 2002, Kai Vehmanen wrote:
> As for transport control, current ecasound's CVS-tree contains an initial
> framework for both transport master and slave operation. When launching
> ecasound you can select between "streaming" (JACK transport info ignored),
> "master" and "slave" modes. I've made a few bigger changes that should
> allow ecasound to even support live-seeking. Looping probably won't be
I've now continued this work and the current ecasound-CVS is now able to
both serve both as a JACK timebase master as well as a timebase slave
client. Here's a simple test scenario:
# timebase master (clientname='eca_master'), writes null data to its
# output port (portname='nullout')
ecasound -i null -o jack_generic,nullout -G:jack,eca_master,master -c
# timebase slave, reads from foo.wav and writes to ALSA pcm outputs
ecasound -i foo.wav -o jack_alsa,out -G:jack,eca_slave,slave -c
... you need to give an initial "start" command to the slave, but after
that, you are able to control the slave with commands like "start",
"stop", "setpos 20", "rw 10", "fw 10", etc. Even looping works, but
there's a noticable delay in rewinding to loopstart as
'JackTransportLooping' is not used. More info about the syntax can
be found from ecasound(1) man page.
And yes, live-seeking is also supported even though I once said it would
be never possible with ecasound. :) Currently a relatively large offset is
used. If jackd (master) and slave positions are different, slave's
process() requests the slave disk i/o subsystem to seek to a new position
'jackd_pos+16*bufsize' (I know, it's a lot, but we can optimize this
later). Following process() callbacks just mute the output buffers until
jackd and slave positions match again. Then normal processing continues.
[solving the timebase update problem - approach 4]
> The simplest solution would be to change semantics of
> jack_set_transport_info() to "set transport state for _next_ engine
> iteration". jack_get_transport_info() would report the old info struct
> until, for instance jack_process(), switched to the next transport state.
Hmm, so far no feedback about this issue. Currently I think this is the
best solution. Without limiting client connections, it's always possible
to have the timebase master in the middle of a out-of-process client
chain. In this case updating the timebase before any process()
callbacks always involves an extra context switch.
But if we change the semantics of set_transport_state, like described
above, we avoid this problem. Possible new problems are:
1) transport position of the first engine cycle is unspecified
-> we can force this to be zero; in any case we have to
maintain two jack_time_info_t instances
2) transport control changes have buffersize more latency
-> not nice, but not deadly either; doesn't affect
processing latency nor sample-sync between clients
Anyways, if this sounds ok to everyone, I can do implementation work.
-- http://www.eca.cx Audio software for Linux!
-- To unsubscribe send message 'unsubscribe' in the body of the message to <ecasound-list-request_AT_wakkanet.fi>.
This archive was generated by hypermail 2b28 : Mon Jun 24 2002 - 06:42:32 EEST