I am only writing for Jack2: I absolutely need to be able to "plug and
unplug" jack clients while audio is running. However, I decided to use
spin-locks to make sure my jack_port_id queue is write concurrent
safe. That seemed like a good compromise, considering how little time
the locks are held, and that the hold time is deterministic.
I am porting a radio automation system I originally wrote of OS X/Core
Audio. I made design decision to make all the media players and
recorders/encoders there own processes that connect to the mixer-core
via jack. So jack connections are being made to the mixer and then
removed periodically, and that needs to happen without audio drop-
out. So far, working well.
The recorder/encoder process, which I am working on right now, needs to
be optionally able to reconnect to the mixer, or a processing chain
connected to the mixer if it goes away and is restarted. That is what
this was all about.
I will likely give the core mixer/control program similar persistent
functionality next.
Thanks,Ethan...
On Fri, 2019-08-09 at 14:50 -0400, Tim wrote:
On 8/9/19 12:01 PM, Ethan Funk wrote:
Yes, what you describe is what I am implementing.
I have also
called it "persistence" in my application. Normally, when all audio
ports are disconnected, my application quits. But I have an command
line option to keep it running and have it "persist," not quit, try
to reconnect.
I took it one step further and the 'persistence' is stored in
the song file so that the next time the song is loaded, MusE does
not complain that this or that is missing and will be removed,
instead it simply chugs along happily and when the device
reappears, everything works as before.
I have slowly adopted a policy of "nothing is removed from a
song behind the user's back unless they specifically say so, even if
it is ultimately missing some component, such as a port is
missing or a plugin is missing on the system".Thus, persistent...
everything! across sessions is the goal.
I just implemented a simple queue of
jack_port_ids. Callbacks add
their relevant port_ids into the queue, with my main thread
checking the queue periodically, to further check the queued ports
for re-connection. This was not as hard as I though it would be,
and works well so far. Just queueing the port id is a lot simpler
that what you are doing in MusE, but it is sufficient for my
application.
Yes, as you might see, I actually store a few callback types in
our callback queue and I must 'review' the queue when something
happens to carefully determine what exactly took place, for
example did a port disconnection happen before an unregistration
or was it an unregistration alone, etc.It was tricky. Those port ID
functions sure help though.
One remaining question: Am I safe assuming that
jack2 will call my
callbacks one at a time from a single thread, or do I need to make
my port id queue writing function thread safe, just in case jack2
calls my callbacks concurrently?
Don't quote me, I might be getting this wrong, if I recall correctly
;-)Jack 1 issues all callbacks in the realtime audio thread.Jack 2
issues some important callbacks, such as the Sync callback, in the
realtime audio thread, but most other callbacks are issued in ONE
separate thread.Therefore I don't think it could call them
concurrently, but I'm not an expert here...I think our queue is
multi-writer anyway so I probably might not have noticed if they
were concurrent, but I don't think I noticed anything unusual.
Tim.
> Ethan...
> On Fri, 2019-08-09 at 01:52 -0400, Tim wrote:
> > On 8/8/19 10:20 PM, Ethan Funk wrote:
> > > In an application I am writing, I am getting an error message
> > > out stderr(see email subject), and a connection failure return
> > > result, when I tryto use jack_connect() from inside a
> > > jack_set_port_registration_callbackfunction, using Jack2. My
> > > goal is to have the application remember andre-connect to a
> > > disconnected port if/when it "comes back." Am I going toneed to
> > > create a mostly sleeping thread just for port re-
> > > connectionsattempts, or is there something obvious I am
> > > missing?
> > > Thanks,Ethan...
> >
> > If I understand your goal, I did this in MusE.I called it
> > 'persistent connections', or 'persistent ports'.
> > For example you can unplug a USB midi device currently in use
> > by MusE as a 'Jack device', then re-plug it, and MusE will
> > automatically reconnect to its ports as if nothing happened and
> > you may continue playing.(I made our 'ALSA devices' do the same
> > thing!)It should also work with other Jack clients.
> > Look in our driver/jack.cpp, at: static void
> > registration_callback(...), static void
> > port_connect_callback(...), and static int
> > graph_callback(...), // This is called in the gui
> > context, // triggered by graph_callback() void
> > JackAudioDevice::graphChanged().
> > It was complicated. Very. I needed to support Jack 1 and 2.So
> > there are a few sequences of calls and resulting sequences of
> > callbacks for example that are different in Jack 1 and 2.
> > Several tricks and traps. See comments.
> > My system relies HEAVILY on the jack port 'alias
> > names', because it was pretty much the ONLY thing you can rely
> > on, because the regular port names and port numbers
> > change upon re-plugging. It automatically chooses which alias
> > is best or falls back to the not so good canonical port name.
> > So, that's what it 'remembers' between device plug ins - simply
> > the port alias or name text.
> > HTH.Tim._______________________________________________Jack-Devel
> > mailing listJack-Devel(a)lists.jackaudio.org
> > <mailto:Jack-Devel@lists.jackaudio.org>
> >
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
> >