| [ please note the qm-dev mailing list inclusion in the Cc: line ]
>with Gtk and other Linux type stuff, it's not clear where, if at all, the
>GUI can be severed from the kernel.
Its as completely separate as I could make it. There are just two
"connections":
1) in nmain.cc:
UI *ui;
if ((ui = ui_factory (&argc, &argv)) == NULL) {
error << "Cannot start Quasimodo UI" << endmsg;
return 1;
}
UI is an abstract class that declares the following functions:
virtual bool running () = 0;
virtual void quit () = 0;
virtual void request (RequestType) = 0;
virtual ModuleSet &default_module_set () = 0;
virtual void new_module_set () = 0;
virtual int nstate_query (size_t nstates, const char *prompt, ...) = 0;
virtual void queue_error_message (Transmitter::Channel, const char *) = 0;
virtual void run (Receiver *) = 0;
The things that really make the UI work are in a concrete UI class
that implements the virtual methods as well as its own (see
src/qm/abstract_ui.h for the definition)
2) various methods of the UI class are used by way of the global "ui" pointer.
So, to make this work in Java, you just write a new concrete UI class
implements the required methods. You don't need to fix up ui_factory,
because presumably, there would be a different "main()" if things ran
inside Java (but src/qm/nmain.cc shows very clearly how
straightforward it is to get things running).
>It's also not clear to me whether currently compiling Csound scores and
>orchestras would run with Quasimodo, without modification, which is a
>requirement of my proposal: complete backward compatibility with existing
>scores and orchestras. Sorry if I didn't make that clear.
The orchestra parser is complete (I think), and handles all Csound
instruments that I've been able to find that use the opcodes I've
ported thus far. It actually handles a few things more sensibly than
Csound as well, but attempts to be backwards compatible. For example,
value converters that return an i-time value can be used as an i-time
argument to another opcode, instead of first storing their return
value in another variable.
The only (intended) notable change is that Quasimodo has no concept of
"header statements", so setting kr, ksmps, etc. at the top of a .orc
has no effect whatsoever. It wouldn't be hard to change that, but if
you plan to load several different instrument files the way that
Quasimodo does, the idea that these variables should be set in any one
of them is just plain wrong.
The score file stuff is both more compatible (in that there are no
changes whatsoever), and less complete. It currently does not handle
ramping, npp, lpp and various other things. There is also no support
for the macro system, which I consider to have been an extremely bad
design decision by jpff.
All this is with the proviso that both are still liable to changes,
and the score file stuff doesn't currently work at all (I broke it,
but will fix it today). But hey, its all just Bison and flex
specifications, so changing it is nothing like trying to change the
Csound parser.
>When I say "cross-platform", I mean: you take the sources, which possibly
>have some conditional compilation in one or a few clearly demarcated files,
>define one macro in the makefile, type "make", and then you can run
>JavaCsound with JavaSound on your processor.
Sounds pretty reasonable. Thats the way Quasimodo tries to be "for
itself". There are almost no #ifdef's anywhere in the main code for
different platforms, and I intend it to remain that way. There is a
system-dependent directory with system-specific code in it that
handles all the differences between platforms, as well as a "Platform"
object that can be used for various platform-specific small tasks.
>If it is necessary to create some abstract interfaces (say an abstract
>thread class with different implementations on different platforms) that is
>fine, as long as this part of the work is stable and easily maintained. It
>also is not critical if the compiler-compiler runs only on one (common)
>platform, but I would prefer otherwise.
Well, Bison is out there, and I'm sure there are various versions for
Windows etc. Same with flex.
>in the Csound C or C++ kernel. In other words, the Csound kernel implements
>the guts of several worker thread routines, but those threads are created
>and destroyed outside of the kernel, either in the JavaCsound class or in
>its clients.
Quasimodo is written so that the code to handle various tasks run in a
different thread than the DSP simulator. This is the key to making it
able to use multiple processors. Although the DSP thread could be
thought of as the Csound kernel, thats not really true in Quasimodo:
to implement all that Csound does, Quasimodo uses 3 threads: the DSP
simulator, the real time event thread and some other thread (which
might be running the UI) to handle input/loading and parsing of scores
and orchestras.
This doesn't look like a single function, and if you used it for Java,
you'd presumably need a Java wrapper that invoked the 2 "other"
threads, and took care of the tasks currently done by the UI thread.
Its going to get more complex too: I am about to change things so that
there is one DSP thread per ModuleSet, and then a final (quick)
mixdown of the output of each DSP before it goes off to the
soundcard. This allows me to use N>2 CPU systems efficiently, and even
N=2 CPU's *more* efficiently, since when Quasimodo is running, its
almost always just the DSP thread thats active, leaving a second
processor sitting idle until "something else" happens. It also opens
the door to sound output from Quasimodo coming from things other than
Quasimodo DSP threads, if you see what I mean.
I don't know how this is sounding so far. I do think that Quasimodo
could really benefit from trying to be made into something close to
what you described.
|