On Fri, 2008-01-25 at 14:04 +0200, Juuso Alasuutari wrote:
On Wednesday 23 January 2008 23:21:21 Bob Ham wrote:
A layer that abstracts away the incidental
obligations of being a JACK client would be good but that is very far
from the domain that LASH is intended to help with.
If such a layer could be beneficial (which is my belief also), why do you
think that it's outside the scope of LASH planned improvements?
There's no reason to add a system-specific API layer to LASH itself.
The abstraction could be done by a separate library entirely, eg
libeasyjack.
By "system-specific API layer" do you mean D-Bus?
No, I mean JACK or ALSA or raw1394 or whatever. I'm talking about
something like
lash_easy_jack_client_t *
lash_easy_jack_client(char *client_name,
char *input_port_names[],
char *output_port_names[],
jack_callback_t *cb);
In this case, there's no reason at all to have "lash_" in there.
To me, it seems like overengineering to design the
LASH <-> client protocol
with networks in mind. The lashd daemon can use D-Bus to communicate with
clients, but that doesn't mean that several LASH daemons running on different
computers couldn't communicate session events and data between eachother. The
idea would be that all LASH <-> client connections would be local, but one
session could be composed of several local LASH environments.
The problem here is you then have two communication protocols; one for
local D-Bus communication, and one for inter-host lashd communication.
They're going to be communicating much the same information; client
properties, port names, etc. To have two protocols would be unwieldy.
For example,
yes, you could add support for maintaining the specific
settings of the patch system (I'm referring not just to JACK here) but
that's not what LASH is concerned with. It only cares about patch
configurations and client state. If it's the case that LASH *has* to
control the settings of the patch system just to provide a usable
system, then it points to a problem with the patch system. If the user
wants to change settings on the fly then the patch system itself should
enable that.
Yes, I suppose that the patch system settings for a session could be handled
by a dedicated patch system controller (e.g. QJackCtl), which would itself
just be a normal LASH client within the session. And when you would load a
saved session, the patch system controller would fire up and adjust the patch
system settings. LASH wouldn't care about its doings.
But then again, why should LASH even be concerned with the connections between
clients in the first place?
That's pretty much it's raison d'etre :-) See the following, and note
the file name:
http://teasel.6gnip.net/~rah/why-ladcca.png
Why doesn't LASH just start the clients, tell
them to load their settings, and leave the other stuff to a patch system
controller?
You probably noticed that the question was rhetorical.
My point is: Where is
it precisely defined what LASH's domain is? Where does this reasoning and
concept model come from? I've gotten the feeling that this distinction that
you maintain between LASH and the rest of the system is nothing but a
tradition.
There's three different ideas that could be surmised by "patch system
controller" (at least that I can think of.) There's something like
QJackCtl, which lets users adjust the settings of the patch system like
the sample rate, period size, etc (and we're talking about something
which does it on-the-fly, which doesn't exist yet.) Then there's LASH,
which monitors port connections and manages their automatic reconnection
when a session is restored. Then there's a patch bay, which allows the
user to adjust the connections while a session is active.
There are no inter-dependencies. They all provide distinct sets of
functionality and hence should be separate programs.
LASH is actually two separate sets of functionality in one system:
automatic port reconnection, and non-X11 session management. So, LASH
*does* leave "the other stuff" to a patch system; it leaves it to the
other functionality in itself :-)
It could be the case that the two sets of functionality in LASH can be
separated into different systems but off the top of my head I'm not sure
how inter-dependant they are. Specifically, I'm not sure whether
session management is completely independant of port reconnection, at
least in order to provide LASH functionality.
IMHO, there is
a lot of work to be done to properly provide the kind of
support that LASH is *trying* to provide, without going on and thinking
about what else it might be able to do. Here is the list of future LASH
work from a while back:
I'm afraid I don't understand all of the things you mention below, probably
because there's hardly any descriptions there.
1.0
Client priorities
Can you explain what you mean by this?
What you were talking about before; dependencies in running order of
clients. Priority is one (simple) way to solve that. Referential
dependencies are a lot trickier. Regardless, the issue needs to be
looked at and that's what this point was referring to.
Often there are chains of programs that operate on a single "track" (ie,
stereo audio stream.) Eg,
Drums: Hydrogen -> JACK Rack -> Ecasound
Bass: ZynAddSubFx -> Freqtweak -> JACK Rack -> Ecasound
Lead: QSynth -> Ecasound
In the above, each instance of JACK Rack has to have a separate JACK
client name. Most clients append the PID. JACK Rack (and, I assume
others) will let you set the JACK client name from the command-line. So
if you were constructing the about setup, you might execute the JACK
Rack instances like so:
$ jack-rack --string-name Drums &
$ jack-rack --string-name Bass
Which will create two JACK clients named "jack_rack_Drums" and
"jack_rack_Bass".
The purpose of "Track naming" in LASH would be to automate this and
present a convenient interface for setting track names.
Guaranteed
save directory availability
Does this simply mean that lashd will somehow make extra sure that the
directory exists, and that the client can write there? If so, it sounds good.
Pretty much. At present, in a save operation, clients get told "Save in
$directory" and then the client responds "OK, I've saved there." With
this kind of protocol, the LASH system isn't providing any guarantee
that the directory will stay there. With programs like Ardour, which
need presistent directories, this a problem.
The solution is to have clients tell the server "I want a persistent
directory" when they start up. The server then tells them, "OK, use
$directory." Then, if the project is moved or closed or whatever, the
server tells the client "Stop using $directory." After the operation is
completed, the client can then be told again "OK, use
$possibly_different_directory."
LASH would only "make sure" that it exists within the LASH system
itself. There are, of course, issues of how to deal with things like
the directory being moved by errant user fiddling, or whatever. FAM may
be able to help with that.
"Save big-ass 50M wav file" vs "Save view settings" :-)
> Networked audio
Handle sessions involving clients on different hosts who communicate
with each other over ports that require reconnecting. Eg, JACK clients
connected using firewire/netjack.
> User interface standard
Promote a standard to LASH clients in order to present a consistent user
interface. This would be like the GNOME HIG but audio-specific, eg,
specifying knob widget appearance and behaviour, recommending audio
widget toolkits, etc.
Automatic
client installation
This sounds an awful lot like stepping on the toes of packagers and package
managers. Unless you mean something completely different, of course.
What's meant is: if you load a session and it includes a client that
isn't installed on the system, then make it such that it is installed
and the session can be loaded. This is no small thing. There are a few
options:
1. Create a system which abstracts package management for different
distros
2. Try and create an automatic compilation environment, similar to
ports on Freebsd or portage on Gentoo (lol)
3. Use autopackage
From the client side, this would be very simple: the programmer just
provides a URL to some meta-information that describes the packages
needed for that LASH client. I think this is pretty doable now that
number 3 exists.
And I would
add to that now:
0.6
Redesign client/server communication
Certificate based security/encryption
Why would managing an audio session demand that the connections be certified
and encrypted? Unless you're thinking network-wise (i.e. sessions that span
several networked computers).
I'm thinking network-wise.
Rework API
Genericify patch-system specifics
Provide more useful event system (callbacks, etc)
I think that an API overhaul would be welcome, and especially using callbacks
would be an improvement. But it's not first priority (thought not the lowest
either).
The API is pretty central, considering that both clients and the server
share most of it. It is that from which all else comes. Hence, IMHO,
pretty high priority.
Rewrite client library in gobject
Rewrite server in C++
These sent a cold shiver down my spine... mostly because I don't know C++ and
I'm unwilling to learn it right now. :)
I've looked at the LASH code, and I must say it looks very well written.
You've done a great job. I don't see any reason why the current codebase
would need an overhaul. How do you feel that a rewrite in C++ would help LASH
as a project?
I appreciate the compliment, but with hindsight there are a lot of
things that could have been done much better. In general, the whole
thing would benefit greatly from object orientation.
Given this and the desire to present a C API, there are few options.
You could write the library and server both in C++ and provide a C
wrapper API/ABI. However, wrapping gobject APIs for C++ (and python,
and perl, and Java, and C#, etc, etc) has already been done a gazillion
times before. I know there are tools to help automate C++ wrapping
(which gtkmm et al use.) The weight is all leaning in gobject's
direction.
I'd use C++ for the server because a) C++ rocks, 2) the server doesn't
need to provide an external C ABI, and d) C++ rocks, and that's what I'd
want to use :-)
And about GObject... well, why bother? I understood
from your reply to Nedko
that you're not suggesting that GObject be enforced into the actual LASH API,
which is a relief. I fail to see any benefit in GObject-ifying the internals,
either.
Object orientation. Events and configs in the communication system
share a lot of functionality. The patch system-specific functionality
could and should be generalised. In the server, the JACK- and
ALSA-specific functionality provide almost identical interfaces. When
writing it, I actually cut-and-pasted a lot of the function prototypes,
just changing "jack" to "alsa". A lot of the function bodies were
also
identical algorithms, only using the different JACK- and ALSA-specific
interfaces for the data. There's a lot of code in a lot of places that
could be made a lot better using objects.
Bob
--
Bob Ham <rah(a)bash.sh>