[rec.music.synth] All you wanted to know about MIDI Manager

nick@cs.edinburgh.ac.uk (Nick Rothwell) (02/21/91)

>Would someone (Nick...) like to expound upon the benefits of using Apple's
>MIDI Manager, what it is, what it does, and how one gets it?  I can't seem
to
>find mention of it in any of the Apple literature I have, nor is it listed
on
>Apple's confidential price list.

Well, I'll reply to the THINK C list as well as EMUSIC - it might be of
interest there as well.

What the hell, I'll fire this off to rec.music.synth and the Mac newsgroups
as well. That way, NOBODY will EVER have to ask about MIDI Manager again.
Right? Check...

Non-Mac people might find this interesting as an overview of how to do MIDI
cleanly in a hardware independent manner, and how to provide a clean
abstract interface to the system services required by a MIDI application
and MIDI working environment.

Well, how one gets it for a start. Via APDA, I believe. Actually, I managed
to find MIDI Manager 2.0 on an FTP site somewhere with the Lime notation
software.
Apple haven't publicised it because they're still tied up in a lawsuit with
Apple Corp., the Beatles' record company.

There are three releases: 1.1, 1.2 and 2.0. 1.1 was the initial release
(1.0 never made it out the door). 1.2 fixed the odd bug, but rendered MM
useable only on machines with 256K ROM's, so the Mac Plus was out. 2.0
presumably has extra features, but I don't have any documentation for it,
so I don't know about them. All I know is that it seems a lot more
efficient. MOTU's Performer under MM1.2 was pretty sluggish even on an
SE/30. Performer under MM2.0 is fine. I don't know if MM2.0 runs on a Plus
or not.

What is it? Well, the first MIDI routines for the Mac were the usual
read-a-byte write-a-byte kind of thing. Various buggy versions of Kirk
Austin's assembly code were floating around all over the place, and even
today there are still lots of roll-your-own MIDI driving routines
(HyperMIDI, MIT toolkit, and so on). These are Bad News. Let me explain
why.

[AN ASIDE: Macintoshes have two serial ports, which support RS424 (I think
- the balanced-pair hardware spec. anyway). These are identical (modulo
processor interrupt priority) and plenty fast enough to run at MIDI speeds;
after all, they take AppleTalk in their stride. You need some hardware to
generate MIDI from RS424; you have to convert voltages, nail one half of
the RS424 to ground, build the current loop, and opto-isolate the input. In
addition, the interface provides the 1MHz (usually) signal to clock the
UART, rather than having the Mac try to invent a suitable baud-rate. So, a
Mac can support two independent MIDI Ins and Outs for 32 channels each way
if you use the serial ports; if you want more than that, you can pull
tricks like using a multiplexing protocol - this is what MOTU do for their
MIDI Time Piece, using an otherwise undefined MIDI Status Byte to signify
cable number. So, a MIDI interface is just a box of cheap electronics. I
built a dual-port MIDI interface with bi-colour activity LED's for about
$20. If you don't want to do that, feel free to pay Opcode $200 for
something similar. I don't know of any incompatibilities of the sort you
can get with weird mutant MP401 clones on the PC.]

Anyway: why not roll your own MIDI routines?

        o Hardware dependency. Sure, your routines worked fine on the Mac
512K,
          but for some reason they can't handle the auto sleep routines on
          the Portable (ain't that right Marc?). 'Nuff said?

        o Software parsing of MIDI. It's a real hassle, especially if you
          want to do it right and not fall flat when faced with embedded
          realtime bytes. And if you want to read and convert MIDI Time
Code
          and yes run fast enough to handle full-speed SysEx dumps from
          samplers, then it gets to be a headache.

        o Hardware independence. MIDI is not always going to mean the two
          serial ports on the back of your Mac. There are now expansion
cards
          for the Mac that require to get MIDI feeds from Mac sequencers.
          And I don't see why everybody should extend their applications to
          handle those, or MOTU's MTP, or any new gizmo which comes along.
          In fact, a MIDI program shouldn't know or care whether it's
talking to
          a serial port, a plug-in card, another MIDI program, or itself;
the
          MIDI data transfers and timing functions should work regardless.
          Abstraction's a wonderful thing.

        o Asynchronous communication. Your wonderful ReadAByte/WriteAByte
          echo routine is going to sound rather silly if everything hangs
          for a few seconds when you change layers under MultiFinder or
open
          the Control Panel. MIDI communication should be running all the
time,
          in real time, and not be tied to the event loop. (I know. I've
done
          that. It's not pleasant.)

        o Software cooperation. I don't want my MIDI program to reprogram
the
          serial ports and shoot AppleTalk through the head. Nor should it
          interfere with other programs I'm running. In this age of
MultiFinder
          and true multitasking (shut up) a number of MIDI programs should,
if
          not actually communicate, then at least stay out of each others'
way.
          Of course, it would be ideal if programs could communicate with
each
          other. That way you can build MIDI systems out of smaller
components.

        o Timing functions. ReadAByte/WriteAByte MIDI routines are rather
          hopeless for tying a sequencer to MIDI Time Code coming in off
          a SMPTE-striped tape. Try it if you don't believe me.

So, MIDI Manager solves all these problems. It's an Apple product, which
means that (in theory) everyone has it and so every piece of software
should be using it. Just like the rest of the Toolbox. Why doesn't everyone
have it? Why haven't you even heard of it? Beats me. Ask the lawyers.

What do you get? There's a MIDI Manager INIT - this provides the traps for
the MIDI Manager, and a Sound Manager trap to say that MM is installed and
running. There's the Apple MIDI Driver - this is the link between the MIDI
Manager and the serial ports. The AMD will drive either or both ports at
one of three clock speeds (depending on your interface), and provides some
timecode services. Other vendors will provide alternative drivers for their
hardware (I'm eagerly awaiting MOTU's 8 x 8 MTP driver). And there's the
PatchBay, which lets users graphically connect applications to each other
and the ports. In fact, the PatchBay can be written using the MIDI Manager
traps - there's nothing magical about it. (Well, almost nothing.)

Suppose you want to write a MIDI Manager application. Well, when it starts
up, 
it has to sign into the MIDI Manager (having verified that MM is
installed), and it has to sign out when it's finished. MIDI Manager loads
the port drivers when the first application signs in, and drops them when
the last application signs out.

When your application signs in it provides a name and an icon. This is what
PatchBay uses to display your application to the user.

To do anything useful, you have to create some communication ports and tell
MIDI Manager about them. There are three kinds:

        Input ports: these are created with hook routines which are called
        when MIDI data arrives for your application.

        Output ports: you use these to output MIDI data.

        Timing ports: these are tied to timebases (either internally
generated
        or externally linked) and provide timestamps for MIDI data.

You can have as many ports of whichever kind as you want. These are
presented in PatchBay; the user can then connect them together so that your
application ends up talking to serial ports, other applications, whatever.
Or, you can attach yourself to specific ports (which may still be awaiting
creation). There are interface guidelines for this.

The user can attach input and output ports in pairs using PatchBay; data
flows from output to input. In addition, data can be sent from one output
to several inputs, or from several outputs to one input (MIDI Manager does
the merging). The time ports allow applications to synchronise, so that a
master application (say, a timecode generator) can lock a slave application
(say, a sequencer). The Apple MIDI Driver provides time ports which read
real timecode from the outside world.

I won't go into the timing functions since they're rather complex. Input
and output is easier. Output is simple - to output a message, put it into a
buffer and send it. Long messages (SysEx's) are flagged with continuation
bits. Messages can be queued for future transmission using the time port
features; this is dead handy, since it means you can avoid SCC overruns by
staggering transmission timestamps. By being a little more clever, you can
do your own output buffering and have asynchronous service routines send
stuff out when required - see my example code for details. It's great to be
able to queue an entire SysEx bank dump for transmission over the next 30
seconds and then forget about it - the application happily keeps going,
responding to the user, regardless, as the data goes out under remote
control.

Input is asynchronous. You don't ask for the next message (well, you can,
but it's not cool). Instead, your read hook is called at interrupt time
when something arrives. You then get to deal with it then and there
regardless of what your application is doing otherwise, even if some other
application is frontmost under MultiFinder. Or, you can reject a message
and ask to see it again later when you're not busy. MIDI Echo is easy (the
readhook just sends the message out immediately); more complicated things
require work since the read hook isn't running in a first-class environment
- you don't have the usual access to globals, the ToolBox, and so on. But,
with a little thought, and a few semaphores, it's not too difficult. If you
have time ports, you can set up timer routines which you interface to much
like read hooks. 

I don't think there's much more to say. I love MIDI Manager. It's nice to
see Performer and Anodyne (my MIDI generic editor/librarian) pass data to
each other and update their progress bargraphs in parallel. There are some
subtleties to do with giving each application access to its event loop
every now and then, but nothing difficult for your average Mac power
programmer. MIDI Manager tends to choke on extremely dense SysEx messages.
For example, I can capture a D-50 bank dump easily (it's a set of 200-odd
byte SysEx messages with timing gaps) but the VFX sends a single 65K
message which is a hassle. The problem is probably that my read hook is a
fairly ordinary C procedure. If I wanted top-notch performance I'd have to
assembly-code the thing.

Can't think of much more to say, really, apart from: APPLE: publicise and
distribute the damn thing, and everybody else: use it, dammit.

Nick.

-- 
Nick Rothwell,	Laboratory for Foundations of Computer Science, Edinburgh.
		nick@lfcs.ed.ac.uk    <Atlantic Ocean>!mcsun!ukc!lfcs!nick
~~ ~~ ~~ ~~  Captain Waldorf has analogue filters. You do not.  ~~ ~~ ~~ ~~
~~ ~~ ~~ ~~ Do not try to imitate them or any of their actions. ~~ ~~ ~~ ~~