[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-multimedia
Subject:    Re: New aRts midi interfaces
From:       Stefan Westerfeld <stefan () space ! twc ! de>
Date:       2000-12-08 1:48:44
[Download RAW message or body]

   Hi!

On Fri, Dec 01, 2000 at 12:44:37PM +0000, Pete Goodliffe wrote:
> Stefan Westerfeld wrote:
> > 
> >    Hi!
> > 
> > I wrote some new aRts idl files for midi interfaces. They include
> [snip]
> > Comments, questions, feedback?
> 
> Well, I'll hazard a few comments on the understanding that I don't know
> aRts that intimately, so shoot me down if you want!
> 
> I was doing a lot of thinking about this kind of thing for the TSE3
> library (TSE3.sourceforge.net). I pretty sure that the system I've got
> going there is a good approach, perhaps you'd like to have a look.
> 
> So my thoughts are:
> 
> 1) Why does timestamp have sec and usec? Wouldn't it be easier to just
> base everything on usecs?

As timestamps are absolute, and MCOP uses longs as 32bit, signed, they would
overflow after about an half an hour. It uses usecs (as opposed to msecs)
by the way, because it is sufficient in precision to adress individual
samples.

> 2) I note that you have separate commands for each type of event, a la
> libkmid. IMHO this isn't particularly helpful for working in a streamline
> manner. The TSE3 approach is more (forgive my probable abuse of IDL syntax)
> 
> struct MidiCommand
> {
>   byte status;
>   byte data1;
>   byte data2;
> };
> 
> enum MidiCommandStatusBytes
> {
>   MidiCommand_NoteOff = 0x08,
>   MidiCommand_NoteOn  = 0x90
>   // etc
> };
> 
> struct MidiEvent
> {
>   TimeStamp time;
>   byte      command;
> 
>   // if command is a NoteOn then this is used to hold the related note off
>   // this is a TSE3ism that may want to be ignored, however, it can be 
>   // useful to have such a grouping to help some stream-based operations
>   TimeStamp offTime;
>   byte      offCommand;
> };
> 
> interface MidiPort
> {
>   MidiEvent rx();
>   void      tx(MidiCommand); // sends now
>   void      tx(MidiEvent);   // queue, can only be txed in time order
> };

Ok, I must admit, that if you look at it this way, it is really significantly
more simple. It also is a lot closer to a stream based representation, which
would be a really good reason to prefer this kind of interface to the other
one, that is, it is MUCH close to a stream based approach. So, to sum it up,
yes, I followed your advice. ;)

It looks something like this now:

struct MidiEvent {
	TimeStamp    time;
	MidiCommand  command;	// you wanted to use command above, too, I think?
};

interface MidiPort {
	readonly attribute TimeStamp currentTime;

	// I'll name the methods differently, in order to achieve bindings to
	// languages that don't support method polymorphism (like C)

	oneway void sendCommand(MidiCommand command);	// realtime
	oneway void sendEvent(MidiEvent event);			// delayed, send timed order
};

Using "oneway" means that there will be no blocking when sending a command,
i.e. the sender will not be blocked until the receiver (which may live
in a different process) really got the event. I don't like rx that much,
because it needs polling, and polling implies blocking, too. This is why
a MidiClient can call

	void      addOutputPort(MidiPort port);
	MidiPort  addInputPort();

which means that if you want to PLAY data, you call addInputPort, and can
put data there. If you want to RECORD data, you call addOutputPort, and
give a midiport with it, that you have implemented. That way, you'll get
callbacks with events rather than having to poll them.

> oh, one other thing I's like to check, I /presume/ that the nature of your
> design is such that several apps can be multiplexed onto a single
> destination? Or there are simple destinations that can do a multiplexing
> as a kind of 'stream operation'

Well, it is currently really simple. It is like

               1:n                1:n
MidiManager  ------>  MidiClient ----->  MidiPort
(singleton)           (app or dest)
                      (record or play)

What you connect is clients, in a way that a client can be connected to
multiple other clients, and the MidiManager will have to do multiplexing
then.

  <further_vision>

What the current design doesn't do, is really flow graph oriented connections.
With the event representation you gave above, I guess we would have things
like midi filters, which work like this:

interface MidiMerge2 {			/* merges two midi streams */
	in async MidiEvent stream in1, in2;
	out async MidiEvent stream out;
};

This would be for instance a module that merges two midi streams. Another
one for filtering events that belong into a range of channels might look
like

interface MidiChannelRangeFilter {
	attribute byte minChannel, maxChannel;

	in async MidiEvent stream input;
	out async MidiEvent straem output;
};

So, the current design doesn't allow arbitary flow graphs of midi filters,
but I guess it would be logic to for now ship with the MidiManager, which
should be a powerful enough description for the borders of the flow graph
(where applications attach), and later add a "real" midi flow graph, which
could be used to implement things like all these nice midi filters. And
finally would be a streaming design.

  </further_vision>

Anyway. I committed today the work I did in the last time, and it works
already pretty nice. You can already use it to loop your midi input port
to your midi output port via artscontrol. More to come in the next time.

Now, when we would get the following interoperable with the new midi
interfaces soon (KDE2.1?):

 - libkmid     (should also make kmid, Brahms, knoteedit work)
 - libtse3     (should also make Anthem, knoteedit work)
 - OSS         (somewhat done already)
 - ALSA
 - aRts synthesis
 - artstracker

I think things would get very useful for end-users already.

   Cu... Stefan
-- 
  -* Stefan Westerfeld, stefan@space.twc.de (PGP!), Hamburg/Germany
     KDE Developer, project infos at http://space.twc.de/~stefan/kde *-         
_______________________________________________
Kde-multimedia mailing list
Kde-multimedia@master.kde.org
http://master.kde.org/mailman/listinfo/kde-multimedia

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic