From alsa-devel-owner@alsa.jcu.cz  Sat Feb 27 10:09:39 1999
Received: from camel8.mindspring.com (camel8.mindspring.com [207.69.200.58])
	by marvin.jcu.cz (8.9.1a/8.9.1) with ESMTP id KAA21993
	for <alsa-devel@alsa.jcu.cz>; Sat, 27 Feb 1999 10:08:49 +0100
Received: from [209.138.62.168] (pool-209-138-62-168.dlls.grid.net [209.138.62.168])
	by camel8.mindspring.com (8.8.5/8.8.5) with SMTP id EAA10582
	for <alsa-devel@alsa.jcu.cz>; Sat, 27 Feb 1999 04:08:45 -0500 (EST)
Message-Id: <199902270908.EAA10582@camel8.mindspring.com>
Subject: More stuff about the sequencer [was Re: Instrument abstract layer]
Date: Sat, 27 Feb 99 03:08:45 -0600
From: Data <data@havoc.gtf.org>
To: <alsa-devel@alsa.jcu.cz>
Mime-Version: 1.0
Content-Type: text/plain; charset="US-ASCII"
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

First, let me apologise for the long subject, and long text.  Next, 
please indulge me as I copy this worthy statement:

>ALSA needn't solve all sound trouble all over the world.

Most definitely!  Look at MIDI: a very simple and cheap protocol, and 
it's still going strong through sixteen years of massive technology 
changes.  We've got now boxes crammed with VLSI ASICs that would have 
looked straight out of Star Wars when MIDI was developed, and they 
_still_ use this dinky current-loop interface to talk to the world.  Know 
why?  _Because it still works_.  I think MIDI is an excellent design, and 
I don't care who knows it :)  And besides, there's something awfully neat 
about the fact that my 1985-vintage Juno-106 speaks the same language as 
a 1998-vintage FS1R.  They just made it talk notes: they didn't try to 
build some kind of FDDI for musicians.  We'd do well to take note, I 
think.  (sorry about the pun ..)

Which makes a nice transition to my topic, which I think will go over 
like a lead balloon with some people.  But hey, all they can do is send 
me mail-bombs :) so here goes.  After about a week or so of deliberation 
I finally sat down to tweak the sequencer engine for my own nefarious 
purposes - and shortly found myself ripping its guts out.  Now, my Linux 
box doesn't have a connection to the Internet (unless floppy disks 
count), so the ALSA CVS tree is in no immediate danger.  So I'll merely 
describe my gory and reconstructively surgical thoughts regarding ALSA 
for your pleasure and entertainment (hey, just think, you could be taking 
in a show with your girlfriend right now - what would _you_ prefer?).

Two things primarily bug me about the way the sequencer is set up.  I've 
mentioned these before.  The first has to do with sync: sync troubles 
being the thing that led me to terrorise this mailing list to begin with. 
 I would like the sequencer to talk SMPTE, for starters.  But that's a 
small matter.

The thing that _really_ bugs me is the event types, and the event 
structure.  Actually, that's pretty much it.  I think most of the rest of 
the sequencer is brilliantly done.  But there are way too many kinds of 
events there, I think.

Now, the first rule of computer science is 'never reinvent the wheel'; 
and since we already have a fine and versatile format for passing events 
from point to point (MIDI), I think we should use it.  That is to say, I 
see no reason to define arbitrary constants for note + duration, note on, 
note off, program change, registered parameter number, ignite explosive, 
etc. etc. when that sort of thing is covered already by the MIDI spec.

Even more importantly, consider what has to be done at present to convert 
a plain ol' MIDI data stream into events.  The bytes have to be parsed, 
of course, and the proper event type written.  Then the packet has to be 
time-stamped, and the data copied from the MIDI message into the 
appropriate fields.  That's done in a client.  The client then passes 
this on to the sequencer which allocates a spot in the queue and copies 
the structure with a memcpy.

Conversely, to convert an event into a MIDI message, the event has to be 
parsed - this may require a very large case statement - and the MIDI 
bytes filled in with the appropriate data.  Assuming this is done by a 
driver client, this would have to take place after the sequencer engine 
has dequeued it - meaning extra latency.

Why not instead do away with the redundant event types - e.g. note-on, 
note-off, program change - and replace them all with one: say, 
ALSA_SEQ_MIDI_MSG or something.  The event structure would have, say, a 
sixteen-byte space for storing MIDI bytes.  A driver client would then 
merely copy the MIDI bytes into the event, stamp it & go.  Much quicker.

For sys-ex messages and the like, there are two ways to handle things.  
There's already a provision for variable-length packets; this would work 
fine for large sys-ex dumps and such.  Another way (though a bit less 
efficient) would be to define another message, called maybe 
ALSA_SEQ_MIDI_RAW.  Where ALSA_SEQ_MIDI_MSG would be guaranteed to have 
exactly one complete MIDI message in it, ALSA_SEQ_MIDI_RAW would not be 
guaranteed to have anything meaningful at all.  A driver client could 
dump incoming bytes into these and mindlessly ship them off.  Fast and 
dirty - possibly useful too.  To keep them sorted, the timestamp would do 
nicely.

Of course there is a need for certain event types that aren't present in 
the MIDI spec.  These 'meta-events' are covered by the non-redundant 
event types in the current list - the client information events, for 
example.  But I would like to suggest that the numbers be made 
hexadecimal, categorised by high nybble.  Then you could have a two-level 
case statement or hopefully a mere mask-and-compare, to weed out messages 
you weren't interested in.  That, I think, is not a big deal.

Furthermore, the Standard MIDI File format has a way of representing such 
'meta'-events; that also bears looking into, I think.

Now, believe it or not, this has something to do with the discussion on 
the instrument layer.
As I said before, the discussion seems to be leaning toward a 
GM/XG/GS/Soundfont sort of setup.  Well, I've done a bit of reading, and 
my suspicions were confirmed: though Soundfonts are merely a file format, 
GM/XG/GS mainly are controller definitions and patch names.  That's 
basically it.  The point is that if we make the sequencer talk straight 
MIDI internally, it will inherently support these 'formats', since all 
they are are controller messages and program changes.  Clients could 
fuddle with the details.  Besides, the sequencer core is not in general 
supposed to have too much knowledge of what exactly is in those packets 
it's shovelling in and out.  Its job should be similar to that of an 
overnight postal service, in my view: move the stuff from here to there, 
and quickly.

So the 'instrument layer' could be just a sequencer client that has a 
special friendship with the sound drivers; or some library that can talk 
program changes, soundfonts, sample dumps _and_ sysex; or what-have-you, 
but the sequencer core needn't concern itself with it.  Although I 
suppose that was the idea all along :)

Now, if you're wanting some way of getting soundcards and whatnot to have 
a consistent interface for loading up instruments, I can think of a 
couple of good ones.  First, I really think you should head to 
www.midi.org and have a look at the DLS proposals.  This is (apparently) 
partially based on Soundfonts but is a royalty-free, public-domain 
format, and is designed expressly for this very situation.  It's the 
closest thing I've yet seen to a  universal sound format.

Also, we should note that soundcards are fairly homogeneous as regards 
their soundmaking methods: you get FM and sample-playback.  A few cards 
will have a few extra features: these can be accommodated somehow, but by 
and large the sounds most people want to put in through a standard 
interface will be of the sample-playback variety.  The MIDI Sample Dump 
protocol is a nice example of a way to do that, although I think 
personally it's a bit grotty.

AIFFs are an excellent format - WAVs are MicroSloth's bastardised version 
of AIFFs - and are quite capable of representing all of the information 
I've seen discussed.  AIFFs can, in theory, hold multiple samples, loop 
points, key maps, and all sorts of goodies.  A layer which could 'load' 
such AIFFs into soundcards would not be short on power.

Speaking of which, I've got yet another idea.  The current thinking seems 
to be to communicate with the instrument layer via events and messages - 
if I understand it correctly, these would be sent through the sequencer 
itself.  I see little reason for this.  Why not build the layer as a 
standardised interface or library?  It could include functions such as 
set_key_map, read_sample, or what have you.  It could even be set up as a 
driver: how about a device file you could pipe a SampleCell or Soundfont 
drumkit file to, and then feed MIDI notes to the soundcard to play it?  
No reason that ioctls wouldn't do for parameter changes.  And it could 
still talk to the sequencer: simply make a sequencer client that could, 
for example, listen in for MIDI control and program changes, and punch 
the appropriate interface buttons in turn.  Merely load the right modules 
and bam! instant cheezo software synth (bit like QuickTime Musical 
Instruments on the Mac, I suppose).  I think such a setup could be lots 
of fun, myself.

Anyway I'll be gutting and rewiring fundamental parts of the sequencer 
this weekend, and will deliver a true and accurate account of my 
adventures at such time as I can manage to.  And sorry about rambling so 
much - it's quite late, and I'm _really_ tired :)

so then - cheers,
Michael Ashton

