On Wed, May 04, 2011 at 09:47:25AM +0200, Philipp Überbacher wrote:
Excerpts from Fred Gleason's message of 2011-05-04
00:20:33 +0200:
> Here's a seemingly trivial requirement that
has me stymied: I have a Jack client (external, built against 0.102.20) where it
occasionally makes sense to connect an output port to an input on the same client.
QJackCtl happily makes the connection; the process callback delivers data as expected, but
it's all zeros for the connected input port! I can route the same client output port
to a physical output (ALSA backend) and hear the expected audio. Likewise, a physical
capture port connected to the input on the client receives data from the card as expected.
It's only the "loopback" within the same client that doesn't want to
go.
>
> At first I suspected that the JackPortIsTerminal flag might have some bearing on
this, but changing this value seems to have no effect. Am I missing something blatantly
obvious here, or is this something that is just not within the scope of Jack to allow?
>
> Any pointers greatly appreciated.
I can't tell you about jack API stuff that might
be relevant but I can
tell you that it usually works, there's nothing in jack that forbids it.
There's one thing though you should be aware of: the output will reach
the input one processing cycle after the output was produced, hence it
will be delayed. This is simply a consequence of how jack works.
This may be a long standing bug that has been reported before.
The jack authors seem to see it as a 'feature'.
The summing of signals connected to an input port is done when
that port's owner calls jack_port_get_buffer(). There is an
optimisation: when there is only one output connected, you
just get a copy of its buffer pointer, the sample data is not
copied to separate input buffer.
Now if (1) you make a loopback AND (2) your app clears its
output buffers at the start of the cycle AND (3) it does
this before calling jack_port_get_buffer() on its inputs,
then the looped back output will appear to be empty.
A workaround would be to ensure condition (3) is not true,
i.e. call jack_port_get_buffer() on inputs before clearing
your ouputs.
But even that won't work if there is just one output connected
to the loopback input: the optimisation means its data is not
copied and you will see an empy buffer anyway.
IMHO Jack should make a copy of an output buffer if it is
looped back even if that would otherwise not be necessary.
Not doing this violates assumptions that are (IMHO) very
legitimately made by all authors: either that
(1, strong form) input buffers do not change during a
process callback, or
(2, weaker form) they do not change after the call to
jack_port_get_buffer().
Ciao,
--
FA