\subsection{Midi}
\seclabel{midi}

Midi (``musical instrument digital interface'') is a standard protocol
adopted by most, if not all, manufacturers of electronic instruments.
At its core is a protocol for communicating \keyword{musical events} (note
on, note off, key press, etc.) as well as so-called \keyword{meta events}
(select synthesizer patch, change volume, etc.).  Beyond the logical
protocol, the Midi standard also specifies electrical signal
characteristics and cabling details.  In addition, it specifies what
is known as a \keyword{standard Midi file} which any Midi-compatible
software package should be able to recognize.

Over the years musicians and manufacturers decided that they also
wanted a standard way to refer to {\em common} or {\em general}
instruments such as ``acoustic grand piano'', ``electric piano'',
``violin'', and ``acoustic bass'', as well as more exotic ones such as
``chorus aahs'', ``voice oohs'', ``bird tweet'', and ``helicopter''.
A simple standard known as \keyword{General Midi} was developed to fill
this role.  It is nothing more than an agreed-upon list of instrument
names along with a \keyword{program patch number} for each, a parameter in
the Midi standard that is used to select a Midi instrument's sound.

Most ``sound-blaster''-like sound cards on conventional PC's know
about Midi, as well as General Midi.  However, the sound generated by
such modules, and the sound produced from the typically-scrawny
speakers on most PC's, is often poor.  It is best to use an
outboard keyboard or tone generator, which are attached to a computer
via a Midi interface and cables.  It is possible to connect several
Midi instruments to the same computer, with each assigned a different
\keyword{channel}.  Modern keyboards and tone generators are quite amazing
little beasts.  Not only is the sound quite good (when played on a
good stereo system), but they are also usually \keyword{multi-timbral},
which means they are able to generate many different sounds
simultaneously, as well as \keyword{polyphonic}, meaning that simultaneous
instantiations of the same sound are possible.

Note: If you decide to use the General midi features of your
sound-card, you need to know about another set of conventions known as
``Basic Midi'' which is not discussed here.  The most important aspect
of Basic Midi is that Channel 10 is dedicated to \keyword{percussion}.  A
future release of Haskore should make these distinctions more concrete.

Haskore provides a way to specify a Midi channel number and General
Midi instrument selection for each {\tt Instr} in a Haskore
composition.  It also provides a means to generate a Standard Midi
File, which can then be played using any conventional Midi software.
In this section the top-level code needed by the user to invoke this
functionality will be described; the extended document contains all of
the gory details.

\begin{haskelllisting}

> module WriteMidi (module Haskore.Interface.MIDI.Write,
>                   module Sound.MIDI.File,
>                   module Sound.MIDI.General)
>        where
>
> import Haskore.Music as Music
> import Haskore.Performance
> import Haskore.Interface.MIDI.Write
> import Sound.MIDI.File
> import Sound.MIDI.General
> import Data.List(partition)
> import Data.Char(toLower,toUpper)

\end{haskelllisting} 

Instead of converting a Haskore {\tt Performance} directly into a Midi
file, Haskore first converts it into a datatype that {\em represents}
a Midi file, which is then written to a file in a separate pass.  This
separation of concerns makes the structure of the Midi file clearer,
makes debugging easier, and provides a natural path for extending
Haskore's functionality with direct Midi capability (in fact there is
a version of Haskore that does this under Windows '95, but it is not
described here).

A {\tt UserPatchMap} is a user-supplied table for mapping instrument
names ({\tt Instr}'s) to Midi channels and General Midi patch names.
The patch names are by default General Midi names, although the user
can also provide a {\tt PatchMap} for mapping Patch Names to
unconventional Midi Program Change numbers.
\begin{haskelllisting} 

> type UserPatchMap = [(Instr,GenMidiName,MidiEvent.Channel)]

\end{haskelllisting} 

See \secref{test-functions} for an example of a useful user
patch map.

Given a {\tt UserPatchMap}, a performance is converted to a datatype
representing a Standard Midi File using the {\tt WriteMidi.fromPerformance}
function.
\begin{haskelllisting} 

> WriteMidi.fromPerformance :: Performance -> UserPatchMap -> MidiFile
> WriteMidi.fromPerformance pf pMap = 
>        MidiFile mfType (Ticks division)
>          (map (performToMEvs pMap) (splitByInst pf))

\end{haskelllisting} 
A table of General Midi assignments called {\tt GeneralMidi.map} is
imported from {\tt GeneralMidi} in Appendix~\ref{general-midi}.  The
Midi file datatype itself and functions for writing it to files are
imported from the module {\tt MidiFile}, briefly described below.  The
remaining details are omitted in the basic version of this document.
