Notes on the code
-----------------

These notes are for anyone who wants to re-compile, re-write or re-use
bits of the code.

Compilation
-----------

The file midifile.c and the header file midifile.h are slightly changed from 
the midifilelib distribution. To see the program dependencies, examine the
Makefile.

The code is written in K&R style C and should be fairly easy to compile
on any system with a C compiler and a make utility. Makefiles are
provided for gcc/unix, DJGPP/DOS and PCC/DOS. You may get warning
messages if your compiler prefers ANSI C style function prototypes.

To compile the code, type

make all

If the complete compilation does not work, you can try compiling the 
individual programs separately :

make midi2abc
make abc2midi
make abc2abc
make mftext
---------------------------------------------------------------------
Calling abc2midi or midi2abc from a GUI.
----------------------------------------

The programs should now have an exit value of 0 for normal termination
and 1 for an error state. However, abc2midi will still exit with 0 if
it finds non-fatal errors in the code, so the user should always have
the option of looking at the program's text output (I don't want to
get blamed when useful diagnostic output turns into the ubiquitous
'OK' click-button).

----------------------------------------------------------------------

The abc parser
--------------
abc2midi has been written as a parser program (parseabc.c) and an event
handler program (store.c), which in turn uses genmidi.c and queues.c
for generating MIDI output. The parser has been written so that it should
be possible to write your own utility to handle the interpreted abc and
link it with the parser code. This is very similar to the way that the
midifilelib utilities work. Moreover, the parser makes it is possible
to write out almost exactly what you read in. This means that in some cases
the level of parsing is fairly primitive and you may wish to make use of
routines in store.c which doing further processing on an item. If you
just want to do some fairly simple processing on the abc, you may
find it easier to modify toabc.c, which is the back-end for abc2abc.

In the first phase of parsing, the abc file is read and when, say, a note
is encountered, the routine event_note() is called. The code for event_note
is in the file store.c. Encountering an X in the abc generally causes a
routine called event_X() to be called. abc2midi builds up an internal 
representation of the tune. At the end of the abc tune, a little bit of 
processing is done on the internal representation before the routine 
writetrack() is called to actually write out the MIDI file. If there are
repeats in the music, something that appears only once in the abc may be
invoked twice by writetrack().

The internal representation uses the arrays feature[], pitch[], num[], 
and denom[]. feature[] holds a description of an object while the other
arrays hold data relating to the object. The list of possible features
can be found in the file abc.h . The main features are NOTE, a note of
specified duration, REST, a pause of specified duration and TNOTE, a
note of specified duration with no interval between when it starts and
when the next item starts. This provides a simple way of representing
chords. Ties, broken rhythm signs and grace note brackets are all
deal with before writetrack() is called.

To add your own special features, you could define a new feature type.
However, an easier option is to use the %%MIDI format. If the parser
encounters "%%MIDI command", where command is not recognized by the
routine event_specific(), the string following %%MIDI is stored away
and passed to the routine dodeferred() by writetrack() when the MIDI
file is being written.

Parsing the abc
---------------
The abc is parsed line by line. Each line may be

* A comment
* A package-specific command
* A field (which may have a trailing comment)
* A blank line
* A TeX command

Having detected one of these, the parser calls an appropriate
routine. If it is none of these, then within the tune body it is

* A line of music (which may have a trailing comment).

Which is parsed and individual elements recognized. Outside the tune 
body it is

* A line of arbitrary text.

and an appropriate routine is called.

Routines called by the parser
-----------------------------
These may be a bit out of date - look in the file parseabc.c for the actual
interfaces.

event_init(argc, argv, filename) 
int argc;
char* argv[];
char** filename;
- first routine called by the parser. Expects filename to be the name of the
  abc file to parse on return.

event_text(s)
char *s;
- called whenever a line of text is encountered.

event_tex(s)
char *s;
- called whenever a TeX command is encountered.

event_linebreak()
- called whenever a newline character is encountered.

event_blankline()
- called whenver a blank line is encountered.

event_eof()
- called when the end of file is reached.

event_error(s)
char *s;
- called whenever an error condition is detected. Errors are
  generally not fatal within the parser.

event_warning(s)
char *s;
- called whenever a condition which is likely to be an error is
  detected.

event_comment(s)
char *s;
- called whenever a comment is encountered.

The following are calls are invoked by fields in the abc :

event_specific(package, s)
char *package, *s;
- recognizes %%package s

event_length(n)
int n;
- recognizes L:

event_refno(n)
int n;
- recognizes X:

event_tempo(n, a, b, rel)
int n, a, b;
int relative;
- recognizes Q:

event_timesig(n, m)
int n, m;
- recognizes M:

event_key(sharps, s, minor)
int sharps;
char *s;
int minor;
- recognizes K:

event_part(s)
char* s;
- recognizes P:

When any other field is encountered in the abc :

event_field(k, f)
char k;
char *f;

If a line of music is encountered, the elements of that line each
trigger a call to one of the following events, provided that parsing
of music lines has been enabled :

event_graceon()

event_graceoff()

event_rep1()

event_rep2()

event_slur(t)
int t;

event_tie()

event_rest(n,m)
int n, m;

event_bar(type)
int type;

event_space()

event_lineend(ch, n)
char ch;
int n;

event_broken(type, mult)
int type, n;

event_tuple(p, q, r)
int p, q, r;
- general tuple: q and r are zero if not present

event_chord()
- called whenever + is encountered.

event_chordon()
- called whenever [ is encountered.

event_chordoff()
- called whenever ] is encountered.

event_gchord(s)
char* s;

event_reserved(p)
char p;

event_note(roll, staccato, updown, accidental, mult, note, octave, n, m)
int roll, staccato, mult;
char updown, accidental, note;
int octave, n, m;

In addition, there are 2 other routines :

int getline() - returns the line currently being parsed

parseron() - enable parsing of music lines.

parseroff() - disable parsing of music lines.

---------------------------------------------------------------------

Extensions to the abc Format
----------------------------

1. The parser recognizes 
%%package <string>
as some package-specific command and calls event_specific with the
package name and the string that follows it.

2. The abc standard defines notation for 4 octaves :

C, - B,
C  - B
c  - b
c' - b'

The parser recognizes each additional comma as meaning "going down
an extra octave", giving

C,, - B,,
C,,, - B,,,
and so on.

Likewise, each additional prime symbols s interpreted as "go up an extra 
octave" :

c'' - b''
c''' - b'''
and so on.

