abcMIDI-2003-08-13
abcMIDI-2003-11-12
abcMIDI-2003-12-07
-November 12
November 12 2003

 Midi2abc sometimes places a backslash line continuation
 after the last bar or note on a track. This confuses
 yaps. A check for remaining data in the track is made
 prior to sending a backslash.

-~

December 7 2003

Triplets containing chords are not handled correctly. In the
following example.

X: 1
T: triplet chords
M: 2/4
L: 1/8
K: C
(3[CEG] [DFA] [ceg] G2|

The second and third notes in the third chord [ceg] are not
adjusted for a triplet. The problem occurs in event_note,
in store.c. The function decrements the tuplecount counter
for the first note in each chord. Therefore when it handles
the last chord, tuplecount is already zero when it encounters
notes e and g. The fix is not to decrement tuplecount inside
a chord in event_note and event_rest. Instead tuplecount is
decremented in the function event_chordoff.

I am grateful to Jim Russell who identified this bug and
found the fix.

 ~
 ~
 ~
abcMIDI-2004-01-03
-Triplets containing chords are not handled correctly. In the
Abcmidi does not handle triplets containing chords correctly. In the
 following example.

 X: 1
@@ -1078,7 +1078,30 @@ decremented in the function event_chordoff.
 I am grateful to Jim Russell who identified this bug and
 found the fix.

January 3 2002

Yaps does not handle triplets containing chords correctly. In the
following example,

X: 1
T: triplet chords
M: 2/4
L: 1/8
K: C
(3 [CEG] [DFA] [ceg] (3[CEG] [DFA] [ceg]|\
(3 [CEG] [DFA] [ceg] (3[CEG] [DFA] [ceg]|\
(3 [CEG] [DFA] [ceg] (3[CEG] [DFA] [ceg]|

yaps fails to group the chords into triplets.

Analysis: in printvoiceline (in drawtune.c) notes and chordnotes
are distinguished and are processed differently. For notes, the
function contains extra code to check for tuples and to process
them; however, this is missing for chordnotes.

Fix: the code for treating tuples (in the event that they may
be present) was introduced after a chordoff signal was detected
in printvoiceline.

-~
 ~
 ~
abcMIDI-2004-02-22
-January 3 2002
January 3 2004

 Yaps does not handle triplets containing chords correctly. In the
 following example,
@@ -1103,5 +1103,134 @@ Fix: the code for treating tuples (in the event that they may
 be present) was introduced after a chordoff signal was detected
 in printvoiceline.

-~

January 17 2004

Bagpipe music does not sound right without the continuous
drone. It would be useful to introduce new MIDI extensions
(similar to drum and gchord) for producing a drone accompaniment.
The drone accompaniment would be placed in a separate track
and turned on or off using the commands
%%MIDI droneon
and
%%MIDI droneoff

It is desirable that the new code supporting the drone extension
would follow the same style for producing drum and gchord track.
Since that code was quite convoluted a little description is
appropriate here.

Drum and gchord tracks are produced by the functions dogchord()
and dodrums() which are defined in the file genmidi.c. These
functions are called for each beat by the function
progress_sequence(beatnumber). It is not obvious where
progress_sequence is called so this is described here.

Writetrack is called separately for creating the drum and
gchord tracks. These tracks are not represented as a separate
voices in the feature structure array. Instead there are
special flags GCHORDON, GCHORDOFF, DRUMON and DRUMOFF which
signal that the gchord accompaniment or drum accompaniment
should be started (or stopped) at this point in the music.
I therefore introduced two new feature types DRUMON and
DRUMOFF (see abc.h).

For each track, writetrack rescans the entire feature
structure array. If the track is a gchordvoice or a drumvoice,
the noteson flag is not set and case NOTE: is treated differently.
Noteon and add2Q are not called to create "MIDI on" and
"MIDI off" commands; however the delay() and addunits() are
still called to keep track of the beat when the note is
note inside a chord. (A chord is represented in an abc file
as several notes inside square brackets eg. [CEG]). Delay()
calls timestep() and its associated functions which can be found
in the file queues.c. The function timestep() keeps track
of the beat and calls progress_sequence() which calls
dogchords or dodrums as mentioned above.

The handling of drone does not require all this complexity
since we do not need to keep track of the beat. Therefore,
it is not necessary to place the drone controls in the
progress_sequence() function. Instead it is sufficient
to just turn it on or off using new functions start_drone()
and stop_drone() which follow the switch case: conditions
DRONEON and DRONEOFF. However, like the drum track and
the gchord track, we want the NOTE: cases to only generate
timestep() calls so we are able to determine the length
(in MIDI time units) of the drone note. Fortunately,
timestep() also updates the global variables tracklen and
delta_time which are used by the functions start_drone
and stop_drone().

Now there are a few details connecting all of this together.
New global variables, dronevoice and dronetrack were introduced
into the file store.c. In the function event_specific()
(which handles the %%MIDI commands in the abc file), new key
words, droneon and droneoff are introduced. They insert
the DRONEON and DRONEOFF features into the feature array and
set the dronevoice flag. In the function finishfile() (also
in store.c), a dronetrack number is assigned if dronevoice
has been set.

The new global variables dronetrack and dronevoice
in store.c are linked to genmidi.c as extern int(s).
A new boolean int droneon is also added. A new struct,
dronestruct is introduced. This structure contains the
drone characteristics (eg. MIDI instrument, pitch, velocity,
channel) for the drone. Two tones may be defined,
customarily an octave apart and typically the note A
in the lower octaves.

In starttrack(), the drone struct is initialized to default
values if the flag droneon is set and findchannel() assigns
a midi channel for the drone track..

February 7 2004

Introduced a new %%MIDI command
%%MIDI drone val1 val2 val3 val4 val5
It configures the drone. val1 to val5 should be numbers between
1 and 127. val1 specifies the instrument (MIDI program number)
for the drone; val2 and val3 specify the MIDI pitches for the
two drone notes which are played as a chord; and val4 and val5
specify the MIDI velocities for the two drone notes
(played as a chord). A value of zero means do not change
the setting for the current parameter.  By default the
drone parameters are
drone.prog = 70   (bassoon)
drone.pitch1 = 45 (A,)
drone.pitch2 = 33 (A,,)
drone.vel1 = 80;
drone.vel2 = 80;
If you specify a global transpose, the drone pitchws will
also be transposed.

The new code was added into the function dodeferred(s)
in the file genmidi.c

Modified the function parse_tempo in parseabc.c so that
the syntax
Q: 132
is equivalent to
Q: 1/4=132
This change applies to abc2midi, yaps and abc2abc.

Fixed a bug I had introduced in the function stop_drone (genmidi.c).
The second call  to midi_noteoff should have a delta of zero.

22 February 2004

The -u option in midi2abc.exe does not work.

Problem: despite the fact that xunit was set by the user,
midi2abc changes it when it encounters a time signature
MIDI command. Fix: a new parameter xunit_set was introduced
and is set to 1 if the user sets xunit using the -u option.
The function setup_timesig does not alter xunit if xnit_set
has been set to one.
 ~
abcMIDI-2004-03-07
-~

7 March 2004

abc2abc incompatibility issue with abc2mps.
In the event that voices are indicated by symbols rather
than numerals, abc2abc converted them back to numerals
so that a file

X: 1
T: abc2mps incompatibility
M: 2/4
L: 1/8
K: G
%%staves [S A T]
V: S
cdcd|egeg| cdcd|egeg| cdcd|egeg|
V: A
AGAG|GBGB| AGAG|GBGB| AGAG|GBGB|
V: T
A,CA,C|FDFD| A,CA,C|FDFD| A,CA,C|FDFD|

becomes

X: 1
T: abc2mps incompatibility
M: 2/4
L: 1/8
K: G
%%staves [S A T]
V: 1
cdcd|egeg| cdcd|egeg| cdcd|egeg|
V: 2
AGAG|GBGB| AGAG|GBGB| AGAG|GBGB|
V: 3
A,CA,C|FDFD| A,CA,C|FDFD| A,CA,C|FDFD|

This causes a problem for abc2mps.

Abc2abc was modified so that it will preserve the
symbolic codes for the voices. External links
extern int voicecodes;
extern char voicecode[16][32];
were introduced into toabc.c and event_voice
now checks voicecodes before emitting the
voice command.

Beware, the fix may not work correctly if there is
a mixture of numeric and symbolic codes for voices.
If you use symbols for voices, use them for all
voices.
abcMIDI-2004-03-21

20 March 2004

Midi2abc fails to extract chords when the -sr
(swallow short rests) option is selected.
The problem occurs in the function quantize()
in the file midi2abc. When the -sr option is
specified, the note's length is determined
more by its inter onset time interval rather
(time between onset times of two adjacent
notes) rather than the time between note off
and note on. In the event of several notes
played at the same time, the inter onset
times will be zero for some notes. Because
quantize() failed to test for this condition,
the function assigned a note length of zero
to those notes and they do not appear in the
chord. The problem was fixed by also checking
for zero inter onset time when the -sr option
is active.

Added a bagpipe tune to demo.abc to illustrate
the use of the %%MIDI drone commands.
abcMIDI-2004-04-11

25 March 2004

When transposing guitar chords, abc2abc converts
double accidentals to the note above or below.
For example when abc2abc raises the guitar chord
"Db7" in the C scale to "Ebb7" in the Db scale, it
converts "Ebb7" to "D7". This is strictly not
correct.

Fix: event_handle_gchord in toabc.c was modified to
not convert the double flat or sharp to the next
pitch degree by default. A new option -nda (for
no double accidentals) was introduced which
preserves the old behaviour of abc2abc. (Note
the -nda option is only active when you are
transposing to another key.) This change involved
introducing a new global variable nodouble_accidentals.
See comments for 11 April 2004 for more details.

(I am grateful to Atte Jensen for alerting me to
this problem as well as the following three problems.)

27 March 2004

abc2midi fails to tie notes correctly when the
tie crosses bar lines. In the following example

X:1
T: Tie
M: 2/4
L: 1/4
K: C
E ^F-|F F |

abc2midi reports an error
Error in line 6: Could not find note to be tied.

The problem is that F was sharpened by an accidental, but
since the accidental did not apply to the next bar, the
next F appears as a natural and the function dotie()
fails to match the note with F#. As a result, the two
notes are not tied. One could place an accidental on
the second F, but strictly this is not musicly correct.

"An accidental is valid for the rest of the bar (only
the octave where it's written). Tied notes carry the
accidental to the next bar until the note that ends the
tie is released."

The fix: store.c joins the tied notes in a second pass
after all the notes have been scanned and parsed.
Unfortunately, at this point there is no information
that indicates whether the pitch of the note was
modified by one or more accidentals. A new array
pitchline[] was introduced to store the original
pitch of the note before any accidentals are applied.
The contents of the array are maintained by event_note.
The function dotie now compares pitchline[place] with
pitchline[tienote] rather than pitch[place] with
pitch[tienote]. When it establishes a tie, it
ensures pitch[place] = pitch[tienote].

27 March 2004

abc2abc.exe fails to transfer the clef indication,
clef=F to the output abc file. For example,
V: 1 clef=F
becomes
V: 1

Analysis: the function isclef() in parseabc.c recognizes only
the following clef indications: bass, treble, treble+8,
treble-8, baritone, tenor, tenor-8, alto, mezzo, soprano.
When it encounters clef=F, it fails to recognize F and
assumes there is no proper clef indication. Since
K: G treble+8
is interpreted as
K: G clef=treble+8
the function isclef() must have a fixed repertoire.

Fix: (1) indications clef= F or clef=f have been added to
the function isclef. (2) Since there may be other indications
that have not been built into isclef and it is desirable that
abc2abc copies these indications, I have added a new
flag, int strict, to the function isclef. The flag strict
is 1 when no clef= was found and isclef is interpreting the
given word. The flag strict is 0 when the given word is
preceeded by clef=. When strict is 0, the function isclef
will assume that the word is something meaningful even
though it does not recognize it and pass a warning message.
If strict is 1, isclef will not return words that it
does not recognize.

Unfortunately, this change introduced another conflict.
See comments for April 11 2004.

April 3 2004

When an abc file is missing a meter M: indication, abc2abc.exe
attempts to correct this situation by adding it to the output
file. Unfortunately it does not do it correctly as seen in
the following example.

X:1
T: Missing M:
L: 1/8
K: C
CDEF GABC| CDEF GABC|

output

X: 1
T:Missing M:
L:1/8
K:CM:4/4

CDEF GABC| CDEF GABC|

Analysis:
The function event_refno in toabc.c which is called whenever an
X: command occurs, initializes barlen.num to zero.  The function
start_tune() in toabc.c checks whether barlen.num is still zero,
which indicates that a M: indication is missing. If it is zero,
it calls event_timesig to set it to the default time signature
of 4/4. Unfortunately, it places a linebreak after calling
event_timesig instead of  before. Fix: the function event_linebreak
was moved before calling event_timesig.

April 11 2004

The patch dealing with transposing guitar chords in toabc.c
(refer to March 25 2004 note), did not work correctly so it
was necessary to take a different approach. Apparently,
the code in event_handle_gchord works correctly for all
diatonic guitar chords. The algorithm finds the chord's
pitch ignoring all following accidentals using the offset[]
table. It adds the transpose interval to the pitch and then
shifts it by +1 or -1 in event that the chord is followed
by sharp or flat accidental. For nondiatonic chords (i.e.
contains notes not present in the key signature), the
transpose algorithm yields the correct chord but represents
it incorrectly for the key signature. For example, suppose the
nondiatonic chord in the C key signature is Dbm which is
a degree 2 minor triad. When it is transposed one semitone
to the Db key signature, the chord should now be Ebbm.
However, event_handle_gchord changes it to Dm chord which
has the identical notes but has the wrong representation
(it was changed to a degree 1 minor triad).

To fix this problem, it was necessary to compute the
triad degree in the original key signature and compare
it with the degree of the transposed triad in the new
key signature. If they are identical, everything is fine.
If they are different by one degree, then an adjustment
is needed. The degree actually also depends upon the
mode of the key signature (major/minor/dorian/lydian ....),
however for simplification we shall assume it is the
major key signature. (The toabc.c file is not passed
the key signature but the number of sharps or flats
in the key signature.)

The following changes were made. New global variables
orig_key_number and new_key_number were introduced which
represents the tonic (ignoring accidentals) of the original
and new key signature (assuming major scale). They are
represented by numbers where A is zero, B is 1, etc.
These variables are set by event_key which handles the
K: field command. In the function event_handle_gchord,
the triad degree (old_triad_number) is computed by
subtracting orig_key_number from the key_number.
Something similar is done for the transposed triad, yielding
new_triad_number. If the degrees are not identical, the
tranposed triad is shifted back and a sharp appended or
else shifted forward and a flat appended. Otherwise
nothing is done. (The correction is disabled if the
flag nodouble_accidentals was set by the -nda run time
parameter.)

April 11 2004

Key signature K:F no longer processed correctly.
eg.
X:1
T: key signature problem
M: 2/4
L: 1/4
K: F
G A|B D|F2|

This problem occurs in abc2midi, abc2abc and yaps since
they all share the same parser.

This was caused by introducing F and f as an option in
the isclef(..) function in parseabc. (See March 27 2004
report.) As a result the F is first interpreted as a clef
indication and ignored as a key indication.

Fix: if F or f is used to specify the clef then it
must be preceded by clef=. This is not true for other
indications like soprano+8. To fix this I inserted
the condition strict==0 in the test for F or f in isclef().
abcMIDI-2004-05-02
April 16 2004

Abc2abc: demoted "No repeat expected" from an error to
a warning in toabc.c

April 21 2004

Introduced a new gchord code b (both) which produces a fundamental
and chord in the same beat. Thus b behaves like a combination
of f and c. For example:

%%MIDI gchord fbfc

the second beat would be the fundamental and chord played together.
The new code was introduced in dogchords() and set_gchords()
in genmidi.c.

April 22 2004

Abc2midi: Guitar chord inversions do not work consistently.

For the tune

X:1
T: gchords
M: 4/4
L: 1/1
K: C
"G" z|"G/B" z|"G/D" z|

"G/B" specifies the first inversion of the G major guitar chord
and "G/D" specifies the second inversion of the G major guitar
chord. Running midi2abc on the output midi file we discover
that the second inversion was not produced.

%"G"
G,,z [DB,G,]z G,,z [DB,G,]z|
%"G/B"
G,,z [GDB,]z G,,z [GDB,]z|
%"G/D"
G,,z [DB,G,]z G,,z [DB,G,]
# second inversion not produced.

Inversions are detected by the procedure event_handle_gchords
in the file store.c. It passes the inversion flag to genmidi.c
through the array num[], which is extracted by writetrack for
the  GCHORD feature. The function dogchords in genmidi, generates
the notes of the gchord. The value of inversion refers to
the pitch of the note after the slash relative to the base
note of the gchord.

One problem was traced to the statements
    for (j=0; j<chordlen[chordnum]; j++) {
        if (basepitch + chordnotes[chordnum][j] % 12 == inversion % 12) {
in dogchords.
Parentheses are required in the if statement so that the
modulo 12 acts on the sum of basepitch and chordnotes. Thus the
statement was changed to
       if ((basepitch + chordnotes[chordnum][j]) % 12 == inversion % 12) {

The actual inversion (shifting up of a note in a gchord by one octave)
is done in the statements which occurs in the last for loop prior
to the break.

if (inchord) {
     note = inversion + ((note + 12 - inversion) % 12);
     };

I could not understand the logic in this statement
and found that it does not perform the inversion consistently.

I therefore made the following changes to the inversion algorithm.
The local variable inchord now stores the position of the lowest
note in the inverted chord. Thus for inverted chord G/B, inchord
would be 1 because B is at index position 1 in the chord GBE.
For G/E inchord would be 2. G/G does not represent an inverted
chord so inchord set t0 0 which indicates to do nothing and is
consistent with the logic. The last for loop before the break was
replaced with.
 for (j=0; j<chordlen[chordnum]; j++) {
          note = basepitch + chordnotes[chordnum][j];
         if (j < inchord)
            note += 12;
          save_note(g_num*len, g_denom, gchord.base + note,
                    gchord.chan, gchord.vel);
        };

I tested the new code with the file

X:1
T: gchords
M: 4/4
L: 1/1
K: C
"G" z|"G/B" z|"G/D" z|
"Am" z|"Am/C" z|"Am/E"z|
"Bdim" z|"Bdim/D" z| "Bdim/F" z|

The inversions now appear to be done correctly.

April 23 2004

Abc2abc does not place linebreaks on comments
prior to X:

For example for the file

% comment 1
% comment 2
X: 1
T: Precomments have no linebreaks
M: 4/4
L: 1/1
K: C
D|E|F|

The ouput is

% comment 1% comment 2X: 1
T:Precomments have no linebreaks
M:4/4
L:1/1
K:C
D|E|F|

Analysis: the problem was introduced by the changes
I made on  2003 May 4 as described above. Linebreaks
were suppressed to prevent the production of many
blank lines for abc files with missing reference number
(no X: field). This unfortunately introduced another
problem which was discovered recently. The
X: reference number is  absorbed by one of the
comments appearing prior.

Fix: An event_linebreak is executed after parse_precomment
in parseline (parseabc.c) in event that the parsing flag
is not set. Hopefully this has no impact on yaps and
abc2midi.

May 1 2004

A new gchord feature introduced in abc2midi. It is now
possible to arpeggiate the guitar chords. New gchord
codes g,h,i,j,G,H,I,J were introduced. They reference the
individual notes in the  guitar chord. g is the lowest
note and j is the highest. For example for the
G major chord, g references G, h references B and
i references D. The upper case letters are the same
notes one octave lower.

If you specify a gchord,
%%MIDI gchord ghighi

Then abc2midi would fit the notes GBDGBD in each bar.
Same rules for length of notes apply as before.

Implementation: All the changes were made in the genmidi.c
file.  A new global array gchordnotes[] and global variable
gchordnotes_size was introduced. The function set_gchords
was extended to recognize the new codes hijk. A new
function configure_gchord() was created from part of the
body of dogchords() dealing with case 'c'. The function
loads the gchordnotes array based on the global variables,
basepitch,chordnum and inversion. The function is called
by writetrack for the GCHORD feature (whenever a guitar
chord name is detected). The dogchords() function was
modified to process the new gchord codes and to use
the gchordnotes[] list.

The demo.abc file was extended with another example.
abcMIDI-2004-06-26
May 7 2004

The -Wtraditional flag was removed from the makefile,
since it posed some problems with the lastest gcc
compiler.

The following midi2abc problems were reported by
Werner V. Hoersten with suggested fixes.

The -m option for setting the time signature in midi2abc.exe
causes the program to crash with a floating point exception.
(This is a bug that I probably around October 2003.)
Analyis: when the time signature is provided in the run
time parameters, midi2abc set the flag tsig so that txt_timesig
ignores any time signature metatext commands in the midi
file. Therefore header_asig and header_bsig are still
initialized to zero and a division by zero occurs when
the main function attempts to compute barsize. Fix:
prior to computing barsize, the main function checks
whether tsig was set. If it was set, header_asig and
header_bsig are assigned values specified in the run
time parameters.

I made some minor changes to midi2abc.c to reduce some of
the warning messages.
(1) the function testtrack() is declared at the beginning
of the file so that guessana knows what parameter it returns.
(2) setup_timesig function is declared as returning void.
(3) the function txt_timesig was placed after the definition
of setup_timesig.
(4) The static declaration for ttype[] in txt_metatext()
was removed. (It was necessary for -Wtraditional for the
gcc compiler.)

May 8 2004

Midi2abc fails to identify triplets in midi files with
3/4, 3/8 or any multiple of 3 beats per measure time signature.

For example if you convert the following file

X:1
T: triplets
M: 3/4
L: 1/8
K: C
(3C/D/c/ (3C/D/c/ (3FAc (3FAc |\
(3C/D/c/ (3C/D/c/ (3FAc (3FAc |

to a MIDI file using abc2midi and then back to a abc file
using midi2abc, you get

X: 1
T: from /home/seymour/abc/triplets31.mid
M: 3/4
L: 1/8
Q:1/4=120
K:C % 0 sharps
%%triplets
C/2[c/2D/2]C/2[c/2D/2]F/2A/2 z/2c/2F/2A/2z/2c/2| \
C/2[c/2D/2]C/2[c/2D/2]F/2A/2 z/2c/2F/2A/2z/2c/2|

which is far from what one expect. (Note the chords
[c/2D/2]).

Analysis: for some unknown reason the function dospecial()
in midi2abc checks the time signature of the input and
does nothing if the number of beats in the key signature
is a multiple 3 or if the number of beats is not a multiple
of 2.

Fix: these conditions were commented out and triplets
are now detected.

Midi2abc cannot identify triplets composed of chords.
For example for input

X:1
T: triplets
M: 3/4
L: 1/8
K: C
(3[CE][DF][ce] FADC |(3[CE][DF][ce] FADC |

converted to a midi file, midi2abc produces

X: 1
T: from /home/seymour/abc/triplets41.mid
M: 3/4
L: 1/8
Q:1/4=120
K:C % 0 sharps
%%triplets
[E/2C/2][F/2D/2]z/2[e/2c/2]F ADC| \
[E/2C/2][F/2D/2]z/2[e/2c/2]F ADC|

Analysis, the function dospecial() was not designed
to handle chords. The problem is unresolved.
You will have to edit the output file manually.

Midiabc cannot identify triplets tied to a previous
note. For example,

X: 1
T: tied triplet
M: 4/4
L: 1/8
K: C
G2- (3GBd E2 (3FGA|G2- (3GBd E2 (3FGA|

The MIDI file created  from the above converts to

X: 1
T: from triplet51.mid
M: 4/4
L: 1/8
Q:1/4=120
K:C % 0 sharps
%%tied triplet
G2- G/2B/2z/2d/2 E2 (3FGA| \
G2- G/2B/2z/2d/2 E2 (3FGA|

This is also beyond the capabilities the function dospecial().
The problem has not been resolved.

Improvements in appearance of output.
The function printtrack() in midi2abc places a blank (space)
before the beginning of a triplet.

May 9 2004

Midi2abc cannot resolve 32nd notes played in 4/4 time.
For example, in the last bar of the MIDI file produced
from the abc file

X: 1
T: no thirty-second notes
M: 4/4
L: 1/8
K: G
 CDEF             C/E/D/F/    G/A/B/C/  |
 (3CDE   (3DEF    (3EFG       (3FGA|
 C/4E/4D/4F/4 C/4D/4E/4F/4 G/A/B/C/  z4|

there are a series of 32nd notes.

The output from midi2abc is

X: 1
T: from precis1.mid
M: 4/4
L: 1/8
Q:1/4=120
K:G % 1 sharps
%%no thirty-second notes
CD EF C/2E/2D/2F/2 G/2A/2B/2C/2| \
 (3CDE  (3DEF  (3EFG  (3FGA| \
z/2z/2z/2z/2 G/2A/2B/2C/2

The series of 32nd were replaced by rests.

Analysis: the temporal resolution of midi2abc was set
to half of the abc unit length specified by L: field
command. Thus for L:1/8, the smallest note produced
is a 1/16 th note. Midi2abc automatically chooses
the L: value based on the time signature. For time signatures
less than 3/4 the L: value is set to 1/16. For other
time signatures it is 1/8. The purpose of limiting
the resolution is to avoid unusual note lengths
such as C2-C//2 which should not occur in music notation.
The L: value is set by the function setup_timesig().
The number of parts per L: time unit, is unfortunately
not explicitly expressed in the midi2abc code.

Fix: a new global variable, parts_per_unitlen, was added
to the file midi2abc.c and set to the default value of 2.
If you search for this variable, you can see the places
where the splitting of the time unit into 2 parts
was built in. A new run time parameter, -ppu allows
you to change this value.  For example if use -ppu 4, midi2abc
should be able to handle the 1/32nd notes. This establishes
the basic quantum unit that midi2abc uses.

A new run time parameter -aul which allows you to set
the L: abc unit length was introduced. Checks were
introduced to ensure that the -ppu parameter and the
-aul are powers of two.

May 10 2004

Midi2abc like other abcmidi applications requires that the
run time parameters be place before the parameter list. This
is different from most Unix/Linux applications. However,
in many cases midi2abc is forgiving and is still able to
fine the input filename. This is not true for the -u parameter.
For example,

midi2abc.exe -u 100 precis1.mid

will result in
Error - Cannot open file 100.

Fix: the character u was added to the "ambQkco" string in the
function huntfilename() in midi2abc.c

May 15 2004

Midi2abc/abc2midi incompatibility in the handling of accidentals.
When abc2midi converts the following file to a MIDI file:

X: 1
T: accidentals
M: 4/4
L: 1/8
K: G
FGB^D gdef | FGBD gdef |
FGB^D g=def| FGBD gdef |

the sharp accidental (^) applied to the D also acts on all other D's
in that bar including d which is shifted by an octave (bar zero).
To prevent the sharp applied on the second (shifted D), it is
necessary to place a natural (=). Midi2abc does not comply with
this convention so it produces the following output from the
MIDI file.

X: 1
T: from accid1.mid
M: 4/4
L: 1/8
Q:1/4=120
K:G % 1 sharps
%%accidentals
FG B^D g^d ef| \
FG B=D g=d ef| \
FG B^D gd ef| \
FG B=D gd ef|

Note that in the second bar (starting from zero), no natural
was placed in front of d, resulting in a different note.
(This only occurs when the two notes differ by one or more
octaves.)

Fix (as suggested by Werner Hoersten): in the function
printpitch(), replace

back[trans[i]] = i;

with

for (i=p % 12; i<256; i+=12)
     back[trans[i]] = i;

Now midi2abc and abc2midi are consistent with each other.

May 15 2004

The -gk option  in midi2abc.c is working again.

June 12 2004

Improved the handling of grace notes. The size of the
grace notes is no longer determined by a fixed ratio.
Instead the grace notes are of constant length specified
by a new %%MIDI gracedivider command. The old method
is still supported.

June 25 2004

store.c (abc2midi): Commented out compilation flag
INFO_OCTAVE_DISABLED 1 now allowing the handling of [I: octave=1].
(It was disabled in July 19 2003. The instruction field
command I: is parts of the proposed abc standard 2.0.
so I have decided to enable it.)

June 25 2004

abc2midi.c: For the -sr option to swallow rests, you can
specify the size of the rest in quantum units. Quantum unit
is defined in readme.txt updated today.
abcMIDI-2004-11-21
July 3 2004

midifile.c: added new global Mf_bytesread (number of
bytes read in track).

July 4 2004

midi2abc: added new runtime option -Midigram. If it
is selected, all other options are ignored and no
abc file is created. Instead, a new function midigram()
is called and the program lists all the notes occurring
in the file where each line represents a note on/note off
event. The line is in the following format.
on_time off_time track channel midi_pitch midi_vol.
The on/off time is given in quarter beat units (ie.
midipulses/ppqn where ppqn is pulses per quarter note
specified in the MIDI header). The last record indicates
the duration of the MIDI file in MIDI pulse units.
Though in theory, this feature should be put into a separate
program, it was felt there were enough programs in the abcmidi
package.

The code to convert the midi file to an abc file in
main() was stuffed into a new function called midi2abc.
New functions (no_op0,,no_op5, print_txt_noteon,
print_txt_noteoff, init_notechan, open_note, close_note
and initfunc_for_midinotes were created.

July 11 2004

abc2midi, yaps, abc2abc, midi2abc. Introduced a new
parameter -ver which prints out the current version number
of the program.

Added a new program, midicopy to the abcmidi package.
(Documentation put in midicopy.1 and readme.txt.)
All the makefiles were updated, however I am unable to
check out the ones in the makefile subdirectory.

July 17 2004

abc2midi (store.c), yaps (yapstree.c), abc2abc (toabc.c),
midi2abc (midi2abc.c) midicopy (midicopy.c) for -ver
parameter changed exit(1) to exit(0) after printing
out version number.

August 21 2004

A lot of abc files indicate ornamentations using the tilde
operator ~. Abc2midi has been substituting a roll for the
ornamentation. Guido Gonzato has suggested that it should
be replaced with an acciaccatura for all notes except
dotted quarter notes. The dotted quarter note should
be replaced with three eight notes where the second
note is preceded with an acciacatura and the third note
is preceded with an appoggiatura.

Two new procedures were introduced in store.c.
Doornament applies the action when decorator[ORNAMENTATION]
is encountered. The function doornament calls the new function
makecut which inserts a grace note. (Unfortunately the length of
the grace notes cannot be adjusted using the %%MIDI gracedivider
as described on June 12 2004 since the %%MIDI commands are
processed later.)  The procedure event_note was modified
to call doornament instead of doroll when an ornament is encountered.

September 05 2005

A new feature was introduced in the abcmidi package.
Abc2abc: a new run time parameter, -nokey was introduced.
It will suppress the key signature and place all the
necessary accidentals. Abc2midi, abc2abc, yaps understand
the key signature K: none. For such key signature, no
sharps or flats will be assumed. The -t (transpose) function
in abc2abc should work with K: none.

Changes were made to parsekey in parseabc.c and to
event_key and event_note in toabc.c (search for nokey)
to recognize K: none. When K: none is encountered,
abc2midi, yaps and abc2abc assumes no key signature
is supplied.

September 06 2005

Yaps does not display the note length correctly when no
L: is declared in the abc header. Fix: in start_body (yastree.c)
replace
   setfract(&thetune.unitlen, 1, 16);
with
    event_length(16);
etc.

September 12 2005

More work was needed to the -nokey option working correctly.
In order to ensure that toabc.c works the same way without
the new feature, event_note was divided into two functions
event_note1 and event_note2. Event_note1 is an exact copy
of the original event_note and is called when nokey is not
set. Event_note2 contains all the new code for transposing
notes when nokey is set. When event_note is called it either
calls event_note1 or event_note2 depending upon the status
of the flag nokey.

Event_note2 performs the transposition in a different
fashion. The note is converted to a midi representation.
The number of semitones is added to the midi representation
and the midi representation is converted back to the
note representation. Code for converting to the midi
representation was borrowed from store.c and code for
converting the midi representation back to the note
representation was borrowed from midi2abc. There was
a small incompatiblity between setmap representation
(character versus numeric representation) which had
to be fixed.

The -nokey option was split into two options.
-nokeys will use sharps. -nokeyf will use flats.

September 13 2004

Added gchord default for 12/8 time (fzcfzcfzcfzc).

September 17 2004

Cleaned up all source code to reduce the number of compiler
warnings reported by Microsoft Visual C++.  ANSILIBS
is now defined when compiling with Visual C++.

September 19 2004

Many abc tunes do not specify the tempo with the Q: command.
By default abc2midi uses a tempo of 120 quarters notes per
minute. For many tunes, this is too slow. A new run
time parameter -Q was introduced into abc2midi, allowing
you to specify the default tempo in the event that no tempo
was specified. If the tempo is specified in the abc file,
this parameter is ignored.

A new global default_tempo (initialized to 120) was introduced
in store.c. This parameter can be changed using the -Q run
time option added to event_init.

September 20 2004

Fixed bug in applygrace_new which causes floating point
exception (divide by zero) for some abc files.

September 26 2004

abc2abc does not recognize the parameter name="some string" eg.
in the multivoice command. For example,
V: 1 name="alto 1"
instructs abcm2ps to print "alto 1" on the staff. Unfortunately,
abc2abc does not show this parameter in the output file.
This is part of the proposed abc 2 standard.

Fix, parsevoice in parseabc.c now extracts the name= parameter
in the V: command. The event_voice command (which appears
in store.c, yapstree.c and toabc.c) now has two extra parameters
for passing the name string. In toabc.c, event_voice prints out
the name string when it is found in the voice command. I introduced
a new function parsename, which processes the "name= ..." parameter.
In addition I fixed a bug which causes V: transpose=1 to produce
a segmentation error.

October 2 2004

As mentioned above on August 21 the new implementation of
dooranment did not allow configuring the length of the grace
note using the %%MIDI gracedivider command. This was fixed
by replacing the implementation of the procedure makecut.
Initially gracedivider was alway 4 (the default when it
is not specified).

October 8 2004

The abcguide.txt and proposed abc standard 2 includes the use
of  multirepeats (i.e |:  ..|[1,3 .. :|[2,4.. :| ).
Though yaps and abc2abc can handle this syntax,
abc2midi fails to handle it despite some earlier effort to
introduce it.  For example, some of the code added to in genmidi.c
to handle multirepeats includes (eg. inlist(j, passnum)).
Furthermore, the old feature codes REP1 and REP2 was replaced
with PLAY_ON_REP.  Nevertheless, the code does not process
correctly multirepeats.

For reference the parser (parseabc.c) maps the repeat symbols
into the features in the following manner.

|:    BAR_REP
:|    REP_BAR
::    DOUBLE_REP
[1, [2 etc PLAY_ON_REP and places the count in pitch[] or
a text string.

The problems occur in two places: (1) writetrack in genmidi.c and
(2) fixreps in store.c. Writetrack needs to keep track of the number
of times the section has been repeated using the variable "pass"
so that it knows which bars to play. However, for both case REP_BAR:
and case DOUBLE_BAR: the pass variable is allowed to assume only values
of 1 and 2. Therefore, it cannot handle |[3 or whatever. If more
than one :| (REP_BAR) is associated with a |: (BAR_REP) this
causes an event_error.

To make things more confusing there is another variable 'additive'
which refers to an undocumented feature in  the P: command where the
symbol + and - indicates whether repeat marks in a part section are
to be processed or ignored. I don't beleive this feature has ever
been used.  I have therefore removed this feature to make the code easier
to support. From now on additive is always assumed. In other words
if a repeat section occurs in a PART it is always repeated. There
is now no way to ignore the repeat command.

Fixreps was primarily designed to insert a BAR_REP (|:) when
it is missing in the beginning of the tune. However, it tries
to do much more. It checks for syntactical errors such as two
or more closing repeats associated with an opening repeat as an error.
If it finds an extra closing repeat, it attempts to insert a matching
opening repeat (which is not desirable for multirepeats). If it
finds two opening repeats a row, it attempts to correct the situation
by changing the second opening repeat into a double repeat ::.
Unfortunately, these checks get in the way when you have multirepeats.

The multirepeats syntax appears to allow the use of either
a :| or || for separating sections. This does not seem to
be built into the writetrack code.

This seems to more than a weekend project.

October 15 2004

In order to handle multirepeats, several changes were
introduced into the writetrack code in genmidi.c

First a new variable, maxpass, which specifies the
maximum number of repeats was introduced. It is
initialized to 2 and reset to 2 any time a left
repeat symbol is encountered. The code for the
switch block REP_BAR (:|) was changed so that
the variable pass can be incremented until it
reaches maxpass. A check for whether a right repeat
was expected (i.e. a left repeat was found), is
only made on the first pass. (The flag expect_repeat
is cleared after the first pass.)

More changes were made to the switch block code for
PLAY_ON_REP which handles any of the indications such
as |1 , |[1, |[1,3 etc. The code
... parts !=-1) {
    passnum = partrepno = 1;
was removed since it was a remnant of the undocumented
additivity feature. The error "Cannot find :| || [1 ..."
is not invoked when encountering PLAY_ON_REP while
skipping a variant ending. When a variant ending is
found maxpass is set to pass+1 in case this is not
the last variant ending.

The fixreps code in store.c also required changes.
The code mainly inserts a |: in the beginning
of the tune in case it is needed. Unfortunately,
the code can make other unexpected changes
and does not understand multiple repeats.
For example, if it encounters two left repeats (|:)
without intervening right repeats, i.e.
|: some stuff |: some stuff etc.
then it assumes the second left repeat was a
mistake and changes it to a double repeat :: without
any warning. If fixreps finds two right repeats (:|) in a
sequence, then it returns a message that a spurious
right repeat was found and inserts a new left repeat
at a previous bar line.

For the case PLAY_ON_REP, fixreps identifies
two situations, denom[j] == 1 corresponding to [1 and
denom[j] == 2 corresponding to [2. For the second case,
it was assumed that no more REP_BAR (i.e :|) would be
encountered so the flags expect_repeat was cleared.
This is not correct for multirepeats, so those lines were
commented. Furthermore, when a [1,3 or something similar
is encountered, denom[j] is now 0 and the code falls into
the next case statement BAR_REP2 which should never happen.
Another break statement was added to prevent this from occurring.

Major changes were made to fixreps. Now it only checks
for missing |: before [1 :| or ::. It also checks
for two |: |: in a row. If you use multirepeats, i.e.
more than 1, be sure to end last variant with a double
bar line.

Other related changes to store.c: got rid of the obsolete
functions event_rep1 and event_rep2. They are no longer
used.

Corrected abcguide.txt on the handling variant endings.

Added protection for file runaway in eputc in midifile.c.
abc2midi.exe will abort if it attempts to create a midifile
larger than 500000 bytes.

October 24 2004

More work was needed to correct problems with the abc2abc
-nokeys option. Propogation of accidentals across bars was
not working.

Fix for toabc.c: the pitchof() function was changed. The
function setupkey() was eliminated and printpitch() was
rewritten. It now handles propogation of accidentals
across bar lines but not between bar lines in event
of a tied note. The latter case would involve considerable
more development since no code for linking tied notes
is present in toabc.c. (Store.c, for abc2midi, does the linking
in a separate pass -- dotie, but toabc.c does everything in
a single pass. The code can get quite hairy if we have
interleaved voices.)

October 29 2004

For K:none, abc2abc uses flats or sharps depending upon the
variable useflats in the function printpitch (toabc.c).
The variable useflats is set by the run time parameter
-nokeyf. For some music, one might want to have the
variable useflats be adaptive to the type of guitar
chords (gchords) transposed by abc2abc.  I introduced
as an experiment the option of adapting useflats to
the presence of flats or sharps in the guitar chord.
When the variable adapt_useflats_to_gchords is set,
some adaption is done after the guitar chord is processed.
In general for K:none, abc2abc tends to use sharps
in the guitar chords for any transpositions unless
flats have been written into the guitar chords.

November 4 2004

Chord syntax extension: it is convenient to express a chord
as [CEG]3 instead of [C3E3G3] which is part of the proposed
abc standard version 2. Presently the abcmidi parser will consider
the 3 after the ] as a stray number however other software
such as abcm2ps allows this extension.

Current practice: the parser run differently in each
application (abc2midi, abc2abc, and yaps) so each has
to be examined separately.

abcmidi:
writetrack in genmidi.c checks whether a note
is inside a chord. If it is in a chord, a midi_noteon is sent
to the MIDI file and a midi_noteoff based on the feature/num/denom
information is sent to the queue. The delay time is not advanced,
so that all remaining notes in the chord will start at the
same time. When the end of chord marker is encountered, the
delay time is advanced by the amount in the feature/num/denom
arrays so that the next note will start at the right time.
at the right time. This amount recorded with feature CHORDOFF
is (modified) by tiefix to be the last note length encountered
in the chord.

Fix:

Parseabc.c was modified to pick up the chord length placed
after the clocking bracket "]". If it is not indicated, it
gets 1/1. The chord length is passed to event_chordoff
via new parameters chord_n and chord_m.

abc2midi:
In store.c, the event_chordoff handler checks the chord_n,chord_m
values. If they are 1,1 then addfeature sends a CHORDOFF feature
and everything runs the same; otherwise addfeature sends a
CHORDOFFEX and chord_n*4,chord_m*v->default_length is placed in
num, denom storage. CHORDOFFEX is a new feature type added
to abc.h for handling this situation. Genmidi.c treats
CHORDOFF and CHORDOFFEX the same way.

A new function fix_enclosed_note_lengths was introduced to
readjust the note lengths of all the notes in the chord in
the event that it is set outside the enclosing brackets
(i.e. CHORDOFFEX).

The function tiefix now keeps track of the chord start ([)
in the variable chord_start. When it encounters a CHORDOFFEX,
it calls fix_enclosed_note_lengths.

November 07 2004: -chord extension continued

yaps:

Unlike abc2midi, yaps only performs one pass through the
abc file while preparing a very detailed layout of the music
in a complex data tune data structure. You can view part
of this structure by running yaps with the -d parameter.
This data structure is passed to printtune() in drawtune.c.

A new function fix_enclosed_note_lengths was created in the
file yapstree.c to adjust the note durations. This function
is called by event_chordoff when the parser encounters
the end of a chord (']'). The new function does nothing
if ] is not followed by a note length. Otherwise it corrects
cv->barcount in order to avoid warnings regarding the
number of beats in the bar. It replaces the note duration
of each note in the chord with the new note duration.
The function count_dots is called to replace the note
duration representation. (There still seems to be a
problem here.)

abc2abc:

Minimal changes in toabc.c were made. The function event_chordoff
was modified to output the note length information following
the chord if any and to correct the bar count.

November 20 2004

The fix for handling chord extensions in yaps did not work
properly and would frequently place tails on notes which
should not have tails. It was discovered that chords have
their own structure for indicating their PostScript representation
and their tail is drawn by a function called drawchordtail.
The yapstree.c function event_chordoff was modified to also
update the chord structure when the chord extension occurs.

Introduced a new folder called programming in the doc subdirectory
and moved abc2midi.txt, midi2abc.txt and coding.txt into this
folder. The folder contains some program implementation details.
The file yaps.txt was renamed to yapshelp.txt. A new file
yaps.txt describing the implementation of yaps was prepared.
abcMIDI-2004-12-04
November 28 2004

Abc2midi new feature: all notes in a chord are started at the
same instant. Inserting a short delay between the start of the notes
in the chord would provide more control over the timbre. However to
ensure that the music is not lengthened, it is necessary to ensure
that all the notes end at the same time.

Implementation of this feature was not easy due to the way the
notes are handled are converted to MIDI commands in genmidi.c
and the complexity of the queues.c code. MIDI note on commands
are sent by a long chain of function calls starting with the
function call to noteon(). Noteon() determines the velocity
of the note from the beatstring and current context and then
calls noteon_data(). Noteon_data() calls midi_noteon() and
updates the tracklen. Midi_noteon() calls mf_write_midi_event
which finally records the MIDI command.

The MIDI command to stop playing the note is sent to a queue
by the function addtoQ which is defined in the queue.c file.
Finally if this note is not inside a chord, or if a end of chord
feature has been encountered, the notes in the queue all processed
by calling the function delay(). Delay() converts the note duration
in MIDI tick units and calls the function timestep() which
is defined in queues.c.

The global variable delta_time indicates the time delay in
MIDI tick units to execute the MIDI command. All MIDI command
specify times relative to the time of the last command. Functions
in genmidi.c generally reset delta_time to zero after sending
a MIDI command. Otherwise, delta_time is adjusted by timestep()
in queues.c.

In order to control the delay intervals between notes in a chord,
new global variables notecount, notedelay and totalnotedelay were
introduced into genmidi.c. If notecount is greater than 1, delta_time
is changed to notedelay and totalnotedelay is incremented by this
amount.  It is necessary to shorten the shifted notes by totalnotedelay
so that they end at the same time. The new length is passed to addtoQ
in queues.c. At the end of the chord, notecount and totalnotedelay
are reset to zero.

December 4 2004:

(Continued from November 28 2004.) Unfortunately addtoQ does not
know that the shortened notes have been shifted.  When correcting
the delay of the cached note in the structure, addtoQ now takes
into account that the new note was shifted with respect to the
previous note by notedelay which is also passed as a global variable.
Finally, it was also necessary to adjust delta_time in timestep()
by totalnotedelay. More comments were added to the code addtoQ
and timestep in queues.c.

The notedelay variable is set to 10 MIDI units as a default. (There
are 480 MIDI units in one quarter note beat.)  A new MIDI command
%%MIDI chordattack n, was introduced in dodeferred() (genmidi.c)
to allow the user to fine tune this variable. I do not recommend
making this variable larger than the smallest note in the tune,
(eg. 30 units if there are 1/16 note chords.) The abcguide.txt
and abc2midi.1 documentation was updated. Thanks go to Hudson
Lacerda for suggesting this improvement.

Midi2abc outputs MIDI metatext commands as abc comments. In
some cases they can be interpreted as pseudo comments causing
undesirable actions by other software. For example, in the
following the title MIDI program 17 is converted to metatext
in the MIDI file. When midi2abc converts the MIDI file back
to an abc file the text can be interpreted as a %%MIDI command.

X:1
T:MIDI program 17
C:Hudson Lacerda
M:12/8
L:1/8
Q:1/4=120
K:C
%MIDI
C,^C,D,^D,E,F,^F,G,^G,A,^A,B, |
C^CD^DEF^FG^GA^AB |
c^cd^def^fg^ga^ab |
c'^c'd'^d'e'f'^f'g'^g'a'^a'b' |

-- output from midi2abc --

X: 1
T: from (null)
M: 12/8
L: 1/8
Q:1/4=120
K:C % 0 sharps
%%MIDI program 17
%%MIDI
C,^C,D, ^D,E,F, ^F,G,^G, A,^A,B,| \
=C^C=D ^DE=F ^F=G^G =A^AB| \
=c^c=d ^de=f ^f=g^g =a^ab| \
=c'^c'=d' ^d'e'=f' ^f'=g'^g' =a'^a'b'|

As suggested by Hudson Lacerda, the fix is to add a space
before the metatext. The sprintf statement near the
end of the function txt_metatxt() was modified.

Midi2abc should place the input file name in the title
line instead of null. This has been changed.
abcMIDI-2004-12-18

December 09 2004

Abc2midi new feature: introduced %%MIDI randomchordattack n.
The delay between notes in a chord will vary randomly between
0 and n-1 MIDI units. It is recommended that n is not longer
than the shortest chord. (If the shortest chord consisting
of two notes is a 1/16 note then n should be not greater than
480/4 = 120. If there are three notes in the chord n should
be less than 480/8 since the delays add up.)

December 12 2004

New feature: chord extension applied to tied chords.

In order for abc2midi to handle the syntax [CEG]3-[CEG]2 or
something similar, it was necessary to make more changes
in the code store.c. The code dotie() was not easy to
figure out. To avoid working with this code, abc2midi
patches up the feature,num,denom arrays so that it
appears the same as if the old syntax [C3-E3-G3-][C2E2G2]
was used instead. New functions, insertfeature() and
removefeature() were written to insert or remove a feature
in the middle of the arrays. The dotie() function was
modified to also detect the CHORDOFFEX feature and
treat it the same way as a CHORDOFF. The function
fix_enclosed_note_lengths was modified to also catch
the TNOTE feature and treat as a NOTE feature. A
new function patchup_chordtie was introduced. The
function stuffs a TIE feature after each note in the
chord and returns the position of the first TIE.
Many changes were made to the tiefix function().
Another local variable, chord_end was added. Chord_start
and chord_end keep track of the feature index positions
of the last chord scanned. If a TIE feature is immediately
preceeded by a CHORDOFF or CHORDOFFEX feature, then
that tie is stripped off and new ties are stuffed
into the chord using the function patch_chordtie.
Tiefix then backups into this chord so it can run
dotie on all the internal ties.

December 17 2004

Finished debugging chord tie feature. Tiefix no
longer runs fix_enclosed_note_length when it
backs up into the chord.

Abc2midi:
Limin Wang discovered and  D.J. Bernstein reported
two unprotected buffer overflows in store.c.  This
allows an attacker to gain control of the computer
through a malicious abc file in an email message or
from a web page that is fed into abc2midi. This
applies to all versions of abc2midi.

The buffers are now protected.

Yaps, midi2abc: minor changes to reduce likelihood
of buffer overflow.

December 18 2004

Abc2midi new feature:
Abc2midi recognizes the !f!, !pp!, etc indications
and adjusts the audio level in the output MIDI file accordingly.
Unfortunately this may get in the way for multivoiced abc files
where the indications are placed in one voice but not the others.
When the file is typeset by abcm2ps the output looks fine, but
one of the voices is inaudible in the MIDI file. An example,
is shown below.

X: 1
T:ff_pp_1_1
C:ff_pp_1_1: the second voice is covered by the first one
C:but the score could be interpreted as they both have to
C:be played with the same intensity
M:4/4
L:1/4
Q:1/4=100
%%MIDI transpose -12
%%staves (1 2)
V: 1 clef=treble
V: 2 clef=treble
%V: 3 clef=treble
%
K:C
%%measurenb 0
%
[V: 1]  G A c e | e c A G | A G A G |
[V: 2] !ppp!C E E E | G E E E | F E D C |

Things get more complicated when 2 or 3 voices share one stave
(eg. classical guitar notation). It is not desirable to have
to many "p"s printed over and under the stave. Abc2midi
does not understand !crescendo! and !diminuendo! notation.
A simple but not a perfect solution, is to introduce a new
option in abc2midi which will tell abc2midi to ignore all
dynamic indications.

Fix: thanks to Michele for the code and suggestion. A new
option -NFNP (no f no p) was introduced in store.c. Abcguide.txt
and abcmidi.1 documentation was also updated.

Abc2midi:  Wrong tempo when L: missing in a multivoiced file.
Abc2midi should assume a L:1/8 when the meter is 3/4 or larger
and L:1/16 otherwise in the event that the default length of
a note is not specified.. This works correctly for most abc
files but fails in the following example. (The tune is
played at the wrong tempo.)

X: 1
T: no L
M: 3/4
L: 1/8
Q: 80
V:1 clef=treble
V:2 clef=treble
K: G
V: 1
abcdf2|gabcG2|
V: 2
ABCDF2|ABCDF2|

Analysis: abc2midi checks for missing L: in the function
headerprocess() when it reaches the start of the tune body
(the first K: field).  If the note length,  global.default_length,
was not set at this point then it is set to 8 or 16. When a new
voice is created by event_voice, it assumes a note length
specified by global.default_length. In the above example,
an event_voice is called prior to the start of the body
so global.default_length is still undefined. The default_length
for the voice remains undefined and abc2midi runs unpredictably.

Fix: headerprocess now sets default_length to global.default_length
for any voices that have already been created.
abcMIDI-2005-01-09

January 1 2005

Abcmidi: does not handle a tie broken by a voice switch.
In the following example,

X:1
T: tie
M: 2/4
L: 1/4
K: G
V:1
AB-|
V:2
cd|
V:1
Bc|
V:2
G2|

the tie joining B is interrupted by a voice change. Abc2midi fails
to join the notes. Fix: the functions tiefix and dotie now check
for a voice change and do not attempt to tie notes belonging to
different voices.

Abcmidi: abcmidi fails to assign the channel to correct program
(musical instrument) for the first note in a multivoiced abc
file. In the following example:

X:1
T: MIDI program
M: 2/4
L: 1/4
V: S   clef=treble   name="Soprano"
V: A   clef=treble   name="Alto"
%%MIDI program 1 60
%%MIDI program 2 60
K: G
V: S
G A|B C|G A|F G|
V: A
z2|G A|F G|G A|

The first note G is played on the piano instead of
the French Horn as indicated by the command %%MIDI program 1 60

Analysis: the MIDI indications are inserted into the track
number associated with the voice. In this example, voice A is
mapped into track 2 and all the program indications are put
into track 2. The midi player processes the tracks sequentially
and does not see the program change in time to affect the first
note in voice S so it is played on the default instrument,
acoustic grand (piano). The simplest fix is to ensure all
the MIDI indications go into the first voice as shown here.

X:1
T: MIDI program
M: 2/4
L: 1/4
V: S   clef=treble   name="Soprano"
V: A   clef=treble   name="Alto"
V: S
%%MIDI program 1 60
%%MIDI program 2 60
K: G
V: S
G A|B C|G A|F G|
V: A
z2|G A|F G|G A|

Alternatively you can place the %%MIDI program indication
in the voice that it affects. (The channel number is no
longer needed then.) See below.

X:1
T: MIDI program
M: 2/4
L: 1/4
V: S   clef=treble   name="Soprano"
V: A   clef=treble   name="Alto"
V: S
K: G
V: S
%%MIDI program 60
G A|B C|G A|F G|
V: A
%%MIDI program 60
z2|G A|F G|G A|

I shall update abcguide.txt regarding this issue.

January 8 2004

Another exploitable error in store.c was found by Anselm Lingnau
which causes a buffer overflow for %%abc-copyright. A fix using
the snprintf routine was suggested. The snprintf routine is a
recent addition to the C compiler; for those running older
compilers you will need to download a portable GPL implementation
of snprintf() from http://www.ijs.si/software/snprintf in order
to compile and link abc2midi. (In case the web site changes,
search for snprintf portable implementation.) If you are running an
old or nonstandard operating system for which there is little
likelihood of a buffer overflow exploit taking over your computer
and it is too cumbersome to include snprintf, then you can define
NO_SNPRINTF (in store.c) and it will use sprintf.

Michele has added an additional correction to the broken tie
fix I made on January 1 2004. In order to handle the following
example which includes a chord in voice 2.

X:1
T: tie
M: 2/4
L: 1/4
K: G
%
V:1
AB-|
V:2
[dA]c|
V:1
Bc|
V:2
GG|

it is necessary to add
if(localvoiceno != voiceno) break;
after case CHORDOFFEX:
in the function dotie.

January 9 2004

Abc2midi:  new decorations !arpeggio! and !breath!
are introduced.  When the !arpeggio! instruction precedes a
chord, the notedelay time is temporarily set to three times
its normal value. For the time being, the !breath! instruction
is treated exactly the same as a staccato marking. (i.e.
the length of the note is halved and followed by a
rest of the same value.)

Implementation: a new decoration BREATH was added and a
new feature ARPEGGIO was added in abc.h. In store.c,
additional code was added to event_handle_instruction to
handle the !arpeggio!  and !breath! commands. In event_note,
both STACCATO and BREATH decorator flags are checked and
treated the same way.

New global variables staticnotedelay and staticchordattack
were added and linked to notedelay and chordattack in several
places.  In writetrack, genmidi.c, a separate
case statement in the main switch statement was introduced
for ARPEGGIO. It changes the values of notedelay and noteattack
to 3 times its nominal value. (They are restored back to
their nominal values after a CHORDOFF or CHORDOFFEX feature.)
abcMIDI-2005-01-22
Jan 22 2005

Abc2midi: a missing break statement caused abc2midi to crash
when encountering !arpeggio!. Added a tune demonstrating
the !arpeggio! instruction to demo.abc.

Midi2abc: normally midi2abc groups the notes forming a beat
together so that abc*2ps produces a pretty output. For some
raw  abc output, (eg.)
B3/2z4^dz/2e3/2z3/2|
it is easier to edit it if there is a space between every note (eg.)
B3/2 z4 ^d z/2 e3/2 z3/2|
A new option -nogr has been added to midi2abc. If it is included
as one of the run time options, then a space is inserted between
all notes that are not in triplets. Changes were made to printchord
and printtrack in midi2abc.c. (Search for nogr to see changes.)
abcMIDI-2005-02-05
-after the clocking bracket "]". If it is not indicated, it
after the closing bracket "]". If it is not indicated, it
 gets 1/1. The chord length is passed to event_chordoff
 via new parameters chord_n and chord_m.

@@ -2780,7 +2780,7 @@ z2|G A|F G|G A|
 I shall update abcguide.txt regarding this issue.

-January 8 2004
January 8 2005

 Another exploitable error in store.c was found by Anselm Lingnau
 which causes a buffer overflow for %%abc-copyright. A fix using
@@ -2820,7 +2820,7 @@ after case CHORDOFFEX:
 in the function dotie.

-January 9 2004
January 9 2005

 Abc2midi:  new decorations !arpeggio! and !breath!
 are introduced.  When the !arpeggio! instruction precedes a
@@ -2863,4 +2863,87 @@ all notes that are not in triplets. Changes were made to printchord
 and printtrack in midi2abc.c. (Search for nogr to see changes.)

February 03 2005

Abc2abc: introduced a new run time parameter -usekey. This
is a generalization of the -nokeys -nokeyf transformation
which converts the music representation to the key of C
inserting any accidentals to preserve the original key
signature. Now you can force abc2abc to represent the
music in any key signature. The -usekey parameter is followed
by a number specifying the number of sharps (positive
number) or number of flats (negative number) in the
desired key signature.

Implementation in toabc.c: if usekey parameter is set to a
nonzero value, the nokey parameter is set so that event_note2
is used to process the note. Setup_sharp_flats adjusts the
arrays flatsym and sharpsym to match the desired key signature.
The function printpitch prints the notes using these two
arrays.

February 04 2005

Abc2midi: It has been proposed that a new option be introduced
that would propogate dynamic indications (pp, ff, etc) from
voice 1 to all other voices so that they need only be declared
once in voice 1. This would provide another solution to the problem
discussed in December 18 2004 resulting in the introduction
of the -NFNP option. Introduction of this feature is deferred
for the time being but here is a description of what is involved
in implementing such a feature.

When parseabc.c sees an instuction eg. !ff!, it calls
event_instruction (in parser2.c) which calls split_string
which calls event_handle_instruction (in store.c).
Event_handle_instruction interprets the instruction and
calls event_specific with a MIDI beat x x x x command.
Event_specific passes the string to textfeature which
adds an entry DYNAMIC to the feature array and a pointer
to the string in the pitch array. Note the feature array
is used to handle all the voices, and the list of voice
features are separated by VOICE entries. The problem is
that it is impossible to propogate the DYNAMIC instructions
to the other voices because the other voices may not exist
(in the case the voices are specified serially in the abc file).
The function writetrack in genmidi.c separates the specific
voice from the feature array and creates a separate MIDI
track for each voice.

To address this problem, we would leave the code in store.c
and parseabc.c however we would need to change writetrack
in genmidi. Writetrack would now have to keep track of the
beat number when processing a voice. When a DYNAMIC feature
is encountered in voice 1, the beat number where this has
occurred would be stored in an array, along with a pointer
to the dynamic indication string. For all other voices,
the DYNAMIC feature would be ignored but instead the
beat number would be compared with the beat number where
the dynamic indication occurred and dodeferred would be
called when the beat number equals or exceeds the numbers
cached away for voice 1.

Worked on this project is deferred for the present time.

February 05 2005

Abc2midi tie bug:

For the file
X:1
T: tie bug
M: 2/4
L: 1/8
K: G
[FA]-[FA] FA|

abc2midi fails to tie the F# note.

Fix:
replaced the line 737 (in removefeature) in store.c
pitchline[i] = pitch[i+1];
with
pitchline[i] = pitchline[i+1];
abcMIDI-2005-02-26
February 12 2005

Michele reports the following bug in the function dotie
in store.c. For the following tune,

%
X: 1
T: Tie bug
M:C
L:1/4
K:D
[V: 1] | f/e/g/f/-f2 |
[V: 2] |  d3/2 d/-d2 |

abc2midi returns the message
Error in line 7 : Could not find note to be tied.

The message is wrong, since abc2midi handles both
ties correctly.

Michele added the conditional break statements
 if(localvoiceno != voiceno) break;
after case TIE: and after case CHORDON:

which seems to fix the problem.

Analysis: The function dotie is a real birds nest of
code. Here is a description of how it works.
Dotie is called by tiefix when a TIE feature is
encountered. It has two parameters, j the index
in the feature array where TIE was encountered and
xinchord, a flag indicating whether the TIE is
enclosed in a chord (eg [A-B] A). The reason for the
complexity of the code is because the function dotie
is controlled by three semaphores tietodo, done,
and tied_denom. To start, dotie searches backwards
for the note preceding the tie, and calls its address
(in the feature space) tienote. It changes
feature[tienote] from NOTE to TNOTE. It changes
feature[j] from TIE to REST and sets the rest length
to that of tienote (so they are both the same).
Finally it sets the semaphores
done = 0; tied_num = num[tienote]; tietodo = 1;
which controls the stopping conditions of the following
while loop that searches for the following note to be
tied to tienote. Now the fun begins. To simplify things
assume we do not have chords.  The loop begins with the
variable place set to j, the original position of the TIE
now converted to a rest. So the first feature in the loop
is gauranteed to be a  REST. case REST: subtracts
the length of the rest from tied_num so it is back to zero.
Now the semaphores are
done = 0; tietodo = 1; tied_num = 0;
The loop variable place is incremented and now feature[place]
probably points to a NOTE. Case NOTE: since tietodo is not
zero the function compares the pitches (pitchline) of
place and tienote. If they are equal, the tienote length
is increased by the place note, the tied_num semaphore
is also increased by the place note. Feature[place] is changed
from a NOTE to a REST and to make things more confusing,
if we are not in a chord the length of tied_num is now
decremented by the place note so that it is back to zero.
Finally the tietodo variable is also set to zero indicating
that we have finally joined the two notes in the tie. The
semaphores are now:
done = 0; tietodo = 0; tied_num = 0;
Unfortunately the while loop does not stop here and this
is the reason for the spurious error message described above.
In order for the while loop to stop, the variable done must
be set to a nonzero value. This usually happens when the
next NOTE or REST is found. In the above example, the
next note is found in a different voice.

The remedy is probably to end the while loop when tietodo is
zero. However, since the code is working fine now I am
rather reluctant to try it in case another bug surfaces.

Feb 13 2005

Abcmidi /abcm2ps incompatibility problem for decorations
applied to chords. It is perfectly normal to apply a
fermata or a staccatto to a chord, eg H[C2E2G2] or
.[CEG]; in fact abcm2ps prefers that you do it this way
rather than [.C.E.G]. Abc2midi handles both notations
correctly but it sends the following warning message if you use
the former convention.

Warning in line 6 : decorations applied to chord

Nevertheless, abc2midi sends the chord decoration to each
note in the chord and everything works fine provided you
don't attempt to apply roll, trill or ornamentation
to a chord. In the later case you receive an error message
and the decoration is not applied. It is therefore preferable
that parseabc does not produce this warning when abc2midi
is running.

Fix: it is convenient if  parseabc.c knows which program
is running (i.e. abc2midi, abc2abc or yaps). A new typedef
programname which distinguishes ABC2MIDI, YAPS, and ABC2MIDI
was added to abc.h. A programname variable called "program"
was added as a global variable to store.c, yapstree.c and
toabc.c and set to proper value. The program variable is
linked to parseabc.c as an extern global. This variable
is used to fine tune parseabc.c.

Unfortunately not everything is well with yaps and abc2abc.
Like abc2midi, the chord decoration is applied to every
note in the chord. In the case of yaps, this does not produce
an aesthetically pleasing result. Since yaps is not the
preferred postscript converter and I am also not very
knowledgeable of its internals, yaps shall remain as it
is and the warnings serve a useful purpose. In the case
of abc2abc, it is not desirable that it automatically
converts H[A2C2E2] to [HA2HC2HE2] or something similar.
A few more changes are necessary.

It was necessary to introduce a new parameter (chorddecorators)
into the function event_chordon. This entailed making changes to
parseabc.h, parseabc.c, store.c, yapstree.c and toabc.c.
In store.c and yapstree.c the new parameter is not used;
however, in toabc.c extra code was added to event_chordon
to print out any decorations applied to the chord. In parseabc.c
the decorators were not inherited from the chorddecorators
when parseabc.c was linked to toabc.c.

Unfortunately event_chordon is also called by the function
event_chord which handles the obsolete form of chords
+CEG+. For store.c, yapstree.c and toabc.c, I introduced
a global array dummydecorators[DECSIZE] which is initialized
to zero's in event_init. This array is used in event_chord.

February 14 2005

Abc2abc prints garbage in the V: field (reported by Hudson Lacerda).
Given a normal file :

X:1
T: abc2abc V: bug
M: 4/4
L: 1/8
K: C
V: 1
CDE FGABC| def gab c'2|
V: 2
C8|C8|

abc2abc outputs

X: 1
T:abc2abc V: bug
M:4/4
L:1/8
K:C
V:1 name=(LI
CDE FGABC| def gab c'2|
V:2 name=(LI
C8|C8|

Analysis: the local variable gotname in the function
parsevoice in parseabc is never initialized to zero.
The problem was fixed by adding
gotname = 0;

February 21 2005

I have started to introduce microtone note capability into abcMIDI.
A _/ means lower the pitch of the following note by a half a semitone.
A ^/ means raise the pitch of the following note by a half a semitone.
The microtone notation does not propogate across a measure but
applies to only the immediate note. For chords in the same channel
(voice), the microtone will apply to both notes no matter
how it has been notated. For example [C_/E] is the same as
[_/C_/E]. The abcm2ps program provides more flexibility, however
I need more clarification before I can proceed.

Implementation: added a new function ismicrotone() called by
parsenote() in parseabc.c. I also introduced functions
event_microtone() and event_normal_tone() in store.c, yapstree.c
and toabc.c. This is presently an undocumented feature.
abcMIDI-2005-03-27
-I have started to introduce microtone note capability into abcMIDI.
Microtone note capability has been introduced into abc2midi.
 A _/ means lower the pitch of the following note by a half a semitone.
 A ^/ means raise the pitch of the following note by a half a semitone.
 The microtone notation does not propogate across a measure but
 applies to only the immediate note. For chords in the same channel
 (voice), the microtone will apply to both notes no matter
 how it has been notated. For example [C_/E] is the same as
-[_/C_/E]. The abcm2ps program provides more flexibility, however
-I need more clarification before I can proceed.
[_/C_/E].

Following the convention in abcm2ps, (see features.txt in abcm2ps
distribution), _3/4C will depress C by 3/4 of a semitone. It is
assumed that the pitch range of the MIDI synthesizer pitch wheel
is + or - two semitones in compliance with the General MIDI
specifications. The maximum permissible pitchbend is therefore
2 semitones.

 Implementation: added a new function ismicrotone() called by
 parsenote() in parseabc.c. I also introduced functions
 event_microtone() and event_normal_tone() in store.c, yapstree.c
-and toabc.c. This is presently an undocumented feature.
and toabc.c. There has been no change to the operation of yaps
or abc2abc.

February 26 2005

Finished microtone implementation and added microtone
documentation in abcguide.txt.

March 12 2005

Abc2midi: There is a loss of synchrony in multivoiced files
when a fermata is applied to notes of unequal lengths. For
example:

X:1
T: Fermata
M:2/4
L:1/4
K: G
V:1
cdef|B2 Hc2|gabc|
V:2
efga|DHe3|gabc|

the fermata is applied to c2 and e3 for voices 1 and 2. The fermata
doubles the length of the notes c2 and e3 and there is a loss of synchrony
between the voices in the next bar.

Solution: I introduced new MIDI commands which control how the
fermata is applied.
%%MIDI fermatafixed
The fermata adds a unit lengths to the note so HC2 is played C3.
%%MIDI fermataproportional
(default) the unit length is doubled so HC2 is played C4.

Implementation: added new global flag fermata_fixed and modified
event_specific to set this flag. Modified FERMATA treatment
in event_note and event_rest.

March 18 2005

Microtones in abc2midi. It is not clear whether the microtone
notation should be treated as an accidental or a decoration.
The abc2midi software treats it as a decoration. Thus in the
following:

X:1
T:micro
Q:60
K:C
=C ^/C ^C _/D  D _/D ^C ^/C =C

the second to last note ^/C is played as ^^/C since the
accidental in the previous note propogates across the measure.
If you want =^/C you must specify it in this manner.
If ^/ and _/ satisfy the rules of accidentals then,
they would be interpreted the same way as double sharps and
double flats. Thus if you wrote ^^F E ^F G: the first note
would be played as G and the third note would be played as
F#. (You would not write ^^F E ^=F G.) It is not clear from
the abc standard, the meaning of the following:
[K: G] ^/F D E G|
Is the first note a F natural raised a quarter tone,
or is it a F# (as indicated by the key signature) raised
by a quarter tone? Presently abc2midi treats it as the
latter.

To treat the notation as accidentals would mean that the
quarter tones would propogate across a measure like sharps
and flats. This would require introducing more code into
abc2midi. (Further there would be other issues relating
to transposition in abc2abc.)

March 19 2005

abc2midi optional guitar chord syntax. The function
event_handle_gchord in store.c was modified to ignore
the parentheses in the guitar chord. (eg.  "(C)" CDEF etc. )
The optional guitar chord is played.

March 25 2005

abc2midi: note tied to two notes. In the following sample
the tied note is not played correctly in the repeat.

X:1
T: note tied to two notes
M: 2/4
L: 1/8
K:G
%%MIDI program 73
|:G2D2|ABCD-|[1 D4 :|[2 D2 G2|

Unfortunately this is a difficult problem to fix. Store.c
creates a feature/pitch/num/denom arrays which tells writetrack
in genmidi.c how to create the MIDI file. Repeat actions are encoded
into the feature array using the instructions BAR_REP, REP_BAR,
PLAY_ON_REP, etc, which instruct writetrack to backtrack
in the feature array and repeat certain sections. In other words
the repeats are not expanded until writetrack creates the MIDI
track.  Tied notes are handled by the function dotie in store.c
that determines which notes are tied and combines the tied notes into
one note instruction in the feature array. In the above example, the
tied note D-D4 in the first repeat and D-D2 in the second repeat
have different durations. Dotie can only assign the D tied note
one duration so it will be wrong in one of the repeats. To
make things worse the code in dotie is unmanageable (see
comments February 12 2005).

To fix the problem the joining of ties, it would need to be
done at the time that the repeats are expanded in writetrack
rather than in a separate pass performed by dotie in store.c.
The handling of ties is messy because they can also be embedded in
chords; they cross barlines introducing problems with accidentals
in music notation; interleaving of voices breaks up ties; we want
abc2midi to gracefully handle tie syntax errors provide useful
error message. Multiple repeats (eg |...|[1...|[2,3...|[4... :|)
introduce another headache.

One way of avoiding this problem is to notate the above sample
differently as shown below.

X:1
T: better way of handling tied notes in repeats
M: 2/4
L: 1/8
K:G
%%MIDI program 73
|:G2D2|[1 ABCD-| D4 :|[2 ABCD-| D2 G2|

There is now five bars instead of four, but it avoids the above
problem.

Abc2midi: an alternative method for embedding %%MIDI commands.

The syntax for placing %%MIDI instructions in the abc file
requires that each command occupies a separate line in the
abc file. This makes the resulting file look messy when
you want to do drumon, drumoff, gchordon, gchordoff, in the
middle of a line. The problem gets worse when the abc file
also has lyrics included using the w: field command.

It has been suggested that there should be an option
to place MIDI instructions in the information field:
eg.[I: MIDI drumon]. Abc2midi does have provision
to parse inline I: fields using the function event_info.
However, the code expects the field satisfy a specific
syntax of the form [I: key1 = value1 key2 = value2 etc.]
Thus you specify as many keys as you wish in the
I: field.

So far I have modified the function event_info_key in
store.c so that it will now forward any info field commands
of the form [I:MIDI = stuff] to the function event_specific
which handles all %%MIDI commands. Thus you can now do
the following.

X:1
T: event info used for MIDI
M:4/4
L:1/4
K:G
[I: MIDI =  program 70] DDEE|[I:MIDI=program 42] GEFG|

instead of

X:1
T: event info used for MIDI
M:4/4
L:1/4
K:G
%%MIDI program 70
DDEE|\
%%MIDI program 42
GEFG|

Any %%MIDI command described in abcguide.txt may be embedded
in the I: field; however the '=' is very important. Otherwise
abc2midi will assume this field is just for the user's
interest and just ignore it. Here is another example:

X:1
T: event info used for MIDI
M:4/4
L:1/4
K:G
[I: oboe MIDI = program 69 MIDI = gchord fzcz MIDI = chordprog 1] BAG2|\
"G" EC GG|[I:MIDI= bassprog 100] DDDD|[I: MIDI =gchord ffffffff] G4|

The I: field has rarely been used except for information to the
user. Support for this syntax may be withdrawn at a later time
as the abc standard evolves. I do not recommend making wide
use of this feature at this point.
abcMIDI-2005-04-10

March 28 2005

Acciaccatura grace note notation. Abcm2ps compatability feature.
Abc2mps accepts the notation {/b}a where the slash before the
b tells it to display the grace note b as an acciaccatura.
Parseabc.c does not understand this notation and returns an
error message "Unrecognized character /".

Fix: parseabc.c was modified to keep track whether it is inside
a grace sequence using a new global variable ingrace. When
the function parsemusic encounters a / that is not a note length
indicator, it will call event_acciaccatura if ingrace flag is
set. This function does nothing in abc2midi and yaps but it
prints the / character in abc2abc.

April 02 2005

Abc2midi does not handle microtones properly in multivoiced
files. For example in,

X:3
T:Miudezas
C:Hudson Lacerda
M:none
Q:1/8=132 "ca."
L:1/8
K:none clef=treble
V:1 name="Clarineta em Sib"
{=B}_/G {=B}^g | {=B}^F {_/e}=B {_/e}^/c' |\
{_/e}_/G {_/e}_/d' {=a}_/e |

the first note B (grace note) was affected by the microtone which was
intended to be applied on the second note G.

Analysis: Multivoiced files (i.e. using V:1, V:2 etc.) place a
header track (track 0) in the MIDI file where global DYNAMIC
features such as %%MIDI program may be defined for all other
voices. The microtone is sinces it uses the %%MIDI pitchbend,
is also treated as a DYNAMIC feature. As a result the header
track contains many pitchbends but no notes. This unfortunately
handles all other notes in channel 0 in a random fashion.

Fix: a new parameter, noteson,  was introduced into the function
dodeferred which handles all DYNAMIC features. Noteson is
also a local variable controled by writetrack to specify whether
NOTE features are to be processed by writetrack. This flag
is now also used by dodeferred to determine whether pitchbend
MIDI commands are to be inserted.

April 07 2005

Introduced a new feature to midi2abc. Midi2abc.exe -mftext
will now produce a mftext output of a specified input MIDI file.
It was preferable to build mftext into midi2abc since I
changed the output format; also runabc already links to too
many executables and I would not like to keep track of version
numbers for another program.

April 09 2005

I have modified toabc.c (abc2abc) so that it will no longer
transpose voices assigned to the drum channel (%%MIDI channel 10).
Implementation: added a new entry, drumchan, in the voicetype
structure which indicates whether this voice is to played
on drums. Also added a new global, drumchan which is linked
to voice.drumchan for the currently active voice. The event_specific
function has been extended to catch %%MIDI channel 10 and
update drumchan. The function setvoice() initializes voice[].drumchan
to 0 when a new voice is created. The functions event_note1 and
event_note2 now check the drumchan flag before transposing the note.

April 10 2005

Abc2abc - abcm2ps compatibility issue. Abc2abc does not recognize
the sname= "...". Fix: introduced new function parsesname in parseabc.c
added new parameters to event_voice in parseabc.c, store.c,
yapstree.c and toabc.c. (See September 26 2004 in this file
for more details.)
abcMIDI-2005-04-26
-
April 15 2005

Midi2abc: fixed problem causing midi2abc to crash when the
MIDI command indicating the time signature is missing from the file.

April 22 2005

Abc2midi: pitchbend inside a tied note. In the following
example, the third note is held too long.

X:1
T: bends
M: 2/4
L: 1/8
K: G
%%MIDI program 60
G4|G4|G2-_/G2|G4|

Fix: in function dodeferred() (genmidi.c) for command == pitchbend, added
 tracklen = tracklen + delta_time;
  delta_time = 0L;
after  write_event(pitch_wheel, chan, data, 2);

Also listen to the example 11 in demo.abc.

April 23 2005

Abcmidi: introduced two more MIDI commands.
%%MIDI portamento n
turns on the portamento controller on the current channel and
sets it to n. n is a 7 bit number which specifies the rate
slides the pitch between two notes. (Unless you are composing
20 th century classical music, you may not wish to use this
feature. Avoid slides between large pitch intervals.)

%%MIDI noportamento
turns off the portamento controller on the current channel.

April 24 2005

Integration of abcmatch into abcmidi package. The main() function
in parseabc.c was moved into store.c, yapstree.c, and
toabc.c .The function parsetune was placed in parseabc.c.
All makefiles were updated. (I cannot verify all of them;
report any corrections to me.) The files abcstore.c and abcparse.c
are no longer needed; delete them if they are lieing around.