2003 March 27:
Updated the man pages to abc2abc, abc2midi and midi2abc and created a
new man page for yaps.  Minor changes to midifile.c and midifile.h
were made to minimize the number of warning error messages. Midi2abc
was upgraded to be in line with the version I use with the script
midi2abc.tcl. The syntax in mftext.c was improved to reduce the
number of compilation warnings.


2003 April 12
abc2midi: for abc tunes with no guitar chords, an error
message "Command not recognized" is issued whenever a %%MIDI
chordprog or %%MIDI bassprog command is encountered.
The problem occurs mainly with runabc, which
performs only one pass through the tune and is unable to
know whether guitar chords are present before sending 
%%MIDI commands. Since no MIDI program command is issued
in this situation, the error message  was disabled, The
fix was made in dodeferred() in genmidi.c

2003 April 12
abc2midi assumes the ratio of 2:1 for long/short notes
in broken rhythms specified with angle brackets (eg. c>d),
Though this can be changed using the %%MIDI ratio command, it
is inconvenient for many users since it is necessary to edit
each tune in the abc file in order to effect this change.
A new command parameter -RS (ratio standard) changes default
ratio to 3:1 which is the standard music notation. The new
parameter still allows the %%MIDI ratio command to override
the default. The change was incorporated in event_init()
of store.c.
 
2003 Apri 19
The proposed abc standard allows non numeric identifications
for the voice field, eg. V: soprano instead of V:1.  If you
are creating a midi file, each unique identification string will
mapped to a sequential numbers 1,2 etc, as if you had used numbers
originally. The change allows abcMIDI to handle a number of 
new multivoiced abc files which have adopted this convention.
Only the first 20 characters of the identification
string are distinguished. Anything following the identification
string is ignored. The identification string should not end with
an equal sign =.  If nonnumeric identifications are used,
abc2midi will print the mapping between the id's and the numbers.
This may be useful for catching spelling errors in the id's.
The fix was made in function parsefield in parseabc.c. The
change does not yet allow V: commands to appear before the
body of the tune.

A number of abc files may designate a rest using x instead of
z. This means that this rest exists but should not appear 
in the printed score. I have modified the parser so it shall
now interpret x as rest; however, if you are using yaps to 
print the score, this rest will still remain visible. Abc2midi
will now treat x exactly like z. Abc2abc will probably
automatically convert the x's to z's whether you want it or not.
A minor change was made in parsemusic in parseabc.c. It is
necessary to modify toabc.c and yapstree.c to fix the
remaining problems.

2003 April 27
Guitar chords. The base note preceded by a slash in the guitar
chord may now  be in lower case as well as upper case. For example,
"G/B" and "G/b" will both be treated the same way. This complies
with the proposed abc standard 1.7.6 (abc-draft.txt) and avoids
problems with some files in the Nottingham database. The fix was
made in event_handle_gchord in store.c.

Guitar chords. When there is a change of meter, the gchord beat
does not seem to get changed. I inserted a call to setbeat()
in writetrack() in genmidi.c whenever a TIME feature is encountered.
It was also necessary to change the definition of setbeat in
store.c from static to external.

2003 May 3
Karoake lyrics: Improved the documentation for the functions
write_syllable and getword in genmidi.c  which handle the lyrics
in the w: body line. If a bar line is placed in the lyric
line between two tied notes, for example see below,

"C6" c> G E2- | E2 (3 c d c | "E7" B> ^G E2- | E4 |
w: All of me, | * why not take | all of me.*
              ^
write_syllable loses synchrony with the music while searching
for the next bar line in the music. The problem was fixed
by resetting waitforbar to 0 between the two calls of
write_syllable, in writetrack (genmidi.c) after TNOTE is 
handled.

I found most warning messages about mismatched
lyric syllables to music notes have to do with users
failing to notate syllables correctly when tied notes
occur.  (Failure to place a * or  _ (underscore)  preceding
syllable of tied note. Confusing hyphen with underscore...)



2003 May 4

abc2midi file xref: Abc2midi has the option of converting
only a particular tune in a abcfile to a midi file by specifying
the X: reference number immediately following the abc file name.
When this feature is used, warning messages such as

Warning in line 28: T: outside tune body - possible missing X:

The problem occurs in the function parsefield in parseabc.c.
In order to catch the reference number of the selected tune,
every line of the input file is parsed. A flag "parsing" equal
to 0 or 1 is used to turn on the parsing inside the body of
the of the music. This flag is turned in function event_refno()
in store.c by calling the function parseon() in parseabc.c.
Unfortunately all field lines (eg. T: , M:, L:, V: ...) were 
unaffected by this flag and continued to be parsed. When the
T: field command is encountered, it falls through to the
default: in parsefield and it is processed by the function,
event_field in store.c. Event_field was designed to treat
the T: and R: conditions but before handling these conditions
it checks whether the control flag dotune is set. This flag
is also set by event_refno. If the flag is not set, then 
event_field assumes that a T: field command was encountered
without a preceding X: reference field which is a valid
error condition.

Since all field lines in the abc file are parsed this
introduces other problems. Any anomaly in the field lines
whether they are from the selected tune or not are reported.
For example, if a user has selected for example tune 500
from a large abc file, errors in the field lines of other 
tunes will be reported. Furthermore, in some cases the
program may crash in processing a field line of another tune.

To address these problems, the functions parseline and
parsefield in parseabc.c were modified so that all field
lines (except for the X: field line) and all text lines are
ignored for nonselected tunes. Parseline checks whether 
the flag parsing is set before calling parsemusic or
event_text. In parsefield, the condition key == 'X'
was moved from the switch control structure and
treated separately immediately when entering this function.
If parsing flag has not been set, the function returns
immediately after checking for key == 'X'.

This introduces a new problem. If the abc file has no 
X: field, the abcmidi programs does nothing 
without any error indication. To handle, this situation
I introduced a the global variable parsing_started into
parseabc.c, It is initialized to 0 and set to 1
when the function parseron() is called. Prior to the
end of the function parsefile, the parsing_started
variable is checked. If it is still 0, an error message
is returned.

Finally, event_linebreak() is suppressed in parsefile()
whenever the variable parsing is not set. This avoids
a lot of blank line output from abc2abc whenever the
X: field is missing from the input abc file.

This is a major change to the code, since it affects
three programs, abc2midi, yaps and abc2abc. I hope this
has not introduced new problems.

2003 May 11

Many tunes have a left repeat sign (|:) missing. In most
cases it is fairly clear where to place the repeat sign
and abc2midi merely puts a warning message "Assuming repeat".
When you are processing a large group of abc tunes these
messages may be annoying. A new parameter -NAR (no assuming
repeat) will suppress this message when you are
running abc2midi. However, occasionally you get the error
message "Found unexpected :| ...". This is a more serious
problem.  Due to some ambiguity, the program store.c was
unable to place a missing |: into the tune. During the
second pass, genmidi.c encounters the :| and does not know
where to begin the repeat. This is a real error since the
repeat will not occur. This error message is not suppressed.

The instructions !trill! and !fermata! are recognized by
yaps and abc2midi and are treated in the same way as the
decorations T and H preceding a note. To do this I introduced
a new integer global array decorator_passback[] which is set
by event_handle_instruction in both yapstree.c and store.c.
The array is passed between files parseabc.c, store.c
and yapstree.c as an extern.

2003 May 18

The symbol y used to denote a space in Barfly, is ignored
and no longer causes an error message. It is deleted by
abc2abc.

2003 May 19

Added an option to number bars in yaps. Note the bar numbers
may not match those in abc2midi or other abc*ps programs.
Introduced global flag barnums and global integer nnbars in 
yapstree.c which is set by event_init and linked to 
drawtune.c. Added new -k option in event_init
in yapstree.c. In event_bar in yapstree.c passed the current
bar number instead of NULL in addfeature. In drawtune.c
introduced a new function printbarnumber which is called
in various places in the function printvoiceline.

%%MIDI chordname accepts negative semitone shifts relative
to root. In function event_specific in store.c, replaced
readnump with readsnump.

2003 May 22

Bar numbering in yaps is now in agreement with abc2midi but
may differ by one unit with abc2ps and other members of its
family. See abcguide.txt for more discussion. I moved the
position of the call to checkbar() in event_bar() (yapstree.c)
so it occurs before addfeature is called rather than after.

The decoration field line d: (used inabcm2ps) is not parsed as
a music line but is an ignored field line. Change
was made in parseabc.c in parsefield() and parseline().

2003 May 31

Yaps crashes when it encounters text preceded by an underscore
in a  guitar chord. For example 
"G" AB/2B/2 "_quiet" DD| g/2g/2d/2d/2 |
here yaps crashes when the function event_handle_gchord (in
yapstree.c)  encounters the text _quiet. The problem was fixed
by ensuring that, cv->instruction_pending is not NULL prior
to adding anything to this structure.

2003 June 6

Yaps ignores any guitar chords placed in front of a chord if
the notes in the chord are not in descending order. For
example in the following line
|"Gm"[G2B2][Ac]|[Bd][Ac][GB]|"D"[A/2c/2][A/2c/2][Ac][Bd]|
the guitar chords Gm and D do not appear because they precede
a chords [G2B2] and [A/2c/2]. This problem also applies to
any instructions (eg. !quiet!) which immediately precede 
a chord. The problem has to do with the way the gchord
and instructions are processed by yapstree.c. When they
are first encountered they are placed in temporary places,
cv->gchord_pending and cv->instructions->pending. When
the next note is encountered, the function newnote moves 
them to fields associated with that note. Unfortunately,
when printvoiceline in drawtune.c processes the notes in
a chord it expects the guitar chord or instructions to be
associated with the first note encountered in the chord.
(It checks chordcount variable.) This is not always true
because the function insertnote in yapstree.c for some
reason will reorder the the notes in the chord if they
are not in descending order.

The fix was to modify noteinsert in yapstree.c so that
if it reorders the notes in the chord, it also moves the
gchord and instructions fields to be with the first note.


14 June 2003

Yaps produces a segmentation error when it fails to
find an expected continuation line and attempts to
print a guitar chord.(eg.)

X:1
T:example
K:C
"C" abcd|\

(In this example there is no more records following the
backslash.)

The error occurs when it tries to execute showtext in
the function notetext in the file drawtune.c. The fix was
to ensure that the pointer spacing is not NULL prior to
calling showtext.


21 June 2003

Abc2midi assumes the last %%MIDI gchord string specified
as the default for the start of the tune. In the following
tune,
 
X: 1
T: gchords
M:4/4
L:1/4
K:C
"C" CCCC|CCCC|
%%MIDI gchord czcz
FFFF|FFFF|
%%MIDI gchord fzzz
 GGGG|GGGG|
%%MIDI  gchord fcfz
 CCCC|CCCC|

the gchord string was not set for the first two bars. It was
expected that abc2midi would use the system default for 4/4 time,
i.e. fzczfzcz. Instead, the last defined gchord fzfz was assumed,
which is not expected. If the user places another %%MIDI
gchord string before the first bar or adds a redundant meter
field M:4/4 just before the first bar, everything is ok.
Abc2midi calls setbeat which calls set_gchords just after
it processes the first K: declaration in the field area.
When abc2midi writes the first track writetrack(0) containing
the melody, everything is still ok, except that the accompaniment
is not written at this point. Each time writetrack encounters
another %%MIDI gchord declaration, set_gchord changes the
gchord string. When it is time to start the accompaniment track,
the gchord string was left as the last declared string.

The fix was to move the setbeat invocation from headerprocess()
in store.c to the beginning of writetrack in genmidi.c  when
the accompaniment track is identified. I also added a short
caveate in abcguide.txt about the setting of MIDI gchord
string.


28 June 2003

The %%MIDI transpose command transposes all channels including
the drum channel. For the drum channel, the pitch component
selects the percussion instrument, so transposition is not
appropriate here.

The fix was applied to the function save_note in the file
genmidi.c. Transposition is blocked if the drum channel
9 (counting from 0) is selected.

29 June 2003

Besides the key signature, the K: field can contain many
other descriptors, such as the clef (treble, bass...), the
octave and transposition. The code for parsing the K: field
parsekey was rather convoluted and hard to understand. It
was simplified by breaking it up into several functions.
During this process, I discovered an Easter Egg (undocumented
feature) in abc2midi. It is possible to transpose an
individual voice without affecting the other voices.
The documentation to these features was improved in abcguide.txt.


1 July 2003 

The single voice transpose function described above does not
work correctly in combination with the global transpose initiated
by the %%MIDI transpose (or rtranspose) function. The original
code in store.c and genmidi.c was confusing since communications
between the two files was performed by both the feature/pitch
arrays and a global variable global_transpose which was linked
to both files using an extern int declaration. Here is a
short description on how it was originally.

Parsekey passes transpose to event_key. When a
new transpose value is obtained from event_key, the TRANSPOSE
flag is  added to the feature array and the value of transpose
is put in the pitch array. In addition the  global_transpose
variable (a variable linked to genmidi.c) is also set to
transpose if event_key obtains the transpose value before
getting to the body of the music.  When a transpose value
is obtained from event_specific (i.e. from a %%MIDI transpose
indication) a TRANSPOSE flag is also added to the feature
array and the linked variable global_transpose is always
set to the transpose value.

Genmidi.c processes the TRANSPOSE feature in the function
writetrack. At the start of every track, writetrack sets
the transpose variable (here not linked with store.c) to
global_transpose. When TRANSPOSE feature is encountered the variable
transpose is extracted from the pitch array. The transpose
value is added to the note pitch whenever a note is issued. The
transpose value is also stashed away by save_state in case a
REPEAT feature is encountered. In this situation, the stashed value
is recovered by restore_state.

It would make more sense to treat transpose and
global_transpose independently. i.e.
new pitch = pitch + transpose + global_transpose.
Also it would be be a good idea not to pass global_transpose
to genmidi.c using "extern int" but setting it using a new
feature GTRANSPOSE in the feature array.

Fix: GTRANSPOSE introduced in abc.h. global_transpose variable
and associated code eliminated from store.c. In writetrack
in store.c, another switch condition for GTRANSPOSE was
introduced. global_transpose initialized to 0. transpose initialized
to 0 in starttrack. In noteon_data and addtoQ transpose +
global_transpose are added to pitch. These changes now allow
global_transpose and transpose functions to work together and
independently.

Basically transposition is now performed by either or both
variables 'transpose' and 'global_transpose'. The only difference
between these variables is that the transpose variable is
reinitialized to zero each time a new track is started, while
global_transpose is only initialized at the start of the tune.
These variables are set only through the feature/pitch
arrays in store.c.

5 July 2003

Abcm2ps allows the voice field to contain additional
descriptor information such as the clef name. This information
may indicate a voice transposition by one octave. Abc2midi
and other abcMIDI programs currently ignore this information.

Fix:
A new function parsevoice was introduced into parseabc.
which contains a combination of the code in both parsefield
and parsekey. New parameters were introduced to event_voice
in store.c, yapstree.c, toabc.c, parseabc.c and parseabc.h
in order to pass this information. In store.c, event_voice
will call event_octave if gotoctave is set and insert
a TRANSPOSE feature in the feature/pitch array. In toabc.c,
event_voice will also output the clef if gotclef is set.

In the event that treble+8, treble-8, or tenor-8 is 
specified, parsevoice will set octave to the appropriate
value and set gotoctave so that event_voice in store.c will also
issue an event_octave. The transpose indication in the
clef is detected in the function isclef() in parseabc.c
which now has extra parameters.

Please note no transposition is assumed for the bass clef.
If it is desired that abc2midi transpose that voice, a
octave=-1 or -2, should be included in the K: or V: field.
 


6 July 2003

Abc2midi considers the placement of a V: indication outside
the music body (in the header) as an error and ignores it.
Other applications such as abcm2ps permit V: indications to
occur music header.  In such instances, the voice field
specifies information such as the clef to be used for that
voice. Several changes were needed to handle the this
convention.

(1) In event_voice, the check "pastheader" was disabled; however,
it is important not to call checkbreak() prior to passing the
header. (2) It is necessary to create the first voicecontext
structure immediately after the parser is started rather than wait
for the first K: field (which ends the header block).
Therefore, the code 

   v = newvoice(1);
   head = v;

was moved to event_refno and event_key was replaced
   getvoicecontext(1);

(3) Normally event_octave will transpose all the music voices
if it is called in the music header. This needs to be disabled
when it is called from event_voice. A new parameter, local
(as opposed to global) was introduced into event_voice to
indicate such a situation. (It was necessary to also
put this change in parseabc.c, yapstree.c, toabc.c, parseabc.h,
in addition to store.c)



12 July 2003

Abc2midi loses synchronization between voices when a voice
change occurs in the middle of a bar. The following tune
does not get converted correctly into a MIDI file.

X:1
T: sample
M: 2/4
L: 1/8
K:G
V:1
|:AG Bc|
V:2
|:C2 C2|
V:1
 AG Bc|[1
V:2
 C2 C2|[1
V:1
  CDEF:|[2
  EFG2|
V:2
  D2 D2:|[2
  G4|

The problem occurs when writetrack (in genmidi) is processing the
second repeat. When it comes to the bar marked
with a [1 it attempt to skip to the bar labeled [2, however,
it failed to check for a voice change. (It is unusual to
switches  voices in the middle of a bar.)  Instead it another [1 
and outputs numerous error messages.

The problem was fixed by checking for a voice change and searching
for the continuation of the current active voice using the 
findvoice function.



Yaps terminates prematurely if a tune does not contain a
M: indication in the header. Yaps reports that there is no
M: field but when it attempts to set it to the default 4/4
in startbody(), no voice structure has been created.
To fix this problem  lines of code, setvoice(1) and
startbody() were interchanged in event_true_key() in yapstree.c


13 July 2003

Yaps bar alignment fails in multivoiced files containing
tuples (eg. triplets). For example,

X: 1
T: yaps trips on triplets
M: 2/4
L: 1/8
K: G
V:1
C4|C4|(3BBB (3BBB|C4|C4|
V:2
F4|F4|F4|F4|F4|

The bars for the second line do line up after the triplets.

The function advance() in position.c does not set the
notelengths in the case of triplets. As a result,
spaceline() in position.c has the incorrect temporal position
of the notes when it tries to place the notes on the staff.

Fix: a new variable tuplenotes was introduced in the struct
note (struct.h). This variable is set in event_note, in yapstree.c
and contains the sequence number of the tuple note (descending).
In event that advance() detects a tuple note (based on this
variable), the temporal length is adjusted by multiplying it
by the tuplefactor. (A new function mulfract was introduced
for this purpose.). The notes and bars are lined up now,
but more work is probably needed to get more pleasing spacing.


19 July 2003

Abc2midi fails to set key signature sharps or flats pattern in 
multivoiced tunes with voice indications in the header.
For example in the following tune,

X: 1
T: G minor scale
M: 2/4
L: 1/8
V:2
K: Bb
V:2
GABc|defg|

the notes B and e are not flattened in the output MIDI file.
This is a new bug I introduced in July 5, 2003 when I extended
the abcMIDI package to handle voice field indications in the
header block. For each voice there is a separate voicecontext
structure which contains its own basemap for sharpening or
flattening selected notes. See store.c code.  (This permits
the option of a voice to have its own key signature which is
different from the other voices.)  There is also a global
voicecontext structure used for applying the key signature to
all voices if they are not indicated separately. The global
key signature is copied to the voicecontext of a separate voice
at the time that the voicecontext structure is created.
Unfortunately, if the voicecontext structure is created prior
to setting the overall key signature with the first K: indicator,
then the basemap for that voice is set for C major or A minor.

Fix: a new flag, keyset was introduced in the voicecontext
structure. This flag indicates whether the key signature was
known at the time when the voicecontext structure was 
allocated by newvoice(). Whenever getvoicecontext() switches
voices context, it now checks keyset to determine whether
it is necessary to copy the basemap and related variables
from the global voicecontext structure.
  
I: octave=n has been disabled in abc2midi.
Since an octave shift can be indicated in either the
K: or V: field, it is no longer necessary to use the
info field for setting the octave range. I have disabled
this feature to discourage using the info field for
setting the octave range.


20 July 2003

The hidden rest (x) was introduced in abcMIDI in April 19
2003. Abc2midi treated it as a regular rest but abc2abc
automatically converted it into a regular rest z. The
new  functionality to transpose separate voices that was
introduced in abc2midi now makes abc2abc even more useful.
I have upgraded abc2abc so it now preserves the hidden
rests in the abc files. Yaps continues to not distinguish
the two types of rests (like abc2midi).

Fix: introduced an extra variable in event_rest in 
parseabc.c, store.c, yapstree.c, toabc.c and parseabc.h.
In toabc.c event_rest emits an x instead of a z if
a hidden rest is detected.


16 August 2003


Abc2midi: The drum accompaniment is started or stopped using the 
instruction command !drum! and !nodrum!. The !drum! and
!nodrum! commands are not part of the abc standard so
other applications such as abc2ps and related clones do
not understand this instruction. The programs either ignore
or it or return a warning.

I have introduced an alternate method of starting and stopping
the drum track using the MIDI indications.

%%MIDI drumon
and
%%MIDI drumoff

This is similar to the method of starting and stopping gchords.
(%%MIDI gchordon and %%MIDI gchordoff). I feel this is the
preferred method and the older method will probably be
deprecated. Fortunately, I am the only one using drum
accompaniment (eg. isra.abc) so all of this has little impact.

August 22 2003

Midi2abc creates a abc file with a blank title. It is
more useful to place the name of the input midi file in the
title.

Midi2abc puts a blank line in the abc file in the
event that a newline character \n is embedded in the 
meta_text. A blank line signifies the end of a tune, so
the remaining part of the abc file is not processed.
The function remove_carriage_return was updated so it
now checks for both \r and \n.

August 31 2003

Reorganized and improved documentation of midi2abc.c

Many MIDI files have multiple tempo indications. In fact
some MIDI files change the tempo at every beat. Midi2abc
assumes the last tempo indication; however, in some MIDI
files the tempo slows down at the end. When the resulting
abc file is converted back to a MIDI file it plays much
slower than the original. I have modified midi2abc so
that it now assumes the first tempo indication and
ignores all following indications.

September 8 2003

Midi2abc identifies drum tracks (channel 10) but it needs
to issue a %%MIDI channel 10 to that voice so that abc2midi
will know to assign that voice channel 10. Printtrack was
modified to test for a drum track.

Added two new parameters, -bpl and -bps to control the
formatting of the output abc file. These parameters
control the number of bars printed per line, and the number
of bars to be associated with a music staff. The -obpl
(one bar per line) parameter is deprecated.


September 13 2003

Midi2abc by default does not use the PPQN information in the
MIDI header to determines the note length in MIDI pulses.
Furthermore it ignores any time signature information in
the MIDI file that may be present.  Most MIDI files do
contain valid information so midi2abc produces the best 
output when run time options -xl and -xm are included.
Midi2abc was modified to make these run time options the default
and the unnecessary flags -xl and -xm are now removed. 
To allow the user to force midi2abc to estimate xunits
(MIDI pulses per standard unit note length) from the note
duration statistics, a new option -gu was now introduced.
Since this is a major change in how midi2abc runs, the
version number was bumped up to 2.6.

September 14 2003

Contrary to the documentation, the anacrusis is not specified
in beats but in abc half unit lengths where a unit length is
given in the L: field in the header.  For example if
L:1/8 and M: 4/4, an anacrusis of 1 beat is specified as 4 (i.e.
four 1/16 units).  This is due to the way the quantized 
music is represented in midi2abc. Midi2abc does not allow notes
shorter than than 1/2 an L: unit. Therefore if the unit length is
L: 1/8, the shortest note that can be produced by abc2midi
is a sixteenth note. Note lengths are stored internally in
midi2abc as numerator/denominator where the denominator is
always 2. So a sixteenth note is quantized to a numerator
value of 1. Therefore midi2abc has difficulty representing
very short notes that are encountered in trills or drum
rolls. In such situations you should use the -s option
for short notes to get an approximation.

This also explains why printtrack, findana and guessana want
the barsize to be measured in half abc unit lengths (barsize
is doubled in the calling sequence for these functions.) 

I have corrected the readme.txt and the midi2abc.1 man file.

September 21 2003

Laura Michaels contributed patches to store.c, genmidi.c
and abc.h to handle the Copyright extended information field
(see abc2-draft) and to improve the production of Karaoke
MIDI files. Laura Michaels also provided makefiles for
other compilers such as Ming and Watfor. More details follow.

The proposed standard introduces a new field using the
syntax

%%abc-copyright (c) Copyright John Smith 2003

Abc2midi now inserts this in the MIDI file in the form of a
metatext copyright tag. Changes were made to the event_specific
function in store.c to process the copyright information.

Karaoke file applications such as Winamp, VanBasco;s Karaoke
player, and WinKaraoke (on Windows) have difficulty extracting
the composer and copyright information fields and confuse them
with the Karaoke text. The function karaokestarttrack in genmidi.c
was modified to handle additional @T information lines for
composer and copyright information after the title line in the
first MIDI track. In the Karaoke track (track 3), this
information was also added in the form of @I fields. Also
other abc information fields such as H: and A: were suppressed
in the Karaoke track by setting texton to 0 in printtrack.

The 98 character limit for text lines handled by event_field
in store.c was changed to 255 (see default case in switch (k)).



September 28 2003

For multivoiced abc files there is a need to be able to apply
a fermata to a rest. For example, consider this file.

X: 1
T: fermata applied to rest
M: 2/4
L: 1/8
K: G
[V:1] CDEF|GAF!fermata!G|C2 C2|
[V:2] EFGA|Bcd!fermata!z|C2 C2|
[V:1] CDEF|GAF!fermata!G|C2 C2|
[V:2] EFGA|Bcd!fermata!G|C2 C2|

If the fermata is not applied to the rest, there is a loss
of synchronization between the two voices.

The function event_rest was modified to get the array decorators
from one of its passed parameters. In store.c event_rest would
double the length of the rest (including hidden rests) if
decorators[FERMATA] is set. In parseabc.c it was necessary to
to update the decorators array for the case 'z' and 'x', prior
to passing it to event_rest. Changes were also required in
yapstree.c and toabc.c even though event_rest does not use the
decorators array in these files. The declarations for event_rest
in parseabc.h also needed to be changed.

September 29 2003

A new problem with setbeat (store.c) was discovered. For the
file

X:1
T: time sig
M: 2/4
L: 1/8
K: G
"C" G2 G2| G2 G2|
[M:3/4] G2 G2 G2|G2 G2 G2|


The gchord output was not correct for the first two bars.
This was caused by several problems in the code. (1) Setbeat
calls set_gchord to set the gchord_seq, gchord_len, g_num,
and g_denom used by dogchords. The values for g_num and g_denom
were incorrect because they were computed from mtime_num
and mtime_denom which were set by set_meter. The values
of mtime_num and mtime_denom were the last values in the 
previous tracks processed so if there was a change of meter 
in the tune they would not reflect the initial value.
(2) Setbeat chooses the appropriate gchord string on the basis
of the time signature stored in the time_num and time_denom
array. It is therefore necessary that these values remain
current to the current context during the writetrack pass.
Therefore set_meter was modified to update time_num and 
time_denom whenever it is called.

Set_meter is called in several places. It was called in
starttrack with the global parameters time_num and time_denom.
Unfortunately these parameters are affected by the event_timesig
which is called during the parsing stage. Therefore their
values reflect the last time signature encountered during
the parsing stage. It is necessary to cache the initial settings
of the time signature set in the header block. New variables
header_time_num and header_time_denom are defined in store.c
and passed to genmidi.c as externals.

In writetrack, for the accompaniment track it was necessary
to call set_meter() with the header time signatures just prior
to setbeat(). Set_meter is also called by write_meter in genmidi.c.
Write_meter is called whenever a TIME feature (for time signature)
is encountered. Fortunately, the correct time signature stored in
the num[] and denom[] arrays are used. Setbeat is called shortly
after in printtrack.


October 13 2003

Though most MIDI files indicate a time signature few also
indicate a key signature. Though midi2abc reports any key
signature it finds in the MIDI file, it does not use it but
insists on determining it by scanning all notes and choosing
the key signature that minimizes the number of accidentals.
This works fine if there are no key changes in the music.
If the MIDI file does indeed indicate key signatures and
key changes then midi2abc should use this information in
creating the abc file.

In a similar vein, for some MIDI files there may be more
than one meter change. Midi2abc uses the first time signature
that is indicated in the MIDI file. If it encounters other
time signature indications later, it reports it but it still
uses the initial time signature to transcribe the file.
Again it would be desirable if midi2abc would act on this
information.

Looking at midi2abc.c, it was noticed that the function findkey()
is always invoked except when the key signature is passed in
one of the run time parameters. If a key signature or time
signature metatext command is encountered, a time stamped
text message is added to the tlistx structure associated
with that track. These text messages are sent to the
abc file at the appropriate time using the handletext function
which is invoked by printtrack; however, no adjustment is
made for any key or meter change. Further the barsize
is assumed to be fixed. The barsize is a local variable
in the main program and it is passed to printtrack as
one of its parameters. The barsize controls the placement
of bar lines in the output abc file.


Numerous changes were needed to fix these problems.
(1) A new global flag, gotkeysig was introduced to the code.
It is initialized to zero but set to 1 whenever a key signature
metatext command is encountered. (2) A new variable 'type' was
added to the tlistx structure. If tlistx.text contains the
key signature, tlistx.type is set to 1. If tlistx.text contains
the time signature, tlistx.type is set to 2. For everything
else, tlistx.type is set to 0. (3) The 'type' variable was
added to the addtext() function and in the many places where
it was invoked. (4) In the function txt_keysig(), the verbose
message sent to the tlistx structure was replaced with just
the sf and mi (number of sharps/flats and major/minor flag).
(5) In the function txt_timesig(), The verbose message was
replaced with just the time signature nn/denom. (6) Major
additions were made to the function handletext() which now
does more than just print text at the appropriate place.
If the text string is a key signature or time signature as
indicated by the type variable, then the key signature or
time signature parameters are extracted. If it is a key signature,
setupkey(sf) is called which does all the work of printing
the K: field and setting up the tables for suppressing
the accidentals. If it is a time signature, a M: %d/%d %d
command is printed (time signature and pulses per quarter note).
(7) The barsize variable was turned into a global variable
like asig and bsig. (8) The function txt_timesig() was
broken into two functions, txt_timesig and setup_timesig().
The new function setup_timesig() updates the global variables,
asig, bsig and barsize. If unitlen was never set, it is
also set as well as xunit. Because the notes are quantized
in a separate pass, we must use a fixed xunit and unitlen
for the entire file. Setup_timesig() is also called during
the printtrack pass whenever handletext() detects a meter
change. (9) Printtrack uses the barnotes counter to decide
when to place a bar line. It is set to barsize at the
beginning of each bar and it is decremented by each note.
When it reaches zero a new bar line is issued. (It is
done this way in order to handle anacrusis.) If barsize
changes after the start of the bar it is necessary to
correct barnotes. Printtrack keeps track of the previous
barsize (last_barsize) and uses that to fix barnotes.
(10) Added a new option -gk to force midi2abc to guess
the key signature by minimizing accidentals even though
the key signature is already indicated in the MIDI file.
Normally it will automatically guess the key signature if
no key signature is found in the file and the key signature
is not specified with the -k parameter.

Unfortunately, this was not all the needed changes.
For multitrack MIDI files it is customary to reserve the 
first track for handling global operations such as tempo,
key, meter changes, and text messages. The remaining tracks
contain the actual music. In the case of multivoiced abc
files, it is necessary to apply the meter change or key
change to each voice. Therefore for each voice, midi2abc
needs to also check the tlistx structure in track zero for
any such changes. Another handletext() call was added to
to printtrack to handle this situation.

Abc2midi does not follow this convention exactly. For
single voice abc files with possible bass/chord or drum
accompaniment and possible Karaoke, it uses several tracks
but it does not reserve track 0 for this special purpose.
For multi voice abc files, abc2midi does use track 0 for
this special purpose and places text and metatext commands
grabbed from track one; however, because the delta times
from the missing notes were not accounted for, the delta
times for the time signature and key signatures are
not correct.  (They are all zero.) Fortunately, each
track also has any key or time signature metatext commands
with the correct delta times (assuming the abc file
was notated correctly), so that information in track
zero is not needed. The simplest fix was to suppress
output of these meta commands in track 0. In writetrack
(genmidi.c) a new flag 'timekey' was introduced to suppress
MIDI commands for key/meter changes in track 0.

The function setupkey does not work correctly after
the first call to this function. After that, the accidentals
are put in the wrong place. It was noticed that the
array key[] is initialized to zero in the function findkey()
instead of setupkey where it is actually used. Findkey()
is normally only called once if it is called. The 
initialization code was moved to setupkey.

October 25 2003

When the MIDI file has more than one key signature or
time signature, the first key signature or time signature
displayed in the header block reflects the last signature
that was encountered in the MIDI file rather than the
initial initial signature. This is corrected later on,
however the abc file looks strange. To fix this problem
new variables, header_asig, header_bsig, header_unitlen,
header_keysig and header_bb were introduced. When parsing 
the MIDI file, they are set to the first time signature or
key signature encountered. They are printed in the header
block.

For multitrack MIDI files, midi2abc prints out all
the textual information for track 0 immediately following
the end of the header block (first K: indication). This
unfortunately may include a whole list of key signature
or time signature meta text commands resulting in a 
correct but rather confusing abc file. To avoid this
situation a new variable, trackno, was added to the
function handletext. The function handletext now suppresses
the K:, M:, and L: indications for track zero when the MIDI file
has more than one track.

October 26 2003
 
There are still circumstances where a redundant key signature
or time signature is printed in the abc file. To avoid these
situations new variables, active_asig, active_bsig and
active_keysig were introduced. They are set to the current
status. Before printing a new signature, the present status
is checked and only changes are printed.


November 9 2003

Midi2abc frequently fails to detect triplets in the MIDI file;
even when it has been notated correctly using a music notation
program. Therefore sets of triplets may be converted into

D3/2D-[D/2-D/2]D A3/2B-[B/2C/2-]C| 

instead of 

(3D2D2D2 (3A2B2C2| 

which is another annoyance. Midi2abc.c has a special function
called dospecial which attempts to detect broken notes (eg.
C > D) and triplets; however, it does not seem to work
consistently. The problem is that all notes are quantized
to units of 1/32 or 1/16 notes, (depending on the meter).
The length of a triplet note is 1/12 or 1/24 which does
not get quantized exactly. Thus the representation of this
sequence (calling scannotes in the debugger) appears as
follows.
 
Pitch 62 chan 0 vel 127 time 160 xnum 3 playnum 3
Pitch 62 chan 0 vel 90 time 160 xnum 2 playnum 3
Pitch 62 chan 0 vel 90 time 160 xnum 3 playnum 3
Pitch 69 chan 0 vel 90 time 160 xnum 3 playnum 3
Pitch 71 chan 0 vel 90 time 160 xnum 2 playnum 3
Pitch 60 chan 0 vel 90 time 160 xnum 3 playnum 3

time is in units of midi pulses, xnum and playnum
are in quantized half units where xunit = 120 midi pulses.
The time and xnum are the inter-onset time of the note (length
between onset of this note and the next note). Playnum
is the quantized duration of the note (from midi on to
midi off). All of these variables are computed
by the function quantize() in midi2abc. Note that
160 is not divided even by the half unit = 60. Playnum
is rounded up but xnum compensates for the fact
that it may have been too long in the previous note.

The code in the function dospecial is far from transparent.
It looks ahead one or two notes to determine whether
this note and the following notes should be treated
differently (either as broken or triplets) and uses
the return character or featurecount array  to signal
to printtrack how  to handle these notes. One of the
tests in dospecial is the line just before the
broken rhythm tests is (reformatted for clarity)
 if ((v2 < pnum) || (v2 > 1 + pnum) ||
     (pnum == 0) || (v1+v2 > *barnotes
      )) {
    return(' ');

where v1,v2 refer to the xnum values of this note and the
next note and playnum is the playnum value of the next note.
v2 happened to be less than pnum due to the adjustment
discussed above, so the program returns from this function
without testing for broken notes or triplets. I commented
out /* (v2 <pnum) || */, and triplets are now detected
more consistently.  This could have some impact somewhere 
else, but I do not know at this time.

November 11 2003

More tuning for multiple key signatures (see October
26 2003). In printtrack, I moved the call to handletext
after active_keysig, active_asig, and active_keysig
were set. This fixed a problem in single track files,
where the same key signature was printed twice.
In the main function, header_keysig is set to keysig
only if gotkeysig is equal to zero. Otherwise, header_keysig
can be changed to the wrong (last value of keysig) value
if multiple key signatures exist.

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

Abcmidi 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] 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.

January 3 2004

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.


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.


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.


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.


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
preceded 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(). 

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.



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.

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 incompatibility 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 believe 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. Propagation 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 propagation 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  also see June 13 2005

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 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. 

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.



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.


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  - also see June 13 2005

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
preceded 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.


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 2005

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 2005

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.)

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.)


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 propagate 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 instruction 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 propagate 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];


February 12 2005  (also see June 13 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 guaranteed 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

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 propagate 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].

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. 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 propagates 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 propagate 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|



March 28 2005

Acciaccatura grace note notation. Abcm2ps compatibility 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.Since the microtone uses the %%MIDI pitchbend, it
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 controlled 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.)

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 lying around.

April 29 2005

Cleaned up all the compilation errors that occur in
Microsoft Visual C version 6.0.



May 03 2005

Abc2midi abcm2ps compatability feature:
add new %%MIDI command

%%MIDI beatmod n
where n is a positive or negative integer.

The command will increment (decrement) the loudness of the
on beat, off beat and other notes by the amount n.

Introduced new instructions:
 !<(! or !<)! or !crescendo(! or !crescendo)!  which act like
%%MIDI beatmod 15
Also 
 !>(! or !>)! or !diminuendo(! or !diminuendo)!  act like
%%MIDI beatmod -15

Thus a pair of !<(! and !<)! does two loudness increments. One
at the beginning of the crescendo and one at the end of the
crescendo.  This is not a gradual change but it is better than doing
nothing.

If the default beatmod value (15 or -15) is not ideal, you can
change it using
%%MIDI deltaloudness n
where n is a positive number.


Sample test file below:

X: 1
T: crescendo
M: 2/4
L: 1/8
K: G
%%MIDI deltaloudness 20 
!mf!cdef|edcB|
!<(! cdef|!<)! edcB|AAAA|
!>(!  cdef|!>)! edcB|AAA|
!crescendo(! cdef  |!crescendo)!|edcB|AAA|
!diminuendo(! cdef |!diminuendo)!|edcB|AAA|

Implementation: updated dodeferred in genmidi.c, added global
velocitychange in store.c and new code in event_specific and
event_handle_instructions.

abcguide.txt and abc2midi.1 documentation were updated.



May 06 2005

It has been suggested that some abc2midi options could be global
when they are used outside of a tune. For example:

%%MIDI chordname
%%MIDI ratio
%%MIDI beat
%%MIDI program

It is rather difficult to add this feature since the handling of
these options is not centralized but spread out in the store.c
and genmidi.c code. Some of these options apply to specific voices
which do not get instantiated until the voice is defined in the
tune. This makes the full implementation rather formidable.

I have introduced new code event_specific_in_header in store.c
that attempts to handle some of the MIDI directives. Many of
the MIDI directives send information to the feature[] array
which does not exist prior to parsing the tune. I have not
attempted to handle those directives. Presently, the only
MIDI commands that will be recognized outside the tune are

%%MIDI C
%%MIDI nobarlines
%%MIDI barlines
%%MIDI fermatafixed
%%MIDI fermataproportional
%%MIDI ratio
%%MIDI chordname
%%MIDI deltaloudness

All other MIDI commands outside the tune are ignored and will 
produce the warning "cannot handle this MIDI directive here".

The following is a sample test file.

%MIDI C 48
%%MIDI nobarlines
%%MIDI ratio 5 1
%%MIDI chordname ugly 1 2 3 4
X: 1
T: test global settings
M: 2/4
L: 1/8
K: C
"G"CDEF|"Gugly" D>EF>C|^ABDA|AAC2|


May 08 2005

Abc2midi: voice splitting.
In some pieces of  music a voice splits in two or more voices only
in some measures. The new abc standard (and abcm2ps) provides
a syntax for splitting a voice in a bar using the & symbol.
When placed within a measure, it splits the current voice and
attributes the notes that follow to the second voice.

Voice splits are handled by creating separate voices which
are in turn converted into separate MIDI tracks. 

To implement this feature, new variables were introduced into
the voice structure defined in store.c
int nbars; /* counts number of bars processed in voice */
int tosplitno /* points to new voice to handle split */
int fromsplitno /* points to voice initiating the split */
Both tosplitno and fromsplitno are intialized to -1 implying
that a split voice does not yet exit.
In an event of a split, tosplitno points to the new voice to go to. 
If it is -1, a a new voice needs to be created, and fromsplitno
in the new voice is set to the voice from which initiated the split.

In order not to confuse the new voice number with a voice number
generated by a V: field, the split voice numbers start from 32.

Global variables in store.c were introduced.
int numsplits; /* keeps track of the number of split voices generated */
int splitdepth; /* keeps track of the number of splits in a bar */

A new function event_split_voice in store.c is called by parsemusic
in parseabc.c when a '&' is encountered in a music line.

A new function resync_split_voice adds bars of rests into the
split voice so that bar is in the right position.

A new function complete_all_split_voices ensures all split
voices are the right length in order to avoid annoying messages
like:

Warning in line 7 : Track 2 is 3840 units long not 4800

A new function recurse_back_to_original_voice is called to 
recover from a split when a new bar line is encountered (see
event_bar).

Sample test file:

X: 1
T: testing voice split
M: 2/4
L: 1/8
K: G
A4| G4 & e2g2|BGEE|CAEE & d2f2|F2G2|


May 12 2005

Wrote a new function dumpfeat(n1,n2)  in genmidi.c which
prints out the contents of the feature,pitch,num,denom array
between n1 and n2. The function is usually called in the
debugger after stopping at a breakpoint in finishfile.


May 13 2005

Abc2midi split voices: Problems occur when the music contains
repeats. It is necessary to transfer the repeats to the split
voice. The function event_bar checks for any repeat symbols.
There are two cases. If we are already in a split voice then
(eg. abcd & defg :|)
we have to propagate the repeat back to the original voice
while recursing back.  If we are not in a split voice but
we know that this voice does link to split voices, then we
(eg abcd & defg |abcd :|) need to propagate the repeats
downwards to the all the split voices.

The function event_playonrep is also called by the parser
and needs to check for split voices.

May 14 2005

Now there is still another problem: the parser might encounter
a repeat symbol before it knows that this voice splits. We must
find a way of getting those repeat codes into the newly created
split voice. Solution: a new function start_new_voice_and_sync is
called when a split voice is first created. It scans
the parent voice copying rests and various types of barlines
and repeat codes into the feature array of the newly created voice.
If it encounters a %%MIDI program, that is also copied. This way 
the new voice also inherits the same music instrument as its parent.

If you wish to change the instrument of the split voice, you
can do it this way.
C2 EF & [I:MIDI= program 10] F2 D2|
The new instrument will apply to all following bars of the
split voice.

Abc2abc was made split voice compliant.



May 19 2005

Midicopy: will now return the playing time of the extracted segment.
This only works when a segment is extracted using any combination
of the -from and -to runtime parameters. Otherwise it returns 0.0.
The program makes adjustments for any tempo changes that may occur
inside this segment.

May 21 2005

Corrected a bug in midi2abc. It was returning the time in seconds
instead of beats when running with the -mftext option.

May 22 2005

Midicopy: for some reason  the meta command  mf_write_tempo (which
originated from midifile.c) alway writes delta_time 0. As a result 
all tempo meta commands are at the wrong time. When this was changed,
tempo changes seem to be handled better.

Midicopy now caches all tempo changes in a array of structures
called tempo_array. This is used to update the current_tempo
when other tracks (not containing tempo commands) are processed.
The correct tempo is needed in order to get an accurate estimate
of the playing time of the output file. A new function
update_current_tempo is called each time Mf_currtime is updated.


May 28 - 31 2005
June 04-06 2005

Midi2abc often produces a mess for piano music sequenced into a
single track. There are many chords played by the left hand and
the right hand usually has a different rhythm. Midi2abc tries
to place all notes sounding at the same time into a single chord.
To handle notes of different durations, some notes are tied to
the next chord and others are not. The resulting output looks
something like this.


X: 1
T: Scarlatti, sonata 1
%***Missing time signature meta command in MIDI file
M: 4/4
L: 1/8
Q:1/4=120
% Last note suggests Phrygian mode tune
K:F % 1 flats
% (C) John Sankey 1998
z/2d/2 (3efga/2-[a/2A/2] _d/2A/2[=d/2-D/2][d/2-E/2]\
 [d/2-F/2]d/2-[d/2-G/2][d/2-A/2]| \
[d/2A,/2][e/2-_D/2][e/2A,/2][f/2=D/2-] [d/2D/2]z/2[g/2E/2-][e/2E/2]\
 [a/2F/2-][f/2F/2][e/2G/2-][d/2G/2] [_dA]z/2[a/2-A/2-]| \
[a/2A/2][b/2A/2-][b/2a/2A/2]
etc...


Converting it to PostScript file produces something very difficult
to read. Ideally the notes played by the different hands should
be separated into two tracks. Chords should avoid internal tied noted.

The abc standard contains the provision for splitting the notes
in a single bar into separate voices. This should provide a means
of simplifying the output.

A new runtime parameter -splitbars was introduced, producing
an output similar to below.

X: 1
T: Scarlatti, sonata 1
%***Missing time signature meta command in MIDI file
M: 4/4
L: 1/8
Q:1/4=120
% Last note suggests Phrygian mode tune
K:F % 1 flats
% (C) John Sankey 1998
z/2d/2 (3efga zd3- & \
z3A/2_d/2 A/2=D/2 (3EFGA/2A,/2 &\
d/2efgazd/2 z2| \
(3ef/2d/2z/2Ea/2f/2Gz2z/2 (3b/2a/2b/2 &\
EF GA A,_D/2A,/2 =Dz/2g/2& \
z3e f/2d/2z/2Ea/2f/2G/2-| 
b/2a/2b/2  etc....


Implementation:
Separating the parts is complicated and incorporating these algorithms
into midi2abc.c was even more difficult. The anote structure was
extended to contain two new values. Posnum stores the position
of the start of the note in xunit units. Splitnum assigns the
note to one of several split voices. New functions label_split_voices
and label_split scan the entire track and separate all the notes
into separate parts when necessary. A note is assigned to an
existing part if it follows the previous note or forms a chord
matching the length of the previous note. Otherwise, label_split_voices
searches for another active part satisfying this criterion.
If there is no active part available, the note is put into a new
part. Bar lines are ignored at this stage. Once all the notes
are labeled into separate parts, the xnum value associated with
the notes are updated so they indicate the number of units to
the next note in the same part.

A new version of printtrack called printtrack_with_splits was
created from the printtrack code. In order to use as much of
the original printtrack code, it make multiple passes through
the same bar whenever the bar contains notes from different
parts. In each pass a single part active in this bar is processed
and printed.

The code is barely working and is still experimental.
It will probably not  produce correct results for complicated MIDI files.
Fortunately most MIDI files have proper chords and do
not require this feature.


June 04 2005

A problem with abcmatch.c causes it to return a bad xref number
after processing the last tune in the file. This causes
runabc.tcl to report an error similar to
Error: can't read "tuneid(84)" :no such element in array.
when running extras/grouper. The problem is that the notes variable
in abcmatch.c does not get initialized to zero if parsetune()
fails because it encounters an eof. To fix the problem,
the function startfile() in matchsup.c is made global instead
of static and it is called prior to calling parsetune() in
abcmatch.c.

June 10 2005

Midi2abc -splitbars: fixed segmentation error which occurs
for tracks not containing any notes.


June 13 2005

Abc2midi: "Time mismatch at tie" error when chord length
declared outside of chord.


X:1
T: multiple tie
M: 2/4
L: 1/8
K:C
[CE]/2-[CE]/2-[CE]|[CE]/2-[CE]/2-[CE]|
K: G
[C-E-]/2[CE]/2 [F2D2] [FD]|
[C/2-E/2-][C/2E/2] [F2D2] [FD] |

Abc2midi does not tie notes correctly in the above example.
The chord extensions in November 4 2004 and December 12 2004
do not work correctly in combination. The problem occurs
in the function dotie in the lines
        case CHORDOFF:
        case CHORDOFFEX:
          if(localvoiceno != voiceno) break;
          inchord = 0;
          /* subtract time from tied time */
          addfract(&tied_num, &tied_denom, -num[place], denom[place]);
          break;
after addfract subtracts num/denom from tied_num/tied_denom, tied_num
should be zero. However, tied_num/tied_denom was not yet adjusted
by fix_enclosed_note_length, so tied_num/tied_denom is not equal
to num[place]/denom[place]. Since dotie finds tied_num to be
non-zero in code
 /* tie in note */
            if (tied_num != 0) {
              event_error("Time mismatch at tie");
            };
it thinks that the notes inside the chord have unequal lengths
and reports the time mismatch error. Furthermore, fix_enclosed_note_length
is eventually called after the notes were tied making a further
mess.

Fix: Instead of calling fix_enclosed_note_length in a separate
pass during tiefix, fix_enclosed_note_length is called during
the parsing stage whenever a CHORDOFFEX feature is added (see
event_chordoff). The variable nochordfix is now redundant and
removed from the code. This guarantees that dotie sees the
correct note lengths inside the chord.

June 14 2005

Abc2midi: chord ties. In the following example,

X:1
T: multiple ties
M: 2/4
L: 1/8
K:C
[CE]/2-[CE]/2-[CE]-|[CE]/2-[CE]/2-[CE]|

The E notes are not joined.

Fix: the function call patchup_chordtie was moved from
tiefix to event_tie.

In addtoQ (queues.c) a check for negative delay caused
by apeggiate code 

  Q[*ptr].delay = Q[*ptr].delay - wait -notedelay;
        if (Q[*ptr].delay < 0) Q[*ptr].delay = 0;

was added.


June 17 2005

Midi2abc: fixed bug in -splitbars causing program to go
into an endless loop and various other bugs.


June 25 2005

Midicopy: added line void WriteVarLen() in function mf_write_tempo
to be compatible with the new gcc compiler.

June 25 2005

Abc2midi: tieing repeated notes inside chords. Abc2midi returns
a "Time mismatch at tie" error message for the following file.

X: 1
T: tie
M: 2/4
L: 1/8
K: C
[CC]-[CC]-[CC]z|

Analysis. The line is converted to
[C-C-][C-C-][CC]z| and the function dotie attempts
to tie C to the next note it sees which is the next C
inside the same chord. This changes the length of the
note in the chord leading to the above error message.
Fix: a new variable samechord is introduced. When it is
set to 1 it signifies that we are in the same chord where
the tie mark - was placed, we do not link the tienote to
any notes in that same chord.  The flag samechord is cleared
whenever we leave the chord (CHORDOFF or CHORDOFFEX).
It is set again whenever a tie mark occurs inside a chord
is encountered.

Please note: a tie only connects one note.
Therefore C-[CC] will tie C to only the first
C in the chord.

June 26 2005

Abc2midi does not correctly handle more than one bar split.
In the following example,

X: 1
T: testing voice split
M: 2/4
L: 1/8
K: G
%%MIDI program 24
A4 & c4 |G2F2 & BBDD & E,,4| 

E,,4 is played in the first bar coincident with A4 instead
of the second bar.

Analysis: various bugs caused abc2midi to fail with more than
one split. locate_voice() must use voice indexno rather than
voiceno. start_new_voice_and_sync must pass the voice
indexno rather than voiceno to locate_voice().


June 27 2005

Midi2abc: changed name of parameter -usesplits to -splitbars.
Added new parameter -splitvoices which eliminates non homophonic
chords (ie. polyphonic) by splitting entire voices. Implementation:
added new function printtrack_split_voice to midi2abc.

June 28-30 2005

Midi2abc: fixed numerous bugs in printtrack_split_voice()
and printtrack_with_splits().

July 02 2005

Abcmatch: upgraded the handling of chords and ties to be
compatible with abc2midi.

July 09 2005

Abcmatch: added an option to ignore simple bars.

Midi2abc: withdrew -Midigram option and replaced it with -midigram.
Note onset and offset time are now printed in MIDI time units rather
than quarter notes units.

July 14 2005

Abc2midi: voice split causes infinite loop when play on repeat
(eg [1 or [2) specified. For the following file


X:1
T:reproduce the bug in a smaller file
C:H. C. L. Smith
L:1/4
M:1/4
K:C
D|:C|[1F:|[2F|E&C||

abc2midi emits the following error message in an endless loop.

Error in line 8 : Bad variant list : reproduce the bug in a smaller file
Warning in line 8 : Bar 2 has 2 units instead of 1
Error in line 8 : Bad variant list : reproduce the bug in a smaller file
Warning in line 8 : Bar 2 has 2 units instead of 1
Error in line 8 :....

Analysis: when writing the voice split in bar E & C||, the function
inlist (in genmidi.c) fails to get the repeat on repeat number (eg [2))
which was set for top level voice but not for the split voice.

Fix: the problem was traced to the function start_new_voice_and_sync
in store.c. It copies the repeat BAR feature (SINGLE_BAR, DOUBLE_BAR,
etc..) to the split voice but for the PLAY_ON_REP feature it must
also copy the pointer to the part number stored in denom[]. Now
both feature[j] and denom[j] are both copied for all bar type features.

July 15 2005

The above file exposes yet another problem leading to a loss of
synchronization between the voices. The first indication that there is
still something else wrong are the messages.
Warning in line 8 : Bar 2 has 2 units instead of 1
Warning in line 8 : Bar 3 has 3 units instead of 1 in repeat
Warning in line 8 : Track 2 is 4320 units long not 2880

When playing the output MIDI file, the note C in the split
is played two bars late extending track 2.

Analysis:
A play on repeat symbol is always preceded by a bar or repeat bar
(ie. | or :|). The function start_new_voice_and_sync treats the play
on repeat symbol as another bar line and inserts a rest to complete 
the bar when in fact, it should just insert a PLAY_ON_REP.
Since this bar is played twice, the C note comes two bars late. 
Treating PLAY_ON_REP as a separate case fixed the problem.

July 17 2005
Abc2midi: voice split synchronization error when not all measures
are equal in length. In the following file, the tune begins
with an incomplete measure.

X:1
T: anacrusis
M: 2/4
L: 1/8
K: F
AG|Fc Fc| d2 e2 & B2 c2|

Analysis: start_new_voice_and_sync unfortunately assumes that
every measure contains 2 beats. Fix: the function now counts
the number of beats in each bar it processes.


Abc2midi: MIDI attributes inheritance. As discussed in May 14, 2005
split voices inherit the MIDI characteristics from their ancestor.
The following file does not work as expected.

X:1
T:inherit 1 
M:4/4
L:1/16
Q:1/4 =20
K: C
%%MIDI channel 2
%%MIDI program 2 50
B2G2A2B2 EDEF EGFA & z2E4 D2 C8|]

The split voice z2E4 ... is played on the Acoustical Piano (program 0)
instead of the synthetic strings.

However the following file works correctly.

X:2
T:inherit 2
M:4/4
L:1/16
Q:1/4 =20
K: C
%%MIDI program  50
B2G2A2B2 EDEF EGFA & z2E4 D2 C8|]


Analysis: Each split gets its own voice and each voice gets
its own channel number unless it is changed explicitly. 

The above should be equivalent to
X:1
T:inherit 1
M:4/4
L:1/16
V:1
%%MIDI channel 2
%%MIDI program 2 50
B2G2A2B2 EDEF EGFA| 
V:2
%%MIDI channel 2
%%MIDI program 2 50
z2E4 D2 C8

Unfortunately, the %%MIDI channel 2 did not propagate
to the split voice. Voice 1 was assigned channel 2 but voice 2
still had channel 1 (writetrack automatically assigns the
first channel which is not in use). The bug was fixed by
ensuring the CHANNEL feature also propagates into the split voice.

You may wonder why X:2 worked correctly. This is because
the MIDI program command without the channel indication applies
to whatever channel is currently active.


July 23 2005.

Fixed bug causing midi2abc.exe to produce a segmentation error when
running with the -splitbars option. (Failed to save state
when doing a split voice context switch due to encountering
an end of track before an end of measure. As a result the restored
chordhead would point to the wrong place.) Added more
code around line 2480 in printtrack_with_splits in midi2abc.c.


August 13 2005.

Abc2midi.exe does not handle correctly chords of the form
[CE]2 when embedded in a triplet. For example in the file,

X:1
T: triplet
M: 4/4
L: 1/4
K:C
(3C2 D2 [CE]2 |

abc2midi produces an error messages 

Warning in line 6 : Different length notes in tuple
Warning in line 6 : Different length notes in tuple

and the [CE] chord is the wrong length.

Analysis: event_note processes the internal lengths
of the notes in a chord before it encounters the end
of chord marker (]) and it does not know that the
internal lengths may be adjusted externally after
the end of chord. It sees the wrong length, and
sends a warning. Event_chordoff fails to make an
adjustment for the triplet (tuple) so that the
function fix_enclosed_note_lengths sets the lengths
of the internal chord notes to the wrong length.

Fix: event_note bypasses the tuple test (for triplets)
if the notes are inside a chord. The tuple test
was also added in event_chordoff. It adjusts the
setting of the note lengths (chord_n, chord_m) if
the chord is inside a tuple. If chord_n and chord_m
are not 1,1 then fix_enclosed_note_lengths is called.

 
August 13 2005

Abc2midi.exe has difficulty handling tied notes enclosed
in a slur. For example for the tune

X:1
T: slur 1
M: 2/4
L: 1/8
K: G
(GB-B) C|(DEF) B|

the following messages appear

Warning in line 6 : Slur in abc taken to mean a tie
Error in line 6 : Bad tie: possibly two ties in a row
Error in line 6 : Cannot find note before tie

Surprisingly, the output MIDI file is still correct.

Analysis and fix: Abc2midi does almost nothing when it encounters 
slurs. However, when it sees repeated notes inside a slur it 
tries to tie them together.  For example for (G B B), abc2midi 
would try to tie the two B's together. This is the source
of the above problem.  I do not think this is a very useful
feature so I have turned this feature off (in event_sluroff store.c). 

August 13 2005

The abc2-draft standard, 
http://abc.sourceforge.net/standard/abc2-draft.html
has deprecated the !...! notation in favour of the +...+
notation. In order to comply with the change, abc2midi, abc2abc
and yaps were modified to accept either convention.
Thus you can use +trill+, +fermata+ +pp+ etc. as well
as the deprecated notation (!trill! etc.). There is one conflict:
in the early days of abc notation chords were notated
as +CEG+ instead of [CEG]. There is probably very little
music using this old convention. If you need to handle the
old chord notation, you must now add the option -OCC to
abc2midi, abc2abc or yaps.

Sample file:

X:1
T: decorations
M: 2/4
L: 1/8
K: G
+<(+ [CE]4 +<)+  |[CE] +trill+  DEF|
!<(! [CE]4 !<)!  |[CE] !trill!  DEF|

Implementation:

Introduced a new global, oldchordconvention into parseabc.c
which is linked externally to store.c, toabc.c and yaps.c.
If this global is unset (ie. 0), then parsemusic in parseabc.c
treats + and ! in the same manner.


August 17 2005
 
Added new run time parameters to midicopy -fromsec and
-tosec allowing you to select a section in terms of time
in seconds.


September 13 2005

Midicopy using the -fromsec option to select the start of the
output MIDI file causes the music to be delayed by the
the same amount of seconds.

Analysis, the first note on (or note off) of the track has
a delta_time equal to the time of the first note in the
selected section of the original file. TiMidity has no problem 
since it ignores this delay. Other MIDI players are less
compliant.

This is a hard bug to fix properly when the tempo varies
across the MIDI file. For such files, it is recommended that
you use the -from and -to parameters and express the times
in MIDI tick (pulse) units. The program now computes
the right delay using the first tempo specification in the
MIDI file.

I noticed that when midicopy truncates the beginning of
a file, a track may begin with a MIDI off command of a note
that has not been turned on. I don't think this causes
a problem.



September 19 2005 

Incorporated changes suggested by Mikhail Teterin into parseabc.c
and store.c to modernize the C code. This includes the replacing
of the functions casecmp(s1,s2) and stringcmp(s1,s2) with functions
built into the C compiler. If this causes any problems with
your compiler please notify me as soon as possible. Other
changes were added to make the code more efficient and eliminate
some warning messages.



September 19 - October 8 2005

Abc2midi: another bug related to split chords was found. In the
following example

X:1
T: split test file
M: 2/4
L: 1/8
Q: 50
K: D
CD |EF AB & CD FG| G2 | BD D2 & GB B2|

The zero th and second bar are only one beat long. The fix described
on June 17 th handles the zero'th bar correctly but it does not
address the second bar since a different function resync_split_voice
is called to maintain synchrony. This function assumes all bars are
a fixed length as specified in the time signature.

This was a difficult bug to fix since it required major changes
to the code. A new function sync_voice replaces the code for
start_new_voice_and_sync and resync_split_voice. A test file used
to debug these changes, split.abc, is included in the programming directory.
Hopefully, I will not need to return to this file many times.


October 8 2005

Abc2midi, yaps, abc2abc : extraneous warning "Slur within slur".
For the following example, 

X:1
T: 2 slurs
M: 2/4
L: 1/8
K: C
V: 1
C2 (C2 |\
V: 2
(A2 G2) |\
V:1
D2) E2|
V:2
G4|

we get the warning
Warning in line 9 : Slur within slur.

Analysis, there are two overlapping slurs, but they are in 
separate voices so this should be no problem. Parseabc.c
merely keeps a count of the number of open slurs with the
variable slur and does not note that they are associated
with specific voices.

Fix: the warning message has been moved to store.c.



October 9 2005

Abc2midi: grace notes are not applied correctly to a chord.
In the following example,

X:1
T: grace/chord
M:2/4
L:1/8
K:G
V:1
D4|{c'}[g3b3] c|z2 G2|
V:2
F4|G3 e|z2 D2|

The length of the host chord [g3b3] is not adjusted correctly.
This results in a loss of synchronization between voice 1 and 2.
Analysis: several bugs related to host chords were fixed in
my new function applygrace_new() in store.c. The original code,
applygrace_orig was also fixed.

October 10 2005

Updated makefiles/unix.mak. Cleaned up some of the -Wall warning
messages.


November 6 2005

New abc2midi feature for supporting drum tracks. Notes played on
MIDI channel 10 (counting from 1), are interpreted by the General
MIDI instrument as one of 47 percussion instruments (see abcguide.txt
for list). Unfortunately, notating the music in this manner is
rather awkward if you wish to convert it to common music notation
using abcm2ps. Usually, only a few percussion instruments are
used. To allow for better drum notation, you can alter the mapping
between notes and percussion instruments using the new
%%MIDI drummap command. For example for the tune:

X:1
T: illustrating drummap command
M: 4/4
L: 1/8
K: none
%%MIDI channel 10
%%MIDI drummap E 36
%%MIDI drummap G 38
%%MIDI drummap _e 42
|: E2 GE zE z2 & z_e z_e z_e z_e :|

would be played on the percussion instruments
bass drum (36)
acoustic snare (38)
and closed hi-hat (42).

Implementation: added new function parse_drummap() genmidi.c
which handles the %%MIDI drummap command. parse_drummap()
is called from the function dodeferred().

November 6 2005

Abc2midi: split voice does not propagate the octave shift
command. eg.

X:15
T: splits with octave=1
M: 4/4
L: 1/4
K: G octave=1
G A B C & E F G A|

The notes E F G A are played an octave lower than intended.

Fix: the v->octaveshift variable is passed to the
split voice in the function event_split.  


December 08 2005

Abc2midi: the drummap feature illustrated on November 06 2005
produces an improper MIDI file. eg.

X:1
T:unfinished
M:2/4
L:1/16
K:F
V:1
%%MIDI channel 10
%%MIDI drummap ^^g 72 % Long Whistle
%%MIDI drummap  _a 58 % Vibraslap
^^gz _a2-_a4 |]

midi2abc.exe unfinished1.mid -mftext

Header format=1 ntrks=2 division=480
Track 1 contains 40 bytes
  0.00   Metatext tempo = 120.00 bpm
  0.00   Metatext key signature F (-1/0)
  0.00   Metatext time signature=2/4
  0.00   Metatext (Seqnce/Track Name) unfinished
Track 2 contains 35 bytes
  0.00   Metatext (Seqnce/Track Name) unfinished
  0.00   Note on  10   c5 105
  0.25   Note off 10   a5   0
  0.50   Note on  10  a#3  80
  2.00   Note off 10  g#5   0

The note on's have the translated pitches but the
note off's have the original pitches. As a result
none of the MIDI note on's are properly terminated.

For percussion instruments, this may not be noticeable
since a decay is already built in. However, some midi
players may complain.

Fix: the function midi_noteoff in genmidi.c now checks for
for channel 10.
 

December 09 2005

Abcmidi: transposition should not be applied to the music
in channel 10. In the following example

X:1
T: drum transpose
M: 2/4
L: 1/8
K: G transpose=-3
V:1
FAFA|EFG2|
V:2
%%MIDI channel 10
%%MIDI drummap g 72 % Long Whistle
%%MIDI drummap a 58 % Vibraslap
agag|agag|

The transpose=-3 changes percussion instruments.
Fix: a test for channel 10 is made before the call to noteon_data()
in the function noteon() in genmidi.c. Also in writetrack, a similar
test was applied before addtoQ in two places (NOTE: and TNOTE:).


December 17 2005

Abc2midi new feature: certain instruments such as an organ have
no greatly emphasized beat notes and sound unnatural when the beat
algorithm accents the down and off beats. To turn this feature use
%%MIDI nobeataccents
To turn it back on
%%MIDI beataccents
By default beat accents are turned on for any new tune.
Thanks to Mike Scott for contributing the code to genmidi.c

Implementation: a new variable beataccents which acts as a
flag was introduced.


January 7 2006

I have started looking into the problem of adding the
split voice feature into yaps.  In order for yaps to
handle split voices, it was necessary to introduce a new
feature code SPLITVOICE into abc.h.  This had minor impact 
on the debugging code for genmidi.c and matchsup.c.
Event_split_voice in yapstree.c now needs to insert a
SPLITVOICE feature. To avoid "unknown type" message
originating from sizevoice (in drawtune.c) it was necessary
to add a case statement for SPLITVOICE even though it does
nothing. To assist in debugging, the code in the showline
function was split into a new function showfeature in
debug.c.

The real work is done in the function advance(..) in 
the file position.c (see additions in programming/yaps.txt).
In order to allow spacemultiline to process all the notes
playing at the same time, major changes are necessary. We
want advance() to check a measure for splitvoices, and if
found process all the notes in the bar in the order that
they would be played. This means extending the voice
structure defined in structs.h so that it maintains
status information for v->tuplefactor, v->inchord, 
v->place,v->time for all splitvoices and telling
advance() to handle the splitvoices in parallel.
This work is beyond me at the present time and
no further work was done.

January 13 2006

abc2midi fails to tie note correctly in chord with
an augmented unison interval. In the following example


X:1
T:A) Matching non-perfect primes
M:C
L:1/2
K:C
[=D^D-] [=D^D] z
[=D-^D] [^D=D] z

the D- tie and ^D- are done improperly.

Analysis: In order to tie notes across bar lines where the 
accidental is assumed, (e.g. A_B-|BD), the function dotie
performs the tie based on the pitch line (in the staff) rather
than the actual pitch. Unfortunately there are cases where we
run into trouble such as above.

Partial Fix: dotie() has a new flag called newbar, which is set to
1 whenever a nonprocessed tie is followed by barline. The
pitchline[] test is now only activated when newbar is set.

Unfortunately, this is not a complete fix. The same
problem reappears with this file for the second and
third lines.


X:1
T:Matching non-perfect primes
M:2/4
L:1/2
K:C
[=D^D-]| [^D=D] | z2 |
[=D^D-]| [=D^D] | z2 |
[=D-^D]| [^D=D] | z2 |
[=D-^D]| [=D^D] | z2 |

The feature array does not record whether accidentals
have been spelled out explicitly so further checks
cannot be done when applying ties across bar lines.
I recommend that one just changes the order of the
notes in the chord in order to get it to work. Fortunately,
this problem occurs rarely.


January 14 2006

Abc2midi fails to tie microtonal notes correctly.
In the following example:


X:1
T: tied microtonal pitches
M:C
L:1/2
K:C
C
^13/16C - ^13/16C
^13/16C   ^13/16C
^13/16C - C

The two notes on the second line are tied together,
but the first note is in C rather than ^13/16C causing
an audible pitchbend. The notes in the third line
are correct pitches but not joined. The tied notes
in the fourth line are both incorrect pitches.

Analyses: looking at the mftext output from midi2abc
reveals the problem.

midi2abc.exe tmp/X1.mid -mftext
Header format=0 ntrks=1 division=480
Track 1 contains 141 bytes
  0.00   Metatext tempo = 227.00 bpm
  0.00   Metatext key signature C (0/0)
  0.00   Metatext time signature=4/4
  0.00   Program   1 73 (Flute)
  0.00   Metatext (Seqnce/Track Name) tied microtonal...
  0.00   Note on   1   c4 127
  2.00   Note off  1   c4   0
  2.00   Pitchbnd  1 msb=0 lsb=90
  2.00   Note on   1   c4 107
  2.00   Pitchbnd  1 msb=0 lsb=64
  4.00   Pitchbnd  1 msb=0 lsb=90
  6.00   Note off  1   c4   0
  6.00   Pitchbnd  1 msb=0 lsb=64
  6.00   Pitchbnd  1 msb=0 lsb=90
  6.00   Note on   1   c4 107
  8.00   Note off  1   c4   0
  8.00   Pitchbnd  1 msb=0 lsb=64
  8.00   Pitchbnd  1 msb=0 lsb=90
  8.00   Note on   1   c4 117
 10.00   Note off  1   c4   0
 10.00   Pitchbnd  1 msb=0 lsb=64
 10.00   Pitchbnd  1 msb=0 lsb=90
 10.00   Note on   1   c4 107
 10.00   Pitchbnd  1 msb=0 lsb=64
 14.00   Note off  1   c4   0

This is another example where the handling of tied notes
in dotie() store.c and writetrack() in genmidi.c have
gets in the way. (The code was written before microtones
was introduced into abcmidi.) The parser encircles
every microtonal note with an event_microtone and
event_normal_tone. The function dotie changes the
tied note from NOTE to TNOTE, the TIE to a REST,
and the note being tied to a REST. The function writetrack()
unfortunately applies the delay() function for the
NOTE feature but not for TNOTE. As a result, the
pitchbend is restored to normal before the note
even starts playing.

Modernizing the tienote function (see February 12 2005
comments) is not an option since there were too many
cases to worry about and it would probably take a
long time to get out all the bugs out.

Fix: a small patch was added to tienote() in store.c.
It removes the DYNAMIC feature restoring the pitchbend
to normal if it finds one immediately following the
TNOTE.



January 15 2006

The contour matching algorithm in abcmatch.c has
been changed to use pitch interval between adjacent
notes. A new run time parameter, -qnt was added
which quantizes the contour interval. Details
in abcmatch.txt.


January 16 2006

Added new feature to yaps that allows you to switch from black
to red output using !red! or +red+ instruction command.
To restore insert !black! or +black+ in the abc file.

e.g.

X: 356
T:Banks of the Nile
M:4/4
L:1/4
K:Eb
B/2-G/2| F E F G| c B G E| F E- C C| C3 C|!red! E E G B!black!|
c2 e c/2c/2| B B E F| G3 E/2E/2| E E G B| c c e c/2c/2| B B E F|
 G3 B/2G/2| F E F G| c B G E| F- E C C| C3||

The notes in the 6 bar are printed in red for emphasis.

Implementation:
In structs.h added a new structure
  struct dynamic {char color;};

In yapstree.c, added code to event_handle_instruction to detect
!red! and !black! and addfeature(DYNAMIC,psaction) where psaction
is a *dynamic struct. In drawtune.c added code to printvoiceline()
to take appropriate issue a postscript command to change the
color when it detects a DYNAMIC: feature.

January 29 2006

Abc2midi: improved the microtone pitch accuracy. Replaced the
code event_microtone (in store.c) with the code contributed by
Hudson Lacerda.

Introduced some support for single note tuning change using
the universal system exclusive messages. Added new function
in midifile.c single_note_tuning_change(). In function
dodeferred in  genmidi.c added a %%MIDI snt k pitch
command where snt stands for single note tuning, k is the
MIDI pitch being retuned (a number between 0 to 127) and
pitch is a floating point number representing the new
pitch value. Sample file follows.

X:1
T: single note tuning
M: 2/4
L: 1/8
K: G
C \
%%MIDI snt 60 61.5
C cd|

I have not yet updated abcguide.txt since this feature
is provisional right now. Not all MIDI devices support
this universal system exclusive message.


February 05 2006

Abc2midi.exe eliminated the warning for microtones
"divisor not a power of 2". Introduced a new copy
of readlen (readlen_nocheck which is called by
ismicrotone() and does not report this error.)


March 14 2006

Abc2abc does not recognize "middle=XXX" in the V: field
which is used by abcm2ps and silently drops it when
transposing abc files. The fix was provided by Mike
Scott who also cleaned up the parameter calling sequence
to event_voice in parseabc.c. This also involved altering
the code in store.c, yapstree.c, matchsup.c, and toabc.c.
Thank you.

Added #include <stdlib.h> to crack.c, mftext.c,
pslib.c and queues.c which cleans up some of the
compilation warnings.(Thanks to Martin Tarenskeen.)


Apr 21 2006

(Mike Scott) The 'y' spacing character used by Barfly and
abcm2ps was being silently dropped in parseabc.c. Added
support for this (including a length specifier - is this
used by anything?) to parseabc.c and abc2abc.c; stubs in
the other modules including yaps mean they behave as before.


June 7 2006

Midicopy: new runtime parameters -frombeat and -tobeat were
introduced to copy a selection of a midi file.

Midifile: new code was introduced to process an individual
track in a multitrack MIDI file.


June 25 2006

Abc2midi: added new feature to provide control over the 
articulation of the notes. The feature %%MIDI trim x/y
introduces a gap between notes of duration x/y where x/y
is the fraction of the unit note length defined by the
L: field command. This gap is made by shortening every
note by this amount whenever it is possible. If the note
is too short, the gap is reduced. Slurs indicated by
parentheses in the music body temporarily disable this feature.

Implementation: added a new feature SETTRIM in abc.h.
Added new globals variables trim,trim_num,trim_denom in
genmidi.c. Added additional code in writetrack to initialize
trim_num,trim_denom and to modify notes for switch conditions
NOTE:, CHORDOFF:, and CHORDOFFEX. Added new switch state
in writetrack to interpret feature SETTRIM.  In store.c, added more
code in event_specific to interpret the %%MIDI trim command.

Abcguide.txt, abc2midi.1 and demo.abc were all updated.

Thanks to Jacques Le Normand for the suggestion.


July 28 2006

Midicopy still does not extract correctly a segment from
some MIDI files when it is specified using the -fromsec and
-tosec parameters. This occurs in multitrack MIDI files 
containing numerous tempo changes. Time units measured in seconds
do not correspond between tracks.

It was decided to completely change the method of handling 
segment extraction when time is specified in seconds. It is
assumed that all tempo indications are placed in track 1 of 
the MIDI file. Tempo changes in other tracks are ignored.
An initial pass is made through track 1 to extract all the 
tempo changes and store them in an array.  This is used to
map time in seconds to MIDI pulses or ticks.  The -fromsec
and -tosec parameters are converted to pulse units using 
this mapping. The program then extracts the MIDI information
falling in this time interval.


July 28 2006

Abc2midi returns the error message
"First lyrics line must come after first music line"
when processin abc files with lyrics and inline voice commands.
For example

X:1
T: inline voice
M:5/8
L: 1/8
K:G
[V:1] cdefg
w: c d e f g
[V:2] cdefg
w: c d e f g

I have little experience with lyrics in abc files.

The problem is caused by the fact that the inline voice command
starts up a new track which resets the variable thismline = -1.
This indicates that a new music line was not yet encountered
for this voice.  If the notes cdefg were placed in a separate
line, then the variable thismline was be set to the current
line number and everything would be all right. Unfortunately,
this is not the case and the abc2 draft standard excepts this
syntax. See abc.sourceforge.net/standard/abc2-draft.html and
in particular the canzonetta.abc file on that page.
There is no easy way of detecting music information at this
point other than updating the variable thismline every
time a note is processed. Instead, I disabled the error
message by commenting the line 
thismline = -1;   
in genmidi.c. Hopefully, this does not cause more damage.


July 29 2006

Abc2midi: microtones (pitchbend) does not work correctly for tied
notes enclosed in a slur. For example:

X:1
T:bad pitchbend when tie + slur
M:4/4
L:1/8
K:C
"^Bad pitch bend when tie+slur"
(^1/2C- ^1/2C =C) a- a4 |
  ^1/2C- ^1/2C =C  a- a4

In the first bar, the tie does not work correctly and 3 notes are
heard instead of two. Furthermore the first note does not have
a pitchbend applied. In the second bar, the notes are played
correctly.

Analysis: running midi2abc with the -mftext option provides
some indication of the problem.

  0.00   Pitchbnd  1 msb=0 lsb=80
  0.00   Note on   1   c4 105
  0.00   Pitchbnd  1 msb=0 lsb=64
  0.50   Pitchbnd  1 msb=0 lsb=80
  1.00   Note off  1   c4   0
  1.00   Pitchbnd  1 msb=0 lsb=64
  1.00   Note on   1   c4  80
  1.50   Note off  1   c4   0

The pitchbend is set prior to the note but is restored to
normal immediately after the note is started (time 0.00).
This is similar to the problem fixed on January 14 2006
(see this file). This suggests a problem with the function
dotie(). Further analysis, revealed that the parser
places a SLUR_TIE after every NOTE feature when the notes
are enclosed inside a slur. The SLUR_TIE is not needed
by abcmidi but it is used by yaps. Unfortunately, the
function dotie() does not expect a SLUR_TIE to appear between
the TNOTE and DYNAMIC so it fails to remove the DYNAMIC
feature.

Fix: A similar patch described in Janurary 14 2006 was
added to dotie().


July 29 2006

Abc2midi: It is not commonly known that accidentals are  not
supposed to propagate across octaves. In the follow example,

X:1
T: accidentals and octaves
M: 2/4
L: 1/8
K: G
C_EDe|C_EDe-|e2^f2|-f2g2|

Abc2midi normally also flattens the e; however, technically
it should not be doing this. Accidentals only apply to a
specific note and should not affect the same pitch class 
in other octaves.

Fix: in store.c workmap and workmul are now doubly indexed
arrays. The second index keeps track of the octave. 


July 30 2006

Abc2abc transposition always reverts to the major key signature
when it does a transposition.

Analysis: the code in toabc.c represents the key signature
in terms of the number of sharps and flats and ignores the
mode of the original key signature when it is doing a transposition.

Fix: (1) In parseabc.c the index to the array mode[] is
saved in the variable modeindex when a mode string is matched.
(2) in order to pass modeindex to event_key, the function
parameter minor was replaced with modeindex and the
variable minor was turned into a local variable which is
computed from modeindex. This was done in all files where
event_key is defined -- store.c, yapstree.c, matchsup.c,
and toabc.c. (In actual fact, the variable minor was only
used in store.c to set the minor flag in the MIDI file.)
(3) A new function called compute_keysignature() from
the sharps/flat representation and modeindex was added to
toabc.c. (4) event_key in toabc uses this function to
compute the correct key signature.


August 04 2006

abc2midi: The treatment of microtones and microtones with
accidentals for key signatures other than C major (or A minor)
has been changed. Prior to version 1.87, if the music
was in the key of G major, ^1/2F would be interpreted
as raising F# by a half a microtone. Now the underlying
key signature is ignored and the microtone is treated as
a pure accidental. Thus ^1/2F raised F and not F#.
Hopefully this is more intuitive.

Thus accidentals and microtones are assumed to be
applied to the natural form of the note irrespective
of the key signature or the status of previous
notes in the measure. However, accidentals other
than microtones can still propagate to notes which
do not have accidentals. To illustrate consider
the following in the key of C major.

    _E _1/2E E __1/2E E|

The second E is treated as E natural flattend by 1/2
microtone because E is always assumed to be in its natural
form when preceded by any accidentals. Since the assumed
natural of the second E propagates,  the third E is also
E natural and not Eb. The last note is Eb reduced by half
a semitone.  The last E would be played as Eb.  See 
abcguide.txt for another example.


Implementation turned out to be easier than expected. A 
new global (int microtone) was added to store.c. It is
set to 1 by event_microtone and reset to 0 by event_normal_tone.
The function pitchof(), now does not apply the active
flats or sharps (of the key signature) or accidentals when
the microtone global is set.


August 4 2006

Abcm2ps has introduced an extension of the w: field
referenced by the s: field which accepts ~ as a decoration.
Unfortunately, the parser in the abcmidi package does not
recognize this field command and attempts to treat the
line as a music line. As a result a file such as
 

X:1
T: s
K:C
    cd ef  g4       | ag      ab   c'4 |]
s: "C"~~~ "C/E"    | "Dm/F"* "G7" "C"
s: .. ..  +tenuto+ | ..      ..   !fermata!
s: "_5"***"_6"     | "_6"*   "_7"*"_5"
s: "_3"***"_3"     | "_3"*   "_5;3"*"_3"

produces many error messages
Error in line 6 : Single colon in bar
Error in line 6 : Malformed note : expecting a-g or A-G
Error in line 6 : *'s in middle of line ignored
Error in line 7 : Single colon in bar
Error in line 7 : Malformed note : expecting a-g or A-G
Error in line 7 : Malformed note : expecting a-g or A-G
Warning in line 7 : instruction !tenuto! ignored
Error in line 7 : Malformed note : expecting a-g or A-G
Error in line 7 : Malformed note : expecting a-g or A-G
Error in line 8 : Single colon in bar
Error in line 8 : *'s in middle of line ignored
Error in line 8 : *'s in middle of line ignored
Error in line 8 : *'s in middle of line ignored
Error in line 9 : Single colon in bar
Error in line 9 : *'s in middle of line ignored
Error in line 9 : *'s in middle of line ignored
Error in line 9 : *'s in middle of line ignored

Similar error messages occur for other abcmidi programs,
for example yaps, abc2abc etc.

Fix: in parseabc.c: for function
parsefield add s to the strchr string
  if ((inbody) && (strchr("EIKLMPQTVdwW", key) == NULL)) {
    event_error("Field not allowed in tune body");
and also added the case in the switch statement
  case 's':
    break;
finally in parseline() added s to the strchr string in
  if (strchr("ABCDEFGHIKLMNOPQRSTUVdwWXZ", *p) != NULL) {
    q = p + 1;


August 05 2006

Note trimming introduced in June 25 2006 causes loss of
synchronization between two voices when notes are contained
in a grace sequence. 
Fix: introduced a variable graceflag into writetrack() in
genmidi.c. The flag is set when GRACE feature is encountered
and restored to zero when GRACEOFF feature is encountered.
Note trimming is disabled inside a grace sequence. Also
note trimming is shutoff for short notes.
In order to separate two slurs in a row, trimming is
restored for the last note in a slur.

August 08 2006

Abc2midi: split voices. In the file

X:1
T: also D sharp continues in next bar
K:C
M:4/4
L:1/4
C^DEF & C4 | CDEF |

The D in the second bar is sharpened.
Fix: added call to function copymap() in the function
recurse_back_to_original_voice().

August 29 2006

Abc2abc: handling of rests in tuples causes an error
message. The problem does not occur in abc2midi
or yaps. For example

X:1
T: tuple rests
M: 2/4
L: 1/8
K: C
G4|(3z2A2B2|F4|

abc2abc tuplerest.abc -t 3
X: 1
T:tuple rests
M:2/4
L:1/8
K:C
G4|
%Error : Rest not allowed in tuple
 (3z2A2B2
%Error : Bar 1 is 7/12 not 2/4
|F4
%Error : Bar 2 is 1/3 not 2/4
|


Fix: in the function event_rest in toabc.c, the
error message was removed and the beat counter
code was modified to consider tuples.  


September 09 2006

abc2abc: voice numbers not processed correctly. In the
following example:

X:1
T:voices
M: 2/4
L:1/8
K:G
V:1
ABCD|abcd|
V:1I
ABCD|abcd|

V:1I was changed to V:1 producing an incorrect abc file.
Analysis: the parsevoice() in parseabc decides whether the
voice number is a number or a label based on the first character.
Since the first character of 1I is a number it treats it as
a number and ignores the I. This problem also persists for
abc2midi and yaps.
Fix: created a new function isnumberp(s) which determines
whether the string s is a positive integer number and
returns 0 for no and 1 for yes; replaced the original test
with this function. 

September 11 2006

Abc2midi: handling of trilled notes for broken rhythms is not
correct. In the following example,

X:1
T: trill
M: 2/4
L: 1/8
K:C
%%MIDI ratio 3 1
TE>G TF3/A/|

the length of notes E and G are not adjusted for broken rhythm
and remain as equal values.
Analysis:  the handling of broken rhythms is fairly complicated
in the file store.c.  The location of E and G are maintained by 
variables v->thisstart, v->thisend and v->laststart, v->lastend
by the functions marknotestart, marknoteend and marknote. (This
also allows the handling of chords too.) When a > or < is encountered
a number of flags (brokenpending, brokentype, brokenmult) are set
by the function event_broken.  The function marknotend checks
these flags and calls brokenadjust to adjust the lengths of E and
G using the stored variables v->thisstart, v->thisend etc.  Trilling
is handled by the function dotrill() which expands note E
into a sequence of notes whose length depends upon the length
of E and the tempo. In this example, the expansion is done
prior to encountering the broken rhythm indicator >. After
G is encountered, the lengths of the notes are adjusted for
broken rhythm. Unfortunately, there is a bug in dotrill, and
marknotestart was called for the last note in the trill sequence
rather than the first note.  The problem was fixed by changing
this code. Note that in the above example, the number of notes
in the trilled E and the trilled F are different. This is
because E is not effectively expanded until after it was
trilled. There is no easy fix to this problem other than 
avoiding mixing notations for broken rhythms.

trilled F are different.
than the first note


September 22 2006

Midicopy.c: to avoid problems with some systems, the byte val
for the runtime string 
-replace trk,loc,val
is read as an integer (%d) instead of a char (%c).

 
September 22 2006

Abc2abc, abc2midi etc. does not recognize "clef=G".
In the following example,


X:1
T: clef problem
M: 2/4
L: 1/8
K: Am clef=G
"Am"ABCD|ABCD|

The following message appears:
%Warning : cannot recognize clef indication
K:Am clef=G

Fix: added checks for clef=g or clef=G in the function
isclef() in parseabc.c


September 23 2006

Abc2abc removes blank lines from abc files. (These
blank lines are usually to encircle comments between
tunes in a multitune file.

Analysis: whenever parseline() (in parseabc.c) detects
a blank line, it calls event_blankline(). In abc2abc,
event_blankline() only emits a blank line if the flag
newbreaks is set. Unfortunately, this parameter is used
for another purpose (i.e. reformating an abc file with
new linebreaks every X bars using the -n X runtime parameter).
This has nothing to do with handling already existing
blank lines. Since event_blankline is called only when
there is a blank line, it appears that the condition on
the flag newbreaks should not be present.

Fix: the condition statement was removed. A blank line will
always be issued. Note that event_blankline also closes
the tune and parser for that tune as usual.



September 25 2006

Abc2midi: some users have complained about the unnecessary
warnings and error messages issued by abc2midi. For example
standard music practice does not require a leading repeat
mark |: to be placed at the beginning of the sheet music and
it is commonly left out in many abc transcriptions. Abc2midi
typically warns the user that it has been left out but does
the correct thing. Furthermore, the placement of a fermata sign
will likely cause a message that a bar has too many beats.
Too placate the users,

I have introduced a new runtime parameter -quiet which will 
suppress all these messages. 

Note abc2midi parses the abc file in two passes and may not
always handle assumed repeats correctly. For example if the
tune begins with an anacrusis, abc2midi does not attempt
to figure out whether the |: should be placed before or
after the anacrusis. (This depends upon the placement of the
end repeat.) In multipart files, abc2midi fails to place
a starting repeat sign.

In the case of multivoiced files, loss of synchronization between
voices can occur because of user mistakes or because abc2midi made 
the wrong assumption.  (For example, search for the word fermata 
in this file.)

Though attempts have been made to standardize the abc music notation
language, it is a living language and various variants are introduced
now and then. Abc files that have been notated many years ago are
not updated to correct for the various problems that are introduced by
these new features. There is a variety of software to process abc files,
but many of the developers have moved to other things and fail to
maintain their software.  Though these messages are an inconvenience
to users they are useful in diagnosing problems when the MIDI file
does not sound correctly.


September 26 2006

Abc2midi: now supports linear temperament scale using code contributed
by Magnus Jonsson.  New %%MIDI commands are introduced to change the
temperament.

%%MIDI temperamentlinear octave_cents fifth_cents

where the variables specify the size of an octave and size
of a perfect fifth in cents where one cent is 1/100 of
a semitone or 1/1200 of an octave.

%%MIDI temperamentlinear 1200.0 700.0

produces the equal tempered scale.

%%MIDI temperamentlinear 1200.5 698

produces a slightly stretched octaves and narrowed fifths.
Quoting the Help for the program Scala 
http://www.xs4all.nl/~huygensf/scala/

A linear temperament is a cycle or chain of one particular interval,
called the generator or formal fifth. Whenever by doing so a pitch
originates that is outside the range of one formal octave (interval of
equivalence), it is "wrapped" back inside by subtracting the formal
octave value. Examples of this kind of scale are the Pythagorean scale
generated by a pure fifth, and regular meantone scales.

Implementation:
store.c :
  added new globals temperament, octave_size, fifth_size
  which are set by %%MIDI temperamentlinear. Created a new function
  pitchof_b() which is similar to function pitchof() but also returns
  a pointer pitchbend. Pitchof_b() would eventually replace all calls
  to pitchof(). The function pitchof_b() applies the linear temperament
  scale if the global variable temperament is set. It updates the
  pointer pitchbend unless it was already set by a microtone.

  To store the pitchbend value of every note a new array bentpitch
  was added to the other arrays (pitch, num, denom, feature).
  The function event_note transfers the pitchbend value to bentpitch,
  so it can be used by writetrack() in the second pass (in genmidi).

  Other functions that had to be updated were doroll, dotrill, 
  makecut, and doornament.

genmidi.c :
  Added global array current_pitchbend[], which maintains the
  current pitchbend for each channel. It is initialized to 8192
  (neutral value) by starttrack. The pitchbend value is now
  transferred to the function midi_noteon(). It will issue
  a pitchwheel command anytime a new pitchbend value occurs
  for the specific channel. Other functions like noteon_data()
  and save_note() also carry the parameter pitchbend.


Limitations: linear temperament is not applied to guitar gchords.


October 3 2006

Abc2midi: in order that microtones are applied correctly to
in voice chords such as [CEG], it is necessary that each note
in the chord be played on a separate MIDI channel.  A new MIDI
command "makechordchannels n" has been introduced for allocating
MIDI channels specifically for the handling of chords. The
value of n specifies the number of channels to be allocated.
It should be one less the maximum number of notes in the chord.
Note that since you have only 16 channels in a MIDI file and
once the channel has been allocated it is unavailable for
any other use. You need to do a separate allocation for each
voice containing such chords.

Implementation:
In genmidi.c, introduced a global array chordchannels[] which
is used to store the channel numbers for handling chords.
chordchannel[0] is the channel number normally used for
handling notes for that voice. Introduced a global integer
nchordchannels storing the number of channels in chordchannels[].
Created a new function makechordchannels() for assigning
these channels to chordchannels[]. Makechordchannels also
sets the channels program (musical instrument) to the current program
for the voice. (If you need to know the channel numbers that
have been assigned, run abc2midi with the -v option (verbosity)).
Created another branch in the function dodeferred() for handling
the MIDI command makechordchannels(). 



October 15 2006

The following file was not parsed correctly.

X:1
T: 2 or 3 tracks
M: 3/4
L: 1/8
K:G
g2| g2 fe b2|
V:2
A2 |[B4E4] G2|

Analysis: a bug I introduced recently resulted in the voice number (2)
not being read correctly.

Fix: in the function parsevoice() in parseabc.c, I changed the
statement
if (isnumberp(&s)) {
to 
if (isnumberp(&s) == 0) {

apparently, this function returns 0 if the string contains a
positive number and 1 otherwise.


October 27 2006

Abc2midi: using the command %%MIDI drumon causes the error
MIDI read/write error : error: MIDI channel greater than 16
and abc2midi fails.

This is another bug I had introduced. Adding the pitchbend
parameter 8192 to save_note in function dodrus() in genmidi
fixes this problem.


October 27 2006

Abc2abc transpose places spurious spaces between notes
breaking up the beaming pattern. For example for,
X: 1
T: beaming error
L: 1/8
M: 4/4
K: Eb
^C,,2 z2 z^C,/D,/ =E,/^F,/G,/=A,/ | B,/=A,/G,/^F,/ G,/=E,/^C,/D,/
E,/F,/G,/A,/ B,/A,/G,/A,/ |

abc2abc beaming.abc -t 1 produces

X: 1
T:beaming error
L:1/8
M:4/4
K:Emaj
^^C,,2 z2 z^^C,/2 D,/2 ^E,/2^^F,/2 G,/2^A,/2 | B,/2^A,/2G,/2^^F,/2  G,/2^E,/2^^C ,/2 D,/2
 E,/2 F,/2 G,/2 A,/2  B,/2 A,/2 G,/2 A,/2 |

(note all the spaces between the notes in the second line of the body).

Analysis: the local variable mult in event_note1() in toabc.c is
used before it is defined.

Fix: event_note1() now sets it to zero in case it is not set elsewhere.




November 3 2006

Abc2midi bug: pitches are incorrect for staccato notes. eg

X:1
T: staccato bug
M:3/2
L:1/2
Q:1/4=70
%%MIDI program 16
%%MIDI nobeataccents
K:C
=B=c=d | .=B.=c.=d |

The pitches of the last three notes have been affected by
a pitchbend.

Analysis: This is a bug I recently introduced. The bentpitch[] feature
was not set to 8192 for staccato notes.

Fix:  added the following line
  bentpitch[notes] = active_pitchbend;
before
  addfeature(NOTE, ...);

in event_note() in store.c. Also added it in doornament().



November 3 2006

Abc2midi bug: the following file causes the error message
MIDI read/write error : error: MIDI channel greater than 16
to appear.

X:1
T: makechord
M:3/2
L:1/2
Q:1/4=70
V:1
%%MIDI nobeataccents
%%MIDI program 16
%%MIDI makechordchannels 2
V:2
%%MIDI program 16
%%MIDI makechordchannels 2
V:3
%%MIDI program 16
%%MIDI makechordchannels 2
K:C
%
V:1
[c'_/e'g']
V:2
[c_/eg]
V:3
[C_/EG]


Analysis: there was a missing parameter (bentpitch) in the function
call to noteon_data() when channel == 9. As a result the function
noteon_data() received a meaningless channel number. However,
since channel 9 is reserved for percussion, it should never have 
been assigned. To fix this problem, the global variable channels[9]
was set to 1 in writetrack() (genmidi.c), so that findchannel()
will not select this channel.


December 9 2006

Abc2midi bug: the %%MIDI drone command returns an error
MIDI channel > 16.
Fix: missing parameter in function midi_noteon(), pitchbend,
was added.


December 12 2006

Abc2midi bug: split voices does not work correctly when
it is embedded in a part (eg. P:B). For example:

X: 1
T: bad merge
M: 4/4
L: 1/8
K: C
P:A
| C2 D2 E2 F2 | G2 A2 B2 c2 |
P:B
| C2 D2 E2 F2 & C,2 D,2 E,2 F,2 | G2 A2 B2 c2 |

The split voice does not merge correctly in the
above example.

Analysis: not all voices may be indicated in a part. As a
precaution, genmidi calls partbreak which fills in any missing
voices. Unfortunately, split voices are automatically resynced
which causes the voice to be filled in twice.
Fix: a new global array dependent_voice[] was added in 
store.c and linked to genmidi.c. This array contains flags
indicating where the particular voice was a natural voice
created by a voice command (V:) or whether this is a 
split voice dependent on the natural voice. The function
partbreak checks this flag and does nothing if is a
dependent voice.
 

December 21 2006

Voice bug (abc2midi, yaps): the fix described in September 9 2006
caused another bug. For the following example:

X:1
T: noel
M: 2/4
L: 1/4
K: C
V: alpha
C E|D F|
V: beta
A C| G B|

The parser fails to handle nonnumeric voice numbers.
Fix: in line 996 of parseabc.c isnumberp returns 1
if the character string is a positive number and 0 if
it is not. The 0 was replaced with 1 as shown below.
if (isnumberp(&s) == 1) {

December 26 2006

Midi2abc bug. Some music notation programs automatically place
short rests between notes and chords in order to improve the
articulation. Midi2abc is able to ignore these rests using
the -sr parameter as described in the midi2abc.1 documentation.
Unfortunately, this feature does not work correctly when rests
are placed in between chords.

Analysis: the quantize() function decides whether to eliminate
the rest based on the difference between the inter note interval
(note->xnum) and the "on" time of the note (note->play). For
some of the chordal notes, note->xnum is zero since all the notes
in the chord start at the same time. This causes the program
to produce erroneous results.

Fix: a new function xnum_to_next_nonchordal_note() was introduced
to look ahead past all the chordal notes and return the quantized
note interval to the next nonchordal note. The quantize function
uses this value when the -sr option is turned on. (I have
a feeling this fix may not work correctly when the notes in
the chord are not all equal length. In other words I do not
recommend using the -sr option with -splitbars or -splitvoice.)


January 02 2007

Abc2midi bug: %%MIDI trim does not work according to documentation.
The trim command is used to control the articulation of notes.
Like staccato it shortens the playing time of the note,
leaving a silent period before the next note. According to
the documentation the amount shortened should be the trim
fraction time the unit note length. It turns out that
the trim length was not adjusted for the unit note length
so that the following example did not work.

X:1
T: trim
M: 2/4
L: 1/8
K: C
%%MIDI trim 1/2
CDEF|

Fix: store.c was modified so that trim value set is a fraction
of the unit note length as defined by the L: field command.
Note, that if the unit note length is changed again, it is
necessary to reissue another trim command, eg.


X:1
T: trim
M: 2/4
L: 1/8
K: C
%%MIDI trim 1/2
CDEF|
L: 1/16
%%MIDI trim 1/2
CDEF CDEF CDEF CDEF|

Otherwise the trim length will remain unchanged.


January 06 2007

Abc2midi bug: wrong bar count when %%MIDI trim command
mixed with chords. In the following example,

X:1
T: Bad barcount
M: 2/4
L: 1/8
K: C 
%%MIDI trim 1/2
AB CD |AC DF |[A2c2] DF |
[AB]2 [CD]2 |

Abc2midi produces the following warnings:

Warning in line 9 : Bar 2 has 7/4 units instead of 2
Warning in line 10 : Bar 3 has 3/2 units instead of 2

Furthermore, this may throw off the gchord accompaniment
if it exists.

Fix: in writetrack for case CHORDOFF: and CHORDOFFEX:,
the function addunits() is called before trim adjustment
instead of after.


March 15 2007

Abc2midi ends a MIDI track immediately after the last note.
On some MIDI synthesizers, this introduces a small artefact
at the end of the MIDI file. Fix, a short delay of 25 MIDI
pulses is inserted before the end of track. This was incorporated
in the function clearQ() in queues.c.

Midi2abc -mftext mode was modified to report end of track meta
command.


December 09 2007

New feature in abc2midi: the program now recognizes the command

%%propagate-accidentals not

as described in http://abc.sourceforge.net/standard/abc2-draft.html
directive 11.3

This command suppresses propagation of accidentals across a bar.
The commands
%%propagate-accidentals pitch
or
%%propagate-accidentals octave

restores propagation. Presently only octave method is used.

For example:

M:2/4
L:1/8
K:Eb
%%propagate-accidentals not
A =A A2|

A2 is flattened since the natural sign does not propagate.


January 04 2008

Running yaps with the -E option to produce encapsulated
postscript file (.eps) causes the program to crash with
the error message
*** glibc detected *** yaps: double free or corruption (!prev): 0x08d5f390 

Analysis: the program attempts to close the output file twice.
close_output_file was called once by printtune() (when it encountered
a blank line) and again by event_eof() when it encountered an eof.
The operating system does not set the filehandle to NULL after the
file was closed defeating the conditional test in close_output_file.

Fix: after closing the file the file handler is set to NULL.


March 09 2008

Midi2abc: added a new option -title for providing the title
of the tune to insert in the abc file.

June 07 2008

Abc2midi: introduced a warning for chords containing
unequal notes (eg. [c2e] will cause a warning to be issued).
The warning was added in writetrack in genmidi.c. In
order to get a reasonable output, the incorrect chord
will be played as [c2e2]. (The length of the first note
dominates.)


June 13 2008

Abc2midi: produces a warning "Different length notes in tuple"
when one of the notes in the tuple is a chord. eg.
X:1
T: triplet chord
M: 2/4
L: 1/16
K: D
[DF]4 (3[B2d2]c2d2 |

Analysis: the problem was traced to a bug in the function
event_chordoff in store.c which was introduced with the
chord syntax extension described in November 4 2004.
In computing the tuple adjusted note length, the function
always uses chord_n and chord_m parameters even when
they do not apply (equal to 1/1). Fix new local variables
c_m and c_n are introduced which are set to chord_n,chord_m
or num[chordstart] and denum[chordstart] depending on
whether the chord syntax extension is used or not. The
tuplet adjusted note length is computed from c_n and c_m.

It was also necessary to change event_note so that
tuples are processed for chords too.

June 14 2008

Abc2midi: ornaments (eg ~G3) does not work correctly for
default length other than 1/8 (L: 1/8). Analysis, doornament
(in store.c) assumes L:1/8 for dotted quarter notes. This was fixed.
 


June 24 2008

Abc2midi: new feature. The %%MIDI drum line can sound quite
monotonous if it is repeated each bar. To circumvent this problem
a new MIDI command
%%MIDI drumbars n
where n is a small number will spread out the drum string over
n consecutive bars. By default drumbars is set to 1 maintaining
compatibility with existing abc files. You should take
care that the drumstring is evenly divisible between the
drumbar bars. Also the time signature should not change
between bars in a drumbar unit.

Sample usage:

X:1
T: splitting a drum string into two bars
M: 2/4
L: 1/8
K: G
%%MIDI drum zdzdzdzd 39 59 50 60
%%MIDI drumon
z4| z4| z4| z4|
%%MIDI drumbars 2
%%MIDI drum zdzdzdzd 39 59 50 60
z4| z4| z4| z4|



Implementation: All the changes were confined to genmidi.c
Two new variables drumbars and drumbarcount are introduced.
Drumbars modifies drum_denom in set_drums. (This changes 
the duration of a unit drum hit.) The function checkbar resets
the drum_ptr every drumbars using the drumbarcount variable.

July 2 2008

Regarding the drumbars implementation it is necessary
to reset drumbarcount to 0 in writetrack after drumbars is
initialized back to 1.


July 17 2008

Abc2midi bug: the following sample causes abc2midi to issue
a warning

Warning in line 9 : Bar 0 has 10 units instead of 6 in repeat

X:1
T: meter change
M:5/8
L:1/8
K:C
%
|: [M:6/8] D6 &\
[M:6/8] E6 |
[M:4/8] F4 :|

Analysis: the warning is issued when writetrack is processing
track 2 which is the split voice track during the repeat.  The
two [M:6/8] field commands ensure that the split voice track
also sets the meter to 6/8 time. However the split voice track
was not reset to [M:4/8] unless we do it explicitly with
[M:4/8] F4 & [M:4/8] z4|. Store.c/sync_voices inserts a required
rest z4 into bar 2 of the split voice but it does not include
a time signature command which is needed to ensure that 
genmidi/checkbar will process the bar correctly.

Fix:

Added 

    case TIME:
       addfeature(feature[j], pitch[j], num[j], denom[j]); /* copy feature */
       break; /* [SS] 2008-07-17 */

into the code of sync_voices.


July 17 2008

Abc2abc: removed the space between X: and the reference number.



July 21 2008

Removed all static declarations in parseabc.c
In parsekey(str) initialized the local string
clefstr and modestr.

July 21 2008

Abc2midi bug: key signature and accidental propagation
applied to drum channel. In the following example,

X:1
T: drum key
M: 4/4
L: 1/8
K: A
V:1
Z|ABcd efga|
V:2
%%MIDI channel 10
G,, ^F,, z1 F,, E,, ^D,, z2|G,, ^F,, z1 F,, E,, ^D,, z2|

voice 2 is assigned to the drum channel so the notes
G,, ^F reference individual drum instruments rather than
pitches. Since the key signature is A major (F#, C# and G#),
event_note automatically raises G and F one semitone
and propagates ^F across the bar. This is not desired
for the drum channel.

Fix: in store.c, a new variable, int drumchannel was
added to struct voicecontext. It is initialized to 0.
When event_specific handles a %%MIDI channel 10,
drumchannel is set to 1. For other channels it is set
to 0. A new function barepitch() was created from
the function pitchof_b. This function does not apply
the key signature or note propagation. The function
event_note now checks whether v->drumchannel is set and calls
barepitch() instead of pitchof_b() in such circumstances.
(See Cuckoo's Nest in demo.abc for a sample.) 


August 4 2008

Midi2abc: new feature. The -mftext prints the name of
the drum patch for channel 10 and noteon commands.


August 11 2008

Abc2midi bug: The following abc file cause abc2midi
to halt with a segmentation error.

X:1
T: trim problem
M:3/4
L:1/4
%%MIDI trim 1/8
K:C
ABC|DEF|

Analysis: the error occurs in event_specific when the function 
   addfeature(SETTRIM, 1, 4*a, b*v->default_length);
is called. The voice structure does not exist causing
a segmentation error when v->default_length is addressed.
(v does not exist until the body of the abc file.)
Fix: if v does not exist, addfeature(SETTRIM,...)
get the default_length from global.default_length.
Comment: event_refno creates the voice structure and
then destroys it when it calls startfile(). This does
not cause a problem but makes the code obscure. 


August 12 2008

Another abc2midi trim bug: the following warnings are

Warning in line 9 : unequal notes in chord 7/8 versus 1/1
Warning in line 9 : unequal notes in chord 3/4 versus 1/1

are the produced from this file.

X:1
T: trim problem
M:3/4
L:1/4
K:C
%%MIDI trim 1/8
%%MIDI makechordchannels 2
CD[ABc]|

Analysis: the problem was traced to the function writetrack in genmidi.c.
The note length is trimmed inside the switch case for NOTE:. The
length of the trimmed  note is saved and trimming is reapplied to this
length for each note of the chord.  This bug was probably introduced
in June 7 2008 in order to make the the first note in a chord to dominate.
Fix: new variables tnote_num and tnote_denom are introduced specifically
for note trimming.

August 12 2008

Still another abc2midi trim bug. For split voices, the notes are
trimmed in only one voice. In the following example, the notes
CDE are trimmed but not EFG.

X:1
T: another trim problem
M:3/4
L:1/4
%%MIDI trim 1/8
%%MIDI makechordchannels 2
%%MIDI program 20
K:C
CDE & EFG| 

Fix: another case statement SETTRIM: was added to sync_voice() in store.c
Note that %%MIDI trim command only applies to a single voice.


September 17 2008

Abc2midi bug: wrong bass note when expanding guitar chord with inversion.
The bass note should be the note after the / rather than the pitch
of the chord. Thus "C/E" should be represented by E,,x [G,E,C,] rather
than C,,x [G,E,C].

Fix: case 'f' in function dogchords() in genmidi.c no tests for
an inversion. If an inversion is indicated, the bass note is changed.
  

September 18 2008

Abc2midi new feature: added the run time option (-NCOM) to suppress
some textual comments in the output midi file. 

September 24 2008

Abc2midi bug: for multitune abc files, the temperament is not automatically
turned off at the start of the next tune. Fix: temperament is initialized
to zero in startfile() in store.c

September 24 2008
Abc2midi new behaviour: the 'strange note' in a gchord is no longer
included in the chord. (i.e. F/G is now expanded as G,, [F,A,C] instead
of G,, [G,,F,A,C]. (Suggested by H. Lacerda). Change made in
configure_gchord() in genmidi.c


September 28 2008
Abc2midi bug when selecting tune from collection. When the abc2midi
is used to create a single MIDI file from an abc file containing
a collection of tune which contains %%MIDI commands, abc2midi
numerous warnings 'cannot handle this MIDI directive here' for
the non-selected tunes. For
example
abc2midi balk2.abc 237 -v
Reference X: 180
Warning in line 9 : cannot handle this MIDI directive here
Reference X: 181
Warning in line 34 : cannot handle this MIDI directive here
Warning in line 35 : cannot handle this MIDI directive here
Warning in line 36 : cannot handle this MIDI directive here
Warning in line 37 : cannot handle this MIDI directive here
Reference X: 182
[snip]
This obscures real warnings from the selected tune.

Analysis: the messages are issued by event_specific_in_header()
which was designed to process MIDI commands which appear before
the first tune (X: refno), in the file. The function is called
when dotune == 0, which is true for unselected tunes. This means
that some of the directives in the nonselected tunes (e.g. nobarlines,
fermatafixed, ...) can affect the selected tune. Furthermore,
some other MIDI directives which are not recognized by the function
cause the above warnings to occur. In the following example
(headercommands.abc),

%%MIDI nobarlines
X:1
T: tune 1
M: 2/4
K:G
%%MIDI barlines
%%MIDI program 100


X:2
T: tune 2
M: 2/4
K: F
etc.

the directive %%MIDI nobarlines appearing before the first tune
is to apply to all tunes in the abc file except where specifically
overrided (in tune 1). When we run

abc2midi headercommands 2

we are expecting %%MIDI nobarlines to apply to tune 2. However,
this was changed in the nonselected tune 1 and the %%MIDI program 100
command causes the message 'cannot handle this MIDI directive here'.

Fix: a new global variable started_parsing initialized to zero was
introduced in store.c. When event_refno is invoked, the variable
started_parsing is set to 1. The function event_specific_in_header
is called only if started_parsing is still 0.

 
February 20 2009
Yaps bug. The -E option (for encapsulated postscript) does
not compute the boundingbox correctly if the abc file contains
note fields (N:). eg.

X:1
T:A test
N:A note
K:C
AB cd ef ga | \
AB cd ef ga | \
AB cd ef ga | \
AB cd ef ga |
AB cd ef ga | \
AB cd ef ga | \
AB cd ef ga | \
AB cd ef ga |]

The bottom part of the last staff is cutoff.

Analysis: the function tuneheight() in drawtune.c did not
account for space used by the note fields.

Fix: added several lines of code to the function to scan
through the notefield list and adjust the page height.


March 17 2009

Abc2midi new feature: a new command
%%MIDI gchordbars n
was introduced that acts in the same manner as %%MIDI drumbars (see
June 14 2008).  but applies to the gchord string instead. The command
spreads the gchord string over n consecutive bars.  In the following
example:

X:1
T: gchordbars
M: 2/4
L: 1/8
K: C
%%MIDI gchordbars 2
%%MIDI gchord fzczIzHz
"C" c2 "G" c2|"C" g4|"G"c4|g4|

fzcz applies to bars 0 and 2 while IzHz applies to bars 1 and 3.
For this function to work properly, it is important that
the length of the gchord string be exactly divisible by n
where n is the number of bars that the gchord string applies to.
If gchordbars is not specified, it is assumed to be one bar.

Implementation is similar to drumbars. New variables gchordbars
and gchordbarcount were introduced in genmidi.c


June 23 2009

Abc2midi does not attempt  to fill in missing left repeats |:
in multipart and multivoiced files. New code was introduced
to solve this problem. The functions scan_for_missing_repeats(),
add_missing_repeats(), clear_voice_repeat_arrays() was added
to store.c.


July 22 2009

Abc2midi produces irrelevant error messages
 %%MIDI drumon must occur after the first K: header
when extracting a particular tune in a file containing a
collection, eg.
abc2midi balk1.abc 10

Fix: in event_specific() in store.c now check the flag dotune.
 if (strcmp(command,"drumon") == 0 && dotune) {
   addfeature(DRUMON, 0, 0, 0);
   etc.

July 22 2009

Abc2midi produces the error message
 found another |: after a |:
for the file

X:1
T:title
M:4/4
L:1/4
K:C
A2 c2 :: d2 c2 :|

Fix: set bar_rep_found[voicenum] = 1 after inserting missing BAR_REP.



September 20 2009

Abc2midi bug: the following file produces a faulty midi file.  

X:1
T: bug
M: 4/4
L: 1/4
K: G
V:1
%%MIDI control 7 49
C4|\
%%MIDI control 7 48
C4|\
%%MIDI control 7 47
C4|\
%%MIDI control 7 46
C4|
%%MIDI control 7 45

Analysis: As seen below track 1 which contains only control codes is 56 beats
long while track 2 which contains the notes is only 16 notes.
The control codes in track 1 are not placed at the correct times.


ur@localhost abc]$ midi2abc err1.mid -mftext
Header format=1 ntrks=2 division=480
Track 1 contains 57 bytes
  0.00   Metatext tempo = 120.00 bpm
  0.00   Metatext key signature G (1/0)
  0.00   Metatext time signature=4/4
  0.00   Metatext (Seqnce/Track Name) bug
  0.00   CntlParm  1 Volume = 49
  4.00   CntlParm  1 Volume = 48
 12.00   CntlParm  1 Volume = 47
 24.00   CntlParm  1 Volume = 46
 40.00   CntlParm  1 Volume = 45
 56.05   Meta event, end of track
Track 2 contains 67 bytes
  0.00   Metatext (Seqnce/Track Name) bug
  0.00   CntlParm  1 Volume = 49
  0.00   Note on   1   c4 105
  4.00   Note off  1   c4   0
  4.00   CntlParm  1 Volume = 48
  4.00   Note on   1   c4 105
  8.00   Note off  1   c4   0
  8.00   CntlParm  1 Volume = 47
  8.00   Note on   1   c4 105
 12.00   Note off  1   c4   0
 12.00   CntlParm  1 Volume = 46
 12.01   Note on   1   c4 105
 16.00   Note off  1   c4   0
 16.01   CntlParm  1 Volume = 45
 16.06   Meta event, end of track

Explanation: when abc2midi produces a type 2 MIDI file (multitracks),
track 1 only contains comments, time signature and control codes
while the other tracks contain the actual note-on/note-off codes
corresponding to the different voices. When abc2midi produces a
type 1 MIDI file corresponding to the bare bones abc file (no
voices or accompaniment), then there is only one track and
all note-on/note-off commands are in the same track. For
historic reasons, MIDI control codes are placed in both
track 1 and track 2 for voice 1, and the control codes for the
other voices are put into their own track. (I dare not
change this since it could cause a problem somewhere else.)
However, there appears to be a bug since the times of the
control codes seem to be incorrect.

Fix: I reset delta_time to 0 at the end of the function
genmidi.c/dodeferred(). It seems to fix the problem.
 

October 23 2009

Abc2midi bug: the function dograce fails to adjust the length
of the host notes in a chord. In the following example

X:1
T: grace chord problem
M: 2/4
L: 1/8
K: C
A2 B2|{edc}[cg]2 d2|

The chord [cg]2 is not shortened by the length of the grace
note {edc}; however if the chord is expressed as  [c2g2] the
chord is shortened correctly.

Analysis:the function applygrace_new() in store.c  fails to
recognize the CHORDOFFEX feature which is used to express chords
of this type. Fix: the function now checks for that feature.

December 12 2009

Abc2midi bug: dynamics (eg !pp!) deletes previous rest.
In the following example:

X:1
T: dynamic problem
M:4/4
L:1/4
K:C
|ABcd|Az3|!pp!dcBA|]

The rest z3 is destroyed by the !pp! indication. Analysis:
this bug was introduced on September 20 2009 when
delta_time was reset to 0 in dodeferred(). Fix, a global
variable rest_pending was added to indicate that a rest
has not yet been instantiated in the MIDI file and not
to reset delta_time. The variable rest_pending is set to
zero for every NOTE, TNOTE  or CHORDON feature but set
to 1 for a REST feature. 
**note** this change was undone Feb 4 2010

 
December 18 2009

Abc2midi bug: split voices (also known as voice overlay) works
incorrectly when there are in repeats. For example

X:1
T: voice overlay in repeats 
M: 2/4
L: 1/4
K: G
|:C D &b/c/d/e/| F G:|

used to work but now does not repeat the voice overlay. (It does not
matter whether an opening repeat |: is present.)  However, if you
put a V:1 after K:G as shown here

X:1
T: voice overlay in repeats
M: 2/4
L: 1/4
K: G
V: 1
|:C D &b/c/d/e/| F G:|

it then works correctly.

Analysis: this is a new bug that was introduced after the changes
on June 23 2009. The function scan_for_missing_repeats corrupts the
feature arrays. Here is the feature arrays just before calling
scan_for_missing_repeats.
0 LINENUM   2 0 0 0 
1 TITLE   0 0 0 0 
2 LINENUM   3 0 0 0 
3 LINENUM   4 0 0 0 
4 LINENUM   5 0 0 0 
5 DOUBLE_BAR   0 0 0 0 
6 LINENUM   6 0 0 0 
7 MUSICLINE   0 0 0 0 
8 BAR_REP   0 0 0 0 
9 NOTE   60 8192 1 1 
10 NOTE   62 8192 1 1 
11 SINGLE_BAR   0 0 0 0 
12 VOICE   2 0 0 0 
13 DOUBLE_BAR   0 0 0 0 
14 BAR_REP   0 0 0 0 
15 NOTE   83 8192 1 2 
16 NOTE   72 8192 1 2 
17 NOTE   74 8192 1 2 
18 NOTE   76 8192 1 2 
19 SINGLE_BAR   0 0 0 0 
20 VOICE   1 0 0 0 
21 NOTE   66 8192 1 1 
22 NOTE   67 8192 1 1 
23 REP_BAR   0 0 0 0 
24 VOICE   2 0 0 0 
25 REST   0 0 2 1 
26 REP_BAR   0 0 0 0 
27 VOICE   1 0 0 0 
28 MUSICSTOP   0 0 0 0 
29 LINENUM   7 0 0 0 
30 VOICE   2 0 0 0 
31 SINGLE_BAR   0 0 0 0 

Here is the feature array afterwards.

1 TITLE   0 0 0 0 
2 LINENUM   3 0 0 0 
3 LINENUM   4 0 0 0 
4 LINENUM   5 0 0 0 
5 DOUBLE_BAR   0 0 0 0 
6 LINENUM   6 0 0 0 
7 MUSICLINE   0 0 0 0 
8 BAR_REP   0 0 0 0 
9 NOTE   60 8192 1 1 
10 NOTE   62 8192 1 1 
11 SINGLE_BAR   0 0 0 0 
12 VOICE   2 0 0 0 
13 DOUBLE_BAR   0 0 0 0 
14 BAR_REP   0 0 0 0 
15 NOTE   83 8192 1 2 
16 NOTE   72 8192 1 2 
17 NOTE   74 8192 1 2 
18 NOTE   76 8192 1 2 
19 SINGLE_BAR   0 0 0 0 
20 VOICE   1 0 0 0 
21 NOTE   66 8192 1 1 
22 NOTE   67 8192 1 1 
23 BAR_REP   0 0 0 0 
24 REP_BAR   0 0 0 0 
25 VOICE   2 0 0 0 
26 REST   0 0 2 1 
27 REP_BAR   0 0 0 0 
28 VOICE   1 0 0 0 
29 MUSICSTOP   0 0 0 0 
30 LINENUM   7 0 0 0 
31 VOICE   2 0 0 0 
32 SINGLE_BAR   0 0 0 0 

Note that feature BAR_REP was placed at 23 immediately before
REP_BAR. The problem is that the first VOICE 1 feature was found
after the first bar was processed and a split voice (VOICE 2)
was generated. scan_for_missing_repeats automatically places
a BAR_REP 3 indices past (24) the VOICE 1 (20) command which it expects
to be before the first note. This messes up the feature array.
If the abc file has a V:1 after the K: then the BAR_REP is placed
at the right place.

Fix: Always place a VOICE 1 command after the first K: in the
abc file. In event_key (store.c) addfeature(VOICE, ...) after
getvoicecontext(1) if not inside body of abc file. (There may
be a K: indication inside another voice and we do not want
to automatically switch to VOICE 1.) ***This change was
removed on December 21 ***.



December 20 2009

abc2midi bug:


X:1
T: embedded V: command and voice overlay
%%MIDI program 2 41
K:C
[V:1] | cde2 & egc'2 | C8 & z4 e'4 | c8 :|
[V:2] |C,D,E,2 | C,,8 | C,8  :|

the voice overlay gets garbled but if we write
V:1
 | cde2 & egc'2 | C8 & z4 e'4 | c8 :|
V:2
 |C,D,E,2 | C,,8 | C,8  :|

it works fine. In scan_for_missing_repeats changed
 add_leftrepeat_at[num2add] = voicestart[voicenum]+3; 
to
 add_leftrepeat_at[num2add] = voicestart[voicenum]+2; 


December 21 2009

abc2midi bug: abc2midi fails to convert the simple file

X:1
T: one track
M: 2/4
L: 1/4
K: C
CD|EF|GA|Bc|

Fix: removed insertion of VOICE feature after the event_key.
instead event_key remembers the location to place a VOICE
feature in the variable v1index in case a event_split_voice
is encountered and voicesused is 0.
 

January 05 2010

abc2midi bug: loss of voice synchronization when stacatto,
chords and dynamics mixed. In the following example,

X:1
T:staccato and dynamics
M:4/4
L:1/8
K:G
V:1
C4 G4|A4 G4|
V:2
[.D4.G4]!p!C2C2|D4F4|

the chord [.D4.G4] is one beat two short causing a loss of
synchronization between the two voices. However if abc2midi
is run with the option -NFNP which causes abc2midi to ignore
the dynamic indication !p!, the voices remain in synchronization.

Analysis, the stacatto markings embedded in a chord causes
a REST feature to be embedded in the chord.
21 CHORDON   0 0 0 0 
22 REST   62 0 2 1 
23 NOTE   62 8192 1 1 
24 NOTE   67 8192 1 1 
25 CHORDOFF   0 0 2 1
normally a stacatto places the rest after the shortened note
but for chords it is done differently. (It is rather unusual
to find stacatto markings inside a chord.) Nevertheless, the
notes are still played with the rest following. (Another
quirk of abc2midi.) 
Fix: in writetrack() (genmidi.c) rest_pending is no longer
reset to 0 if the note is inside a chord.
**note** this change was undone Feb 4 2010


January 06 2010

Abc2midi new feature: a missing Fermata in a multivoiced tune
can cause a loss of synchrony between the voices. As an aid
in detecting this problem, a new run parameter was introduced.
-NFEM will cause abc2midi to ignore all fermata markings in
the abc tune.

Implementation: introduced a new global variable ignore_fermata
which is normally set to 0 into store.c. If it is nonzero, then 
decorators[FERMATA] is ignored.


January 10 2010

Abc2midi new feature: though abc2midi should shorten the notes
preceded by a grace sequence in some circumstances it may fail
to shorten it the right amount causing the voice track to lose
synchrony with the other tracks. As an aid to detecting this
problem, a new run parameter was introduced. -NGRA will cause
abc2midi to ignore all notes in a grace sequence (enclosed
in curly brackets {}).

Implementation: a new global variable ignore_gracenotes (normally
set to 0) was introduced in store.c. If both ignore_gracenotes
and gracenotes are nonzero, then event_note ignores the 
current note.


January 14 2010

Abc2midi bug: the -NGRA option messes up the output abc file
for the following example. Track 2 is shorter than track 1.


X:1
T:-NGRA option makes a mess
L:1/2
M:2/2
K:C
V:1
|: {d-}[de]f|ga  :|
V:2
|: {E-}[EF]G|AB :|

Analysis: (You should review the operation of dotie and tiefix as described
in this file at February 12 2005. Note the many other problems that
were encountered with this code.) Before calling tiefix, the feature
array looks as follows.

(gdb) call dumpfeat(0,notes)
0 LINENUM   3 0 0 0 
1 TITLE   0 0 0 0 
2 LINENUM   4 0 0 0 
3 LINENUM   5 0 0 0 
4 LINENUM   6 0 0 0 
5 DOUBLE_BAR   0 0 0 0 
6 LINENUM   7 0 0 0 
7 VOICE   1 0 0 0 
8 LINENUM   8 0 0 0 
9 MUSICLINE   0 0 0 0 
10 BAR_REP   0 0 0 0 
11 GRACEON   0 0 0 0 
12 TIE   0 0 0 0 
13 GRACEOFF   0 0 0 0 
14 CHORDON   0 0 0 0 
15 NOTE   74 8192 2 1 
16 NOTE   76 8192 2 1 
17 CHORDOFF   0 0 2 1 
18 NOTE   77 8192 2 1 
19 SINGLE_BAR   0 0 0 0 
20 NOTE   79 8192 2 1 
21 NOTE   81 8192 2 1 
22 REP_BAR   0 0 0 0 
23 MUSICSTOP   0 0 0 0 
24 LINENUM   9 0 0 0 
25 VOICE   2 0 0 0 
26 LINENUM   10 0 0 0 
27 MUSICLINE   0 0 0 0 
28 BAR_REP   0 0 0 0 
29 GRACEON   0 0 0 0 
30 TIE   0 0 0 0 
31 GRACEOFF   0 0 0 0 
32 CHORDON   0 0 0 0 
33 NOTE   64 8192 2 1 
34 NOTE   65 8192 2 1 
35 CHORDOFF   0 0 2 1 
36 NOTE   67 8192 2 1 
37 SINGLE_BAR   0 0 0 0 
38 NOTE   69 8192 2 1 
39 NOTE   71 8192 2 1 
40 REP_BAR   0 0 0 0 
41 MUSICSTOP   0 0 0 0 
42 LINENUM   11 0 0 0 
43 SINGLE_BAR   0 0 0 0 

Note that that there is a TIE feature enclosed in the GRACEON and GRACEOF
area but there is no NOTE or REST preceding. This is because we ran
abc2midi with -NGRA which had removed all the notes enclosed by the
grace complex.  When dotie, attempts to process the TIE at 12 it fails
to find a NOTE or REST and exits; however when dotie attempts to 
process the TIE as 30, it finds a NOTE in a different voice
at position 21 and all hell breaks loose a big mess.

Fix: to prevent dotie from searching for a NOTE or REST in a previous
voice, we cause a break when feature[TIENOTE] == VOICE.
 while ((tienote > 0) && (feature[tienote] != NOTE) &&
         (feature[tienote] != REST)) {
    tienote = tienote - 1;
    if (feature[tienote] == VOICE) break; /* [SS] 2010-01-15 */
  };
to prevent a TIE from appearing in the first place in a grace
complex when -NGRA was specified we add
if (gracenotes && ignore_gracenotes) return; /* [SS] 2010-01-12 */
in the event_tie() function.

 
 
January 23 2010

Code clean-up to remove the numerous warnings when compiling
with the -Wall compilation flag. genmidi.c, mftext.c, midifile.c,
midifile.h, and store.c were modified. There are still a few
warnings to be checked out later.


February 01 2010

Code clean-up. Removed unused functions -- slurtotie(), applybroken(),
and delendrep() in store.c.



February 01 2010

Abc2midi: support for multivoiced lyrics introduced.
The following tune illustrates multivoiced lyrics.

X:1
T:multivoiced lyrics
M:2/4
L:1/16
K:C
V:1 clef=treble
V:2 clef=treble
%%staves 1 2
V:1
C4 C4 | E4 G4 | c8 |]
w: 1 2 3 4 5
V:2
C4 E4 | C4 B,4 | C8  |]
w: 11 12 13 14 15

A warning "More than one voice with words in" appears.
Though the MIDI file plays properly, the lyrics do not appear
correctly in MIDI file players such as Melody Player.  
It was necessary to some significant changes to
the way the information in the w: field is transferred to 
the MIDI file in order to ensure compatibility.


This section describes how abc2midi treats the w: field in order to
incorporate lyric text into a karoake style MIDI file.  For multivoiced
abc files, abc2midi only handles the lyrics in the first voice. There
is interest in generalizing the program so that it can handle lyrics
in multiple voices which are common in choir music.

Parsing stage (store.c)
------------------------

All lyric text is copied into string array called words
char** words;
which is allocated by checkmalloc(maxwords*sizeof(char)
where maxwords is set to INITWORDS 20.

Each time a w: field is encountered, event_words() in store.c is
invoked and places the string of text in the w: into 
words[wcount] where wcount is incremented. A new feature,
WORDLINE is added to the feature array. The index wcount is
saved in the pitch[] component of the feature arrays.
If there is no continuation, of the w: command, then a
WORDSTOP feature is added to signal the end of the w: field.

In the event that the wcount index reaches maxwords, the function
textextend() doubles the allocated space in words[] and doubles
maxwords.

event_words() also verifies that the lyrics originate from only
one voice.


Creation of the MIDI file (genmidi.c)
-------------------------------------

Genmidi records the MIDI tracks using the function writetrack()
which is called by mfwrite() in midifile.c. Mfwrite() was called
by finishfile() in store.c

There is no one to one correspondence between voices and MIDI
tracks. Some voices may have two tracks. A voice containing
lyrics is mapped into two tracks, one for the notes and another
for the words. Two semaphores, wordson and noteson signal 
writetrack whether to record only the words, only the notes or both
in the track. When writetrack scans through all the features
in the feat array for the specific voice, the NOTE: and TNOTE:
blocks inscribe the words or notes in the MIDI file depending on
the status of the wordson and noteon semaphores.
The gchord accompaniment is placed in a separate
track, gchordtrack which was set by finishfile() in store.c. The
voice containing the gchord indications is passed from store.c
to genmidi.c by means of the variable gchordvoice. The same applies
to drumtrack and dronetrack which rely on drumvoice and dronevoice
to establish the synchronization.

The voice structures used in store.c are not passed to genmidi.c.
All the information for writing the MIDI tracks come from the
above semaphores and the feature,pitch,num,denom arrays which
were passed from store.c. Genmidi does not know whether it
is writing a split voice track (voice overlay) or a regular
voice track. They both look the same.

Genmidi must know the number of tracks in the MIDI file since
this is recorded in the header chunk of the MIDI file. 

The current design of writetrack() assumes that if a lyrics
track exists it must be in track 2 (counting from zero). There
can be only one lyric track. 

To allow more than one lyric track (or voice containing lyrics),
to allow a track to have notes as well as words embedded requires
passing more information to genmidi. For instance we need to know
whether a particular track should record lyrics or notes, and
which voice number is the source. 

Changes:
-------

Created a new function dump_voicecontext() in store.c which prints out
the descriptors of all the voice contexts.
Created a new structure trackstructure in store.c
struct trackstruct {enum {NOTES, WORDS, NOTEWORDS, GCHORDS, DRUMS, DRONE} tracktype;
                    int voicenum;
                   };

and a new array
Created struct trackstruct trackdescriptor[40];
which will be shared with genmidi.c
Created a new function setup_trackstructure() in store.c which
modifies trackdescriptor[].
Modified writetrack() in genmidi.c so that it can write more than
one lyric track.
Introduced an option to write lyrics in either the same track as
the notes or else in a separate track (-STFW).
Added "int hasdrums" to voice structure in store.c.
Added "int hasdrone" to voice structure in store.c
Cleaned out dronevoice, drumvoice, dronetrack, drumtrack, gchordvoice,
gchordtrack variables from store.c and genmidi.c
Removed warning "More than one voice with guitar chords in"

One of the benefits of the new organization is that now you can
have drums and gchords in more than one voice as shown in the
following examples


X:1
T: double gchords
M: 2/4
L: 1/8
K: C
V:1
%%MIDI chordprog 1
%%MIDI gchord fffff
"G" z4|z4|
V:2
%%MIDI chordprog 90
%%MIDI bassprog 90
%%MIDI gchord ghii
"G" z4|z4|



X:1
T: drums in two voices
M: 2/4
L:1/8
K: C
V:1
%%MIDI drum dddddddd 35 36 37 38 35 36 37 38
%%MIDI drumon
|G4|G4|
V:2
%%MIDI drum d2d2 40 41 
%%MIDI drumon
|C2D2|EFGA|





February 04 2010

Abc2midi bug: the following tune is not converted correctly and
the drone is not heard.

X: 129
T: Drone Bug
M: 2/4
L: 1/8
K: Gdor
Q:1/4=140
G\
%%MIDI drone 109 67 67 50 50
%%MIDI droneon
%%MIDI program 41
| c2 c2   |(3cBA GB|c2 c2   |(3cBA GB |
%%MIDI program 111
%%MIDI droneoff

Analysis: this yet another bug introduced by the change in dodeferred
(September 20 2009). (See also December 12 2009 and Jan 05 2010).
Fix: in dodeferred replaced the lines
/*********  delta_time = 0L;  [SS] 2009-09-20 [SS] 2009-12-12*/
  if (!rest_pending) delta_time = 0L; /* [SS] 2009-12-12 */

with
if(wordson+noteson+gchordson+drumson+droneon == 0) delta_time = 0L;

This is a better fix to the bug addressed on September 20 2009.
Removed the variable rest_pending and all references in genmidi.c


February 07 2010

Abc2midi: segmentation errors when applying abc2midi on a large
collection of tunes in an abc file.

Analysis: two array index out of bounds problems  were identified in store.c.
The variable num2add was not reset to 0 in the function scan_for_missing_repeats()
causing the array add_leftrepeat_at[100] to overrun when a large collection
of tunes is processed. (Also many spurious BAR_REP's are inserted into
the feature[] array.) A separate problem caused by insertion of BAR_REPs
is that the part_start[] array no longer points to the correct location
of the PART feature in the feature[] array. This causes fillvoice() to
induce a segmentation error because partlabel contains bad data.

Fix: (1) reset num2add to 0 in scan_for_missing_repeats(), (2) add_missing_repeats()
also increments the addresses in part_start[] after each insert in the
feature[] array. As a precaution, fillvoice() in genmidi() reports an
error if variable partlabel is out of bounds.

As a precaution v1index is also reset to -1 and splitdepth set to 0 in startfile().

 
February 09 2010

Abc2midi bug: drum voice fails to materialize in this tune.

X: 30
T: Drum fails to materialize
M: 8/4
L: 1/8
Q: 1/4=120
K: D octave=1
%%MIDI program 74
%%MIDI drum dzdzdzdzzzzzzdddd 41 43 41 43 45 45 45 45
|:z2g2e2c2 gagfe2c2|\
%%MIDI drumon
z2g2e2c2 gagfe2c2|
c2^d2e2ga g2^d2ccg2|\
c2^d2e2ga g2^d2ccc2:|

Analysis: setup_trackstructure() sets the number of tracks to
1 if there is no drumvoice, gchordvoice, karaoke, or dronevoice.
Unfortunately drumvoice was not set when %%MIDI drumon was
encountered.
Fix: drumvoice is set to v->indexno when %%MIDI drumon is found.




February 23 2010

Abc2midi lyric bug: abc2midi does not treat the double hyphen
in the w: line. In the following example

X:1
T: lyric bug
M: 5/4
L: 1/4
K: G
cdefg
w:one two--three four
the word four should be under the g note not f.

Analysis: the problem occurs in the function getword() in genmidi.c.
After processing a syllable the second 'while loop' skips over
all following control codes. It should increment syllcount when
it encounters a hyphen so that another note will be skipped.


February 23 2010

Abc2abc does not copy s: and d: (symbols and decoration
lines)  but instead puts a blank line. In the following example:

X: 2
T:Aaron's (Rarefied) Air
M:4/4
L:1/4
K:G
D|"G"DG "D7"FA|"G"G2 DD|G3/2A/2 Bc|\
d3d|"C"e3/2d/2 ce|"G"d3/2c/2 Bd|"Am"cB AG|\
s: .. .... .... .... 
"D7"FG AD|

abc2abc example.abc


abc2abc aaron.abc -t 2
X:2
T:Aaron's (Rarefied) Air
M:4/4
L:1/4
K:Amaj
E|"A"EA "E7"GB|"A"A2 EE|A3/2B/2 cd|\
e3e|"D"f3/2e/2 df|"A"e3/2d/2 ce|"Bm"dc BA|\

"E7"GA BE|

Fix: added event_field(key, place) to case 'd' and case 's' in
parsefield(key,field) in parseabc.c.



March 27 2010 - contributed by Bas Schoutsen

abc2midi now reads w: lines starting with hyphens, example:

X:1
K:C
A
w:la-
BcdA
w:---la

X:2
K:C
A
w:la--
BcdA
w:----
BcdA
w:--la 

Fix: introduced new global variable hyphenstate in genmidi.c/getword().



April 08 2010  contribution by Bas Schoutsen

Abc2midi lyric bug: tied notes at the end of the line shifts the lyrics
one place further ahead in the following example.


X:1
T: tie 2
M:4/4
L:1/4
K:C
cdef-|
w:c d e x-
fgag
w:-g a g

Fix: in genmidi.c a new global variable onemorenote
were introduced plus additional code in getword() and checksylables()
to handle the situation.


April 15 2010

Abc2midi: incompatibility with Melody Player, MidiNotate, NoteWorthy Player
and other commercial products. In the following example,

X:1
T:Zijn niet de tien gereinigd
C:Willem Vogel
M:C|
K:C
z4z2A2|[M:5/4]c4A2A2A2|[M:3/4]c4A2|[M:5/4]d4B2B2B2|[M:C|]e4A4|d4G4|c4B2A2|G6G2|A4E2E2|G4D4|E4F4|D8-|D8-|!fermata!D8|]

the time signature 5/4 is placed at the beginning instead of the second
measure.

Analysis, the MIDI meta Text event Time signaturea= 5/4 is
placed at MIDI Time = 1919 instead of MIDI Time = 1920. Apparently, when
the MIDI Player performs the division 1919/480 (where 480 is the number
of divisions per beat) the result is truncated instead of rounded.

Fix, in set_meter(n,m) defined in genmidi.c, the last statement
was changed to

mf_write_meta_event(delta_time, time_signature, data, 4);

(delta_time replaces 0L.)

**Note** this change was retracted on July 07 2010 and a
different fix was introduced.

April 21 2010

Abc2midi bug: The fix described on April 15 2010 introduced a more
serious bug. In the following example

X: 15
T: Accompaniment starts at the wrong time
M: 2/4
L: 1/8
K: Am
%%MIDI program 57
| CDEF|CDEF| CDEF|CDEF|
M:2/4
%%MIDI drum dddz 35 48 60
%%MIDI drumon
%%MIDI gchord fczz
%%MIDI bassvol 40
%%MIDI chordvol 40
|"D" dcBd       |d2B2      |cBAc      |B2A2      |\
     z2d2-      |d2B2      |c4        |B2A2      |

Both the drum and chordal accompaniment start 4 bars late.
If the second M:2/4 indication is left out, the accompaniment
starts at the correct time.

Fix: in set_meter() the change
if (noteson) /* [SS] 2010-04-21 */
  mf_write_meta_event(delta_time, time_signature, data, 4); /* [SS] 2010-04-15 */
else
  mf_write_meta_event(0L, time_signature, data, 4); /* [SS] 2010-04-15 */

seems to fix the problem.

**Note** this change was retracted on July 07 2010 and a
different fix was introduced.

May 08 2010

Abc2midi new feature: the abc draft standard 2.0
 http://abc.sourceforge.net/standard/abc2-draft.html#K:%20-%20key
allows one to explicitly define all accidentals of a key signature
using the notation
K:<tonic> exp  <accidentals>
Thus K:DPhr ^f could also be notated as K:D exp _b _e ^f
where exp is an abbreviation for explicit. The standard states
that the notes should be in lower case; however, as a compatibility
measure with abcm2ps upper case notes are also allowed with
this feature.

Fix: in parseabc.c (parsekey) checked for string "exp" and
set a new variable explict to 1 if the string is present.
Added the variable explict to the function event_key(..)
which is defined in store.c, toabc.c, yapstree.c, matchsup.c, and
parseabc.h. Note the applications abc2abc, yaps, abcmatch do
not support this feature presently. 


May 20 2010

Abc2midi in compatibility. For the following example


X: 1
T: Araber tants  
R: Terkish
M: C
L: 1/8
K: Dphr ^F
D2 "A"\
| "D"FGA2 A2A2 | "Gm"B6 AG | "D"^FGA2 "Eb"BAGA | "D"GF3 z2D2 |

abc2midi ignores ^F in the K: field command. The draft 2.0 standard
states that modifiers should be in lower case. Thus the K: field
should be written as
K: Dphr ^f
Since abcm2ps allows upper case modifiers too and distinguishes
them, I now allow both upper and lower case modifiers.
Fix: commented out 
if (expict) in parseabc/parsekey().
This also maintains compatibility with various Klezmer transcriptions.



May 21 2010

Abc2midi bug: abc2midi crashes when the -c option (checking only)
is selected. eg. 
abc2midi test.abc -c
Floating point exception

Analysis: division by zero occurs when set_meter(header_time_num,
header_time_denom) because both input parameters are zero. These
parameters are not set when the c option is selected.

Fix: in finishfile() (store.c) set header_time_num and header_time_denom
when check is set.

  if (check) {
      Mf_putc = nullputc;
      header_time_num = time_num; /* [SS] 2010-05-21 */
      header_time_denom = time_denom; /* [SS] 2010-05-21 */
 


May 24 2010

Abc2midi compatibility bug: the key signature 
K:C^f^c
is not parsed correctly. (Such indications occur in many
Klezmer tunes.) Analysis: parsekey (in parseabc.c) expects
a space separating the key signature modifiers ^f and ^c.
Fix: readword() in parseabc.c was changed so that it splits
a string when it encounters '^' and '_' as well as '='.


May 26 2010

Abc2midi crashes with a segmentation error for file demo.abc
(included with abcMIDI package) when run on any specific tune eg.

[seymour@localhost abc]$ abc2midi demo.abc 2
writing MIDI file demo2.mid
Segmentation fault

Analysis: abc2midi scans the entire demo.abc file. When it 
encounters %%MIDI drumon in tune 7, it attempts to set
v->drumon = 1. The v structure has not been allocated,
so a null pointer is encountered.

Fix: also tested the variable dotune in the following test
 if (strcmp(command,"drumon") == 0 && dotune) {  /* [SS] 2010-05-26 */
in event_specific, in store.c.


May 31 2010

Abc2midi does not process K: field when key is missing but sharps
and flats are indicated explicitly. This typically occurs in some
Klezmer tunes. In the following example

X:1
T:explicit key
M:2/4
L:1/8
K:^c^d^e
CDEF|DEGA|

abc2midi returns the messages

Error in line 5 : First K: field must specify key signature
Warning in line 6 : Ignoring text: CDEF|DEGA|
Error in line 7 : No valid K: field found at start of tune

and does not produce a MIDI file

Analysis: the messages are produced when parsekey returns a zero
value for the flag gotkey. Fix: if parsekey succeeds in parsing
some information in the K: field (parse == 1), then gotkey is
set to 1 and sf is set to 0 (i.e. C scale).


June 26 2010

Abc2midi bug. Tempo command (eg Q:60) applied at the wrong place
in a multivoiced abc file containing a change in dynamics. In
the following example:

X: 1
T: Branles
M: 4/4
L:1/8
Q:1/4=110
K:C
V:1
CDEF GABc | CDEF !p!GA[Q:60]Bc |
V:2
K:C
|[C,G,]4 [G,,F,]4 | [C,G,]4 [G,,F,]4 |

the Q:60 is applied after the second note (D).

Analysis: the !p! command resets delta_time to zero in track 1 (where
the TEMPO command is inserted) because of the line
if(wordson+noteson+gchordson+drumson+droneon == 0) delta_time = 0L;
at the conclusion of the function dodeferred (in genmidi.c). As a
result when TEMPO is encountered, delta_time only reflects the next two
notes GA after the !p!. Unfortunately, if we do not set delta_time
to 0L, then another bug comes back (September 20 2009). 

Fix: it is necessary to introduce another global delta_time_track0
which is shared between genmidi.c and queues.c. delta_time_track0
is updated by queues.c but is only used by the TEMPO command
in genmidi.c


July 1 2010

Abc2midi does not recognize tabs in field commands K: and V:
eg.

X: 1
T:Danse
M: 4/4
L:1/8
Q:1/4=110
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
V:1	nm=Oboe	snm=Ob
V:2	nm=Basse	snm=Bs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
V:1	% Oboe
%%MIDI channel 1
%%MIDI program 68
K:Gm
GABc def2|edcd BcA2 | GABc def2|ec[Q:100]B[Q:90]d[Q:80] A[Q:70]F[Q:60]G2|]
V:2	% Basse
%%MIDI channel 2
%%MIDI program 46
K:Gm
[G,,D,]4 [G,,D,]4 |[G,,D,]4 [G,,D,]4 |[G,,D,]4 [G,,D,]4 |[G,,D,]4
[G,,D,]4 |]
%%%

Analyses: tabs instead of spaces occur after V:1 and V:2. Abc2midi
processes 1\tnm=Oboe as a single word etc. As a result abc2midi
identifies four voices instead of 2.

Fix: in readword() (parseabc.c) added (*p != '\t') in the while
predicate.


July 07 2010

Abc2midi bug occurs when a rest is followed by a time signature.
In the following example:

X:1
T: time signature
M: 2/4
L: 1/8
K: C
V:1
E2D2|[M:2/4] D2F2|
V:2
z4|[M:2/4] f2e2|

the rest z4 is held too long causing a loss of synchrony between the
two voices. If the following meter change is removed in the two voices,
the problem disappears. The rest is also held too long in the single
voiced tune (no V: command).

Analysis: this bug was introduced with the April 15 - April 21 2010
changes to write_meter() in genmidi.c (see above). Fix, I restored
write_meter() to its original state reintroducing the incompatibility
with Melody Player and several other players.

To fix the incompatibility, delta_time was initialized to 1 instead
of 0 in writetrack() (genmidi.c).


July 11 2010

Abc2midi: new feature. Added warning "no default gchord string for this meter".
The message appears once if no gchord string could be set and a guitar chord
appears in the music. Implementation: the gchord string is set to 'x' by
default. If dogchords finds 'x' it outputs the message one time.


July 27 2010

Abc2midi: possible bug. No voice command assumed. In the following
sample:

X:1
T: voices
M: 2/4
L: 1/8
K: G
GABc|BAGF|
V:2
FGAB|defg|

tht V: field occurs past body; will include this body with this voice.");
1 voice command is missing after the K: G. abcm2ps understands
that there are two voices; however, abc2midi appends the second
voice to the first voice. Analysis: in order to handle named voices
parsevoice in parseabc.c assigns a sequential number starting from
1 to the first voice it encounters. This gets confused with the
body which also has the same voice number. I did not see any clean
way of fixing this problems; however, there is now a warning
in event_voice (store.c) when this potential problem occurs.

{event_warning("First V: field occurs past body; will combine this body with this voice.");

In order to detect this problem, it was necessary to introduce
the flag bodystarted.


July 29 2010

Abc2midi bug: in the following tune


X:1
T: K: bug
M: 4/4
L: 1/4
K: E
V:1
K: treble
EFGA|Bcde|

the E major scale was not set up. Analysis: this bug was introduced
in May 31 2010. In the second K: command, parsekey (in parseabc.c)
sets sf to 0 and gotkey to 1. This forces event_key to change
the key signature to the C major scale. Fix: in order to handle
key signature mods, we introduced a new flag modnotes which is
set when it encounters a ^, _ or == in the K: command. If gotkey is
zero and modnotes is set, then explct is set to 1 so that 
event_key will process the key signature modifications.



August 12 2010

Abc2midi bug: delayed start of drum pattern for second voice. In the
following example:

X:1
T: drumbug
M:4/4
L:1/1
K:C
%
V:1
%%MIDI drumon
%%MIDI drum d2zd  35 38   120 50 
%|
x|x|
%
V:2
%%MIDI drumon
%%MIDI drum dzdz 67 68  100 80 
%|
x|x|

the drum generator for the second voice begins one bar late. If you
remove the comment before the single bar in second to last line,
the second voice starts on time.

Analysis: dodrums() in genmidi.c is called by progress_sequence in queues.c
provided the Q structure is not empty (Qhead not -1). In the case of
the first voice, the Q structure is setup by checkbar() in genmidi.c
because it was called by softcheckbar() when the DOUBLE_BAR feature
was encountered. For the second voice, no DOUBLE_BAR feature was
encountered, so the Q structure was not set up for the drum track.
If the voice starts with a single bar, checkbar() is called and
everything is properly initialized.

Fix: added to starttrack() in genmidi.c
 if (drumson) {  /* [SS] 2010-08-12 */
       drum_ptr = 0;
       addtoQ(0, drum_denom, -1, drum_ptr, 0);
       }

This seems to fix the problem.





August 28 2010

abc2midi bug: voice splits does not work when the unit length
is not the default value 1/8. In the example

X:1
T: split voice bug.
K:C
L:1/2
|:cd |1 c2 & e2 :|2 C2 & G2 |]

The split voice was transformed with the wrong unit length. If
L: is set to 1/8 the MIDI file is correct.

Analysis: 
v->default_length has the wrong value for the split voice.

Fix: in event_split_voice (store.c) v->default_length is transferred to
the split voice.



August 31 2010

abc2midi bug: rests inserts after [Q:1/4=100]. In the following
example

X:1
T: Rallentando
M: 4/4
L: 1/4
Q:1/4=120
K: C
C C C C | C C C C | C C C C | C C [Q:1/4=100]C  [Q:1/4=80]C | C1 |]

there is a large silent period inserted after the Q:1/4=100 command.
Inserting a V:1 after K: C fixes this problem.

Analysis: this bug was introduced on June 26 2010 in effort to
fix a related problem. Unfortunately, for single track MIDI
files this caused another problem.

Fix: if the MIDI file has only one track, the program reverts
to the old code.


September 28 2010

abc2midi bug: multiple repeats does not work correctly. In the
following example,

X:1
T: repeats
M: 2/4
L: 1/8
K: C
|:G2A2|[1,3 B2f2:|[2,4 B2c2:|

G2A2 is played again after the last repeat. Analysis: in genmidi.c
maxrepeats was incremented to 5. Fix: limited maxrepeats to 4 or
less. (Note [1,3,5 does not work because inlist() in genmidi.c
does not check beyond two numbers.)


November 21 2010

abc2midi bug: when the path name to the abc file contains embedded periods,
eg. 
"C:\Documents and Settings\midi.stadsmuur.INTERN.018\Local Settings\Temp\temp.abc"
abc2midi places the output midi file in the wrong folder
eg.
"C:\Documents and Settings\midi

Analysis: the problem is in the code
   *filename = argv[1];
    outbase = addstring(argv[1]);
    for (j = 0; j< (int) strlen(outbase); j++) {
      if (outbase[j] == '.') outbase[j] = '\0';
    };
  };
in the function event_init() in store.c. 

Fix, the loop should go backwards and stop at the first period.

outbase = addstring(argv[1]); /* [RM] 2010-11-20 */
 for (j = (int) strlen(outbase); j>0 ; j--)  {
    if (outbase[j] == '.') {
     outbase[j] = '\0';
     break;
    }
 };

Thank you Reinier Maliepaard for identifying the bug
and proposing a solution.


December 07 2010

abc2midi: New feature: tempo indication compatibility with abc standard 2.0.
The standard allows the following syntax for the Q: command;

X:1
T:tempo
M:2/4
L:1/4
K:G
Q: "Adagio"
CD|EF|
Q: "Adagio" 1/4=40
GA|Bc|

Explanation: "Adagio" translates into 1/4=59. In the second Q: command,
1/4=40 overrides the default tempo for "Adagio". See abcguide.txt for
other tempo directives. Please note that the double quotes are
mandatory.

Implementation: in store.c, translation tables temponame[] and
temporate[] were added; also the function get_tempo_from_name()
was introduced.



December 10 2010

Abc2midi bug: abc2midi crashes if the above tempo descriptor
is not enclosed in double quotes. See example below.


X:1
T:tempo causes crash
M:2/4
L:1/4
K:G
Q: Adagio
CD|EF|


Analysis: the segmentation error occurs in the new function
get_tempo_from_name(s) in store.c. The string s is empty nad
causes the program to crash when strcasecmp() is called.

Fix: added the test

if (s == NULL) return 0; /* [SS] 2010-12-10 */

in get_tempo_from_name(s). Now the program returns
Error in line 6 : malformed Q: field ignored


December 12 2010

yaps: bug.  The following file crashes yaps.

X:1
T:yaps segmentation error
Q:1/4=60
M:2/4
L:1/16
K:Bb
Q:1/4=60
"F"F2FF AFAc |"Bb" B2 z2 B2 \
 z2 | z4 |
%%printtempo 0
   "Bb"((3_b2a2g2) f2d2 | B2BB dBdf | "F"F2FF AFAc | "Bb"B2z2 "D"A2z2 |
P:Accelerando  --------------------------->---------------->-----------------------
 [Q:1/4=65] "Gm"G2B2 G2B2 |[Q:1/4=70] "D"A2 D4 D2 |[Q:1/4=80] "Gm"G2B2 G2B2 |[Q:1/4=90] "D"d2z2 d4 |

Analysis: yaps does not expect such a long label in the P: field.

Fix: in event_parts(s), in yapstree.c, changed
char label[20] to char label[200].



January 1 2011

abc2midi irrelevant messages when running on a collection of tunes
in a file. (eg. "voice mapping ..." and "First V: field occurs past body...").

Analysis: the variable voicecode in parseabc.c was not reset to 0 when the
next tune was processed. Also the variable bodystarted in store.c 
was not reset to 0 when the next tune was processed.

Fix: in parseabc.c, call init_voicecode() after event_ref() called;
in store.c, set bodystarted to 0 in event_ref().


February 21 2011

abc2abc : the program now attempts to transpose the key modifications
in the key signature. For example: K: Dphr^F will be transposed to
EPhr^G (for abc2abc -t 2). Explicit key modifications are also supported.
These key signatures are used a lot in Klezmer music.  Unfortunately,
the algorithm does not always work correctly.  Perhaps someone can help me.
All the new code is in toabc.c before the function event_key(). I
have given up in treating double sharps and double flat modifications.


April 14 2011

abc2abc bug: when using the voice extraction feature -V n, the program
still reports errors occurring in other voices causing some confusion.
In the following example, voice 1 has 5 beats instead of 4 in bar 1
(we count from zero).

X:1
T: confusing error message
M: 4/4
L: 1/4
K: C
V:1
ABcg|dcABE|
V:2
Acde|feFE|

When extracting voice 2:

abc2abc xabc.abc -V 2
X:1
T:invisible note problem
M:4/4
L:1/4
K:C

%Error : Bar 1 is 5/4 not 4/4
V:2
Acde|feFE|

The error message applies to a problem in voice 1 even though the
program is extracting voice 2.

Analysis, abc2abc processes the entire file but merely suppresses
all voices except the one requested. Error messages in other voices
are not suppressed.

Fix: the flag output_on in toabc.c is used to suppress output of
the unwanted voices.  The functions event_error(s) and
event_warning(s) now check both flags echeck and output_on
before printing.


April 14 2011

abc2abc bug: when extracting a particular voice, abc2abc fails to
print the part field command P:. In the following example,


X:1
T: abc2abc missing part
M: 2/4
L: 1/8
K: G
P: Intro
V:1
V:2
V:3
P:A
V:1
V:2
V:3

abc2abc pabc.abc -V 1
X:1
T:abc2abc missing part
M:2/4
L:1/8
K:G
P:Intro
V:1
V:1

P:A is missing in the output, however

abc2abc pabc.abc -V 3
X:1
T:abc2abc missing part
M:2/4
L:1/8
K:G
P:Intro
V:3
P:A
V:3

P:A is present when the last voice is requested.

Analysis: P:A is considered to be part of voice 3, so it was
suppressed when any other voice was extracted.

Fix: the P: command should be treated as the start of a new
section so that the control flag output_on should be set to
1 whenenver this command is encountered. This occurs in the
function event_part() in toabc.c.


April 17 2011

abc2abc new feature: normally abc2abc converts all instructions
(decorations) like !ppp! to +ppp+ in order to comply with the
abc standard 2.0 which has deprecated the former convention.
A new option -noplus, causes abc2abc to use the deprecated convention
to represent all instructions and decorations.

Implementation: a new global integer noplus was introduced in
toabc.c code.


April 17 2011

abc2abc bug: abc2abc fails to recognize clef=perc, eg.

X:1
T: clef= error
M: 2/4
L: 1/8
K: G
V:drum clef=perc 
!f! CDEF|

causes abc2abc to issue a warning

%Warning : cannot recognize clef indication


Fix: added to isclef() in parseabc.c

if (strncmp(s, "perc",1) == 0 && strict==0) {
    gotclef = 1;
  }   /* [SS] 2011-04-17 */



April 18 2011

abc2abc bug: fails to transfer all voice parameters. In the
following example


X:1
T: missing stafflines parameter
M: 2/4
L: 1/8
K: G
V:drum clef=perc stafflines=1
 CDEF|

abc2abc fails to copy 'stafflines=1' to stdout.

Analysis: parsevoice in parseabc.c ignores anything it does not
recognize. stafflines=1 is a parameter used by abcm2ps.

Fix: 
added to voice_params in parseabc.h
  int gotother;
  char other[V_STRLEN];

added to parsevoice(s) in parseabc.c
  vparams.gotother = 0;
  vparams.other[0] = '\0';
  if (!parsed) parsed = parseother()...

introduced a new function in parseabc.c
  parseother();

added to event_voice() in toabc.c 
if( vp->gotother ) { sprintf(output, " %s", vp->other);
            emit_string(output);} 

April 19 2011

parseother() in parseabc.c added check for break caused
by '='.


April 19 2011

Abc2midi: By popular demand the message
"missing BAR_REP for voice inserted for voice ... "
has been suppressed. The BAR_REP |: is still inserted 
back when it is expected. (It could be inserted in the wrong place.)


April 29 2011

Abc2midi: Jurgen Schwietering has contributed the roll ornament for
the harp described here.

The operation is quite simple, instead of generating a grace the ~ ornament on
harp is a roll with the same 3 notes (always) which can be quite accurately
transcribed as
~n2 := n/n/n (BTW played always with fingers 4 3 2 [a m i])
~n3 := n/n/n2 (for dotted, execution same as previous)
It is NOT a movement done before the beat like graces.
It is very common among folk harpists.

A new MIDI command
%%MIDI harpmode 1
changes the ornament to harp mode. To switch back to regular mode, use
%%MIDI harpmode 0

Alternatively, you can specify the harp mode in the command line to
abc2midi, eg.

abc2midi inputfile.abc -HARP

Implementation: a new global variable harpmode was introduced which
is modified by the MIDI command or set in event_init() in store.c.
The function doornament() checks the harpmode flag and calls the
new functions makeharproll3() or makeharproll() in store.c.

Here is a sample file to test this feature.


X:61
T:The Glass of Beer
C:Reel, Trad. Irish
C:Arr. Gráinne Hambly
M:4/4
L:1/8
K:D
Q:1/4=130
%%MIDI program 1 46
%%MIDI harpmode 1
~B3 ~B4 B|
~B2 B/B/B ~B4|
%%MIDI harpmode 0
~B2 B/B/B ~B3 B|
~B2 B/B/B ~B4|


June 6 2011

Abc2midi bug: For the following file,

X:1
T:part not found
M:3/8
L:1/16
P:B
K:Dphr^f
%MIDI gchord fzz
P:A
"G"cdefga:|
P:B
M:2/4
|:d4e4:|

(Comment: a common trick in transcribing music to abc is
to temporary split it into parts so that you do not have
listen to the beginning each time you are checking it out.
The following problem occurs when you attempt to skip the
beginning.)

abc2midi returns the error message
genmidi.c:fillvoice partlabel -55 out of range
genmidi.c:fillvoice partlabel -55 out of range
and the resulting MIDI file does not contain any music.

Analysis:
The function findpart (in genmidi.c) looks for P:B in the
feature[24] which was its original location, unfortunately it
has been moved to feature[25] by add_missing_repeats() (store.c)
but part_start was not updated correctly. The problem is with the loop,
for (j=0;j<parts;j++). parts is 1 and not 2 since it starts
from -1. There part_start[1] was not incremented to 25 by
missing_repeats. The fix was to add an = after < in the
for loop. for(j=0;j<=parts;j++)


June  7 2011
Abc2abc: a new feature has been added to abc2abc to support
multivoiced tunes. Using the -P X option, where X is the voice
number, abc2abc will act on only voice X and leave all the other
voices untouched. For example, if the input file t.abc is

X:1
T: Example 1
T:Solo instrument plays the same as the upper voice of the piano
M:3/4
L:1/8
V:1 clef=treble sname="violin"
V:2 clef=treble sname="piano"
V:3 clef=treble
V:4 clef=bass
%%staves 1 {(2 3) 4}
K:G
V:1
K:G
G2 D2 GA | B6 |]
V:2
G2 D2 GA | B6 |]
V:3
B,2 C2 B,C | D6 |]
V:4
G,2 F,2 E,D, | G,,6 |]

and we wish to transpose voice 1 up a tone for a Bb clarinet. We run
abc2abc t.abc -P 1 -t 2. The output will now look like.

X:1
T:Example 1
T:Solo instrument plays the same as the upper voice of the piano
M:3/4
L:1/8
V:1 clef=treble sname="violin" " 
V:2 clef=treble sname="piano"
V:3 clef=treble
V:4 clef=bass
%%staves 1 {(2 3) 4}
K:G
V:1
K:Amaj
A2 E2 AB | c6 |]
V:2
G2 D2 GA | B6 |]
V:3
B,2 C2 B,C | D6 |]
V:4
G,2 F,2 E,D, | G,,6 |]

Please note in order for the key signature K:Amaj to appear in voice V:1,
it was necessary to place K:G after V:1 in the input file. I have not
tested this feature with other options. It is important that you
know how this feature is implemented as discussed below.

The implementation introduces a new command which is a
slight variation of the -V X command that is used to
extract a particular voice from the abc tune. The -V command
merely suppresses output when the particular voice does
not match the requested voice. The program still continues
to process the voices so hence error messages from
other voices can be present).  The -P command acts
in a similar fashion, however instead of just suppressing
the output for the other voices it replaces it with the
the unprocessed input lines.

Here is how the feature was implemented.

In parseabc.c, a new function print_inputline() was introduced. This
function prints a line in the input file verbatim. A new flag,
passthru was added in toabc.c and initialized to 0. If the -P X
option appears in the runtime sequence, then the selected_voice
(the same variable used by -V X) is set to the voice number X
and the flag passthru is set to 1. The flag output_on is automatically
set when ever the voice number is selected_voice (X). (This is
part of the -V X code.) One more addition in toabc.c, completes
the implementation. In the beginning of the function
event_linebreak() (in toabc.), I added.

if (!output_on && passthru) print_inputline(); /* [SS] 2011-06-07*/


As a final comment: The toabc.c code is quite difficult to understand
-- in particular the function newabctext(). The trick used here,
was least invasive.



June 10 2011

Abc2abc bug. The -V option sometimes suppresses vital field command
information.

For the following file voicehead.abc.


%%barnumbers 1
X:1
V:1 clef=treble
V:2 clef=bass
%%staves [1 2]
T: Lost field commands
M:6/4
L:1/16
K:E
V:1
[K:E]
e8 e4- e4 d4 e2d2| c8 c4- c4 B4 c2B2| A8 B4 F8 G4-|-G8 A4B12 |]
V:2
[K:E]
G,4 B,2A,2 G,4 F,12 | E,4 G,2F,2 E,4 D,12 | C,12 A,,12| B,,8 F,,4 B,,12|]

abc2abc ../Desktop/voicehead.abc -V 1

produces

%%barnumbers 1
X:1
V:1 clef=treble
V:1
[K:E]
e8 e4- e4 d4 e2d2| c8 c4- c4 B4 c2B2| A8 B4 F8 G4-|-G8 A4B12 |]

The field commands, T:, L:, M: and K: are lost.

Analysis: This bug was probably around for a long time.
Since voice 1 was requested, the V:2 command in the header
suppresses output by setting output_on = 0 when it is first encountered.
The resulting output is no longer a correct abc file.

Fix: in event_voice, output_on is set to 0 only if xinbody is nonzero.

June 10 2011, abc2abc bug -P option.

For the voicehead.abc file (immediately above)

abc2abc ../Desktop/voicehead.abc -P 2 -t 2

%%barnumbers 1
X:1
V:1 clef=treble
V:2 clef=bass
%%staves [1 2]
M:6/4
L:1/16
K:F#maj
V:1
[K:E]
e8 e4- e4 d4 e2d2| c8 c4- c4 B4 c2B2| A8 B4 F8 G4-|-G8 A4B12 |]
V:2
[K:F#maj]
A,4 C2B,2 A,4 G,12 | F,4 A,2G,2 F,4 E,12 | D,12 B,,12| C,8 G,,4 C,12|]

The program should not change the key signature of the first K: field
declaration since it applies to all voices. Fortunately, the key
signature to voice 1 was already declared; otherwise F#maj would have
been assumed.

Analysis: if we are extracting a single voice and transposing it using
the -V 2 -t 2 command, this behaviour would be desirable. (If the
key signatures were not declared in the individual voices, we would
require that the K: field be changed to F#maj.) However, for the
-P option this could lead to a problem.

Fix: this is not an elegant fix since it could cause problems elsewhere.
The passthru flag is used to indicate that the -P option was used.
Normally the source of the output is controlled by the event_linebreak()
function. However, it was not easy to figure out how to intercept
the K: output so it was necessary to try a different approach.
The event_key function was modified to do nothing except print
the original K: command if this K: command does not occur in the
body. A new function print_inputline_nolinefeed() was needed
in parseabc.c.


July 4 2011  -- also see August 17 2011

Abc2midi new feature. The Phil Taylor stress algorithm has been
implemented in abc2midi on an experimental basis. This algorithm
stresses notes by varying their loudness and duration based on their
position in the bar. Note durations are shortened by lengthening
the inter-note silences so that there is no affect on the 
tempo. This model runs in opposition to the standard model in
abc2midi, so that regular commands for affecting dynamics such as
!p!, %%MIDI beat, %%MIDI beatstring, are ineffective.
Also the %%MIDI trim x/y command is also turned off by the stress model.

To turn on Phil Taylor's stress model, load one of his stress models
using the MIDI command
%%MIDI ptstress hornpipe.txt

where hornpipe.txt is some file resembling

8
110 1.4
90 0.6
110 1.4
90 0.6
110 1.4
90 0.6
110 1.4
90 0.6

To switch back to the regular or standard beat model use:
%%MIDI beataccents

The stress model file is formatted as follows.
The first value in the file is the number of segments -- here it is 8. 
This is followed by eight lines specifying the velocity
(volume) and duration associated with each segment.

The model adjusts the loudness and duration of the note
based on which segment it falls into.  Its duration is
scaled by the second factor. Since we can only shorten notes, the
duration is actually scaled by the ratio of the specified
duration over the maximum duration which is here
1.4. When a note overlaps several segments the parameters
are averaged over those segments.

There is no constraint on the number of segments other
than it should be less that 31, the amount of allocated
space in the program. For some irregular rhythms, such
as 7/8 time, one may use an odd number of segments.
A few sample stress files can be found in the pt folder.

Here is a sample tune you can test.


X:1
T: stress test
M: 4/4
L: 1/8
K: G
Q:1/4=160
%%MIDI program 73  flute
%%MIDI ptstress pt/hornpipe.txt
"G"dd2d d2d2|"Em"dd2d d2d2|"D7"dd2d d2d2|"G"G2A2 B2c2|



Implementation:

New global variables were introduced in genmidi.c

int beatmodel = 0; /* a flag selecting either the standard model
                      or Phil Taylor's model */
int nseg;  /* the number of segments in Phil Taylor's model */
int ngain[32]; /* gain factors for each possible segment */
float fdur[32];/* duration modifiers for each possible segment */
float maxdur; /* maximum duration modifier */
int segnum,segden; /* segnum/segden is the size of the segment.
                   It is computed from nseg and the time signature */

The function noteon(n) was split into two functions, noteon()
and note_beat(n,&vel). A new function stress_factors(n,&vel) implements
Phil Taylor's model. The function noteon(n) either calls note_beat()
for the standard model or stress_factors() depending on the state
of the variable beatmodel. The function note_beat() contains the
original contents of noteon(). The function stress_factors() affects
the note duration in an indirect manner by modifying the trim_num/
trim_denom variables which are already used for articulating the
notes using %%MIDI trim x/y command.

Another function, readstressfile() was written to load one of the
Phil Taylor's stress models.

The beatmodel flag is reset to 0 when a MIDI beat or trim command is
encountered.

In dodeferred(), a new command, ptstress is introduced which loads
the selected model.


July 18 2011

Abc2midi: support for EasyABC (http://www.nilsliberg.se/ksp/easyabc/)
To allow EasyABC to follow the score while the MIDI file is playing
additional positional information needs to be embedded into the MIDI
file. This is done by placing the line and character position of each
note in the MIDI file. If abc2midi is started with the -EA run time
parameter, this information is included.

Implementation: this is a joint effort with Nils Liberg.
parseabc.c -- added two new global variables char *linestart and
int lineposition. lineposition stores the position of the current
token (usually a note) in the music line being parsed. The variable
lineposition is passed to store.c as an external.
abc.h -- a new featuretype META is added
store.c -- a new flag int easyabcmode is introduced. It is set to
1 when the -EA run time parameter is included.  addfeature(META,...
inserts the line number and line position into the feature, num, denom,...
structure whenever a chord or note is started. (Search for easyabcmode
in the source code store.c).
genmidi.c -- in the switch control structure in writetrack() a new
branch case META: was added. Presently, it merely prints the line
number and character position. Nils Liberg will replace this print
statement with the appropriate MIDI output statements.


August 3 2011

Abc2midi bug. Abc2midi does not play part C in the following example.

X:1
T: part bug
M: 2/4
L: 1/8
P:C
K: C
P:A
EDBc|B2 C2:|
P:B
DEFG|ABc2|
P:C
GABc|c4|

This is another instance of the bug reported in June 6 2011. Unfortunately,
the variable parts refers to the number of parts to be played. For
example if the header specifies
P: (AB)2
then readspec() expands this to
P: ABAB
and parts is set to 3 (since it starts from -1) indicating that
there are 4 parts to be played.

There is no variable indicating the number of parts occurring in the
body, but we do not need it.

In add_missing_repeats we change 
   for (j=0;j<=parts;j++) {  /* [SS] 2011-06-06 */
to 
for (j=0;j<26;j++) {  /* [SS] 2011-08-03 */

part_start[i] is initialized to -1 so it will be
less than add_leftrepeat_at[i] if the part was not defined.
The index of part_start[i] is set to [(int)*p - (int)'A']]
where *p is the part code between A and Z.



August 07 2011 new build system

Note if everything has been working fine, you can continue using
the usual method for compiling the code. 

Nils Liberg has introduced an autoconf build system similar to what
is used in abcm2ps. The files config.h.in, configure, configure.ac,
install-sh, and Makefile.in were added to the distribution. To
use this system, delete or rename the current makefile called
'makefile'. Make the file configure executable, (on linux or unix,
chmod 764 configure). Run the script configure and then make. Thus,

mv makefile makefile.bak
chmod 764 configure
./configure
./make

Note the script configure has various options. To see them, 

./configure --help

For example, ./configure --enable-debug will compile the code with
the -g flag.



August 09 2011

The address of the Free Software Foundation was changed from
59 Temple Place, Suite 330, Boston, MA 02111-1307
         to
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301

in the sources drawtune.c, genmidi.c, matchsup.c, midi2abc.c
parseabc.c, position.c, pslib.c, queues.c, store.c, toabc.c
and yapstree.c


August 17 2011 to August 27 2011

More work was done on the Phil Taylor stress models during
this period of time and there are now two versions of the
model. To use these models you must include the -BF runtime
parameter in the execution string. For example,

abc2midi myfile.abc -BF

You may follow -BF with either the numerals 1 or 2 which specifies
the stress model version to use. Model 2 is more similar to the
one used in Barfly and is the current default. Alternatively
you may include the MIDI directive.

%%MIDI stressmodel 1

Nevertheless, you must still include the -BF runtime parameter
in the execution string for either model to be effective.

The stress model descriptors corresponding to the different rhythm designators,
(eg. Reel, jig, hornpipe, and etc.) are built into the code, so
there is no need to reference an external file; however, this is
still permitted using the %%MIDI ptstress directive described
in July 4 2011. 

Implementation:

More code was added in the files store.c, genmidi.c and a
new file stresspat.c. The implementations of the two models
are very different. Model 2, requires a separate pass to be
performed through the internal abc representation (feature, num,
denom,...) prior to writing the MIDI file. This pass is 
is performed by a new function called apply_bf_stress_factors()
in store.c which is called after other passes such as
scan_for_missing_repeats(), tiefix(), and dograce(). During
this pass, the note durations in the num[] and denom[] arrays
are modified by means of a new function in genmidi.c called
beat_modifier(). The functions changes these values for NOTE,
TNOTE and REST features.  Beat_modifier() is called
whenever a bar line is encountered. It scans all the notes and
rests up to the next bar line and changes their durations.

A new global array fdursum[] derived from fdur[] was introduced in
order to modify the note durations. The functions readstressfile_simple()
and readstressfile() were modified to initialize fdursum as well
as other new globals segnum/segden which specifies the size of a
segment. (The function readstressfile() was based on original
format of Phil Taylor's stress file and is not used. It may be
removed in future versions of the software.)

Conversions of the note durations is done in beat_modifier() by
first computing the actual positions of the notes in the bar based
on all the offsets stored in the num[],denom[] arrays.
The positions are remapped into the new space and the note offsets
in the num[] and denom arrays are replaced. Special care was
required to handle chords (notes enclosed by CHORDON, CHORDOFF,
and CHORDOFFEX features) and tied notes (TNOTES). (Note that
it is possible for a tied note to extend across a bar line.)

(For reference tied notes are initially represented as 
NOTE TIE NOTE etc. The function tiefix() changes this representation,
to TNOTE REST REST. (It was desirable not to change the durations
of the two following REST features for some reason.) (I do not
know what will happen when tied notes occur inside chords and
I do not want to have to find out.)

The implementation was also complicated by the fact that all
durations are represented by fractions rather than decimal numbers.
Thus all arithmetic was done using fractions.

Note velocities are recorded at the time that the notes are written
to the MIDI file (see noteon()) through the intermediary function
stress_factors() in genmidi.c. In order to pass the stress modulated
note velocity it was necessary to introduce another global array
handled like feature[], pitch[], etc. which is called stressvelocity[].
The function beat_modifier puts the segment number based velocity,
into stressvelocity[] which is pulled out at a later time by
stress_factors() for beatmodel == 2. The original function
stress_factors() was renamed to articulated_stress_factors()
which now handles beatmodel == 1. 

If you run the abc2midi with runtime parameter -v (for verbosity),
you can see how the program operates.

 
Implementation: to avoid any problems with finding and opening files
in different operating systems, the BarFly stress model descriptors
for the different rhythms are stored internally
in array structs stresspat[]. These arrays are defined in a new
C file called stresspat.c which is now linked with abc2midi.
The file defines two functions, init_stresspat() and 
load_stress_parameters(). Init_stresspat() initializes the stresspat[]
arrays. Load_stress_parameters() identifies the appropriate stress
pattern from the rhythm designator and meter, and places the required
information in the external variables segnum, segden, nseg, ngain,
maxdur, fdursum and beatmodel.

Parseabc.c was modified to save the contents of the M: command
as a char timesigstring[] which is passed to stresspat.c as an
external. This allows handling time signatures such as C|.

A new flag, barflymode which is set by the -BF runtime parameter
was introduced in store.c. A new global char rhythmdesignator[32]
was added in store.c which is set in event_field when the R: field
is processed.

If barflymode is set, event_field() in store.c will not set
the hornpipe flag which converts sequences of eighth notes into
broken notes.

The Makefile.in and makefile were modified to include stresspat.c.

i.e.

OBJECTS_ABC2MIDI=parseabc.o store.o genmidi.o midifile.o queues.o parser2.o stresspat.o

and

stresspat.o :   stresspat.c

August 26 2011
Abc2midi: the -v option (verbose) accepts a number indicating the
level of verbosity. If a number does not follow, the verbosity is set to 1.

Abc2midi: the -BF option (barflymode) accepts a number which indicates
the stress model to use. If none is supplied, it uses model 2.


September 06 2011

Abc2midi bug: for the following tune,

X: 2
T:test2
M:4/4
L:1/4
%R:hornpipe
K:G
%%MIDI ptstress hornpipe.txt
V:1
c B A G| c/B/A/B/ A G|
V:2
z/C,/ z/C,/ z/C,/ z/C,/ | z/C,/ z/C,/ z/C,/ z/C,/ |

when the file is run without the -BF run time parameter the
MIDI file created is silent. All the notes are
assigned a velocity (loudness) of 0.

Analysis: the %%MIDI ptstress directive sets the beatmodel control
variable to 2 indicating that stress adjustments should be made.
Because the -BF was not present, the %%MIDI ptstress directive
is processed too late and the function apply_bf_stress_factors()
was not run prior to writetrack. However, stress_factors () is
still called to adjust the note velocities using the information
in stressvelocity array. But the stressvelocity array contains only
zero's. 

Fix: in the function noteon in genmidi.c, we call note_beat()
in case stress_factors() returns a zero velocity.

Note: that if the file is executed with the -BF flag, the notes
in the first bar still have a zero loudness because the first bar
does not begin with a bar line and beat_modifier was never called
for that bar. However, the above file exposes another bug.


Abc2midi bug: for the preceding tune, when abc2midi is called with
the -BF parameter, the first G in voice 1 is held too long causing
a loss of synchronization with the second voice.

Analysis: the function fdursum_at_segment returns the wrong values
for val_num/val_den because the value of fdursum[nseg] was incorrect.

Fix: in readstressfile_simple() I replaced the lines
if (fdursum[nseg] != (float) nseg) fdursum[nseg] = (float) nseg;

with

lastsegvalue = (float) nseg * (float) qnoteden / (float) qnotenum;
/* ensure fdursum[nseg] = lastsegvalue [SS] 2011-09-06 */
if (fdursum[nseg] != lastsegvalue) fdursum[nseg] = lastsegvalue;
 


September 07 2011

Abc2midi no feature:

The %%MIDI ptstress directive now also accepts the ptstress directly. For example,

%%MIDI ptstress 4 100 1.3 60 0.7 100 1.3 60 0.7

instead of 

%%MIDI ptstress test.txt

where test.txt is

4
100 1.3
60 0.7
100 1.3
60 0.7

You can still, pass a path to a file. If it cannot parse the MIDI
command as stress parameters then it will assume a file name is
being passed.


September 13 2011

Abc2midi fails to tie notes separated by a double bar line.
For example:

X:1
T: tie test
M: 2/4
L: 1/8
K: G
d2 g[_c_e]/-||[c2e2] g2|

the message was returned

Error in line 6 : Could not find note to be tied
Error in line 6 : Could not find note to be tied

Fix:

In dotie() in store.c a new condition was added to the switch structure,

 switch (feature[place]) {
        case SINGLE_BAR:
        case BAR_REP:
        case REP_BAR:
        case DOUBLE_BAR: /* [SS] 2011-09-13 */

      

October 19 2011

Abc2midi new feature: sustain pedal. One of the pedals on the piano sustains
a note after the piano key is released. Two new instructions +ped+ and
+ped-end+ or !ped! and !ped-end! using the old instruction notation were
introduced. In the following example,

X:1
T:Ped in pianomusic
M:C
L:1/8
K:C treble
K: clef=bass
Q:1/4=60
%%MIDI program 70
+ped+G,A,B,C+ped-end+DE|

the notes, G,A,B,C were sustained. Though the bassoon does not
have a sustain pedal, the scale is played on that instrument to
make the effect more obvious.

Implementation: the sustain is accomplished using the MIDI controller
64. The ped and ped-end instructions are detected in
event_handle_instructions() in store.c. They in insert PEDAL_ON and
PEDAL_OFF in the feature() array. Two new functions pedal_on() and
pedal_off() which handle the PEDAL_ON and PEDAL_OFF features are
introduced in genmidi.c. abc.h was updated to included the PEDAL_ON
and PEDAL_OFF features.



October 21 2011

Abc2midi bug: %%MIDI control command after a rest causes loss of
synchronization. In the following example



X:1
T: Synchronization Loss after rest (z2)
V:1
V:2
M: 4/4
K:F#dor
V:1
|: A,G, | F,G,F,G, A,B,A,G, | F,4-F,2 :|
V:2
%%MIDI program 65
|:\
%%MIDI control 7 40
 de|  f4 z2
%%MIDI control 7 80
GA|  f4-f2\
:|


The control command is used to modulate the loudness of the alto saxophone
in voice 2. The second control command which attenuates the saxophone
to velocity 80 introduces another delay of z2 causing the following
notes G and A to be played one beat late (into the next bar).

Analysis: The second control command introduces a beat delay because
delta_time is not zero when the function write_event is called. (Delta_time
is not zero after a rest so that the following note will be delayed.)

Fix: write_event should not introduce any delay, so that delta_time was
replaced by 0 in the function call mf_write_midi_event(..). The function
write_event is also called to turn on (off) portamento, to handle
pitch_bend, pedal on and pedal off MIDI commands. (Hopefully, this
change does not introduce a bug in the other functions.)


November 18 2011

Abcmidi new feature. The MIDI commands, chordprog and bassprog have
been extended to allow for an octave offset. In the following example

X:1
T: octave test
M: 2/4
L: 1/8
K: C
Q:1/4 =96
%%MIDI program 74 Recorder
%%MIDI chordprog 0 
%%MIDI bassprog  0
"C"C4|C4|C4|C4|
%%MIDI chordprog 0 octave=2
%%MIDI bassprog  0 octave=2
"C"C4|C4|C4|C4|

The piano bass chordal accompaniment is shifted up two octaves from its
usual position. The amount of shift is limited to + or - two octaves.
To reset to the default position put,
%%MIDI chordprog 0 octave=0
%%MIDI bassprog  0 octave=0

Implementation, in dodeferred() in genmidi.c, I added a few lines of
code beginning with p = strstr(p,"octave="). For bassprog and
chordprog declarations, the function searches for string "octave=" anywhere
in the command line and then grabs the value following the equal sign and
puts it in the temporary variable octave. gchord.base and fun.base are
reset by
if (found == 1 && octave > -3 && octave < 3) gchord.base = 48 + 12*octave;
if (found == 1 && octave > -3 && octave < 3) fun.base = 36 + 12*octave;

gchord.base is used in configure_gchord() and fun.base is used in 
dogchords(), both in genmidi.c.


November 30 2011

Abc2midi slurring bug. In the following example,


X:1
T:Slur Bug
M:C|
L:1/4
%%MIDI trim 1/2
K:C
%%MIDI program 70
(cde)c | (cdec) | (cd)(ec) | (e/d/c) Gc/e/ | d2ed | c4 ||

The last note of every slur complex is not separated from the
next note which is not in the complex.

Analysis: writetrack() in genmidi.c looks turns off slurring when
it sees a SLUR_OFF one unit away from the note it is processing.
Unfortunately, there is always a SLUR_TIE there and writetrack should
be looking two units away. (SLUR_TIE is used in yaps.) Fixing this
situation introduces another problem; when SLUR_OFF is finally
encountered writetrack discovers that slurring was already turned off
and sends a warning. To fix this problem, a new global was_slurring
is introduced and is used to detect the situation where slurring was
turned off recently.

December 8 2011

Abc2midi: fermata bug. When a rest is preceded by a fermata symbol
H, abc2midi fails to recognize the rest. For example,

X:1
T: Malformed note
M:4/4
L:1/8
K:C
E2 DG  +fermata+z2 FG | E2 DG  Hz2 FG | AGFD HE2 FG | ABdg e4 |

The first fermata is expressed correctly, but the fermata in the
following bar causes abc2midi to issue the following message.

Error in line 6 : Malformed note : expecting a-g or A-G

Analysis: parsemusic() in parseabc.c expects decorations to be always
followed by a note and calls parsenote().

 while(*p != '\0') {
    lineposition = p - linestart;  /* [SS] 2011-07-18 */
    if (((*p >= 'a') && (*p <= 'g')) || ((*p >= 'A') && (*p <= 'G')) ||
        (strchr("_^=", *p) != NULL) || (strchr(decorations, *p) != NULL)) {
      parsenote(&p);
    } else {
   
Parsenote() does not see a note since the decorations is followed by
a rest. The rest is not processed. If the fermata is indicated using
the instruction !fermata! or the more modern notation +fermata+,
then cases 'x' and 'z' in parsemusic() process the rest getting the
decorations from decorators_passback[] and everything works well.

Fix: the easiest fix is to add a check for rests in parsenote(). New
code was added.

/* [SS] 2011-12-08 to catch fermata H followed by a rest */

  if (**s == 'z') {
          *s = *s + 1;
          readlen(&n, &m, s);
          event_rest(decorators,n, m, 0);
          return;
          }
  if (**s == 'x') {
          *s = *s + 1;
          readlen(&n, &m, s);
          event_rest(decorators,n, m, 1);
          return;
          }

Prior to looking for accidentals in the note.



December 11 2011

Abc2midi: lyrics bug with inline voices. When abc2midi is applied to the following
tune,

X:1
T:Lyrics bug
M:4/4
L:1/8
Q:80
V:1 clef=treble %%MIDI program 73 % General-MIDI "Flute"
V:2 clef=treble %%MIDI program 26 % General-MIDI "Electric Jazz Guitar"
K:C
[V:1] ABcd            e2   dc     | ABcd               e2  dc     |
w:    This is just a test. Just a | quick-ie lit-tle test To see |
[V:2] ABcd            e2   dc     | ABcd               e2  dc     |
%
[V:1] ABcd            e2 dc        |  C8     | 
w:    what is go-ing on  With lyr- | ics   |
[V:2] ABcd            e2 dc        |  c8   | 
%

It returns the following errors and warnings.

Warning in line 7 : Line of music without lyrics
Error in line 11 : Verse 1 mismatch;  8 syllables in music 7 in lyrics

Furthermore, the lyric information in the ouput karaoke MIDI file
is mangled. The first line "This is just ..." is not associated with
the individual notes and the second line "what is go-ing..." is missing.

However, if we eliminate all the inline voice fields,

X:1
T:Lyrics bug
M:4/4
L:1/8
Q:80
V:1 clef=treble %%MIDI program 73 % General-MIDI "Flute"
V:2 clef=treble %%MIDI program 26 % General-MIDI "Electric Jazz Guitar"
K:C
V:1
 ABcd            e2   dc     | ABcd               e2  dc     |
w:    This is just a test. Just a | quick-ie lit-tle test To see |
V:2
 ABcd            e2   dc     | ABcd               e2  dc     |
%
V:1
 ABcd            e2 dc        |  C8     | 
w:    what is go-ing on  With lyr- | ics   |
V:2
 ABcd            e2 dc        |  c8   | 
%

There are no errors or warnings and the resulting MIDI file is
correct.


Analysis: when abc2midi detects lyrics in the w: field, it calls event_words
(in store.c) which saves the entire line in one of the entries of the global
array words[]. It indicates the particular entry location in the words[]
using the WORDLINE feature.  During the final pass, writetrack() calls
write_syllable() each time it encounters a NOTE, TNOTE (tied note), CHORDOFF
(end of chord). At the end of line of notes signaled by MUSICSTOP,
checksyllables() is called which merely verifies that it had successfully
matched the notes with the line of lyrics. For this to work properly,
findwline() must associate the line of music with the line of lyrics
stored in the words[] array. Given a starting location in the feature[]
which matches a particular music line in the tune, findwline searches
the feature[] array for the next WORDLINE feature where it will get
the address of the lyrics in the words[] array. This search is aborted
if findwline() encounters a WORDSTOP, PART, VOICE, or MUSICLINE prior
to WORDLINE. The starting location for this search is given in the
global variable thismline which gives the location of the last MUSICLINE
that was processed. Writetrack() updates thismline each time it encounters
another MUSICLINE feature.

The source of the bug is that inline voice commands are not immediately
followed by a MUSICLINE feature as would occur when the V: command is
on a separate line. As a result, the variable thismline has not been
updated to reflect the current music line. findwline() starts searching
from the beginning of the feature[] array and aborts as soon as
it encounters a VOICE or MUSICLINE feature. The function write_syllable,
assumes it does not have any lyrics for that line. More confusion
occurs when the next music line with lyrics is processed.

Fix: now include
  /* [SS] 2011-12-11 inline voice commands are not followed
       by MUSICLINE where we would normally get thismline */
      if (wordson) {
        thismline = j+1;
        nowordline = 0;
      };

in writetrack() after processing the VOICE feature.

As an added comment, when genmidi.c is processing a voice with lyrics
it assumes that every line of music for that voice has a line of lyrics.
checksyllables() puts out annoying messages when a line of lyrics is
missing. I do not completely understand the code in checksyllables().


December 19 2011

Abc2midi clef-octave bug. In the following example, the clef=treble
declaration does not restore the octave setting to zero.

X:1
T:Octave-Shifting Syntax Test
M:6/8
L:1/8
K:G
[V:1 clef=treble]   GAB c2d | efg eBG || % in correct, notated  octave
[V:1 clef=treble+8] GAB c2d | efg eBG || % an octave higher, as requested
[V:1 clef=treble]   GAB c2d | efg eBG || % should be original octave, but isn't
[V:1 clef=treble-8] GAB c2d | efg eBG || % octave below ABC notation, correctly
[V:1 clef=treble]   GAB c2d | efg eBG || % should be original octave, but isn't


Fix:

Added to the function isclef() in parseabc.c after

if (strncmp(s, "treble", 6) == 0) {
    gotclef= 1;

    *gotoctave=1; /* [SS] 2011-12-19 */
    *octave=0;
    if (fileprogram == ABC2MIDI && *gotoctave != 1 && *octave !=1) event_warning("clef= is overriding octave= setting");
  };


January 29 2012

Abc2midi: extended %%MIDI chordname command to handle up to 10 notes (instead
of 6).


March 08 2012

Abc2midi: grace bug with voice overlay. Abc2midi loses synchronization when voice overlays and gracenotes present. In the following example

X: 1
T: Grace Bug
M:C|
L:1/8
Q:1/2=80
K:G
|{ABcB}c2B2B2A2|d2f2 g4 &D2F2 G4|

the overlay D2F2 G4 appears two quarter notes late. When the
grace notes are removed the voice overlay is in sync.

Analysis: the problem is in the code sync_voice in store.c.
Sync_voice determines the delay for the voice overlay; unfortunately,
it does not distinguish regular notes from grace notes which should
not have any time value in the calculation.

Fix: added two new cases to switch (feature[j]), GRACEON and GRACEOFF
to detect grace notes and to control the gracenotes flag. For case NOTE:
check that gracenotes is not set before addfract().


March 22 2012

Abc2midi repeat error message: for the following file



X:1
T:Mary Had a Little Lamb 1
C:Folk Song
M:C
L:1/4
K:Cmaj
%%score {RH|LH}
V:RH clef=treble
V:LH clef=treble
%
[V:RH] e3/2 d/ c d | e e e2 | d d d2     | e g g2  |
[V:LH] [CEG]4      | [CEG]4 | [B,DG]4    | [CEG]4  |
[V:RH] e3/2 d/ c d | e e e2 | d d/d/ e d | c4     :|
[V:LH] [CEG]4      | [CEG]4 | [B,DG]4    | [CEG]4 :|

X:2
T:Mary Had a Little Lamb 2
C:Folk Song
M:C
L:1/4
K:Cmaj
%%score {RH|LH}
V:RH clef=treble
V:LH clef=treble
%
[V:RH] e3/2 d/ c d | e e e2 | d d d2     | e g g2  |
[V:LH] [CEG]4      | [CEG]4 | [B,DG]4    | [CEG]4  |
[V:RH] e3/2 d/ c d | e e e2 | d d/d/ e d | c4     :|
[V:LH] [CEG]4      | [CEG]4 | [B,DG]4    | [CEG]4 :|


abc2midi runs without error messages if the tunes are processed
individually eg.
abc2midi lamb.abc 1
abc2midi lamb.abc 2

However, if abc2midi process the whole file, the program returns
error messages.

seymour@corsair:~/abc$ abc2midi lamb.abc
voice mapping:
RH  1   LH  2   
writing MIDI file lamb1.mid
voice mapping:
RH  1   LH  2   
writing MIDI file lamb2.mid
Error in line 28 : Found unexpected :|
Error in line 28 : Found unexpected :|
Error in line 29 : Found unexpected :|

Analysis: the messages are returned by writetrack() in genmidi.c as
it is creating the midi file lamb2.mid. In most cases the position
of the missing left repeat |: can be inferred, (in particular if
it is at the beginning of the tune). However, in some cases the
missing repeat is put at the wrong place or abc2midi fails to
apply the repeat. In June 23 2009 new code was introduced to 
address this problem since it is proper for the left repeat to be
omitted when it should occur at the beginning of the tune. 
The new functions scan_for_missing_repeats(), add_missing_repeats(),
and clear_voice_repeat_arrays() were added to store.c. (See this
file.) Unfortunately, the array bar_rep_found[] was not cleared
between songs and the function scan_for_missing_repeats did not
operate correctly.

Fix: added the function call clear_voice_repeat_arrays() at the
beginning of scan_for_missing_repeats() in store.c


March 26 2012

Abc2midi fermata bug: in the following example

X:1
T: Another fermata bug
M: 2/4
L: 1/4
K: G
%%MIDI program 68 oboe
C2 H[CEG]2|C2 H[C2E2G2]|

The first fermata is not held but the second one is held.

Analysis: when the length of the chord is set outside the chord, the
function fix_enclosed_note_lengths() in store.c is called to readjust
the length of each note comprising the chord. The function did not
take into account that the chord was being held longer.

Fix: a new global flag, apply_fermata_to_chord, was introduced and
used by the fix_enclosed_note_lengths to determine whether the notes
in the chord should be lengthened. The flag is set in event_chordon
by the variable chorddecorators[FERMATA]. It is reset to zero by
fix_enclosed_note_lengths.


March 29 2012

Abc2midi bug: abc2midi applies fermatas to all chords in which the
length is set outside the chord.

Analysis:
3721	if (apply_fermata_to_chord && !ignore_fermata) ;  /* [SS] 2012-03-26
There should no semicolon ending this statement.

Fix: removed the semicolon


March 30 2012

Abc2midi bug: more bugs when fermata is applied to a chord.

In the following example:

X:1
T: Another fermata bug
M: 2/4
L: 1/8
K: G
+fermata+[C2G2] z2|+fermata+[CG2] z2|

only the first note in the chord is held.

Analysis: +fermata+ is one of the many instructions which is
treated quite differently. Most of the instructions are not note
decorations eg. +pp+ and are handled inside store.c. Unfortunately,
+fermata+ is different since it is treated as a note decoration which
is passed to event_note from parseabc.c. For this reason it was
necessary to introduce a new array decorators_passback[] which
is shared with parseabc.c (as well as toabc.c and yapstree.c)
(See 2003 May 11 in this file.) The method worked well for single
notes, however it has never worked for chords. The array
decorators_passback[] is cleared to zero in parsenote() in parseabc.c
as soon as it is used to transfer information to the decorator[]
array. As a result, the second note in the chord is not held.

Fix: it was still preferred to reset decorators_passback[] in parseabc.c
rather than in all the files sharing this variable. Unfortunately,
parseabc.c does not know whether a given note is inside a chord or
not. A new flag, inchordflag, shared between parseabc.c and store.c
was introduced. This flag is managed by event_chordon() and event_chordoff()
in store.c. Now parsenote() does not zero the decorators_passback[] array
if the note is inside a chord.

A different fermata bug was exposed in the following example:

X:1
T: Yet another fermata bug
M: 2/4
L: 1/4
K: G
%%MIDI program 68
C2 +fermata+ [CEG]2|C2 +fermata+ [C2E2G2]|

The first fermata is never applied to [CEG]2.

Analysis: the new function fix_enclosed_note_lengths does not apply
the fermata because the flag apply_fermata_to_chord was not set.
This flag was not set because chorddecorators[FERMATA] was not
set in event_chordon(). In this case event_chordon() was called
inside the function parsemusic() rather than parsenote().

Fix: It was necessary to update chorddecorators with information in both
decorators[] and decorators_passback[] prior to calling event_chordon().
It was also discovered that the local array decorators() was not
initialized inside the function parsemusic().


April 1 2012

Abc2midi: new feature. Introduced a new option (-TT)  to tune the key of
A above or below 440.0 Hz but less than a semitone. The output MIDI
file will re-tune to that frequency. The purpose of this feature
is to accommodate some instruments like the accordion which are
not tuned exactly to 440.0 Hz.

Implementation: in store.c introduced two new globals
retuning and bend which will be shared with genmidi.c.
Also added code in event_init() in store.c to handle the
-TT option. Abc2midi now needs to link to the math library
so all the makefiles need to include -lm as well as Makefile.in
which is used by configure. If the user inputs a valid
frequency for the -TT option, the flag retuning is set
and the integer bend contains the amount of pitch shift
for all notes.

In genmidi.c created a new function midi_re_tune() which
sends the control RPN commands and the control data entry commands
for changing the master coarse and master fine tuning. This
function is called at the beginning of the track if the
flag retuning is set and the track either contains notes,
chordal accompaniment, or bagpipe drone.


April 03 2012

Abc2midi -tuning. Changed to the lower frequency limit to 414.9 to
permit A=415 Hz, a common tuning for Baroque music. The bend
variable is still limited between 0 and 16383.


April 15 2012

Abc2midi - lyrics. The function checksyllables() in genmidi.c emits
warnings even when there do not seem to be any errors in the
placement of the lyrics. I do not know how to fix this problem,
or even whether a fix exists. Furthermore, the warnings do not
appear useful as they are not very specific. Users can easily
check the placement of the syllables by viewing the score produced
by abcm2ps.  The error message in checksyllables() is now suppressed
except when running abc2midi in verbose mode.


May 28 2012

Abc2midi - added a missing break command following the META: case in
in writetrack() in genmidi.c

May 29 2012
Abc2midi - bug. When running in -EA mode (easyabc), the META command
carries the pitchbend value but the NOTE command has the wrong pitchbend
value (usually garbage depending on the compiler).

Analysis: in event_note() bentpitch[notes] was set before the META
command rather than the NOTE command.

Fix: moved the line setting bentpitch so it occurs before
addfeature(NOTE...).


May 31 2012
Abc2abc bug: abc2abc returns a bar count error when processing bars
with split voices. For example for tune,

X:1
T:Test
L:1/8
M:2/4
K:Cmaj
G | c4 & E2C2 ||

abc2abc produces

X:1
T:Test
L:1/8
M:2/4
K:Cmaj
G | c4 & E2C2
%Error : Bar 1 is 1/1 not 2/4
||

Analysis: abc2abc adds the length of every note in the measure, regardless
of the &-split voice.

Fix provided by Frank Meisshaert: the code for event_split_voice() was
replaced by

event_split_voice () {
char msg[40];
  emit_string("&");
  if ((count.num*barlen.denom != barlen.num*count.denom) &&
      (count.num != 0) && (barno != 0) && (barcheck)) {
    sprintf(msg, "Bar %d is %d/%d not %d/%d", barno,
           count.num, count.denom,
           barlen.num, barlen.denom );
    event_error(msg);
  };
  count.num = 0;
  count.denom = 1;
}

The code resets checks the length of the bar and resets count.num,
count.denom when a & is encountered.


June 4 2012

Abc2abc error messages: the following is musically correct.

X:1
T: abc2abc errors
M: 2/4
L: 1/8
K: Am
G|ABcd|[1efg:|[2f|edcB|

However, processing it through abc2abc returns many error messages.

X:1
T:abc2abc errors
M:2/4
L:1/8
K:Am
G|ABcd| [1efg
%Warning : No repeat expected, found :|

%Error : Bar 2 is 3/8 not 2/4
:| [2f
%Error : Bar 3 is 1/8 not 2/4
|edcB|

First abc2abc complains that an opening repeat |: is
missing at the beginning. Next it complains that bar 2 and 3
[1efg:|[2f| are incomplete measures. 

Fix: Jef Moine has contributed a ingenious fixes in toabc.c.
In start_tune() the flag expect_repeat is set to -1 instead of 0
to signal the start of tune. In event_bar, there is a check that
expect_repeat is greater than zero. Finally, if the number of
beats in the bar does not match the time signature, the error
message is suppressed for if the bar ends with :|, |:, |[1, :|[2
or :: and bar length is not reset to 0 so that it contributes
to the next bar.


June 04 2012

Abc2abc compliance with 2.1 standard:
the abc music standard 2.0 recommended changing the syntax for
decorations from !...! to +...+. Thus a mezzoforte indication
should be indicated as +mf+ instead of !mf!. Abc2abc was 
modified on April 17 2011 to be compliant with this change.
This recommendation was revoked in the 2.1 music standard,
(Dec 2011) http://abcnotation.com/wiki/abc:standard:v2.1

Fix: the option to output decorations using the +...+ syntax
has been removed and the default is now !...!. Any decorations
using the +...+ syntax are automatically changed to !...! syntax.
The flag noplus is now initialized to 1 instead of 0. The redundant 
runtime parameter -noplus was removed. 


July 03 2012

Abc2midi trill and roll problem: an attempt was made to fix the
problem reported on September 11 2006. For multivoiced tunes,
this can cause a loss of synchronization between the voices
as illustrated in the following example.

X:1
T: broken trill
L:1/8
M:3/4
K:G
[V:1] G>D   B,>D  G>TB | GA   Bc  dc | GA   Bc  dc |
[V:2] B,>A, G,>A, B,>D | G,A, B,C DC | G,A, B,C DC |

The problem also appears when trills are combined with grace
notes as illustrated here.


X:1
L:1/8
M:3/4
K:Am
Q:1/4=60
V:1
c2 {d}TcB/c/ d>B | BA Ac e>d |
V:2
A2{B}A^G/A/ B>G  |^GE EA c>B  | 


Analysis: The trilled or rolled notes are expanded into a sequence of notes
as soon as they are detected. As a result, the grace or broken rhythm is applied
to the first note of this sequence. To fix this problem it is necessary
to expand trills and rolls after broken rhythms and grace notes are treated
rather than as soon as they are detected. 

Fix: (2012-05-29 to 2012-06-03) a new function expand_ornaments ()
is called by finishfile() that converts trilled and rolled notes into
a sequence of notes. The defunct function dotrill() was split into
dotrill_setup() (called by event_note) and dotrill_output() called
by expand_ornaments(). Similarly, doroll() was split into doroll_setup()
and doroll_output().  Notes to treated by expand_ornaments() were
flagged using a new feature array called decotype[] which was checkmalloc'd
like stressvelocity, and pitchline.  If the note was flagged it
is treated by either dotrill_output() or doroll_output() depending
on its type.

The implementation was complicated by the problem, that the internal
representation of the music in the feature arrays does not preserve
the key signature information which is needed to decide whether to
ascend (descend) a tone or semitone in the trill or roll. Therefore 
it was still necessary to analyze the context of the trill or roll
at the time of detection using the .._setup() functions and save
the generation parameters for .._output() in a specifically designed
struct called notestruct. These structures are generated as needed,
but a pointer array noteaddr[1000], (assuming not more than 999
trills or rolls occur in a particular tune) is used to find the
struct. The notestruct struct thus acts as a bridge between the
setup and output functions. Treatment of microtones added another
complications and at this point I have not verified whether the
new code is correct with regard to microtones.

There is still a synchronization problem when broken rhythms
are combined with ornaments as illustrated below.

X:1
T: ornament test
M: 2/4
L: 1/8
K: G
V:1
D2 >~B2 |c2 G2|
V:2
F2 >D2| e2 D2|

Ornaments are handled in a different fashion. If harpmode is set,
then ornaments are expanded into a sequence of notes like trills
and rolls. If harpmode is not set, then a grace note is inserted
prior to the note and graceon() is called to make the final adjustments.
Furthermore if the note is dotted, then two grace notes are added.
For the present time you should avoid combining ornaments with
broken rhythms in multivoiced tunes.


August 08 2012

Abc2midi, yaps, abc2abc: The time signature C| or c| is now
interpreted as 2/2 instead of 4/4.

Implementation: added another test in void readsig() in parseabc.c


October 03 2012

Chinese character support in lyrics was added to abc2midi by
Bow Yi Jang <byjang61@gmail.com>. Changes were restricted to
the function getword(.) in genmidi.c


November 03 2012

Abc2midi multirest bug. In the following example,

X:1
T: multirest problem
M: 2/4
L: 1/8
K: G
Z|G4|\
M:3/4
L:1/8
Z|D6|

The second multirest preceding D6 is held for two beats instead of
three and the warning
Warning in line 9 : Bar 2 has 2 units instead of 3
appears.

Analysis: the function event_mrest (store.c)  uses the initial time
signature 2/4 stored in time_num/time_denom which does not get updated by
event_timesig() once the parser is in the body. abc2midi must keep
track of two time signatures: time_num/time_denom which is declared in
the initial field commands and mtime_num/mtime_denom which may be
updated in the middle of the body. The initial time signature, is
important for multivoiced tunes where the initial declaration is carried
to the start of all the voices. The active time signature
mtime_num/mtime_denom is only updated in the second stage in
set_meter() when genmidi is processing the feature[] array and
writing the MIDI tracks. However, the active time signature is
also needed when event_mrest is called to write multiple bars
of rests. Unfortunately, the active time signature was not maintained
during the initial parsing stage (first stage).

Fix: the variables mtime_num and mtime_num are now also used
during the first pass and maintained in event_timesig(). event_mrest()
uses the active time signature mtime_num/mtime_denom rather than
the initial time signature time_num/time_denom.


November 08 2012

Abc2midi: multirest bug part 2. The problem with meter change and
multirests persists in multivoiced tunes. In the following example,

X:1
T: Multirest bug part 2
M:C
L:1/4
K:F
V: 1
V: 2
%%MIDI program 1 73
%%MIDI program 2 40
%%staves [{ 1  2 }]
[V: 1] F A z c| z4 | [M:3/8][L:1/8] F/>G/ FA|B/>c/ BA | G/>A/ GF|C3|]
[V: 2] A F3   | Z | [M:3/8][L:1/8] Z | G/>A/ GA | B/>c/ BA | G3|]

The first multirest Z in voice 2 is held for 3/8 instead of of 1/4.

Analysis: voice 1 changes mtime_num/mtime_denom to 3/8 and it
remains in that state at the start of voice 2.

Fix: new variables int active_meter_num, active_meter_denom are
introduced into the voicecontext struct. They are used to maintain
the values of mtime_num and mtime_denom over voice switches.


November 15 2012

Abc2midi extension: abc2midi treats Xn the same way as Zn, to be
compatible with the new version of abcm2ps. Fix in parseabc.c added
case 'X': /* [SS] 2012-11-15 */
after case 'Z':


November 21 2012

Abc2midi: verbose option provides more detail if set to 4 or 5 for
tracking segmentation errors.



November 22 2012

The fixes for the following two problems were provided
by Philippe De Muyter.

The input line size in parseabc.c was increased from 256 to 512
to accommodate abc files that are automatically generated (eg midi2abc).
char inputline[512];


Abc2abc truncates the voice ids when it encounters the first
invalid character without giving any warning. eg.

X:1
T: invalid voice
M: 2/4
L: 1/8
K: G
V: A_1
abcd|
V: A_2
DEFG|

only one voice is detected.

Fix:
In interpret_voicestring() in parseabc.c the following code was added
after c = readword(code,s);

if (*c != '\0' && *c != ' ' && *c != ']') {
     sprintf(msg, "invalid character `%c' in Voice ID", *c);
     event_error(msg);
    }

Now abc2abc and abc2midi complain that they encountered an invalid
character.


November 23 2012

abc2midi bug: unable to trill or roll tied notes. In the following
example

X:1
T:trill-issue
M:2/4
L:1/8
K:F
V: 1
z4|z3d|
V: 2
%%MIDI program 1 73
%%MIDI program 2 40
 TF2   Tc2-| c Tf2-f|

The tied notes c2-c and f2-f do not get trilled.

Analysis: this bug was introduced on July 03 2012 in the attempt
to fix other problems associated with trills. The function
expand_ornaments() only processes NOTE features and ignores
TNOTE features used to designate tied notes.

Fix: The solution is to change TNOTE to a NOTE. However,
writetrack() in genmidi.c processes TNOTE features in a special way
in order that checkbar() will work when a tied note extends
over a measure. The TNOTE invokes a midi on command but a midi
off command is deduced from the following REST(s) which are
associated with the tied note. Therefore, if we change TNOTE
to a NOTE we also need to eliminate the REST(s) which are
part of the TNOTE sequence. This is done by a new function,
convert_tnote_to_note(). Unfortunately, this is not a clean fix.
Checkbar() will give a misleading message when the tied note
extends over a measure. Also, lyrics may not align correctly
with tied and trilled notes. It gets messy to make expand_ornaments()
to split up a trill across a measure.


November 25 2012

Abc2midi: the compiler on Windows PC does not initialize arrays
to zero when they are allocated. As a protection the arrays the bentpitch
and decotype are now initialized to 0 when they are allocated.
Some array pointers are now checked for valid values.


December 01 2012 -- submitted by Philippe de Muyter

abc2abc truncates a line to 512 characters without warning in the
-P mode. (This is the continuation of the changes November 22 2012.)

Analysis event_error is muted during the output so it is necessary
to simulate it with a plain printf in the function print_inputline_nolinefeed()
in the file parseabc.c.

December 11 2012

abc2midi: bend note, new feature. Placing the instruction !bend! slides
the pitch of the following note up.

For examples:

X:1
T: pitchbend
M: 6/8
L: 1/8
K: Gdor
%%MIDI program 78 whistle
%%MIDI transpose 12
DEF G3|DEF !bend!G3|

the second G is slid up.


Implementation: added a new function note_effect to queues.c which
is called by timestep(). Note effect inserts a sequence of pitch bend
events prior to sending a MIDI note off. Added a new integer member,
effect, to struct Qitem. The flag, effect, determines whether note_effect
is invoked. An additional parameter, effect, was added to the function
addtoQ which is also defined in queues.c. The function addtoQ is called
in many places in genmidi.c. In abc.h added a new feature called
EFFECT. The feature is inserted before a note when the instruction
!bend! is encountered --  see event_handle_instruction() in store.c. 
In genmidi.c added a global flag, effecton, which is usually set to
zero except when the EFFECT feature is encountered. The NOTE: handler
in writetrack returns effecton in one of the addtoQ function
calls.


December 12 2012

abc2midi: bend configuration. Introduced two variables bendvelocity and
bendacceleration into note_effect. Note_effect inserts 8 MIDI pitchbends
equally spaced inside a note. The pitchbend is initialized to the neutral
value of 8192. During the loop repeated 8 times, pitchbend and 
bandvelocity are incremented as follows.

pitchbend = pitchbend + bendvelocity
bendvelocity = bendvelocity + bendacceleration.

The pitchbend is limited between 0 and 16383 usually corresponding
to a negative and positive shift of two semitones on most General
MIDI instruments.

The variables bendvelocity and bendacceration can be set by the 
following  %%MIDI command.

%%MIDI bendvelocity n1 n2

where the integers n1 and n2 are the velocities and acceleration
respectively.  By default, n1 and n2 are initialized to 100 and 200.


December 25 2012

Abc2midi part/trill bug. Introducing trills or ornaments in a
multipart abc file causes erratic behaviour. For example,

X:1
T:parts
M:2/4
L:1/8
P:B
K:C
P:A
CDEF|TGABc|
P:B
cBAG|FEDC|

Part B is not played when the trill is present in part A.

Analysis, abc2midi stores the start position of each part in
the array part_start during the parsing stage. Unfortunately,
things may move around during the later stages. The function
expand_ornaments() inserts additional notes in the feature
arrays when it does its expansion. This shifts the position
of the parts and the information in the part_start array is
no longer valid.

Fix: created a new function fix_part_start() in store.c which
is called after expand_ornaments() in finishfile().


Jan 27 2013

Abc2midi: the abc2midi allows but does not recommend the tempo
command to just specify a number. eg. Q:320. abc2midi automatically
assumes that this number refers to a quarter note; however,
the abc standard 2.0 specifies that it should refer to the unit length
specified by the L: command prior to the body.

Fix: in parseabc.c changed a=1 to a=0 in the function parse_tempo().
The existing code in tempunits() in store.c does all the rest.

Jan 28 2013

Abc2midi: the above change was withdrawn since there is disagreement
between abc standard 1.7.6 and abc standard 2.0.

February 25 2013

Abcmatch: introduced -wpitch_hist runtime parameter for computing
the pitch histogram weighted by the note length. Some minor clean-up
of the output.

February 26 2013

Abcmatch: negative array index fixed in abcmatch.c (compute_note_histogram).
Problem is exposed on Windows operating system.


March 08 2013 -- patch submitted by Philippe De Muyter

Abc2abc: the -V and -P options have been generalized so that more
than one voice can be selected using a comma separated list.

Implementation:

The long global variable selected_voices represents the selected
voice in a bit map. Each bit in the word corresponds to a specific
voice number. Two new functions are introduced. parse_voices_selection
parses the voices_string in the -P or -V command and converts it
into the bitmap in the selected_voices variable. must_emit_voice(n)
examines the n'th bit of the selected_voices and indicates whether
it is on or off. The other change is the replacement of the control

-  if ((selected_voice != -1) && (n != selected_voice)) {
with
+  if (!must_emit_voice(n)) { /* [PHDM] 2013-03-08 */




March 10 2013 -- also submitted by Philippe De Muyter

abc2abc: fix chord's tuple length calculation

Up to now, bar length was increased at first note of chord, and
tuple status was lost at first note of last chord.  When a chord
in a tuple had a length modifier, the resulting bar length
was wrong, which caused wrong error messages.

With
        X:1
        T:wrongbarlengtherror
        M:4/4
        L:1/8
        K:C
        z8 | z6 (3  [fd]/ [fd]3/ [fd] | z6 (3 [f/d/] [f3/d3/] [fd] |
abc2abc gave a wrong message :
        %Error : Bar 1 is 13/12 not 4/4

Fix that, by incrementing bar length and decrementing `tuplenotes' at
chordoff time, not at first chord note.
Move also the tuple-implied length conversion in `addunits', to
avoid code duplication.
Because there are two ways to specify a chord length,
        [c2e2g2]
and        [ceg]2
in the first case, we must now memorize the note length to be able
to retrieve it at chordoff time; this is done in the new
`chordfactor' variable.

Additionnaly, as 'addunits' is only called when we know the exact length
of a note or chord, `repudiate_lastaddunits' is now useless and removed.



March 14 2013

Abc2midi: part/repeat bug. In the following example

X:1
T: Part - repeat bug
Q:1/2=120
M:2/2
L:1/4
K:D
%%vskip 0
P:Intro
|: "Em"e4 ||
P:A
|| "D"d4 :|

abc2midi returns the following messages:
Error in line 12 :  found another |: after a |:
Warning in line 12 : Assuming repeat
Warning in line 12 : replacing with double repeat (::)
writing MIDI file temp21.mid

Furthermore, the e4 in the Intro is repeated and then the D4
in part A is repeated. Since the P: are only labels here
(there is no P: command preceding K:), it was expected that
the entire the tune would be played as
|: "Em" e4 | "D" d4 :|

Analysis: the function scan_for_missing_repeats() which was
introduced in June 23 2009 is the source of the problem. The
function assumes that the tune is actually in two parts and
inserts a |: in the beginning of part A. When fixreps() is
called it discovers that two |: occur without an
intervening :|, so it decides to replace the second |: with
a double repeat ::. (Note that fixreps() would not be called
if the parts were real and not just annotations.)
 
Fix:
The useless conditional statement
if (J == PART || j == VOICE || j == BAR_REP etc.
was commented out since it does nothing.
In the following statement, an additional check parts != -1
was added. If parts == -1, this implies that the part indications
are merely annotations and do imply a real part as abc2midi is
concerned. Therefore bar_rep_found[] and voicestart[] are not
cleared again, implying that a |: may need to be introduced at
the beginning of the part if the part ends with a :|.




March 20 2013

Abc2midi: invisible and visible multirest confusion with field commands.
Z and X are used both as field declarations (X: reference number
and Z: transcription source) and as multirests in the body. In unusual
cases where the multirest is followed by a repeat sign and happens
to be at the beginning of a line, it can cause confusion. For example,


X:1
T: rests
M:3/4
K:C
c6|e6|^g6|\
X ::\
C6|e'6|^G6|\
Z :|\
[CE^G]6|]


X:2
T:rests
M:3/4
K:C
c6|e6|^g6|\
X1::\
C6|e'6|^G6|\
Z1:|\
[CE^G]6|]

are two examples which abc2midi fails to interpret correctly. parseline()
in parseabc.c attempts to treat X :: and Z :| as field commands even
though they are malformed. Abc2abc also does not produce correct output.

Fortunately parseline issues warnings

Warning in line 8 : whitespace in field declaration
Warning in line 8 : potentially ambiguous line
Error in line 8 : Missing Number

and the transcriber is urged to reformat the line to avoid this problem.

Fix: I am not sure whether I should fix this problem. In any case,
I have put a small patch in parseline() so that the above examples
are treated correctly.


March 21 2013

abcmatch: several bug fixes and a new feature -pitch_table.
Given a file containing a collection of tunes eg. Modes.abc,
abcmatch Modes.abc -pitch_table
will output the interval weighted pitch histogram for each
tune. If the output is stored in a separate file, eg. Modes.tab,
this table could be used for searching for the tune having the
closest matching pitch histogram (a feature to be introduced
in runabc).



March 26 2013

abc2midi bug: if a chord is preceded by a Roll or Trill indication,
abc2midi fails to encode the chord in the MIDI file.

For example:


X:1
T: chordtrill
M: 4/4
L: 1/8
K:C
V:1
%%MIDI program 16
T[ceg]4 [AEc]4 :|
V:2
%%MIDI channel 10
GA GA GA GA :|

A warning is issued that trills and rolls are not implemented for
chords, but [ceg]4 is not encoded in the MIDI file.

Fix: in event_note, in store.c added the lines 

      pitchline[notes] = pitch_noacc; /* [SS] 2013-03-26 */
      bentpitch[notes] = active_pitchbend; /* [SS] 2013-03-26 */
      addfeature(NOTE, pitch, num*4, denom*2*(v->default_length)); /* [SS] */

following the statement
     event_error("Rolls and trills not supported in chords");


April 10 2013

Abc2midi: new feature. Added a new runtime option -CSM <filename>.
This option allows one to customize the BarFly stress models by
providing an external file.

Background: the 32 stress models are presently built-in the source
code in the file stresspat.c. This has the advantage that executables
can be distributed without an auxiliary data file containing
the models. However, the user does not have much leeway to alter
the models or add additional stress models. The -CSM feature
addresses this limitation by allowing the user to add more
models for other rhythm designators (eg lesnoto), and to alter
one or more of the existing models. There is room to add up to
16 additional models. The feature requires the user to specify
a text file which contains these models. 

Description of the external file and how it works is given
in abcguide.txt and a sample of such a file is given in the
pt folder (customstress.txt).

Implementation: a new function read_custom_stress_file()
was introduced in the file stresspat.c. Assuming the file
conforms exactly with the expected format, the function
reads all the models provided. For each model, if the rhythm
designator and meter conflict with one of the existing standard
models, the function will update the characteristics of that model.
Otherwise the function will append the model to the current
list.


April 11 2013

Corrected a minor error in init_stresspat() (Tango) in stresspat.c.
As a convenience, I have produced default_stress.txt in the format
that read_custom_stress_file() accepts. Default_stress.txt contains
the built in models to abc2midi. You can find the file in the pt (Phil
Taylor) folder.


April 17 2013

Abcmatch: numerous bugs fixed. Introduced a new matching -norhythm.
The matching algorithm ignores the length of the notes and only
matches the sequence of pitches in a bar. The file abcmatch.txt
was updated. More internal documentation was added in abcmatch.c


April 20 2013

Abc2midi bug: combination of chords and broken rhythm. In the
following example,

X:1
T: broken rhythms
M: 2/4
L: 1/8
K: F
[DF]2 > [CE]2|

The second chord [CE]2 begins before the end of chord [DF]2.

Analysis: the function brokenadjust() (store.c)  is called
to adjust the lengths of the notes to effect the broken rhythm.
It adjusts the notes inside the chord but fails to adjust the length
associated with the CHORD (CHORDOFFEX feature). This causes
timestep() in queues.c to be called too early, causing the
second chord to start to early.

Fix: in the function lenmul() added another condition,
  || (feature[n] == CHORDOFFEX)) /* [SS] 2013-04-20 */


April 21 2013

Fixed: a potential memory overflow in parsing the repeat string.
In getrep() (parseabc.c) ensured the array index for playonrep_list
does not exceed 50.


April 24 2013

Suppressed warning in abc2midi. For the following example,

X:1
T:TEST TUPLES
M:2/2
L:1/4
Q:1/2=80
K:G
[F,A,D] (3[df]/[eg]/[^e^g]/ [fa][CF] |
[F,A,D] (3[d/f/][e/g/][^e/^g/] [fa][CF] |

abc2midi issues the following warnings.
Warning in line 7 : Different length notes in tuple for chord
Warning in line 7 : Different length notes in tuple for chord
Warning in line 7 : Different length notes in tuple for chord

Analysis: the message is issued when closing each of the
tuple chords in the first line. The length of the note in the
tuple is stored in the variables tnote_num, tnote_denom when
the first tuple note is encountered. Unfortunately when
the chord note duration is applied (here one half), the
note length no longer matches the stored values tnote_num
and tnote_denom and a warning is sent. The output midi
file nevertheless correct.

Fix: abc2midi stores the note length of the tuple in tnote_num,
and tnote_denom. A chordoff feature can modify the value of a tuple
note (i.e. chord) if its length is indicated outside the chord (eg.
[CE]3/2. If the modified chord length does not match the stored value
tnote_num, tnote_denom set by event_note, a warning is issued.
It is getting too complicated to keep track of a tuple note
inside and outside a chord, so I have decided to just suppress
the error message for tuples of chords. (i.e. I would have to
make extensive changes to the logic of the program to get it working
properly.)



May 07 2013

Abcmatch: introducing -fixed <n> runtime parameter. It allows
matching to go across a bar line. See doc/abcmatch.txt for
more information.


May 10 2013

Midicopy: bug in extracting a segment of a MIDI file. When
the segment starts in the middle of a note playing, it causes
a loss of synchronization between the tracks.

Analysis: there was an attempt to write a negative MIDI time
increment when Mf_currcopytime exceeds Mf_currtime.

Fix: set negative values to zero in the function WriteVarLen(value).



June 06 2013

Abc2midi: potential segmentation error when applying stress model.
The following tune contains stray text which abc2midi assumes
to be part of the body of the tune.

X: 157
T: Cliffs of Moher
N: page 51
R: jig
M: 6/8
K: Ador
"Am"eaa bag| (4efaf "G"ged| "Am"c2A BAG| "Em"EFG ABc|\
"Am"eaa bag| (4efaf "G"ged| "Am"cAA BAG| "Em"EFG "Am"A3 :|
"Am"efe dBA| efe dBA|  "G"G2d dBA| GAB dBd|\
"Am"efe dBA| efe dBA|  "G"GAB dBG| "Em"EFG "Am"A3| 
~e3 dBA|~e3 dBA|"G"~G3 dBA|GAB dBd|\
"Am"efe dee|cee Bee|"G"EFG BAG|EDB, "Am" A,3|
This abc file is used to generate the MIDI files and pdf file for volume 2
of the music collection used by the Ottawa Slow (Celtic) Jam.
The file is derived from 
http://www.ceolas.org/pub/tunes/abc.tunes/sessionTunes.abc

When the stray text is processed in the Barfly mode (-BF),
the array index to the variable fdursum exceeds the allocated
memory 32 which can cause a segmentation error on some
systems.

Fix: in the function fdursum_at_segment in genmidi.c, replaced
inx0 = inx0 - nseg;
with
inx0 = inx0 % nseg; /* [SS] 2013-06-07 */
which is executed if inx0 > nseg.


June 09 2013

Abcmatch: in -br mode the program returns both the number of matching
bars in the tune and template.


September 04 2013

Midicopy: new feature. Introduced the run time option -tempo n (beats/min). When
this option is included all tempo messages in the midi file are
replaced with the specified value.

Implementation: in metaevent() when a tempo message is encountered,
if newtempo is greater than zero, write the newtempo value instead
of the value in the source midifile. The value of newtempo is set
by the -tempo run time option.


September 06 2013

Midicopy: new feature. Introduced the run time option -speed f (multiplier).
When this option is included all tempo messages in the midi file are
are multiplied by the factor f where f is a floating point number between
0.05 and 10.0. This speeds up or slows the music by this factor.


September 07 2013

Midicopy: new feature. Introduced the run time option -drumfocus n m
where n is the pitch code of the selected drum line and m is the velocity
value to be applied to all other drum lines. The feature, highlights
the selected drum line by attenuating all other drum lines by playing
them at level m (m varies from 0 to 127).

Implementation: the velocities of the other drum lines are set to
m in function chanmessage() prior to sending a 'note on' message.

September 08 2013

Midicopy: fixed function tick_to_seconds so it returns the correct
time when the tempo is changed by -tempo or -speed.


September 10 2013

Midi2abc, midicopy: bug fix. Midi2abc or midicopy may fail for some
midi files which use the running status. A few midi files attempt
to save a few bytes by not transmitting the status byte for a channel
message when status byte has not changed. For clarification, the
status byte contains the channel message like "note on channel 10".
The status byte is followed by one or two data bytes specifying the
particular note it applies to and the velocity value. Since
data bytes are restricted to 6 bits and status bytes always
contain a value exceeding 6 bits, it is easy to tell when a status
byte is missing. The running status, saves a few bytes when
several notes in a chord are turned on (or off) at the same time.
The bug occurred when a metatext message is inserted inside
a running status complex (eg. note on channel 10, metatext, note on
channel 10). Midi2abc and midicopy abort with the message
"unexpected byte 0x..".

Analysis: the bug was traced to the code writetrack() in midifile.c
and also midicopy.c. It is necessary to store the last status byte
that occurred in the last channel message. Note a metatext message
is not a channel message. A new local variable, laststatus, was introduced
in the code.


September 15 2013

Midicopy: new feature. Added an option -mutenodrum [level] to mute
all channels to velocity level if the channel is not 9 (drum channel).
If level is not provided, it is set to zero.


Ocotober 1 2013

Midicopy: new feature. Added the option -setdrumloudness n m
where n is the drum number between 35 and 81 inclusive and m
is the new velocity between 0 and 127, All instances of the
selected drum are assigned the given loudness (velocity).

October 15 2013
Abcmatch: new feature. Added options -interval_hist and
-interval_table to analyze the pitch intervals between
adjacent notes. The program produces a histogram of the
note intervals in MIDI (semitone) units.


October 22 2013
Abcmatch: new feature. Added the option to accept
a certain number of insertion, deletion, and substitution
errors using the Levenshtein distance measure.


October 28 2013
Midicopy: new feature: added the option to list the tracks
to exclude from copying. eg. -xtrks 4,5 indicates to copy
all tracks except 4 and 5.


October 30 2013
Abc2midi: bug fix. A key change in the middle of a tune does
not propagate to the split voice. In the following example,


X:1
T:Test
L:1/4
M:2/2
Q:1/2=110
K:C
V:1
C4 | [K:Bb]B4 & B,4 |

B,4 was not flattened.

Analysis: the key change [K;Bb] was not propagated to the split
voice. 

Fix: in event_split_voice() in store.c, the active basemap and basemul
arrays for the voice was saved in a temporary area and transferred
to the split voice. 


October 31 2013

abc2midi and yaps bug: for the following example,

X:1
T: :|] ending
M:C
N:Portland p.19
R:march
K:D
|:"G" b2a2 "A"g2e2| "D"d4 d4 :|]

abc2midi returns the error
Error in line 10 : Chord already finished
and
yaps returns the error
Error in line 7: no chord to close

Analysis: these are extraneous error messages. Parsemusic() in
parseabc.c detects the THIN_THICK bar line |] but does not
detect it when it is preceded with ':'.
Fix: check for ']' in this case and skip over.


November 02 2013

Abc2midi: some instructions which are meaningful to abcm2ps are
meaningless to abc2midi and cause a warning. In the following
example, abc2midi cannot interpret !4! and !0!. 

X:1
T: instructions
M: 4/4
L: 1/8
K: A
"E"FEF(G "A" A2) !4!!0! [A2A2]|

Warning in line 6 : instruction !4! ignored
Warning in line 6 : instruction !0! ignored

Analysis: event_handle_instructions(s) in store.c issues this
warning when it cannot interpret this message.

Fix: the message is suppressed if -quiet is included in
the runtime parameters.



November 2 2013

abc2midi indicates the wrong line number in a warning. In
the following example,

X:1
T: Slurs
M: 2/4
L: 1/8
K: F
z(GFE
|:DE) FG|
AB (3cBA:|

abc2midi returns the message
Error in line 8 : Unexpected end of slur found

The end of slur is actually in line 7.

Analysis: on the second repeat, no slur was started so an end of
slur is not expected - but the line number in the error message
is wrong. The repeat :| causes writetrack (in genmidi.c) to backtrack
it restores the state variables to the condition where the opening
repeat sign |: occurs but the state variables do not include the
line number used by the warning or error message.

Fix: expanded the functions save_state() and restore_state() so
that the line number can also be saved.


November 4 2013

abc2midi bug: A bug was detected when abc2midi is run with the Barfly
stress model (-BF 1). For the following file t.abc

X: 1
T: Barfly implementation bug
R: jig
M: 6/8
L: 1/8
K: G
  |:  "C"c3 "G/B"B3 | "D7/A"AGF "G"GBd :|

abc2midi t.abc -BF 1
the note c3 or B3 may be inaudible in some instances.

Analysis: the local variable vel in the function noteon() may end
up being undefined. In certain cases stress_factors() called
by noteon() may not set the variable vel, in which case
we expect note_beat() to be called. Unfortunately, if vel
was initially nonzero note_beat is note called and vel
has a random value.

Fix: initialize vel to 0 in noteon().


November 04 2013
yaps fix: On January 16 2006 an option to display the notes in
red was introduced. This code did not work well because the
other musical components were also colored red. The problem
was fixed by maintaining the color in black and temporarily
switching the color to red when a note, beam or rest is
drawn. A new variable redcolor was introduced in drawtune.c
and set by the !red! command and reset to zero by !black!.
The functions drawnote(), drawrest, and drawbeam() test this
variable and switch the color to red on a temporary basis in
order to draw the object.
  

November 12 2013
abcmatch.c improvement. When running in absolute versus contour
mode, abcmatch frequently transposes in the wrong direction when
the key signatures differ since it does not know which direction
to go. abcmatch now transposes in the direction of minimum distance
between keys.

For cut time C| abcmatch translates it to 4/4 rather than 2/2
so it can find more matches. Both changes are in abcmatch.c


November 17 2013
abcmatch.c. Bug fixes so the matched bars have correct bar numbers.

November 26 2013
abcmatch.c -br threshold applies to the number of matched bars
in template instead of matched tune.


December 2 2013
abc2midi bug - split voices and repeats. The following tune
is not converted correctly.


X:1
T: test split file 13
M: 1/4
L: 1/4
K: G
|:G & E |1 D:|2 F & A|


On conversion:
writing MIDI file s11.mid
Error in line 8 : Need || |: :| or ::  to mark end of variant ending
Warning in line 8 : Track 2 is 1946 units long not 2426

The program produces to MIDI tracks of unequal length.
Track one contains G D G D F and track two contains E z E A.
In other words track 1 plays both section one and two in the repeat
instead of just section two.

Surprisingly if we replace |1 and |2 with |[1 and |[2 respectively,
the conversion is done correctly and there are no errors or
warnings.

Analysis: in the first pass the feature PLAY_ON_REP belonging
to voice 1 was placed in voice 2 and two PLAY_ON_REP features
appear consecutively in voice 2 resulting in the error,
"Need || |: :| or :: ..." message. When the [1 and [2 are
used, the internal representation contained in the feature
arrays is correct.

The problem was traced to the code in event_bar in store.c.
When the [1 and [2 is used, the PLAY_ON_REP is handled correctly
by event_playonrep() which is called directly by parsemusic in
parseabc.c. When |1 or |2 is used, parsemusic does not catch
these codes and they are handled (mishandled) by event_bar
when a split voice is present.

Fix: event_bar() was reorganized so that bar commands are sent
to the original voice rather than the child split voices. When
the child split voices are sync'd the bar commands are copied to
the child voices. This seems to work better.  The function
recurse_back_and_change_bar() is no longer in use.

The test tune was added to split.abc in the doc/programming/ folder.


December 14 2013
abc2midi: The warning "track x is xxxx units long instead of ..."
was changed to "track x is .... quarter notes long instead of ..."
The change is was made in writetrack() in genmidi.c.



December 25 2013
abc2midi bug: abc2midi does not read customstress files correctly
using the -CSM option.

The following file containing

Lesnoto
7/8
7 7
110 1.3
90  1.0
80  0.7
100 1.2
90  0.8
100 1.2
90  0.8

is not read correctly. Neither the name Lesnoto or the meter is stored
in the stresspat structure.

Analysis: in the function read_custom_stress_file() in stresspat.c
the lines
stresspat[index].name = name;
stresspat[index].meter = meter;

copy the address instead of the contents of string arrays name and
meter. The lines should read
strcpy(stresspat[index].name,name); /* [RZ] 2013-12-25 */
strcpy(stresspat[index].meter, meter); /* [RZ] 2013-12-25 */

also gain and expand are not copied into the structures.
add
stresspat[index].vel[i] = gain; /* [RZ] 2013-12-25 */
stresspat[index].expcoef[i] = expand; /* [RZ] 2013-12-25 */

I am grateful to roman.zimmermann@gmx.at for identifying the
bug and providing the fix.



January 01 2014

Abcmatch: fixed matchsup.c so it catches only the first title
of a tune in case that it has alternate titles.


January 05 2014

Midiabc: bug the msb and lsb values were interchanged in mftext_pitchbend.
mftext_pitchbend now also returns the value of bend in MIDI units.


January 06-09 2014
abc2midi new feaure: introducing an option to provide microtone tuning
in the key signature  for example K:F ^1/2D besides flattening
B also flattens D's by a half a semitone.
  
Implementation includes changes to parsekey in parseabc.c which
now has to check for microtones in the list of notes following
the key signature.  A new parameter modmicrotone is introduced in the
function event_key() which is found in parseabc.c, store.c, yapstree.c,
toabc.c and matchsup.c. A new struct 'fraction' was added in parseabc.h.
In store.c altermap() has a new parameter struct modmic[7], which
is used to transfer the key signature microtone specifications from
modmicrotone in event_key to a new struct in the voice struct called
basmic[7]. v->basmic stores the key signature microtone specs if present.
Function newvoice in store.c transfers global->basemic to v->basemic.
Function pitchof_b in store.c checks v->basemic to see if the note
has a microtone defined in the key signature. parsenote in parseabc.c resets
microtone to 0 (through event_normal_tone()) if the note is not a microtone.
This is a lot of changes. I hope, I have not introduced new bugs.

If a microtone is detected by parsenote(), its parameters are
stored in the struct fraction setmicrotone. This struct is automatically
reset to 0,0 if no microtone is detected.


January 12 2014

abc2midi new feature: Makam style music (Turkish) uses a more
complex music scale (as opposed to the equal temperament scale).
The comma53 scale divides an octave into 53 microtones. To use
this scale put "%%MIDI tuningsystem comma53" in your abc file.

Implementation: added to new functions in store.c
init_p48toc53 initializes the array pt48toc[]. convert_to_comma53()
changes midipitch and midibend values. Added a new command,
%%MIDI tuningsystem comma53

January 14 2014

corrections to convert_to_comma53(). Some debugging #defs.

January 16 2014

some fixes to pitchof_b and parsekey.

January 20 2014

abc2midi: microtones now propagate across a bar just like accidentals.
Major modifications to pitchof_b and other minor fixes (in store.c) were made.

January 26 2014
abc2midi: more microtone bug fixes. Each octave can hold its own
microtones. i.e. v->workmic is now a two dimensional array just
like workmap and workmul.



February 05 2014

abc2midi: the following file causes abc2midi (and other programs) to
behave erratically.

X:9
T:Have you ever wondered?
L:1/8
M:4/4
Q:1/2=90
K:G
V:1
CDEF |
W:| Have you ever | wondered why the | girls do | skipping, and the
W:| boys play | football and the | grans do | knitting?
W:| Who made the | rules that the | people all o- | bey?  And
W:| What's with the | "girls' thing", | "boys' thing" | anyway?

X:10
T:Warm-up 1
L:1/4
M:2/2
Q:1/2=80
K:Bb
|[B,DFB]2z2 |

abc2midi returns the message
Warning in line 9 : Potentially ambiguous line.
Warning in line 9 : Ignoring reserved character W
Error in line 9 : Unrecognized character: o
Error in line 9 : Malformed note : expecting a-g or A-G
Error in line 9 : Unrecognized character: r
Error in line 9 : Unrecognized character: w
Error in line 9 : Unrecognized character: o
Error in line 9 : Unrecognized character: n
and many more messages

Analysis: abc2midi sees :| after the W and assumes it is an end
repeat in the body. It tries to treat the rest of the line like
music.

Fix: I have improved the warning in parseabc.c so it is more meaningful.
It is now
Warning in line 9 : Potentially ambiguous line - either a :| repeat or a field command -- cannot distinguish.

This applies to all programs, yaps, abc2abc etc but it is too much trouble
to give them new version numbers.



April 03 2014

Abc2midi bug: tied note at end of bar combined with Barfly stress model.
In the following example:

X:1
T: Stress model bug
L:1/8
M:2/4
K:Gmin
%%MIDI ptstress 4 100 1.10 100 1.10 100 1.0 100 0.8
|Gc BA-|AG FG|

Abc2midi returns the following error message
writing MIDI file stress1.mid
Warning in line 7 : Bar 1 has 21/10 units instead of 2

Analysis: the problem is with the tied note A which
crosses a measure. The tied notes A-|A are tied together
into a single note by the function tiefix() in store.c
and the stress model is applied to the combined note. This
becomes obvious when running abc2midi with -v 2 option.r 2
pitch 67 from = 0/1 (0/1) to 1/2 (1/1) becomes 0/1 11/20 - 11/20
pitch 72 from = 1/2 (1/1) to 1/1 (2/1) becomes 11/20 11/10 - 11/20
pitch 70 from = 1/1 (2/1) to 3/2 (3/1) becomes 11/10 8/5 - 1/2
pitch 69 from = 3/2 (3/1) to 5/2 (5/1) becomes 8/5 51/20 - 19/20
bar 3
pitch 67 from = 0/1 (0/1) to 1/2 (1/1) becomes 0/1 11/20 - 11/20
pitch 65 from = 1/2 (1/1) to 1/1 (2/1) becomes 11/20 11/10 - 11/20
pitch 67 from = 1/1 (2/1) to 3/2 (3/1) becomes 11/10 8/5 - 1/2
bar 4
writing MIDI file stress

The fix is to apply the stress model prior to combining
the tied notes. The fix was applied to the function finishfile()
in store.c


April 10 2014

Abc2midi bug: The P: field was introduced to allow repeating
parts of the tune in complex patterns such as P:ABCBD; however
it is frequently used just to annotate a section of the music.
When it is used as annotation, you often get annoying warnings
such as.
Error in line 10 : Part must be one of A-Z
In some situations, this annotation may cause the music to
play incorrectly. For example in this tune,

X:1
T: part annotationmistaken
M: 3/4
K: G
V:1
B3c BA|B3c BA|B4e2|B3d ef|
 g4 g2|f4 e2|f3 gf2|B6|
V:2
G3A GF|G3A GF|E4B2|G4E2|
P: section B
B4 B2|^d4 ^c2|^d3 e d2|F6|

the last line in V:2 is played twice.


Fix: in event_part() in store.c we check whether a valid P:
command like P:A2BC was detected in the header. If none was
found, abc2midi ignores any P: commands after the header.



April 24 2014

abc2midi: slur bug
Abc2midi sometimes reports unbalanced slurs when they are
actually correct. For example

X:1
T: Slur error messages
L:1/8
M:2/2
Q:1/2=110
K:Dm
P:A
|: "Dm"a2ag a2ag | "^/"agfe dcAF | "Gm"GABA B^cdc | "^/"d^cBA BAGB |
"A"A=B^cB cded | "^/"efgf eA=B^c | "^/"d(^ga)(e f)(^cd)(A |1 "^/"B)AFE GAdf :|2 "^/"B)AFE DCB,A, |
P:B
|: "Gm"G,BBB BcBB | "^/"B,BBB BcBB | "Dm"FAAA Adde | "^/"fedc AFED |
"Gm"DBBB BcBB | "A"EAAA A=B^cA | "^/"d(^ga)(e f)(^cd)(A |1 "^/"B)AFE DCB,A,:|2 "^/"B)AFE "Dm"D4 |

The following messages were returned.
Warning in line 9 : No slur to close
Warning in line 12 : No slur to close
writing MIDI file colin1.mid
Error in line 12 : Unexpected start of slur found
Error in line 12 : Unexpected start of slur found
Error in line 12 : Unexpected start of slur found

analysis: abc2midi could not match the slurs when they cross into
a part section (eg :[2 "^/" B) ...).
fix: slur indications do not affect the output midi file so the
messages are somewhat irrelevant. The warnings and error messages
have been suppressed.


August 11 2014 

Introduced a new variable abcversion and parse the comment
%%abc-version 2.0
or
%%abc-version 2.1
if present.



August 14 2014

Bug: line continuation of a lyric field w: does not work.
In the following example,

X:1
T: vocal
M: 4/4
L: 1/4
K: G
G A G B|\
 E A G B|
w: ga ba la ba |\
 fa ma da ka|
GGGB|
w: la ma fa da|

the line fa ma da ka is not processed as part of the previous
w: field.

Apparently there was an attempt in preparse_words(s) (in parseabc.c)
to handle continuations of the w: field, however, the implementation
was not complete. (There is no signal, telling parseline() to
treat the continuation of the w: field.) Therefore this feature
never worked in all of the abcmidi programs (abc2midi, abc2abc and yaps).
I have decided not to support this feature and instead plan to
introduce an alternative using the +: command defined in the
2.1 abc standard. The following warning message is now being issued when
this situation is detected.
Warning in line 8 : \n continuation no longer supported in w: line


August 15 2014

New feature: the abc-version 2.1 standard introduces a new method for
continuing the w; using the +: for lyrics. It also discourages the use
of the backslash continuation. To handle the +: line, it was necessary
to keep track of the last field command. A new global
char lastfieldcmd was introduced in parseabc. The variable is modified
at the end of function parsefield in parseabc.c. Presently it only
signals a w: field command. For all other field commands it is set
to a blank. A new case statement for +: was also introduced in parsefield().
It calls a new function, append_fieldcmd() if lastfieldcmd == 'w'.
The function parseline() was extended to recoginize +: as a valid
field command. The function parsefield() was modified to allow the
+: command to appear in the body of the tune.

August 16 2014

Continuing from above: introduced a new function concatenatestrings()
in parseabc.c. In store.c, yapstree.c, toabc.c and matchsup.c
introduced a new function called appendfield(). Appendfield() was
only implemented in store.c where it calls a new function called
append_words. In the files, appendfield() merely returns a message
that it is not implemented yet.


September 07 2014

Continuing from above: the function appendfield() in toabc.c was
replaced so abc2abc will also handle the +: command. Note that
abc2abc the -n  X option which reformats with a new linebreak
every X bars will probably not work correctly when the tune
contains lyrics.


September 09 2014

Abc2midi fix: the !bend! action does not apply correctly to microtones.
In the following example:

X:1
T: bend about microtone
M: 4/4
L: 1/4
K: G
!bend!_1/4D2 z2|!bend!D2 z2|
!bend!^1/4D2 z2|!bend!D2 z2|

All the bends start from D natural.

Analysis: queues.c always initializes pitchbend to 8192 rather than
the value set by the microtone.

Fix: it was necessary to introduce another global variable, int bendstate,
to be shared between genmidi.c and queues.c. The variable bendstate
stores the pitchbend value when midi_noteon is called (in genmidi.c).
In note_effect() in queues.c, pitchbend is set to bendstate rather
than 8192.


September 10 2014
September 11 2014
Abc2midi: introducing %%MIDI bendstring n1 n2 n3 ...
This is a more general way of specifying the pitchbend track for
a note. The command is followed by a series of integers n1, n2
etc. which specify the change to pitchbend following each time
increment.

Method: In genmidi.c introduced the array benddata[16] which
holds the series of integers and bendnvals the number of these
integers. Benddata and bendvals is passed to genmidi through
an extern declaration. In dodeferred() in genmidi.c added a test for
%%MIDI bendstring. In queues.c added a new function, note_effect2()
which increments the pitchbend variable by benddata[i], and
produces a %%MIDI pitchbend command at regular time intervals.
In genmidi.c introduced a variable bendtype and set it to 1.
The %%MIDI bendstring command sets bendtype to 2 to signal that the
function note_effect2() should be called instead of note_effect().


September 22 2014
September 23 2014
September 24 2014
Abc2midi: when only one integer follows the %%MIDI bendstring
command, the !bend! command now applies the pitchbend to the
entire note. This provides another method for shifting the
pitch of the note instead of preceding it with a microtone
accidental. At the end of the note, the pitch of the note
is restored to its original value.

Implementation: in dodeferred() in genmidi.c we check for just
one value following the bendstring command and set the bendtype
variable to 3 so that queues.c calls the new function
note_effect3().

September 28 2014

Extended the maximum bendstring length to 50.


October 16 2014

Abc2midi: in some applications it may be desirable to suppresses
all messages. A new option -silent was introduced to suppress the
the other warnings and messages not handled by the -quiet option.
eg.
abc2midi nottingham.abc -silent -quiet
produces almost not output except for the MIDI files.


October 29 2014 ...

Abc2midi: more work was done with the bar repeat code in store.c
Abc2midi returns the incorrect line number when it detects a
problem with bar length on repeat.

Analysis: there are two functions which attempt to detect and
fix problems with repeats in store.c -- scan_for_missing_repeats()
and fixreps() each trying to fix different problems. When the
abc tune does not have voices or parts, it was discovered that
voicestart[0] is still initialized to zero and does not indicate
the position of the start of the music line further the inserted
DOUBLE_BAR code was placed in the wrong place by the function
headerprocess(). The function scan_for_missing_repeasts() was
modified to search for the first instance of MUSICLINE and
to insert a DOUBLE_BAR feature immediately after. The voicestart[0]
variable was set to this position.

November 02 2014

Incorporated changes to the makefile and manpages suggested by
Ross Gammon who does Debian Quality Assurance.


November 02 2014

Abc2midi bug: the b code in the gchord string does not work
correctly when there are inversions. eg.

X:1
T: gchord
M: 4/4
L: 1/4
K: C
%%MIDI gchord fb
"C" z4|"C/E" z4|

The second bar is played at E,,4 [C4G,4E,4C,,4] instead of
E,,4 [C4G,4E,4E,,4]

Fix:
In dogchords() (genmidi.c) case 'b' was changed so that it
is identical to case 'f' except that there is no break ending
that case (it progresses to case 'c').


November 9 2014
Abc2midi grace bug: in the following example, the grace notes
cause a loss of synchronization between the two voices.

X:1
T:Grace problem
M: 2/4
L: 1/4
K: G
Q:1/4 =60
V:1
{cde}f/|ed|cB|
V:2
z|CD|CD|

According to the documentation the grace notes are given
a length of 1/8 or half of the unit length specified in the L: field.
The three grace notes cde add up to be longer than the home note f,
so it is impossible to trim f in order to accommodate the grace
sequence. According to the documentation, abc2midi should cut out
the grace sequence in order to avoid loss of synchronization.
Instead abc2midi does not affect the grace sequence and the
two voices are out of synchronization.

Analysis: the function applygrace_new() in store.c computes the
difference between the length of the grace sequence and the
home note, but the test should read
if (adjusted_num <= 0.0) /* not long enough */
instead of
if (adjusted_den <= 0.0)
I would guess this bug has been around since 2004.

In addition I added a warning that the grace sequence is too long.

The code to change the length of the grace notes to zero
did not work correctly for some reason that I have not
tried to figure out -- (mf_write_midi_event tries to 
record a delta_time = -1). Instead I just removed all the
grace notes from the feature representation.


November 18 2014

Abc2midi fermata bug: the !fermata! instruction applied to a rest
also applies to the following chord. In the following example,

X:1
T: fermata rest bug.
L: 1/8
M: 6/8
K:D
 !fermata!z6 |[A,DF]2G [CDFA]GF |C D2 C D2|

Both z6 and [A,DF]2 are doubled in length.

Incidentally if we substituted Hz6 for !fermata!z6, the
program works correctly. 

Analysis: as evident in this file, this is not the
first !fermata! bug.  Apparently in this case, decorators[FERMATA]
flag was not reset to 0 after the event_rest() in parseabc.c.
The fix was to add the statement decorators[FERMATA] = 0
after the event_rest() call in parseabc.c.

Note it is not correct to apply a fermata to a multirest.
i.e. Z3| means three bars of rests. HZ3 does not mean
three bars of fermata rests and the same applies to
!fermata!Z3. 

In addition, I have improved the bar length warning to
include the track number where it was applied. The track number
is related to the voice number in some way.


December 25 2014

Abc2midi new feature: the error and warning messages now provide
both the line and character position location in the abc tune
where the message was issued.

Implementation: the character position is stored in the variable
lineposition in parseabc.c. This variable is linked as an extern
to store.c and genmidi.c. A new array charloc[] in store.c was introduced
to record the character position when addfeature() is called.
When writetrack is executed in genmidi.c, lineposition is updated
for each feature element processed. lineposition and linenum are
now both printed by event_error() and event_warning() in store.c.



February 22 2015

bugs.debian.org reported that abc2abc, abcmatch, yaps, and midi2abc
crash with certain malformed input parameters. Fixes were applied
to toabc.c, abcmatch.c, yapstree.c and midi2abc.c.

March 11 2015

Abc2midi multirest bug. It is common to list the voices before
the time signature and unit length declaration.

X:1
T: correct test file
V:1  name="1_Requinta_Eb"   sname="1Re_Eb"             %config, program 1 72 /control 7 80 /transpose +3
V:2  name="1_Clarineta_Bb"  sname="1Cl_Bb"             %config, program 2 71 /control 7 80 /transpose -2
V:3  name="1_Saxofone_Eb"   sname="1Sx_Eb"             %config, program 3 65 /control 7 80 /transpose +3
V:4  name="1_Corneta_Bb"    sname="1Cr_Bb"             %config, program 4 59 /control 7 80 /transpose -2
M: 2/4
L: 1/8
K: G
V: 1
C4| C4| C4| C4|
V:2
z4| z4| z4| z4|
V:3
Z| Z| Z| Z|
V:4
Z4|

In this example abc2midi does not get the correct time signature and
unit length for voices 1 to 3.

Fix: Added a new function meter_voice_update(n,m) which sets
the meter for all declared voices if not past the header.



March 16 2015

Abc2midi - new feature. In theory there should not be any limit
on the number of tracks that is produced provided that the user
takes care of assigning the right channels to the voices.
I have extended the voicecode array in parseabc.c so that 24
voices can be handled without overruning the array. In genmidi.c
I have merely changed the name of the array channels[] to
channel_in_use[] so its purpose is better understood. The
use of more than 16 tracks will lead to some warnings issued
but the program should still produce a useful MIDI file.


March 23 2015

Abc2midi - improvements.

In order to support extended voice overlay,
introduced two new functions event_start_extended_overlay() and
event_stop_extended_overlay which are called from parsemusic() in
parseabc.c when (& or &) are detected in the abc file. The
two functions are defined in store.c, toabc.c, yapstree.c and
matchsup.c. The functions turn on and turn off the state variable
extended_overlay_running.

In event_specific() in store.c we verify that channel in
%%MIDI channel command lies between 1 and 16 inclusive. If
not it is set to 1 and an error message is issued.

A new state variable no_more_free_channels is introduced in
store.c and set to zero in finishfile(). When findchannel()
in genmidi.c cannot find a free channel a message "All 16  
MIDI channels used up" is issued and the variable no_more_free_channels
is set to 1.


March 24 2015

Abc2midi - improvements.

Abc2midi in the past did not keep track of the channel assignments.
If we allow inheriting channel assignments for split voices, now
called voice overlays, we need to know the MIDI channel assigned
to the voice. I added midichannel to the voicestruct in store.c
to store the MIDI channel when a %%MIDI channel is encountered.
So far %%MIDI channel also calls addfeature() to add a channel
feature in the feature array. (This is how the channel number
has been passed to writetrack in the past.)

The function findchannel() in genmidi.c does not know that a
channel number was already assigned to the track (if that was
the case). The voicestruct is not passed to genmidi.c from store.c
but trackdescriptor is passed as an external. I therefore added
midichannel to trackstruct in genmidi.h and set trackdescriptor.midichannel
in the function setup_trackstructure() in store.c. Added an
argument tracknum to starttrack() in genmidi.c so it can grab
the midichannel number from trackdescriptor[].

The function event_split_voice() now passes the midi channel number
assigned to the voice to the new voice that it creates. The behaviour
of the split voice now depends on whether a channel number has
been assigned to the original voice. If no channel number has
been assigned, then both the original and child voice will have
a midichannel of -1. If the value is -1, then a new and distinct channel
number is assigned to each voice. Otherwise the original and
child voices will assume to the same channel number that was
given when the voice was created.


March 25 2015 March 26 2015

Adding code to support extended split voices. In event_bar (store.c)
do not recurse back to the original voice if inside an extended_overlay.
In stop_extended_overlay(), recurse back to the original voice.

The following is an example of the extended voice overlay.

X:1
T: extended voice overlay
M:2/4
L:1/4
K:C
GA|(&Bc|de|de&FG|FG|FG|&)|DE|
GA|(&Bc|de|de&FG|FG|FG|&)|DE|


April 08 2015

The parsing of the key signature when it contains modifiers with
double flats or double sharps does not work correctly. For
example:

X:1
T: double flat
M: 2/4
L: 1/8
K: Ab _F__B_/2C
F2 B2|C2D2|

The double flat preceding B in the key signature was interpreted
as a single flat and B2 in the first bar was converted to Bb instead
of A.

Fix: the logic in readword() in parseabc.c was changed so that
a break does not occur on the second flat or sharp.


April 13 2015

Abc2midi, abc2abc, yaps : minor bug. The tune

X:1
T: single colon
M: 2/4
L: 1/8
K: F
[|: ABcd|ABDF:|]

returns a message 'Single colon in bar', otherwise the output is
correct.

Analysis: this is a problem with parsemusic() in parseabc.c.
When the parser encounters | it check for a : following and
treats them both as BAR_REP. On the other hand if the parser
encounters [| it neglects to check for a following : and the
: is not associated with anything. 

Fix: added a check for ':' in case '['.


April 17 2015

Abc2midi staccato chord bug.


%abc-2.1
X:1
T: staccato problem
M:2/4
L:1/4
Q:1/4=116
K:D
%
V:K
%
% Case 1: works if isolated:
% F A/ .[DF]/ |
%
% Case 2: works:
% F A/ [.D/.F/] |  E E & Cx |
%
% Case 3: works:
%  F A/ [DF]/    |  E E & Cx |
%
% Case 4: doesn't work:
 F A/ .[DF]/   |  E E & Cx |
%
% Case 5: doesn't work:
 F A/ [.D.F]/   |  E E & Cx |

Both cases 4 and 5 return an error message

Warning in line-char 26-28 : Track 2 is 4.554167 quarter notes long not 4.054167
and the note C# in the voice overlay comes 1/2 beat late.

Analysis, the staccato introduces a REST in the internal representation
of the chord. When the length of the chord is specified at the end of
the abc chord representation, eg. [CEG]n/m), abc2midi calls the function
fix_enclosed_note_lengths which changes the lengths of all the enclosed
notes to n/m. Unfortunately, the REST in the chord was not expected
and was not modified. The representation of the underlying voice
is incorrect and as a result the overlain voice does not get
synchronized at the right place.

Fix: now test for NOTE, TNOTE and REST in the chord in the function
fix_enclosed_note_lengths in store.c.
 

April 28 2015

Abc2midi: dotted slur

The abc standard recognizes dotted slurs which abcm2ps displays as a
slur with a dotted curve. The dotted slur is indicated with parenthesis
preceded by a period as shown below.

X:1
T: DottedSlur
M: 2/4
L: 1/8
K: A
.(ABcd)|(ABcd)|ABcd|

Currently abc2midi reports the error.
Error in line-char 6-0 : Malformed note : expecting a-g or A-G

Analysis: parsemusic() in parseabc.c assumes '.' is a staccato decoration
and expects a note to follow. Instead it sees a '(' and reports an error.
Since abc2midi does not treat slurs differently, the resulting MIDI
file is correct.

Fix:
If a '.' is encountered, parsemusic checks for a following '('.
The fix also affects abc2abc, yaps, and abcmatch.


April 29 2015

Abc2midi always prints its version number when it runs.



May 11 2015

Abc2midi does not recognize the inline command [r: some remark].

X:1
T:Remark not allowed
C:JWDJ
M:4/4
L:1/4
K:C
[K:D] A2 B2| [r:!fermata!]G4 |]


Analysis: the 2.1 standard allows users to enter a remark inside a
line using the [r: ...] inline field. This command should be treated
the same way as a comment indicated with a '%' in the first column of
the text line (eg.)
% comment
Abc2midi does not recognize r: inside an inline field command and reports an error.
Error in line-char 7-13 : Field not allowed in tune body

Fix:
In parsefield() in parseabc.c, added r to the string EIKLMPQTVdswW+ . Thus
if ((inbody) && (strchr ("EIKLMPQTVdrswW+", key) == NULL)) /* [SS] 2015-05-11 */
The following switch statement falls into case default: which
treats the field as plain text.

Note: Though the standard probably allows the remark to extend over
several lines, eg.

X:1
T:Long remark not allowed
C:JWDJ
M:4/4
L:1/4
K:C
[K:D] A2 B2| [r: some long
remark]G4 |]

this is not supported in the abcmidi package. (It would require
more extensive modification.) The user should use  '%' to insert
multiline comments.


May 13 2015

abc2midi, abc2abc, yaps voice transpose bug.

In the following sample,


X:1
T: octave problem
M: 4/4
L: 1/4
V:1 clef=treble octave=-1
V:2 clef=treble octave=-1
K:G
V:1
ABCD|EFGA|
V:2 
abcd|ABCD|

Applying abc2abc to the tune returns

X:1
T:octave problem
M:4/4
L:1/4
V:1 clef=treble octave=0
V:2 clef=treble octave=0
K:G
V:1
ABCD|EFGA|
V:2
abcd|ABCD|

octave was changed to zero and abc2midi applied on the same tune
does not shift down the pitch by an octave. If we change V:1 and V:2
to
V:1 octave=-1
V:2 octave=-1
the programs work correctly.

Analysis:

This is an issue with the code parsevoice() in parseabc.
The clef=treble also specifies the octave and sets the flag
cgotoctave to 1. This flag indicates that the octave is
also set by the clef command.  If you wanted octave=-1
you should say clef=treble-8.  To avoid further confusion,
in the future, I modified parsevoice so that it allows octave=
following the clef= property  to override the octave value set
by the clef= property.

The parsevoice() code is rather brittle and expects all
the voice parameters to be in a specific order. The code
looks for the following properties in this order.
clef=
transpose=
octave=
name=
sname=
middle=

If the properties are not in this order, they may be missed.
The function parsevoice scans the V: string looking for the properties
in the specific order using the 'while (*s != '\0). Each time
a property is found the pointer *s is advanced past that property
by one of the functions parsetranspose(), parseoctave(),
parsename(), and etc and the while loop goes back to the
beginning. parseclef() is called repeatedly and even though
it does not find clef=, it still returns the variable 'word'
which is used for matching by the above mentioned functions.

If I am rewriting the code, I would replace casecmp() with
strcmp() and use a switch (word) control to call one of the
functions parsetranspose(), parseoctave(), and etc. This
involves changing all of those functions too. Note parsetranspose()
and parseoctave() are also called when the K: field is
scanned.


May 17 2015

abc2midi: %%MIDI makechordchannels bug

The makechordchannels command was introduced in October 3 2006 
for handling chords consisting of notes consisting of microtones.
When the command appears after a V: declaration, too many chord
channels are created which may cause the 15 channel limit (one
channel is used for percussion), to be exceeded. For example,

X:1
T: too many chord channels
M: 2/4
L: 1/4
K:G
V:1
%%MIDI beataccents
%%MIDI makechordchannels 7
G2|
V:2
%%MIDI program 42
%%MIDI nobeataccents
E2|
V:3
%%MIDI program 43
C2|

The following errors are reported.
Error in line-char 10-2 : All 16 MIDI channels used up.
Error in line-char 15-2 : Channel limit exceeded


Analysis: 

During the creation of track 0 (the header track in a type 1 MIDI file),
the entire tune is scanned and some of the MIDI commands are activated.
Unfortunately, the makechordchannels is activated twice; once for
track 0 and once for track 1. The chord channels created in track 0
are never used.

An abc tune that creates at type 0 MIDI file, (i.e. no voices,
guitar chords, percussion etc.) would not pose a problem for this
implementation.

Fix:

Added a test in the function makechordchannels (in genmidi.c) to
prevent the creation of chord channels in track 0 for multitrack
MIDI files.



May 19 2015

Abc2midi temperament support was extended by Hudson F.M. Lacerda.
Microtone accidentals can be used along with temperamentlinear.
In that case, the accidental ratio is based on the new chromatic
semitone size, defined as 7 fifths minus 4 octaves. (Run abc2midi
with the verbose option (-v) to see the temperament values.)
As an exception, the microtonal deviation in cents can be represented
by using denominator=100 in the accidentals. For example:

<pre>
X:1
T:\%\%MIDI temperamentlinear - microtone accidentals in cents
%%postscript /ft5475{M -3 3 RM 6 -6 RL 2 SLW stroke}def
%%postscript /ft35939{2 copy ft0 M -7.5 -3 RM 12 F3 (7) show}def
M:none
K:C
%%scale 1.3
V:1
%%MIDI program 17
%%MIDI temperamentlinear 1200 702 %% Pythagorian tunings
%%MIDI makechordchannels 3
"^Pure;major;chord"\
[C_22/100EG]8 y |\
"^Pythagorian;major;chord"\
[CEG]8 y ||\
"^Pure;4:5:6:7;chord"\
[C_22/100EG_141/100B]8 y |\
"^Pythagorean;7-chord"\
[CEG_B]8 y ||
</pre>

<p>
A new command %%temperamentequal was introduced.
<br>
%%MIDI temperamentequal <ndiv> [octave_cents] [fifth_steps] [sharp_steps]

This command sets a tempered scale defined by 'ndiv' equal divisions
of 'octave_cents' (default is the octave = 1200 cents).
The optional parameter 'fifth_steps', if provided, is an integer that
defines the size of the fifth in steps of the temperament.
This sets where is the note G in the temperament.
When 'fifth_steps' is omitted or 0 (zero), the program computes it
as an approximation of the frequency ratio 3/1, minus the
(possibly tempered) octave.
The optional 'sharp_steps' defines the meaning of the accidentals.
'sharp_steps' is the number of steps between a natural note and
a sharpened note (e.g. between =C and ^C).
By default, the size of a sharp/flat deviation is based on the
size of the chromatic semitone in the specified temperament: 7 fifths minus
4 octaves. The values in use in the temperament can be viewed
by running abc2midi with the command-line option -v (verbose).
With temperamentequal (as with temperamentlinear), microtone accidentals
are interpreted as fractions of the sharp size in the
specified temperament, except if they use denominator=100, which
defines microtonal deviations in cents.
The conventional temperament can be reset with the command temperamentnormal.
See also: temperamentlinear, temperamentnormal, makechordchannels


Implementation: Changes in store.c are marked with [HL] 2015-05-15
New global variable 'sharp_size'
   It is the the size, in pitchbend units, of the chromatic step
   between (e.g.) =C and ^C. (This is computed from octave and
   fifth sizes when using temperamentlinear or temperamentequal.)


event_specific()
   Function changed to modify the command temperamentlinear
   and to add the command temperamentequal.

   temperamentlinear:
        Compute 'sharp_size';
        Print information when -v (verbose option);
        Fix the command name in the error message.

   temperamentequal (new command):
        Compute octave_size, fifth_size, sharp_size;
        Temperament information when -v (Verbose option).


pitchof_b()
        Function changed to handle microtones in user-defined temperaments.
        Global variable 'sharp_size' is used for that.


event_microtone()
   Rounding instead truncation as slight improvement of precision.
   (MIDI bend is rough for tuning.)




May 21 2015

Abc2midi drone bug:

The %%MIDI drone command is ineffective. In the following example,

X: 1
T:Banks and Braes
M:6/8
L:1/8
S:Slow March
K:HP
%%MIDI program 109
%%MIDI gracedivider 4
%%MIDI drone 67 44 45 90 90
%%MIDI droneon
 {Gdc}d2{g}d{g}ede|\
{g}faf{gef}e2{g}d/2e/2| 

the %%MIDI drone 67 44 45 90 90 does not change the drone characteristics.

Analysis: The drone is put in a separate MIDI track. The %%MIDI drone
command is processed in the first track, and updates the elements
of the drone structure. When the drone track is written starttrack()
in genmidi.c, initializes the drone structure destroying any information
that was recorded.

Fix: initialization of the drone structure is done during compilation
time. Note, if the tune has more than one  %%MIDI drone command,
only the last one is effective. 


June 01 2015

Abc2midi new feature: introducing new commands %%MIDIdef and %%MIDIx.
%%MIDIdef code line
links code a unique string less than 7 letters to a line of strings
that normally occurs in a MIDI command. For example
%%MIDIdef bnd1 bendstring 400 400 300 100 -100 300 400 400 400
link the string bnd1 to " bendstring 400 400 300 100 -100 300 400 400 400"
Now you can call up the MIDI command
%%MIDI  bendstring 400 400 300 100 -100 300 400 400 400
using a shorthand
%%MIDIx bnd1.

Example:

X:1
%%MIDIdef type1 bendstring 0 0 600 600 600 600 0 -600 -600 -600 -600 -600 -120 0
%%MIDIdef type2 bendstring 0  0 0 0  0 0 400 800 800 -800 -800 -400 -400 -400
%%MIDIdef inst program 67
%%MIDIdef t3 bendstring 0 0 0 0 0 500 500 600 600 -600 -600 -500 -500
T: MIDI
M:2/4
L:1/2
K: D
%%MIDIx inst
%%MIDIx type1
!bend!A|B|\
%%MIDIx type2
!bend!C|D|


This is useful when you have several different bendstrings and you
wish to call them up in different places in the tune using a code.

There is a limit of 20 distinct MIDIdef's in your tune.

Implementation: in parseabc.c added a new function readaln which
is like readstr but scans for the next word (that may contain numerics)
in the input string. (The words are separated by spaces or tabs.)
In store.c, added two new functions parse_mididefs(s) and 
expand_midix(s) for handling the %%MIDIdef and %%MIDIx commands.
These functions are called in the function event_specific().

June 02 2015
continuation: added strcmp(key, "MIDIx") in event_info_key() in
store.c


June 07 2015

Abc2midi bug: the !bend! command does not work inside a slur.
In the following example,

X:1
T: slur and bend
M: 2/4
L: 1/8
K: F
%%MIDI bendstring 500 500 500 0 -500 -500 -500 
%%MIDI program 73
!bend! D4|(!bend! F4| D4|

a bend is not applied on F4.

Analysis: writetrack() in genmidi.c tests whether a note is inside a
slur. If it is inside a slur, both note triming and note bending were
suppressed. Fix, writetrack() was modified to allow note bending inside
a slur.

The MIDIdef, MIDIx code word was allowed to contain up to 31 characters.
All characters except white spaces are allowed inside the code word.


June 08 2015

Abc2midi bug: !bend! causes tracklenth to be too small. Fix:
in timestep() in queues.c, update tracklen before note_effect is
called instead as after.


June 16 2015
Abc2midi new feature: introducing %%MIDI expand m/n. This acts
like %%MIDI trim m/n except it expands the note by this amount.

Implementation: added feature EXPAND to featuretype in abc.h.
In event_specific() in store.c, test for %%MIDI command 'expand'
and addfeature(EXPAND,...) if found. In genmidi.c introduce
new globals (expand, expand_num, and expand_denom) which are
set in writetrack when feature EXPAND is detected. If the
flag expand is set, then the active note is expanded. Here
is a test tune.

X:1
T: note expansion
M: 4/4
L: 1/2
K: G
%%MIDI program 52 
CD|GA|
%%MIDI expand 1/2
de|fe|BA|


June 16 2015
Abc2midi new feature: added track identification annotation to
midi file so we know whether it is a gchord, note, lyric, drum, etc
track.


June 30 2015
Abc2midi split voice bug: change of unit length defined by L: does
not propagate to the voice overlay. eg.

X:1
T: split voice bug - unit length
M: 4/4
L:1/8
K: G
C8 & E8|\
L:1/4
cdAB & GAEF|G4 & D4:|

causes loss of synchronization starting from the second measure.

Analysis: the L:1/4 does not change the unit length in the split
voice and the notes GAEF and D4 are too short.

Fix: in event_split_voice() in store.c set the unit length
to the same length as the parent voice.


July 02 2015

Abc2abc bug: the fix introduced in May 13 2015 introduced another
problem. In the example

X:1
T: Octave
M: 2/4
L: 1/8
K: G
V:1 clef=treble+8 
CDEF|ABcd|

Applying abc2abc returns

X:1
T:Octave
M:2/4
L:1/8
K:G
V:1 clef=treble+8 octave=1
CDEF|ABcd|

Unfortunately the added parameter octave=1 causes abcm2ps to
also display the notes one octave higher.

Analysis: the parameter octave=1 is useful to abc2midi as
it tells the program to shift the notes up one octave when
it creates the midi file; however, this is not desired when
running abcm2ps. Abcm2ps uses clef=treble+8 to place an 8
above the treble clef and that is sufficient.
The problems occurs in the function isclef() in parseabc.c.
The function changes gotoctave to 1 when it sees treble+8.
The fix on May 13 2015 forces event_voice to issue an octave=1
when it sees cgotoctave = 1. 

Fix: in isclef() a conditional block {} was created for all
if (fileprogram == ABC2MIDI && *gotoctave != 1 && *octave != 1)
statements, and *gotoctave = 1 was moved inside this block.


July 08 2015

abc2midi feature: added sus4 to the list of chord names recognized.
Added hint to message 'Unrecognized chord name ...".


July 15 2015

abc2midi bug: abc2midi crashes (segmentation error) on %%MIDIx.
In the following example:

X:1
T: segmentation error
M: 2/4
L: 1/8
K: G
%%MIDIx crash
ABCD|


abc2midi fails.

Analysis: abc2midi fails to detect that there is no corresponding
%%MIDIdef for the code word 'crash'.

Fix: the function expand_midix() now checks for this case.
 

July 24-28 2015

abc2midi: new feature !shape! and %%MIDI controlstring.
Introduced a new midi command
%%MIDI controlstring n m1 m2 m3 ...
where n, m1, m2, and etc are numbers between 0 and 127.
%%MIDI controlstring n m1
is equivalent to the %%MIDI control command. When more than
one data value m1 and etc. follow, then this defines how
to shape the note following the !shape! instruction. The
following example illustrates shaping the note F4 by
varying the mod wheel.

X:1
T: control string
M: 4/4
L: 1/4
K: G
%%MIDI controlstring 1 125 80 40 0
%%MIDI program 60
!shape! F4| D4|F2G2|

The midi file produced will look like

Header format=0 ntrks=1 division=480
Track 1 contains 115 bytes
  0.00   Metatext (Text Event) note track
  0.00   Metatext tempo = 120.00 bpm
  0.00   Metatext key signature G (1/0)
  0.00   Metatext time signature=4/4
  0.00   Metatext (Seqnce/Track Name) control string
  0.00   Program   1 60 (French Horn)
  0.00   Note on   1  f#4 105
  1.00   CntlParm  1 Modulation Wheel = 125
  2.00   CntlParm  1 Modulation Wheel = 80
  3.00   CntlParm  1 Modulation Wheel = 40
  3.99   CntlParm  1 Modulation Wheel = 0
  4.00   Note off  1  f#4   0
  4.00   Note on   1   d4 105
  8.00   Note off  1   d4   0
  8.00   Note on   1  f#4 105
 10.00   Note off  1  f#4   0
 10.00   Note on   1   g4  95
 12.00   Note off  1   g4   0
 12.05   Meta event, end of track

The whole note F# is modified in 4 equal segments.

Note the !shape! does not work in combination with the !bend! command
presently.

Implementation: created the new function note_effect4() in queues.c

The maximum number of codenames for %%MIDIdef has been increased
to 200. The codename can now be as long as 31 letters.


July 27 2015 - August 3 2015

abc2midi: extension of !shape! for combining %%MIDI controlstring
and %%MIDI bendstring.

Implementation: added a new struct eventstruct and a struct
array eventlist[200]. Created new procedures note_effect5(),
output_eventlist(), and compare_events().


August 4 2015

abc2midi: channel bug. The following tune plays incorrectly.

X: 1
T: channel problem
M: 6/8
L: 1/8
K: G
%%MIDI channel 1
%%MIDI bassprog 68
%%MIDI chordprog 20
D | "G"G3 GAB | "D"ABA ABd |

The melody should be played on the Acoustic Piano; instead
it is played on the oboe (MIDI program 68).

Analysis:

The %%MIDI channel setting is redundant and causes the problem.
Both the melody and the bass accompaniment use the same channel.
The command %%MIDI bassprog 68 causes the melody to be played
by program 68 (the oboe). The bug was introduced in March 16 2015.
The variable channel_in_use[channel] was not set to 1 correctly in
starttrack() in genmidi.c.


August 06 2015

Fixed compile issue on Mac OS 10.10.4 in genmidi.c


August 10 2015 - August 11 2015

abc2midi new feature:
%%MIDI controlstring restores the controller back to its default after
the shaped note is played. The default can be changed with a regular
%%MIDI control command. 

Implementation: added a new array controldefaults[] in genmidi.c which
is linked to queue.c.

Updated abcguide.txt.



August 18 2015

abc2midi: Support for the directive
%%propagate-accidentals not | octave | pitch
was extended to include the three choices described in
http://abcnotation.com/wiki/abc:standard:v2.1#accidental_directives
Furthermore, the default was changed to 'pitch' in compliance
with the standard.

Implementation: All the changes were limited to the source code
store.c. The flag retain_accidentals was eliminated and the
switch nopropagate_accidentals was changed to propagate_accidentals
in store.c. In event_specific(), the switch propagate_accidentals
is set on the basis of the directive %%propagate-accidentals,
to 0, 1, or 2.

In pitchof_b(), the code for propagating accidentals (including
microtones) was reworked.

Here is a simple test file.

X:1
T:accidental
M:2/4
L:1/8
K:C
%%propagate-accidentals pitch
^C2c2|
%%propagate-accidentals not
^C2c2|\
%%propagate-accidentals octave
^C2c2|\
%%propagate-accidentals no

The c2 note is affected by only the pitch directive (default).
The last %%propagate_accidentals returns an error message.



August 19 2015

Abc2midi: complex time signature extension. Abc2midi now
interprets M: 2+3+2/8 as M:7/8.

Implementation: a small loop was added in the function
readsig() in parseabc.c


August 20 2015

Abc2midi new feature: introducing %%MIDI controlcombo. This allows
combining two controlstrings into 1. Here is an example:

X:1
T: control string combo
M: 4/4
L: 1/4
K: F
Q: 1/4 = 60
%%MIDI program 123 # bird tweets
%expression
%%MIDI controlstring 11 110 90 60 40 60 60 90 110
%%MIDI controlcombo
%panning
%%MIDI controlstring 10 0 0 20 40 60 80 100 120 127 127
!shape! c4 |

controlstring 11 varies the expression and controlstring pans
the output from the left to right speaker. The %%MIDI controlcombo
command tells abc2midi that the panning controlstring should be
included with the expression controlstring.

Implementation: in genmidi.c, the controldata array has been
converted into a two dimensional array and controlvals has been
converted from a scalar to a single dimensional array. A flag
controlcombo indicates whether to replace or combine the new control
string.  Each one dimensional component of controldata stores one
of the control strings into a 'layer'. In queues.c, the function
note_effect4 scans all layers for data and appends it to the
eventlist[].


August 20 2015

Abc2midi new feature: If two controlstring are referenced in the
%%MIDIx  they will combined in the manner described above.
Here is a sample file.


X:1
T: control string combo
M: 4/4
L: 1/4
K: F
Q: 1/4 = 60
%%MIDI program 123 # bird tweets
%expression
%%MIDIdef expr controlstring 11 110 90 60 40 60 60 90 110
%%MIDIdef pan  controlstring 10 0 0 20 40 60 80 100 120 127 127
%%MIDIx expr pan
!shape! c4 |C4|


Implementation: expand_midix was renamed to process_midix and the
code was reworked so that it would loop through all the code words
and call event_midi() to process all the %%MIDI commands that
were generated.


August 24 2015

abc2midi bug: the following tune was not processed correctly.


X:1
T: control string bug
M: 4/4
L: 1/4
K: F
Q: 1/4 = 60
%%MIDI program 2
%%MIDI controlstring 11 110
!shape! c4 |
%%MIDI controlstring 11 60
!shape!E4|D4|

All three notes c4,E4 and D4 are played at the same time.

Analysis: in note_effect5() the conditional if (j > 1) should
only apply to the qsort function.


August 25 2015

abc2midi bugs: the following tune was not processed correctly.


X:1
T: controlstring and bendstring problems
M: 4/4
L: 1/4
K: F
Q: 1/4 = 120
%%MIDI program 60 # French Horn
%%MIDIdef expr110 controlstring 11 110
%%MIDIdef expr60 controlstring 11 60
%%MIDI bendstring 0 2000 2000
%%MIDIx expr60
!shape! c2 c2 |

The resulting midi file had two problems. The first c2 was extended
in length and the pitch of the second c2 was effected by the !shape!
command.

Fixes: the pitchwheel was restored to its initial value at the end
of the altered note. When restoring the controller to the initial
state we checked whether a bend string was also processed.


August 28 2015

abc2midi bug:

The following file produces an artefact at the end of note.


X:1
%%MIDIdef voloff100 controlstring 11 100 90  80 70 60 50 40 30
%%MIDIdef no-bend bendstring
T:?
C: ?
M: 4/4
L: 1/4
Q:1/4=130
K: none
%%propagate-accidentals not
%%MIDI beat 100 95 80 1
%%MIDIdef petasth bendstring 0 0     900 900 0  -900 -900 0  -400
V:1
%%MIDI program 60 % french horn
[M:3/4][I: MIDIx= petasth]!shape!A[I: MIDIx=no-bend voloff100]!shape!E2


Analysis note_effect5 restores the controller defaults before the
note ends causing a transient at the end of the note.

Fix: the restoration is done after the note.


August 30 2015

abc2midi bug: in the following tune,


X:1
%%MIDIdef voloff100 controlstring 11 100 90  80 70 60 50 40 30
%%MIDIdef no-bend bendstring
T: controlstring state not initialized at start of track
M: 4/4
L: 1/4
K: C
%%MIDIdef petasth bendstring 0 0     900 900 0  -900 -900 0  -400
V:1
%%MIDI program 60 % french horn
[I: MIDIx= petasth]!shape!A2[I: MIDIx=no-bend voloff100]!shape!E2

the voloff100 is applied to A2 despite the fact the command
occurs after A2

Analysis: abc2midi creates a two track file. While it is creating
the header track, controlnvals[0] was set to a nonzero value after
MIDIx=no_bend voloff100 was processed and controldata[] contained
appropriate data to perform the voloff100. Unfortunately, when
the next track written controlnvals[0] was not reset.

Fix: reset controlnvals[]


August 31 2015

abc2midi bug: in the following file

X: 1
%%MIDIdef slur2 bendstring 0 0 0  0 0 1000 
T: last bendstring not picked up
M: 4/4
L: 1/4
K: G
Q: 1/4=80
%%MIDI program 42 % french horn
V:1
G[I: MIDIx= slur2]!bend!A

the bendstring value 1000 is not picked up

Fix: in do deferred() (genmidi.c)  the statement
if (p* == 0) break; was moved after i = i +1;



September 07 2015

Abc2midi new feature: in genmidi.c, the %%MIDI bendstring command can
now accept up to 100 increments to accommodate long notes (benddata[100]);
and the %%MIDI controlstring command can now accept up to 100 values
to accommodate long notes (controldata[3][100]). In queues.c eventlist
array was extended to 500 to handle the additional complexity. 


September 08 2015

Abc2midi: new commands %%MIDI vol n and %%MIDI volinc m introduced
where n is a number between 0 and 127 and m is a positive or negative
integer. The purpose of these commands is to provide to set the velocity of
the note immediately following. All remaining notes are unaffected.
The commands override the effects of %%MIDI beat, %%MIDI beatstring,
%%MIDI beataccents, %%MIDI beatmod,  %%MIDI nobeataccents,
%%MIDI stressmodel, !ppp!, !pp!, !p!, !mp!, !mf!, !f!, !ff!, !fff!,
!crescendo<!, !<(!, !diminuendo)<!,and  !>) for the particular note
that is affected.

%%MIDI vol n

sets the velocity of the next note to n.

%%MIDI volinc m

increments (or decrements) the velocity of the next note
by m, automatically ensuring that the velocity is in the
range 0 to 127.

For example:


X: 1
T: Velocity alteration
M: 4/4
L: 1/4
K: F
CDEF|C\ 
%%MIDI volinc -30
D E [I: MIDI = vol 100] F| CDEF|

By default the velocities of the notes CDEF are 105, 80, 95 and 80.
(You can use the %%MIDI beat command to change these values.)
The %%MIDI volinc -30, decrements the default velocity of D by
30 so its velocity is 50 instead of 80. The MIDI vol 100
command embedded in the info field, sets the velocity of F
to 100. The velocities of the remaining notes in the last
bar retain their defaults 105,80,95 and 80.

Implementation:

Introduced two global integer variables single_velocity_inc and
single_velocity which are set to the default values 0 and -1
in the writetrack() in genmidi.c. These default values indicate
that no alterations are to be made to the following note.
Introduced new functions apply_velocity_increment_for_one_note()
and set_velocity_for_one_note() which is called by noteon()
in genmidi.c. The function dodeferred() in genmidi.c acts
on the new %%MIDI commands and changes the default values of
single_velocity_inc and single_velocity.



September 08 2015

Abc2midi new feature: a different syntax can be used for changing
the velocity of a single note as illustrated below.

X: 1
T: Velocity alteration -different syntax
M: 4/4
L: 1/4
K: F
CDEF|C\ 
I: volinc = -30
D E [I: vol = 100] F| CDEF|

The behaviour is identical to the above example.

Implementation: the function event_info_key() in store.c was updated
to recognize the key words vol or volinc, generate the respective
%%MIDI commands, and send these commands to event_specific() for
processing.



September 08 2015

Abc2midi: new feature. The I: info command required to have an
'=' sign following the key word, so that it could handle a
group of commands such as 
I: MIDI = program 20 MIDI = drum d2dd 76 75 75
The purpose of the '=' sign was to allow the parser to
distinguish the key word(s) (here MIDI) from the value when more
than one key words appear. When only one command is embedded
it should be unnecessary to include the '=' sign. The
following sample illustrates the more lenient syntax that
is now permitted.

X:1
T: Generalized info syntax
M: 2/4
L: 1/8
K: F
I:vol=  60
% equal sign is optional if only key word is included
% in I: field.
C2 E2 | [I:vol 20] D2 F2| E2 [I:volinc = 50] C2|D2 [I:volinc -50]C2|
C2 E2 |\
%%MIDI vol 20
D2 F2|E2 \
% equal sign is required if more than one key word is present
I: MIDI= drum d2dd 75 76 76 MIDI = program 20
%%MIDI volinc 50
C2|
C2 E2| [I:MIDI= vol 20] D2 F2|


Implementation: the function event_info() in parser2.abc was
updated.



October 04 2015

The #ifdef _MSC_VER block was changed from
 #define snprintf _snprintf_s
to
 #define sprintf _snprintf
in both parseabc.c and store.c
(The function _snprintf_s expects additional parameters and
prevents compilation on some systems.)


October 04 2015

Some problems with Makefile.in were fixed. In addition an uninstall
option was introduced.

October 03 2015

Abc2midi: increased the size of benddata[100] to benddata[256],
controldata[MAXLAYERS][100] to controldata[MAXLAYERS][256],
%%MIDI bendstring will read up to 256 values in dodeferred (genmidi.c).
%%MIDI controlstring will read up to 256 values in doferred (genmidi.c)
eventlist struct was increased to eventlist[1000].


October 08 2015

Edited abcmatch.c genmidi.c midi2abc.c parseabc.c store.c toabc.c in order
to eliminate warnings from Microsoft Visual Studio 2010.
makefiles/makefile.w32 was updated to make dynamically linked executables
(instead of static).


October 18 2015

Edited abcmatch.c, genmidi.c, matchsup.c, mftext.c, midi2abc.c, midicopy.c,
midifile.c, parseabc.c, queues.c, store.c, stresspat.c and toabc.c
to clean up all the implicit int warning messages reported by the
Debian compiler.


November 05 2015

abc2abc:

keep 'M:C' and 'M:C|'; i.e. don't automatically change them to
'M:4/4' and 'M:2/2'


% sample4.abc - this file is part of abcm2ps
X:1
%%abc-version 2.0
T:testing 'common time' and 'split common time' signatures
T: These should be preseved when transposing
% use abc2abc generated from source including fixes from 'abcMIDI-2015.11.5_LM'.
% try command: 'abc2abc common_time_sigs.abc -t 2';
% check that e.g. 'C' hasn't become '4/4'.
M:C
L:1/4
K:C
CDEF |[M:4/4] GABc|]
M:2/2
CDEF |[M:C|] GABc|]


November 15 2015

Addressed the following Debian compiler warning messages reported in
https://qa.debian.org/bls/packages/a/abcmidi.html

    I pointer-cast-size-mismatch midicopy.c:371 (alpha, arm64, kfreebsd-amd64, mips64el, ppc64, ppc64el, s390x, sparc64)
    I pointer-cast-size-mismatch yapstree.c:1338 (alpha, arm64, kfreebsd-amd64, mips64el, ppc64, ppc64el, s390x, sparc64)
    I pointer-cast-size-mismatch yapstree.c:1352 (alpha, arm64, kfreebsd-amd64, mips64el, ppc64, ppc64el, s390x, sparc64)
    I pointer-cast-size-mismatch yapstree.c:1513 (alpha, arm64, kfreebsd-amd64, mips64el, ppc64, ppc64el, s390x, sparc64)
    I pointer-cast-size-mismatch yapstree.c:2176 (alpha, arm64, kfreebsd-amd64, mips64el, ppc64, ppc64el, s390x, sparc64)
    W implicit-declaration abcmatch.c:1274 (alpha, arm64, armel, armhf, hppa, hurd-i386, i386, kfreebsd-amd64, kfreebsd-i386, mips, mips64el, mipsel, powerpc, ppc64, ppc64el, s390x, sh4, sparc64, x32)


In yapstree.c changed (void*) to (int *) to the calls to addfeature.
In midicopy.c changed the call arguments of metaseqnum from 
(int seq) to (char c1, char c2).
In abcmatch.c added #include <ctype.h>


December 19 2015

Abc2midi: bug fix - calculation of equal temperament scale was changed
on October 08 2015. It has now been restored in store.c thanks to
Hudson Lacerda.



December 31 2015

Abc2midi bug:

The following tune causes abc2midi to crash when running with -BF parameter.

X:1
T: Missing R: field
M: 2/4
L: 1/8
K: G
%%MIDI stressmodel 2
CDEF|ABcd|

abc2midi crash.abc -BF 2
3.84 December 19 2015 abc2midi
Floating point exception

Fix: startfile() in store.c initializes rhythmdesignator to an empty
string. apply_bf_stressfactors() in store.c ensures that rhythmdesignator is
set before allowing the function to continue. The function
load_stress_parameters() in stresspat.c now has an error return and reports
an unidentified rhythmdesignator to apply_bf_stressfactors().


January 02 2016

Abc2midi > and < action:

In the past broken notes indicated by A>B and A<B did not expand into
A3/2 B1/2 and A1/2 B3/2 but instead were treated as (3A-AB and (3AB-B
unless abc2midi was run with the -RS option. In order to be compliant
with the ABC standards 1.6, 2.0, 2.1 and 2.2. The behaviour has been
reversed. Now the default ratio is 3:1 instead of 2:1.

X:1
T: broken
M: 4/4
L: 1/4
K: G
A3/2 B/ A/ B3/2|A>B A<B|

Thus for the above example, both bars will now sound the same unless
abc2midi is run with the -CS option. The command
%%MIDI ratio 2 1
still works as before.

Implementation:
All changes are restricted to the file store.c.
global variable ratio_standard set to 0 instead of -1
default_ratio_a and default_ratio_b now set to 2 and 6
In startfile() the actions following if(ratio_standard == -1)
was modified. In event that R: hornpipe occurs, the
default_ratios are set to 2 and 4 (in event_field).
Changed runtime parameter -RS to -CS to warn users of the
change.


January 03 2016

Abc2midi - improved gchord generator

When the %%MIDI gchord string is used to create Alberti Bass, (eg ghighi),
a situation could arise where there are not enough notes in the guitar
chord to produce a note. For example,

X:1
T: gchord
M: 6/8
L: 1/8
K: G
% "G" expands to G,B,D so g --> G, h --> B, and i --> D
%%MIDI gchord ghighi
"G" G6|G6|\
% "G5" expands to G,D so g--> G, and h --> D  but  i --> does not map
"G5" G6|G6|

i does not map producing a gap in the Alberti Bass

Fix: dogchords() in genmidi.c was modified to map to the last
note in the gchord chord in this situation to prevent a gap.
In the above example i would also map into D.


February 08 2016

Abc2midi: changed dim9[5] to {0,3.6,9,13}, added sus2 and 7sus2
(in store.c).


March 03 2016

Abc2abc: K: none sets all following occurrences of K: field
to K: none even when they occur in separate tunes.

Analysis: the global variable nokey gets set by K: none,
but is never reset. This is fine if you are using the -nokeyf or
-nokeys runtime parameter which applies to all tunes but not
what you want if you are dealing with a tune containing a
K: none command.

Fix: introduced a new global nokeysig initialized to 0
into parseabc.c and toabc.c which responds to the abc2abc runtime
parameters -nokeys and -nokeyf. In parsekey() in parseabc.c,
the control variable nokey is initialized to nokeysig.

March 15 2016

Fixed an assortment of spelling mistakes in the documentation in
this file. (Also readme.txt, abcguide.txt, genmidi.c, toabc.c, abc2midi.1,  
crack.c,  midi2abc.1, history.txt, coding.txt). Thank you Ross Gammon.


May 05 2016

Abc2abc: transposition of key modifier bug.

The following example illustrates a problem with the code
to transpose the key modifiers.

X: 25
T: C Natural, with a D sharp added to the key signature
M: 2/4
L: 1/8
K: C ^d
| cdef | gabc |

Transposing this up by one tone (-t 2), this becomes

X:25
T:C Natural, with a D sharp added to the key signature
M:2/4
L:1/8
K:Dmaj =F
| defg | abc'd |

The key modifier was transposed to F natural instead of
e sharp (chromatically identical notes) but as a result
 e was not upgraded to e# and the f# became f natural.

The fix was a completely replacement of the code written
in February 21 2011 (see above) in toabc.c. 130 lines of
code was eliminated and a new function transpose_note()
was introduced. The new function borrowed the transposition
code from event_note, so that key modifiers were transposed
the same way the notes in the music body are modified.


July 20 2016

Midi2abc: note grouping for 3/4 time is incorrect.
For 3/4 meter midi2abc groups the notes as EFG AGF instead
of EF GA GF in a bar.

Fix: in printtrack_with_splits(), printtrack_split_voice(),
and printtrack(), also check for waltz time (asig == 3)
before grouping notes as compound rhythm.


September 20 2016 and September 25 2016

Abc2midi: only handles user defined symbols between 'H' and 'Z'.

Fix: allow user defined symbols between 'A' and 'z'. Also applies
to abc2abc and yaps. Parseabc.c was upgraded.


January 01 2017

Midi2abc: There are times when you may wish to suppress broken
rhythms but still allow triplets. For example,

X:1
T:A Tune For Paddy: A Pint Of Guiness And One For The Goat
M:6/8
K:Emin
edB AGF | GEE E3 |
edB AGF | GEE E3 |

Applying abc2midi and midi2abc results in the second and
forth bar appearing as GEE2<E2 which is not desired.

New feature -nt now suppresses only triplets. To suppress
broken rhythms like C>D you need to use -nb. 


February 01 2017

abc2midi: %%MIDI gchordbars bug. The gchordbars factor does
not start working until after the first bar. For the following example,

X:1
T: gchordbars
M: 6/8
L: 1/8
K: C
%%MIDI gchordbars 2
%%MIDI gchord fffhhh
"G" G6|D6|G6|D6|G6|D6|

The gchord accompaniment is not expanded until after the first
bar.

Analysis: The variable gchordbarcount needs to be reset to 0  after
each call to set_gchords(). checkbars() will set gchordbarcount to
gchordbars if it is 0. Simarly drumbarcount should also be reset
after each call to set_drums(). The code is still temperamental,
so ensure that the MIDI gchordbars statement occurs prior to the
MIDI gchord declaration and precedes the bar line where it will
be applied.


April 10 2017

Abc2midi bug: abc2midi fails to create a midi file for

X:1
T: Microtone
M: 4/4
L: 1/4
K: G staffscale =1.2
G F G =F|

staffscale = is a specification for abcm2ps which is not
recognized by abc2midi. parsekey is attempting to treat
=1.2 as a specification of a microtone in the key signature.
sscanf() returns only one parameter instead of 3.

if (j > 7) j = (int) c - 'a';
if (j > 7 || j < 0) {printf("invalid j = %d\n",j); exit(-1);}

j is not a valid value because the variable c is 0.



Fix: changed

success = sscanf (&word[1], "%d/%d%c", &a, &b, &c);
          if (success > 0)

to

success = sscanf (&word[1], "%d/%d%c", &a, &b, &c);
          if (success == 3)



April 12 2017

Abc2midi,Abc2abc,Yaps new feature: Abcm2ps has many features
for creating a nice document. Abc2midi and other programs in
the abcmidi package may get confused when it sees certain lines.
I have introduced two new commands

%%MidiOff
and
%%MidiOn

which tell abc2midi and other programs to not parse the lines
in between.

For example:

X:1
T: Booth Shot Lincoln
C: Traditional
C: Arr. Pete Showman
R: Reel
Q: 1/2=90
M: 2/2
L: 1/8
K:A
|| y20 "A"ce2c e2ee | "D"fa2f a2fe- | \
"A"eBcB AcBA | "D"F3F F2FF |
%%MidiOff
%%begintext
 The next lines will not be played
%%endtext
%%MidiOn

The commands %%MidiOff and %%MidiOn, delineate a block
of text that we do not want the parser to process. Otherwise,
all the e's, b, a and d in the line "The next lines..."
be treated as notes to be played in the output midi file.


Implementation:
Introduced a new global in parseabc.c, int ignore_line, which
is either 0 or 1. When it is set to 1, parseline() in parseabc.c
will ignore that line. ignore_line is automatically initialized
to 0 any time a new X: command is encountered.


April 16 2017

Fixed a bug I introduced in parseabc.c on April 12 2017.

Had changed
parse_precomment (s)
     char *s;

to

parse_precomment (s)
     char **s;

in order to eliminate a compiler warning; however,
this caused abc2midi to treat %%MIDI as a text comment.


April 19 2017

Abc2abc invisible rest bug: the invisible multirest X gets
transposed to Z. When transposing the following tune,

X:1
T: Invisible rests
M: 4/4
L: 1/4
K: G
ABcx|X2|

X is changed to Z

Analysis: parsemusic() in parseabc.c treats the multirests
X and Z the same way in event_mrest().

Fix: added a char parameter to event_mrest() so it knows
whether it is a X or a Z. This effects store.c, toabc.c,
yapstree.c and matchsup.c.



June 02 2017

Abc2midi: Some of the documentation which comes with abc2midi
states that the MIDI program number should range between 1 and 128;
however, as far back as 2003, abc2midi expects the range to be
between 0 and 127 following the MIDI standard. The documentation
abcguide.txt and the man page abc2midi.1 have been corrected.
Unfortunately, the Abc standard was based on the old documentation.
It is too late to change abc2midi to comply with the abc standard
since there are too many abc existing files using the current
convention. As a temporary compromise, I have added a new
command %%MIDI programbase.

The current default is (so you do not need this line).
%%MIDI programbase 0

To change to the abc standard use
%%MIDI programbase 1

Implementation: added global 
int programbase = 0;
to store.s which can be modified by the %%MIDI programbase command.

Genmidi.c links to programbase using an extern statement and
in the function write_program() I added the lines.
 p = p - programbase; /* [SS] 2017-06-02 */
 if (p <0) p = 0; /* [SS] 2017-06-02 */

Test file:

%%MIDI programbase 1
X:1
T: timpani
% The timpani has MIDI program number 47 if you count from 0
% or 48 if you count from 1.
M: 2/4
L: 1/8
K: C
%%MIDI program 48
CCDD|EEFF|CDEF|CDEF|


June 10 2017

Abcmidi: !shape! bug

In the following example:

X: 1
%%MIDIdef peta bendstring 0 0     900 900 0  -900 -900 0  -400
%%MIDIdef volon125 controlstring 11 125
T: shape bug
C: 1
M: 4/4
L: 1/4
Q:1/4=130
K: C
%%MIDI program 64
AGGF|\
[I: MIDIx= peta]!bend!F[I: MIDIx=volon125]!shape!GAB|

The note G in the second bar following !shape! is held
too long.

Analysis: note_effect5 ends a note with
   midi_noteoff(delta, Q[Qhead].pitch, Q[Qhead].chan);
however the delta does not account of the numerous pitchbend 
commands which has shifted the time base to the end of the
note.

Fix: computed  last_delta = delta - eventlist[j-1].time; /* [SS] 2017-06-10 */
and used that to end the note.
midi_noteoff(last_delta, Q[Qhead].pitch, Q[Qhead].chan);


July 10 2017

Abc2abc: new feature

Added runtime reference -xref n which will only output the tune
with reference number n.

Implementation: in toabc.c add global integer xmatch which is set
to n when the -xref parameter is found. Otherwise it is set to
-1. The function event_refno(n) turns the parser on or off.
We needed to add 'extern parsing' in order to handle blank lines
in event_blankline(). All % abcm2ps directives unfortunately
must be printed since they may not be embedded in the particular
tune.


July 11 2017

Abc2midi infinite loop. The following tune causes abc2midi to
become unresponsive and go into an infinite loop.

X:1
T: abc2midi infinite loop
P:A-B
M: 4/4
L: 1/4
K:C
P:A
DDDD|
P:B
EEEE|

The loop occurs in the function read_spec() in store.c
which processes the line P:A-B. Fix: added a line
to increment the character pointer when it encounters the
character - or +.


August 9 2017 - September 19 2017

Midi2abc - added new option (-stats) to gather and print statistics
of a midifile. (eg. number of notes for a particular channel
in a particular track). This will be used by a new application
called midiexplorer. (The output is not documented and it is
work in progress.)


August 30 2017

Midi2abc - The metatext string is not terminated with a 0 and
as a result can contain random junk, in particular on the Windows
operating system. Fix in midifile.c, the Msgbuff is initialized to
0 when it is allocated.

September 12 2017

Midicopy - two fixes to cover some unusual situations.

September 18 2017

Midicopy - another fix


October 9 2017
Abc2abc bug: the program crashes when it tries to parse the line

V: V1 clef=treble2 middle=B nm="" snm="" merge stem=auto gstem=auto dyn=auto lyrics=auto gchord=auto scale=1 staffscale=1 stafflines=5 

Fix: the buffer output[32] was expanded to output[128] to handle long
lines in event_voice in toabc.c


October 11 2017

Abc2abc bug:

V: V1 clef=treble2 middle=B nm="" snm="" merge stem=auto gstem=auto dyn=auto lyrics=auto gchord=auto scale=1 staffscale=1 stafflines=5 

parameters chopped short. Fix: in parseabc.h increased V_STRLEN to 256.
Probably effects abc2midi too.


October 18 2017

Abc2midi: the complex guitar chords which extend over one octave, were
converted from closed form to open form in store.c. For example:
 /* static int list_11[6] = {0, 4, 7, 10, 2, 5}; */
    static int list_11[6] = {0, 4, 7, 10, 14, 17};


October 22 2017

Midicopy: cleaned up the code somewhat. Midicopy no longer outputs
tracks that are not needed.


October 23 2017
abc2midi and yaps: The parser normally reports a warning
Potentially ambiguous line - either a :| repeat or a field command -- cannot distinguish.
when it sees a line like
A:|cdef|A4|
or
B:|cdef|A4|
(The A: or B: could be interpreted as field commands.) By default the
line is treated as a music line, and in most cases everything works fine.
However, for a line like
w:| A____le-lu-ia | A____le-lu-ia a-le-lu-|
we would prefer that it is treated as a w: command or lyric line.

Fix: parseabc.c was modified to make a special exception for the
w: line and call preparse_words().


November 01 2017 November 08 2017 November 10 2017 November 19 2017

Midi2abc: minor enhancement for -stats function.


November 27 2017
Midicopy: introducing new options -focusontracks n1,n2,... and
-focusonchannel n1,n2....  This attenuates the velocity values of the
notes in all tracks (channels) except except n1,n2,... by the 
attenuation (default 70) units. The attenuation can be specified
by -attenuation n.

December 06 2017
Midicopy: added an option -xchns to exclude specific channels.


December 10 2017
Abc2midi: abc2midi now implements the command
%%abc-include per.abc
where per.abc is typically a header file which defines various
global parameters. For example, the file could remap the channel
pitches to particular percussion instruments using the %%MIDI drummap
command.

Implementation: in genmidi.c the function parse_drummap() is no longer
static so it can be called in store.c. In store.c, the command
%%MIDI drummap is recoginized in the function event_specific_in_header().
The function init_drummap, is no longer activated in the function
finishfile(), but only once in the main() function. This means that,
the %%MIDI drummap command will apply to all the tunes in the file,
irrespective of whether it is in the header (global) area. Finally,
parsefile() in parseabc.c has been extended to recognize the
abc-include file. All the contents of this include file are parsed
as if the lines were included in the open abc file, except that the
line counters do not count the lines in the include file. The
extension to parseabc.c also impacts abc2abc, yaps, and abcmatch.

December 15 2017
Midicopy: added -nobends option.


December 20 2017
Midi2abc bug: When midi2abc.c is compiled without the debugger on
Debian Linux, it fails with the message
**buffer overflow**
On compilation there are frequent warnings:
n function 'strncpy',
    inlined from 'setupkey' at midi2abc.c:3209:3:
/usr/include/x86_64-linux-gnu/bits/string3.h:126:10: warning: call to __builtin___strncpy_chk will always overflow destination buffer
   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
 
Analysis: strncpy was attempting to copy 16 characters from a 12 character
string into a 12 character string.

Fix: changed strncpy to memcpy and limited the copy to 12 characters.


January 02 2018 January 24 2018 February 07 2018 February 22 2018
  March 06 2018
Midi2abc -stats (detecting key signature and time signature meta commands)
Midi2abc -stats returns pitchentropy
Midi2abc -stats returns drumhits, progs, progsact
Midi2abc -stats check for program number between 0 and 127


February 22 2018

Abc2abc does not handle correctly the %%MidiIOff and %%MidiOn
which was introduced on April 12 2017 as seen below.
X:1
T:Booth Shot Lincoln
C:Traditional
C:Arr. Pete Showman
R:Reel
Q:1/2=90
M:2/2
L:1/8
K:A
|| y20 "A"ce2c e2ee | "D"fa2f a2fe- | \
"A"eBcB AcBA | "D"F3F F2FF |
ignore_line = 1




ignore_line = 0
%%MidiOn

Janus Meuris (jmeuris@gmail.com) has contributed several fixes and
minor improvements to parseabc.c, toabc.c and store.c.

In parseabc.c, the printf("ignore_line ...") was removed from
handle_abc2midi_parser(). The error message "Single colon in bar"
was removed since it is perfectly legal in music notation.
In parseline() flushes out the blocked lines enclosed by MidiOff and
MidiOn in the case that abc2abc is running.

The abc2abc output now looks like:
X:1
T:Booth Shot Lincoln
C:Traditional
C:Arr. Pete Showman
R:Reel
Q:1/2=90
M:2/2
L:1/8
K:A
|| y20 "A"ce2c e2ee | "D"fa2f a2fe- | \
"A"eBcB AcBA | "D"F3F F2FF |
%%MidiOff
%%begintext
 The next lines will not be played
%%endtext
%%MidiOn


In toabc.c, in printlen(a, b) , an option to print a/2 and a/4 as
a/ and a// was introduced. 

In store.c, more warnings were suppressed. A guitar chord beginning
with a space is also ignored -- eg. " A major"


March 08 2018
abc2abc bug: abc2abc deletes the leading space in the string following
the w: field command. For example

X:1
T:foo
M:4/4
L:1/4
K:C
c d e f | c d e f |
w: | he-llo wor-ld |

There is a space following w: to prevent parseline from seeing :|.
Unfortunately, abc2abc produces
w:| he-llo wor-ld |
which poses a problem to abc2midi.

abc2midi out.abc
4.02 February 22 2017 abc2midi
Warning in line-char 7-18 : Potentially ambiguous line - either a :| repeat or a field command -- cannot distinguish.

Analysis: the leading blank was already removed by parseline() in parseabc.c
by the time that preparse_words() sees the text.  Rather than messing
around with parseabc.c, I modified event_field() in toabc.c so that it will
automatically place a space between : and | whether or not it is missing.


March 21 2018
abc2midi bug: The only the A part is rendered by abc2midi and
there is no error message.

X:1
T: parts
M: 6/8
L: 1/8
P: A BB CC
K: G
P:A
DCB BAG|
P:B
GGB CBG|
P:C
GF2 G3|

Analysis: the P: command should be written as ABBCC without the spaces.
When this is done, the tune is rendered correctly. The code for deciphering
the P: command (read_spec() in store.c)  has been unmodified
since I have taken over the support of abc2midi. For some reason,
the P: specification allows the user to use a dot '.' to control
the spacing of the command; so A.BB.CC would be legal; however,
the use of spaces causes the command to fail.

The P: command has served two purposes in the past. When the abc
notated tune is rendered to sheet music, the P: command has also
been used to label the different sections of the tune. As a result,
if the P: command does not follow the exact syntax, abc2midi assumes
it is not being used for controlling repeats and ignores the command.
When P: is used for controlling repeats only the characters A-Z,
0-9,-,+,(,), and . are allowed. If a different character, say lower
case letters are encountered, read_spec() immediately ignores the
rest of the specification without any error message.

Fix: the code read_spec() was upgraded so that it now reports
an error in the event that the P: command in the header does not
follow the correct syntax. This can lead to a lot of error messages
if the P: command was used for adding comments to the title.
Fortunately, the user can use the -silent option to suppress these
messages. Furthermore, if read_spec encounters this error, it
restores the state of abc2midi so that all the parts are still
played (in the same order that they are presented and with no repeats).

Finally, I do not see any reason why read_spec() should fail when
it encounters spaces, so I have modified the code so that spaces
can be used to improve the clarity of the command.


April 01 2018

abc2midi reports an error when it encounters a within body I: which
does not contain one of the keys octave, MIDI, MIDIx, vol, or volinc.
For example, for the file

X: 1
T: Test 2 - I:leftmargin, I:rightmargin
T: abcm2ps sets the page margins
L: 1/4
M: 4/4
K: C
%
I:leftmargin 3cm
I:rightmargin 3cm
CCCC|DDDD|EEEE|FFFF|GGGG|

abc2midi normally returns:
Error in line-char 8-0 : I: key ' leftmargin' not recognized
Error in line-char 9-0 : I: key ' rightmargin' not recognized
writing MIDI file test21.mid

The error messages can now be suppressed by running abc2midi with
either the -quiet or -silent run time option.


April 14 2018

abc2midi bug: the following file

X:1
%%MIDI ptstress 3 100 1.5 100 0.75 100 0.75
T: Barfly stress test
L:1/4
M:3/4
K:C
gGg | GgG | gGg | GgG | gGg | GgG 

does not apply the Barfly stress model when abc2midi
is called with the -BF option, but it works correctly
when the -BF option is not included in the runtime parameters.
This can be a confusing issue when abc2midi is called from
a user interface such as EasyAbc.

Analysis: when the -BF option is included, abc2midi is looking
for a R: designator and attempts to match the rhythm designation
with one of the rhythms in the library. If it fails then the
stress model is turned off despite the fact that the stress
pattern has been specified explicitly by a %%MIDI ptstress command.

Fix: parse_stress_model (in genmidi.c) is called when a
%%MIDI ptstress command is encountered. If the command is valid, 
parse_stress_model sets beatmodel to 2 enabling the Barfly
stress model.

April 15 2018

abc2midi bug:

If the -BF runtime parameter is not followed by 1 or 2 (as it
occurs in EasyAbc), the stress model should default to 2, the
Barfly model instead of 1. This has been fixed in store.c.


April 16 2018

abc2midi bugs: more issues with the %%MIDI ptstress command. The
%%MIDI ptstress command was working for the Barfly model 1, but
was never working for Barfly model 2.

Model 2 is applied as a separate pass to the abc file
by the function apply_bf_stress_factors() in store.c. It essentially
changes all the note length values prior to creating the midi file.
The %%MIDI ptstress command is processed by dodeferred() in genmidi.c
during the last pass when the midi file is being written. This is
already too late. In order to fix this issue the processing of
the %%MIDI ptstress command was moved to the function event_midi()
in store.c.

There is also a conflict on how the stress factors are determined.
If no %%MIDI ptstress command is present, abc2midi normally uses the
builtin stress factors which are selected by the rhythm designation
in the R: command. It is necessary to disengage this mode when
the %%MIDI ptstress command is present. A new variable,
stress_pattern_loaded was used to signal that the stress factors
were set by %%MIDI ptstress.

Please note that the abc tune should have not more than one
%%MIDI ptstress command. If more than one is present, only the
last one is effective. The %%MIDI ptstress command requires knowing
the meter of the music, so it should be placed after the M: time
signature specification. By default, the ptstress command assumes
model 2; however, if you wish to use model 1, you can include
%%MIDI stressmodel 1 command.

Here is a sample use of the ptstress command.


X:1
T: another Barfly test
M:3/4
%%MIDI ptstress 3  120 1.6  60 0.8   40 0.6
L:1/4
R:      Waltz 
K:C
cc/d/e | d2g | e/d/ cB | c3 :|

The R: designation is unnecessary and will be ignored. Furthermore,
you do not need the -BF runtime parameter unless you want to
select model 1.



April 24 2018

Midi2abc -stats: some midi files do not define the channel to
program assignments until we reach the last track number. This
results in erroneous data in the progs and progcolor output.
Fortunately we also compute the chanactivity. We can fix this
problem by transfering the chnactivity to the progactivity.


May 02 2018

Abc2midi - deprecated !ped-end! and introduced !ped-up! in
store.c

June 13 2018

Midi2abc - catches negative time increment in midi file.
Check made in readtrack() in midifile.c


June 23 2018

Abc2midi bug: the %%MIDI gchordbars n command is very
idiosyncratic and only works correctly unless the abc is
formatted exactly like this.


X: 1
T: gchord
M:4/4
L:1/4
K: G
%%MIDI gchord ghih
"G" z4 
%%MIDI gchordbars 4
%%MIDI gchord ghih
| z4| z4| z4| z4|

it will not run correctly if the input looks like
 
X: 1
T: gchord
M:4/4
L:1/4
K: G
%%MIDI gchord ghih
"G" z4 |
%%MIDI gchordbars 4
%%MIDI gchord ghih
"G" z4| "G" z4|"G" z4| "G" z4|

(Bar line appears just before %%MIDI gchordbars rather than after.)


Fix: the variable gchordbarcount was eliminated since it was
not useful and the cause of some problems in the function
checkbar(). In dogchords(), we check that g_ptr does not exceed or
equal the length of the gchord string. In dodeferred(), we
reset g_ptr to 0 when we encounter a %%MIDI gchordbars command.

Abc2midi bug: the %%MIDI drumbars n command is also idiosyncratic
in a similar fashion.

Fix: the drumbars feature was implemented in the same way as
the gchordbars, so all of the above applies.


October 25 2018

midi2abc: introduced option mftextpulses which will output in
pulse units instead of beat units.



December 01 2018

abc2abc bug: for multivoiced files where the voices are interleaved,
abc2abc produces error messages regarding repeat symbols. For example,
seymour@corsair:~/abc$ cat repeats.abc
X:1
T: abc2abc repeats in multivoice
M:4/4
L:1/4
K:G
[V: S] gfed|: abcd |
[V: A] edcB|: ABCD |
[V: H] GFED|: ABCD |
[V: S] abcd :|
[V: A] ABCD :|
[V: H] ABCD :|

abc2abc repeats.abc
X:1
T:abc2abc repeats in multivoice
M:4/4
L:1/4
K:G
[V:S] gfed|: abcd |
[V:A] edcB
%Error : Expecting repeat, found |:
|: ABCD |
[V:H] GFED
%Error : Expecting repeat, found |:
|: ABCD |
[V:S] abcd :|
[V:A] ABCD 
%Warning : No repeat expected, found :|
:|
[V:H] ABCD 
%Warning : No repeat expected, found :|
:|

Analysis: in event_bar in toabc.c, the variable expect_repeat
determines whether the error message is emitted. This works
well as long as each voice is processed in sequence but
when the voices are interleaved, it is nececessary to maintain
the expect_variable for each voice. The expect_repeat variable
was moved to the voice struct. Unfortunately event_bar
(which is used in abc2midi, yaps, and abcmatch) does not pass
the voice struct, so it was necessary to reference the
voice struct as a global variable.

December 17 2018

abc2midi: does not recognize the abcm2ps options when embedded
in a inline information command. For example,
K: G clef=bass
F [I:setbarnb 1]|
appears in one of the abc files. [I:setbarnb 1] tells abcm2ps
to start counting bar numbers here from 1. However, abc2midi
does not recognize this command and outputs the message:

Error in line-char 269-2 : I: key ' setbarnb' not recognized

There are numerous abcm2ps options that can be embedded in
an abc file. I am not too sure how to handle this situation.
I can give abc2midi the most common messages and tell it
to ignore these. In store.c I introduced the function
is_abcm2ps_option(). Presently I only check for setbarnb.


December 21 2018

abc2midi: does not recognize THICK_THIN bar line. In the
following example,

X: 1
T: THICK_THIN bar line
M: 2/4
L: 1/8
K: D
EDFD|FGD2]|

abc2midi reports the error
Error in line-char 6-9 : Chord already finished

Analysis: ]| is a type of bar line, however abc2midi assumes that
] is ending a chord. Fix: in the function parsemusic() in parseabc.c
we now check that whether we are in a chord before calling event_chordoff.
We introduce a new function event_ignore() in store.c, yapstree.c, toabc.c,
and matchsup.c to handle such situations.

December 28 2018

toabc.c
The gcc compiler produces numerous warnings like
toabc.c:1223:45: warning: '%s' directive writing up to 256 bytes into a region of size 250 [-Wformat-overflow=]
     if (vp->gotclef) {sprintf(output," clef=%s", vp->clefname);
fix: changed output[250] to output[300] in event_voice.

January 01 2019

abc2midi: warnings from time signature change.

Abc2midi processes this file without warnings.

X:1
T: time signature placed at the beginning of the bar
M: 3/4
L: 1/8
K: G
C2 C2 C2 |[M:2/4]  C2 C2 |[M:3/4]  D2 D2 D2 | [M:2/4] E2 E2|

However, abc2midi produces several warnings when the time signature
is placed before the next bar line.
 
X:1
T: meter change
M: 1/4
L: 1/4
K: G
C [M:2/4] | C C [M:3/4] | D D D [M:4/4]| E E E E [M:1/4]| C|

Warning in line-char 6-24 : Track 0 Bar 1 has 2 units instead of 3
Warning in line-char 6-39 : Track 0 Bar 2 has 3 units instead of 4
Warning in line-char 6-56 : Track 0 Bar 3 has 4 units instead of 1

Analysis: Note that measures count from zero. Though both forms
are musically correct, the latter form confuses abc2midi. Abc2midi
applies the time signature to the bar in which it is embedded.
To fix this issue, I introduced the function
check_for_timesig_preceding_bar_line () in genmidi.c
It scans the entire feature[] representation of the tune and
switches TIMESIG with SINGLE_BAR any time TIME_SIG is immediately
followed by SINGLE_BAR. This function is applied prior to writing
the tracks in the midi file.

January 20 2019

abc2midi: suppressing the warning "clef= is overriding octave= setting"
when the clef is specified in the K: or V: command. Parseabc.c was modified.
It probably effects abc2abc, yaps, and abcmatch.

January 31 2019

abc2midi: offering the option to suppress the messages
4.11 January 01 2019 abc2midi
Warning in line-char 20-11 : Different length notes in tuple
Warning in line-char 20-13 : Different length notes in tuple
Warning in line-char 21-4 : Different length notes in tuple
Warning in line-char 21-6 : Different length notes in tuple
....
using the -quiet option

(A lot of early baroque music may contain tuplets of different
length like: 
[M:2/1](3F6E2D4 | (3C6D2E4 | (3D6E2F4 | (3:2:4G6F2D2E2 | (3F6E2C4 |

Abc2midi should be able to handle tuplets with notes of different lengths.


February 08 2019

abc2midi: does not recognize dotted bar lines. In the example,

X:1
T: Dotted bar lines
M: 2/4
L: 1/4
K: D
GA : BD|EF : CF| D2 : D2|

abc2midi returns the message
Warning in line-char 17-13 : Track 0 Bar 1 has 4 units instead of 2
Warning in line-char 17-22 : Track 0 Bar 2 has 4 units instead of 2

Fix: in abc.h introduced DOTTED_BAR in featuretype.
In parsemusic() in parseabc.c call event_bar(DOTTED_BAR,"") if a
':" occurs by itself. In event_bar() in store.c the DOTTED_BAR is
treated the same as the DOUBLE_BAR.

March 14 2019

abc2midi: warnings and error messages reference the wrong line number.
For example for the tune

X:1
T: warnings
M: 4/4
L: 1/4
K: G
[V:1]A|
[V:2] A|
[V:1]Bcd|
[V:2]EFGA|
[V:1]DAxD|
[V:2]Bcd|
[V:1]EFGA|
[V:2]DAxD|

abc2midi reports that bar 1 (Bcd) has 3 beats instead of 4 in line 7.
Line numbers start from line 1, so bar 1 is in line 8 and not line 7.
Analysis: writetrack() in genmidi did not see feature(LINENUM) because
it bypasses the features whose voice is not the actual voice (track)
being written. Fix: the function findvoice() in genmidi.c now ensures
that the global variable lineno is always updated.


Mar 18 2019 -- Mar 22 2019

abc2midi new feature: if one is not careful, it is easy for one or
more voices to get out of synchronization with the other voices.
When the abc music score is displayed, the barlines
do not align. Abc2midi checks whether the number of beats in
a bar matches the time signature. However, it does not check
whether the beats in the corresponding bars in the different
voices, match. This is rather difficult to do, since abc2midi
writes out each track sequentially. As an experiment, 
abc2midi counts the number of beats played up to each bar line,
and as an option (-c) will output these numbers in a file
called barloc.txt for each voice.  The numbers should match for
all voices. Recall that the -c option processes the entire abc
file (which may contain numerous tunes) and only returns warnings
and error messages without producing any midi files. 
In this implementation barloc.txt only applies to the first
tune in the file.  (This feature is still experimental.)

Implementation: introduced the integer array, barloc[1024] in genmidi.c
which can handle up to 1024 measures in the tune. This array is
reused for each voice. In checkbar() in genmidi.c, barloc[barno]
stores the current track length (in midi pulses). A new function,
dump_barloc() is introduced in genmidi.c that writes the barloc
data in barloc.txt file. In store.c, introduced a new file handler
diaghandle for creating the output file barloc.txt. dump_barloc()
is called from finishfile() in store.c when abc2midi is running
with the -c option (check flag is nonzero).

The number of measures in each voice may be different, (one
voice could end prematurely), but it is fairly easy to determine
during the first pass when the feature array is filled. The
number of measures in the output midi file can be much larger
since all repeats are expanded. A new variable, nbars, was
introduced in the voicecontext structure in store.c.


Mar 23 2019

abc2midi bug. abc2midi can be used for just checking the abc file for
errors using the -c option. No midi files are created. Unfortunately,
abc2midi running in this mode may halt when processing a big file
with the message,

eputc: aborting because of file runaway (infinite loop)

This is a check introduced in October 15 2004 in case abc2midi gets
into an infinite loop and produces a midi file of unbounded size.
The output midi file is prevented from growing over 500,000 bytes.
/* if ((back[trans[p]] != p) || (key[po] == 1)) { [SS] 2010-05-07 */
    if (back[trans[p]] != p ) {  /* [SS] 2019-05-07 */
/* if ((back[trans[p]] != p) || (key[po] == 1)) { [SS] 2010-05-07 */
    if (back[trans[p]] != p ) {  /* [SS] 2019-05-07 */
The check occurs in midifile.c by monitoring the variable,
Mf_numbyteswritten.
Since abc2midi with the -c option does not actually create any
midi files, it is not desirable to do this check.

Analysis: the function finishfile() in store.c calls writetrack()
directly when it is run with the -c option; however when it
is run without this option, writetrack() is called from mfwrite() in 
midifile.c. mfwrite() takes care of initializing Mf_numbyteswritten
for each tune. In order to initialize Mf_numbyteswritten when
abc2midi is run with the -c option, we need to link it to store.c
by declaring it as an extern.

April 13 2019

midi2abc bug: midi2abc crashes with a message "out of memory cannot malloc"
on Windows 10.

Analysis: in the function addstring checkmalloc allocates strlen(s)+1,
but strncpy can copy up to strlen(s)+2 characters.

Fix: increased checkmalloc to allocate strlen(s)+2 characters.



April 22 2019

midi2abc bug: midi2abc insists on making all rests invisible (x). Temporary
fix: printchord() was modified so that it always prints a visible rest (z).


May 08 2019
midi2abc bug: accidentals fail to propagate resulting in

X: 1
T: from accid1.mid
M: 4/4
L: 1/8
Q:1/4=120
K:G % 1 sharps
% note track
% accidentals
^C2 ^C2 ^C2 ^C2|

Fix: in function printpitch(), removed (key[po] == 1) in
the conditional,
if ((back[trans[p]] != p) || (key[po] == 1))
(I could not figure out the purpose of key[po].)
Introduced barback[] array which is used to reinitialize
the back[] array after each bar line.


May 12 2019

midiabc bug: -splitvoices and -splitbars is handled by the functions
printtrack_split_voice and printtrack_with_splits which are rather
complex and buggy. Preceding rests in the midi file corresponding
to the following file

X:1
T: anacrusis
M: 4/4
L: 1/4
K: G
Z2|z2AB|zdef|

are handled correctly without the -splitbars -splitvoices options
but are missing with either options. The gap variable was not
set properly in the code.

May 15 2019

midi2abc issue. By default abcm2ps chooses the clef (bass or treble)
automatically on the basis of the pitch of the following note.
For some tracks,  the pitch range falls in both the
the treble and bass ranges resulting that the clef may oscillate
between treble and bass. If the clef is specified in the voice corresponding
to the track (or channel), then it is locked in. To avoid this
oscillation the pitch histogram is determined for each channel,
and a decision is made whether to lock in the clef. A new
function pitch_percentiles() was introduced in the code to
accomplish this action.

May 29 2019

midi2abc issue: midi2abc makes a mess of type 0 midi files because
it does not separate the music in the different channels.
Fix: for type 0 midi files, the different channels are treated
as if they are put into separate tracks. New functions
txt_trackstart_type0, txt_noteon_type0, txt_program_type0,
addnote_type0, and addtext_type0 which copy the channel command to
to track[chn] instead of track[0].

June 06 2019

abc2abc bug: the fix to recognize the THICK_THIN bar line ]|
introduced a new problem. In the following example,

X: 1
T: bar line chord interference
M: 4/4
L: 1/4
Q:1/4=142
K:F# % 6 sharps
z [gdGG,] z[gdGG,]|z [gdGG,] z [gdGG,]| 
z [gdGG,] z[gdGG,]|z [gdGG,] z [gdGG,]| 
  
applying abc2abc to this file with the -e option returns

X:1
T:bar line chord interference
M:4/4
L:1/4
Q:1/4=142
% Last note suggests minor mode tune
K:F# % 6 sharps
z [gdGG,] z[gdGG,|z [gdGG,] z [gdGG,| 
z [gdGG,] z[gdGG,|z [gdGG,] z [gdGG,| 

The even numbered chords are not ended properly resulting
in nested chords.

Fix: the code in parsemusic() in parseabc.c for handling
the closing of chords was corrected.
Parseabc.c is part of abc2midi, abc2abc, yaps, and
abcmatch.


June 13 2019

Major changes were made to midi2abc.c
The conditional code separated by #if defined SPLITCODE and #endif is now
permanently included in midi2abc. The conditionals have been removed.
The option -splitbars (which produces splitbars with & separators)
is now gone including the function printtrack_with_splits. The code
was unreliable and I cannot support it. Instead you should use -splitvoices
which was improved.
The function printtrack_split_voice() was separated into two
functions; the first with the same name and the second called
printtrack_split(). Printtrack_split_voice assigns splits
to each of the notes using the function label_split_voices().
Label_split_voices returns nsplits, the number of splits that were needed,
and printtrack_split is called for each of the splits.
Printtrack_split creates a new voice for each of the splits.

June 14 2019

Midi2abc: to prevent printing blank lines, newline_flag global variable was
introduced.

June 17 2019:
Midi2abc: added initialization of chordhead and chordtail in
printtrack_split().

June 20 2019:
abc2midi crashes with the message
.20 March 30 2019 abc2midi
*** buffer overflow detected ***: abc2midi terminated
Aborted (core dumped)
for some abc files.

Analysis: the crash occurs in sync_voice() in store.c when attempting
to print a message with more than 80 characters (case PLAY_ON_REP).
Fix: char message[128];


June 26 2019
abc2midi bug: trill - tie problem. The trill-tie combination
disrupts the chordal accompaniment in the following example.

%abc-2.1
X:6
T:trill-tie problem
M:3/4
L:1/4
%%MIDI chordname m7b5 0 3 6 10 %0 _3 _5 _7
I:MIDI=program 110 MIDI=chordprog 24 MIDI=bassprog 32
K:A
"Am"A/^G/ B/A/ c/B/|d/c/ e/d/ f/e/|"Bm7b5"Te3-|"E"e3|
"Am"A/^G/ B/A/ c/B/|d/c/ e/d/ f/e/|"Bm7b5"e3-|"E"e3||

Unfortunately, there is no easy fix. In order to apply
the trill to the tied note, the tied note is converted
into a long note. This is an example where two features
clash with each other.


June 26 2019
midi2abc -splitvoices: fixing more problems in
printtrack_split() function. Introducing firstgap[]
and function set_first_gaps(trackno). Test file:

X:1
T: polyphonic chords
M: 4/4
L: 1/4
K: C
zC-[C-E-][CEG]|\
zC-[C-E-][CEG]|\
[DF-A-][FA-]Az|\
[DF-A-][FA-]Az|

More information was added to file programming/midi2abc.txt.


June 29 2019
midicopy requires that you specify the start and end times (or
start and end beats) even when you are copying the entire
midi file.

midicopy returns the wrong number of seconds copied when -fromsec
and -endsec are specified and are beyond the range of the midi file.

Fixes: functions cut_beginning() and cut_ending() check global
flags use_seconds and use_ticks. If neither are set then the
midi file is not trimmed. These flags are set in main() depending
on the options provided.

We keep track of the current time (currentseconds) adjusting
for tempo changes.


July 05 2019

Midicopy aborts with the message "trackdata overflow"

Analysis: the input midi file contained more than 20 tracks containing
no data. Each of those tracks contained 10 bytes. Midicopy while
adding extra bytes for compatibility with the winamp program,
caused the failure when the number of written bytes exceeded the
track_size.

Fix: in the function append_to_string in midicopy.c, a margin of 6
extra bytes was introduced in the check for overflow. Also midicopy
was modified to allow up to 64 tracks. A check is made to
ensure this is not exceeded.


July 12 2019

Midi2abc. The handling of lyric text is currently a problem with
midi2abc. For the present time I have added a new option -noly which
suppresses lyric output. Introduced a new flag noly in midi2abc.c.

August 02 2019
Midi2abc -stats returns incorrect count of notes in chord.
(This problem only affects midiexplorer.tcl.)
Analysis: chords are identified in stats_noteon by comparing the
Mf_currtime with the last_tick time. last_tick is also used to
compute the note length and is also updated in stats_noteoff.
Fix: introduced last_on_tick array which is only updated by
stats_noteon.

August 11 2019

Abc2midi - valgrind detected a memory leak coming from store.c.
Analysis: event_refno in store.c creates a voice struct, but
it is destroyed without freeing up the the memory in startfile().
Fix: it is not necessary to create the voice in event_refno,
since the function getvoicecontext(1) in event_key() will create
the voice the voice struct automatically if it does not exist.
The function clearvoicecontext() frees up all the voice structs
properly. 

Abc2midi - valgrind detected that the variable chord_num was
used in a conditional prior to being set in tiefix(). The
variable is now initialized.

Both of these bugs were reported by James Cowgill to Debian
Bug Report log 890250
(https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=890250 )

yaps - valgrind detected that i was not set in the conditional
      if ((n->beaming == endbeam)||(i==64)) {
in beamline() in drawtune.c when called from finalsizeline().
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=890250
fix: initialized i to 0 in beamline().

midi2abc -  Integer overflow leading to heap buffer overflow
in addstring().
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=924947
Fix: limited the checkmalloc to 1024 sized string.

October 13 2019

abc2midi: trill broken rhythm interference. Abc2midi returns the
following message when applied to this file.

X: 1
T: trill
M: 4/4
L: 1/4
K: C
A3A|Te>dc2|

Warning in line-char 6-10 : Track 0 Bar 1 has 7/2 units instead of 4

In actual fact the broken rhythm is applied to the second A
and e instead of e and d.  When the trill is removed, the program
runs normally. Fix: in event_note in store.c all call to marknote()
was added at the end of the conditional block beginning with
  if ((decorators[ROLL]) || (decorators[ORNAMENT]) || (decorators[TRILL])) {
to ensure that the start and end of the broken rhythm sequence is
correct.


November 06 2019 November 13 2019

midi2abc: modified output for -midigram output. The header record
now returns miditype ntrks and ppqn. The program line returns
the current time in ticks. The changes were introduces to support
the function show_prog_structure in runabc.tcl.

December 09 2019

abc2midi: some abc files use the $ character to indicate a linebreak
in the score. For example,
I:linebreak $
The score contains numerous $ characters and abc2midi complains that
it does not recognize the character $. Fix, added the lines

else if (fileprogram == ABC2MIDI && *p == '$') ; /* ignore [SS] 2019-12-9 */
                /* $ sometimes used as a score linebreak character */

in parsemusic() in parseabc.c


December 09 2019

abc2midi: new feature. Double quotes are supposed to be used to indicate
chord symbols (guitar chords) which abc2midi uses to create an
accompaniment. Unfortunately, the double quotes notation is frequently
misused to display other information that can cause a problem.
Added the option -NGUI to ignore any guitar chords in the body of
file.


December 22 2019 December 25 2019

midicopy: introduced new options for handling the percussion track.


December 30 2019

midi2abc: fix handling text messages (including %%MIDI and lyrics).


January 03 2020

abc2midi, abc2abc, yaps -- compatibility with abcm2ps.
The %%begintext and %%endtext enclose text which should not
be processed by abc2midi or abc2abc.   The flag ignore_line is set
to 1 when parseline() encounters "%%begintext" and is reset to 0
when %%endtext" is encountered. If ignore_line is 1, the rest of
the code in parseline() is ignored when abc2midi is running.


January 05 2020

midicopy: when copying a region in the middle of a midi file,
it may encounter and copy a midi noteoff message without a
corresponding midi noteon message. midi2abc complains when
it attempts to create an abc file.
Fix: the close_note() function in midicopy.c checks whether
the specified note is still playing. If it is not playing,
close_note() returns -1 and a noteoff channel message is
not issued by copy_noteoff(). In addition, it was necessary
to fix writechanmsg_at_0 called by winamp_compatibility_measure().
To make a proper noteon message the velocity has to be nonzero.
The velocity of value 1 at pitch 0 should be nonaudible.


January 06 2020

midi2abc: chords such as [A3/2C3/2E3/2G3/2] are now expressed
more compactly as [ACEG]3/2. The patch was inserted in printchord()
in midiabc.c.

January 14 2020

abc2midi: addressing ticket #25 on sourceforge. abc2midi hangs
on some systems for this example.

X:1
L:1/4
K:C
2c/2fac'/c'/c'/c'/c'//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////


Fix: add a test for zero denominator in genmidi.c
if (tnote_denom <= 0) {
                      event_error("note length denominator is zero or less"); /* [SS] 2020-01-14 to prevent infinite loop on some systems */
                      exit(1);
              }

in function writetrack().

January 22 2020

abc2abc: added -useclef option, to specify the clef to use. It is
useful if you are trying to learn to read the bass clef and you are
transposing the music down an octave.


February 12 2020

abc2midi: minor changes suggested by Timm Reasbeck to the default gchord
patterns for various meters were incorporated in setbeat() in store.c.


March 25 2020

abc2midi: after the changes to parseabc.c on January 03 2020, abc2midi
no longer sees the %%MidiOn command. For example:

X:1
T:Tune with Repeat Text, MidiOff and MidiOn
M:4/4
L:1/8
K:C
C4 D4 | E4 F4 | \
%%MidiOff
["Repeat" \
%%MidiOn
G4 A4 | B4 c4 |]

only the first 4 notes are recorded in the midi file. 


Fix: in parseline() in parseabc.c, switched the order of the lines

 handle_abc2midi_parser (line);  /* [SS] 2020-03-25 */

 if (ignore_line == 1 && fileprogram == ABC2MIDI) return;


April 30 2020

abc2midi: reports warnings
Warning in line-char 6-0 : Ignoring reserved character S
Warning in line-char 6-3 : Ignoring reserved character P
Warning in line-char 6-7 : Ignoring reserved character O
when it encounters the characters S, P, and O in the music body.

X:1
T: decorations
M: 4/4
L: 1/4
K: G
SDBPAD|OBDEF|

The abc standard defines S as segno, P as uppermordent, and O as
coda, so these are completely valid.

Fix: add characters O,P and S to the decorations string in
parseabc.c. It is now
char decorations[] = ".MLRH~TuvOPS";
In addition, DECSIZE in abc.h was increased to 13 and I added
#define CODA 10
#define UPPERMORDENT 11
#define SEGNO 12

May 06 2020

abc2midi: bug
The command clef=treble+8 or clef=treble-8 fails to have any
effect. This bug was probably introduced on December 19 2011
and was just reported recently.
Analysis: the bug was traced to the code in the function
isclef() in parseabc.c. The code was modified on December 19 2011
to fix another bug. The modification contains the line

 if (fileprogram == ABC2MIDI && *gotoctave != 1 && *octave != 1) 

which causes the problem. Prior to this test, the input string
was matched to 'treble' and *gotoctave was set to 1. The string
also matched 'treble+8', but *octave could not be reset to 1
on account of the above modification.

I see no purpose in the test *gotoctave != 1 or *octave != 1
in the above test, so I changed it to simply to

 if (fileprogram == ABC2MIDI)

wherever it occurred.  This enabled the code for clef=treble+8 
and clef=treble-8. It was found that it was still possible to
switch back from clef=treble+8 to clef=treble.

Unfortunately, the clef=treble+8, affects other designations
such as clef=tenor. It was therefore necessary to reset
*octave = 0. For all these situations and similar.


June 02 2020

Peter Sutton (petersutton2009@gmail.com) who packages abcmidi
for Arch Linux reported a linkage error
/usr/bin/ld: toabc.o:(.bss+0xd7c): multiple definition of ingrace'; parseabc.o:(.bss+0x788): first defined here /usr/bin/ld: drawtune.o:(.bss+0x168): multiple definition ofingrace'; parseabc.o:(.bss+0x788): first defined here

My suspicion is that the changeover to gcc ver. 10 (2020-05-08)
is causing these problems

Fix: in parseabc.c changed
int ingrace = 0;
to
static int ingrace = 0; /* [SS] 2020-06-02 */


June 03 2020

gcc-10: Stuart D Gathman (stuart@gathman.org) detected numerous
potential problems in the C code. eg variables used for they are
initialized, variables declared and not used, missing defaults
in switch statements, indenting in if statements not matching
blocks, possible missing nulls in strings, ...
Suggested changes were inserted without changing the logic
of the code. Changes were marked with [SDG] 2020-06-03 in case
bugs are discovered later.


June 20 2020

In order to improve the handling of the SymbTr Turkish Makam
database https://compmusic.upf.edu/node/287 which was converted
to abc format in https://ifdo.ca/~seymour/runabc/makams/index.html ,
the abc representation of the note pitches has been changed.
The collection of abc notated files will be replaced shortly
and will work with both abc2svg and abcm2ps thanks to the
help of Jef Moine and Hudson Lacerda. Hudson has contributed
patches to the abcmidi package which have been incorporated into
parseabc.c and store.c.

June 22 2020

A minor change was made to midi2abc so that the pitchbend values
are presented in units of cents.

June 23 2020

parseabc: renamed readlen_nocheck() to read_microtone_value().
If the microtone value is an integer instead of a fraction,
(i.e. no / is present), then b (the denominator) is set to 0
to signal that it is an integer.  An integer microtone such
as ^n or _n, implies that its pitch shift is given by n
octave divisions where the number of divisions ndiv is specified
in the command.

%%MIDI temperamentequal <ndiv> [octave_cents] [fifth_steps] [sharp_steps]

For a detailed description of the temperamentequal command,
see the May 19 2015 insert in this document.  The nonfraction
microtones will be used to represent the accidentals for the pitches
in the Turkish Makam database mentioned previously. 

June 25 2020

parseabc: parsekey now accepts integer microtones when %%MIDI temperamentequal 
is set. The temperament flag is declared in parseabc.c and linked to
store.c with an extern statement, so that the parser knows whether %%MIDI temperamentequal statement
was included in the abc file.

June 27 2020

abc2midi: in pitchof_b() in store.c (which implements various 
temperaments), the Hudson Lacerda modified the pitchbends so
that the key of A is still 440.0.
   /* [HL] 2020-06-27 Adjust for A=440.0 with zero pitchbend */
    pitch4096 += (9*SEMISIZE) - (3*fifth_size-octave_size);


July 03 2020
abcmidi: %%temperament command has been implemented by Hudson
Lacerda (in store.c)
July 05 2020
parseabc.c updated to reflect that the temperament integer flag
can take various values.

You can find a test file detune.abc in the samples folder.


July 14 2020
yaps: cleaned up numerous gcc warnings such as
drawtune.c:3245:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
       lineno = (int)(ft->item);

changed 
       lineno = (long)(ft->item);
etc.



July 17 2020

store.c: in order to improve the accuracy of the MIDI temperamentequal
and MIDI temperamentlinear representation, the calculations were
performed in floating point rather than integer arithmetic. The constant
SEMISIZE = 4096 was eliminated, and the global variables octave_size,
fifth_size, sharp_size, and microstep_size were turned into floating
point variables. A new function compute_fifth_size () was introduced,
which computes the perfect fifth interval quantized into the ndiv
comma units. The result is returned in units of cents where one
standard octave is 1200 cents. If you run abc2midi with -v 1 
(verbose level 1), the size of the fifth interval and other variables
is printed.

This is a significant change affecting the code in the functions
event_midi() and pitchof_b().


July 24 2020

store.c Hudson Lacerda corrected the algorithm in compute_fifth_size()
and fixed a bug that I had introduced.

July 28 2020

store.c Minor correction in store.c when the microtone denominator is
equal to 100 (in pitchof_b()).


August 09 2020

genmidi.c: introducing %%MIDI bendstringex.
It is similar to %%MIDI bendstring except that it linearly interpolates
the pitchbends, causing smoother transitions.
Method: created a new function expand_array() which expands an
array {20, -20, ...} to {5, 5, 5, 5, -5, -5, -5 ,5} or something
like that depending upon the parameter factor. The expanded array
of benddatata is now treated like in %%MIDI bendstring in the
queues.c file. Presently, I am using a factor of 4 (not configurable).
Bendstringex limited to 64 or less increments.


September 30 2020

James Allwright has reported several problems with the abcMIDI code
and proposed some fixes and improvements.

There is a bug in parsekey resulting in an extraneous warning for
the following file.

X: 1 
T: parsekey() test
M:4/4  
L:1/8 
Q:1/4=127
K: D phr ^f
| =C^C =D^D =E =F ^F =G |

abc2midi parsekey.abc
4.41 August 09 2020 abc2midi
Warning in line-char 6-0 : Ignoring string '^f' in K: field
writing MIDI file parsekey1.mid

Despite the warning the output file is still correct.

abc2abc and other applications depending on parseabc.c also produce
similar warnings.

Analysis: the problem originates in the function parsekey() in
parseabc.c. The fix consists two small changes shown here.

/* shortcuts such as ^/4G instead of ^1/4G not allowed here */
/* parsed =0; [SS] 2020-09-30 */


  /* if (parsed ==1) { [SS] 2020-09-30 */
  if (success > 0) { /* [SS] 2020-09-30 */



drawtune.c in read_boolean increased dimension of char p[]
to allow for null termination. -- suggested by James Allwright.

stresspat.c in custom_stress_file() added fclose(inhandle)
to close the open input file. -- suggested by James Allwright.

matchsup.c, yapstree.c, and toabc.c: event_temperament declared as
event_temperament(*line) instead of event_temperament(**line).

parsekey() was split into two functions, parsekey() and process_microtones().


October 06 2020

abc2abc bug: abc2abc hangs when it is applied to a multivoiced file
with the -n option. The following file hangs abc2abc

X: 1
T: hangs abc2abc
M: 4/4
L: 1/4
K: C
V:1
C4|E4|D4|E4|
F4|G4|A4|B4|
V:2
D4|F4|G4|A4|B4|c4|
C4|B,4|

eg

abc2abc hanger.abc -n 3
X:1
T:hangs abc2abc
M:4/4
L:1/4
K:C
V:1
C4|E4|D4|
E4|F4|G4|A4|

(Hangs when it encounters the V:2.)

Analysis:
The program hangs in a infinite loop 
331	  while (v->bars_complete > v->bars_remaining) {
in the function complete_bars in toabc.c
v->bars_complete is 2, v->bars_remaining is -1 and bars_done is always 0.

If you insert a comment before V:2, the program runs normally.

Fix: insert the line
 close_newabc(); /* [SS] 2020-10-06 */
in the function event_voice().

Explanation:
v->bars_complete, v->bars_remaining are elements of a voice structure
which has room for up to 30 voices. When V:2 is encountered, the
program automatically calls event_voice and switches to a new voice;
however, the program has not finished with voice 1 and the voice
structure gets corrupted during the switch. Event_voice was modified
so that any remaining data in voice 1 is released before the switch.


October 7 2020
James Allwright has introduced event_score_linebreak in parseabc.c,
yapstree.c, etc. which replaces the change made on December 09 2019.
Except for yapstree.c, event_score_linebreak does nothing.


October 10 2020
midicopy new feature: -zerochannels will set all channel numbers in
the midi file to zero. Some midi files (http://scarlatti.antikytherapubs.com/ )
adjust the tuning by assigning each pitch class to a separate channel
and applying an appropriate pitchbend to each of these channels.
This may pose a problem for some software which attempts to render the
midi file in music notation.


October 12 2020
James Allwright has made significant improvements to parseabc.c, toabc.c,
and yapstree.c related to  repeat checking. In parseabc.c, new functions
were introduced: init_voice_contexts, reset_parser_status,
interpret_voice_label, check_bar_repeats, and check_and_call_bar().
The functions isnumberp(), init_voicecode(), and interpret_voicestring()
have been retired. Reset_parser_status() is called each time a new
X: reference field command is encountered. Check_bar_repeats() replaces
a lot of the code that appears in event_bar() defined in toabc.c and
yapstree.c. parsemusic() calls event_bar indirectly through the
function check_and_call_bar(). Minor changes were made to toabc.c, store.c
and yapstree.c to accommodate the changes to parseabc. In particular,
a new flag repcheck is introduced and connected to parseabc.c as
an extern (in parseabc.h). In addition a new struct (voice_context)
has been introduced in parseabc.h.


October 19 2020
James Allwright has implement the abc draft standard 2.2 clef parameters.
This specifies the clef by letter and line number on which it sits.
See http://abcnotation.com/wiki/abc:standard:v2.2#clefs . An
example is given below.

X:1
T: clef test
M: 4/4
L: 1/4
K: D clef=G2
"Treble" DEFG|AGFE|ABcd|
K: D clef=G1
"French violin" DEFG|AGFE|ABcd|
K: D clef=F5
"Sub-bass" DEFG|AGFE|ABcd|
K: D clef=F3
"Baritone" DEFG|AGFE|ABcd|

The implementation involved major changes to parseabc.c and the creation of
new files music_utils.c and music_utils.h. The function isclef() in parseabc.c
has been revised and now calls get_standard_clef() or
get_extended_clef_details() that are defined in music_utils.c.
The clef is represent by a new structure cleftype_t.  parseclef() and
event_key() defined in parseabc.c have a new parameter, a structure newclef.

Minor changes were made to store.c, toabc.c, matchsup.c. and debug.c.
Significant changes were made to yapstree.c and drawtune.c.

The makefiles folder has been moved to legacy_code.


October 27 2020

James Allwright cleaned up the yaps source code, (uninitialized variables)
and memory leaks detected by valgrind. In particular, one of the elements
in the struct feature (item) was changed to a union of a void pointer
and a number. This change propagated to the other files position.c,
debug.c, yaprstree.c and drawtune.c. There are too many changes in
yapstree.c and drawtune.c to list.


November 01 2020

Yaps: James Allwright fixed a bug introduced recently that caused yaps
to shift the notes down two ledger lines when the clef is not declared
(parseabc.c). More security checks were introduced to prevent yaps
and midi2abc to produce lines greater than 256 characters (drawtune.c,
drawtune.h, yapstree.c  and midi2abc.c).

November 07 2020
Yaps: a missing voidptr prevented the compilation of drawtune.c on MacOS.
Lines 3006-3011 was replaced with
  if (v->place->type == LEFT_TEXT) {
      printtext(left, v->place->item.voidptr, &textfont);
    };
    if (v->place->type == CENTRE_TEXT) {
      printtext(centre, v->place->item.voidptr, &textfont);
    };


December 10 2020

James Allwright has upgraded the parser so it can now interpret
complex time signatures as shown in this example.

X:1
T: Example 1 using complex time signature
M:(3+2+2)/8
L:1/8
K:G
abc de fg|GGG aa bb|gfe GG FF|

In addition the handling of the L: field was improved.
This impacts abc2midi, yaps, abc2abc, and abcmatch.
The implementation of these changes involved creating a new
typedef structure (timesig_details) in abc.h, and numerous new
functions or upgrades in parseabc.c (check_power_of_two,
read_complex_has_timesig, read_L_unitlen, copy_timesig, 
interpret_voice_label, ... Lots of changes to parseabc.h.
Minor changes to store.c, toabc.c yapstree.c to link to the
new functions in parseabc.c


January 21 2021

Abc2midi bug: the following tune exposes several problems.

X:1
T: voice repeats
M: 4/4
L: 1/4
K:C
[V:1] C2E2 |
[V:2] C,4 |
[V:1] D2F2 & f4|
[V:2] D,4 |
[V:1] E2G2   ::
[V:2] E,4 ::
[V:1]d2B2  |
[V:2]B,4 |
[V:1] c2A2|
[V:2] A,4 |
[V:1] B2G2 :|]
[V:2] G,4 :|]

Running abc2midi produces the following messages.
voice mapping:
  1     2   
writing MIDI file repeats1.mid
Error in line-char 8-10 : Expected end repeat not found at |:
Error in line-char 8-10 : Expected end repeat not found at |:
Warning in line-char 18-10 : Track 2 is 48.054165 quarter notes long not 40.054165
Error in line-char 10-13 : Found unexpected ::
Warning in line-char 18-11 : Track 3 is 36.054165 quarter notes long not 40.054165

The first two error messages do not make sense since it points to
line [V:1] D2F2 & f4| which does not contain a left repeat |: .
Furthermore the double repeat E2G2 :: is ignored and that section is
not repeated causing a loss of synchronization between the two voices
and unequal tracks.

Analysis:
If we remove the split voice &f4, abc2midi runs without errors.
If instead we put opening repeats |: in the first measure,
[V:1] |: C2E2 |
[V:2] |: C,4 |
abc2midi again runs without errors.

The problem is caused by a bug in the function add_missing_repeats (store.c)
which is called by scan_for_missing_repeats. After, the first call to
insertfeature, the locations in the array add_leftrepeat_at[] no longer
point directly to the VOICE features but before. (The insertion shifts
everything to the right.) It is necessary to adjust this position by
looking ahead.


January 24 2021

Abc2midi: in some abc files the grace note sequence occurs after the
host note just before a barline. The grace sequence does not steal time
from a note eventually causing a synchronization problem between
the voices. Fix: the grace sequence is removed from the internal
representation using a new function cleargracenotes() in store.c if
a bar line is encountered during the search for the host note.

Hooks to new instructions !accent! !mordent!, !sfz!, !wedge! were
added to the function event_handle_instruction() in store.c.


February 21 2021

Abc2midi bug: unfortunately the fix applied to add_missing_repeats
applied on January 21 2021 caused a new problem for single voice files.
For example:

X: 1
T: repeat bug
R: jig
M: 6/8
L: 1/8
K: G
D |"G" ~G3 GAB |"D"ABA ABd | "G"edd gdB | "D"AGF "G"G2 ::
 A | "G"BAB dBd| "Em"ege "G"dBd | gfg "D"aga | "G"bgf g2 :|

Those files do not contain a VOICE feature, so that the fix results
in the leftrepeat being misplaced. The problem was repaired by
testing the varieable voicesused before searching for the VOICE feature.



March 10 2021

Abc2midi segmentation error: the following tune causes abc2midi to
crash.

X:6
T:TEMP
L:1/4
M:2/2
Q:1/4=112
%%MIDI drum d2dd 39 39 39
%%MIDI drumon
K:G
G4

Fix: in event_midi check that the v structure is not NULL before
setting v->hasdrums to 1. If it is NULL send an error message that
%%MIDI drumon must occur after the first K: header.


March 27 2021
abcmatch.c bug fix reported by umbraticus.
277:
        if (nbars >0 ...
should be
        if (*nbars >0 ...



March 30 2021
abc2midi bug: though grace notes only contain notes, the syntax allows
you to substitute chords for grace notes. For example,

X:1
T:acc
M:4/4
L:1/4
K:G
[DF]|E {[bc]}B cd|D4|

The function applygrace_new (in store.c) was modified so that the two notes
in the chord [bc] are treated as if they were one note. Otherwise
the measure would be too short (B is shrunk to make room for b and c)
and there could be a loss of synchronization between the voices.

April 26 2021

abc2midi: bar line alignment. The feature introduced in Mar 18 2019,
had a few issues. If the bar ends with a rest, the number of beats
is incorrect because there is no MIDI message to indicate a rest other
than a gap between a NOTEOFF and the following NOTEON and barlines
do not exist in midi files. Using a cumulative beat count does not
detect the possibility that the bar lines can realign because of
two errors cancelling out. As an experiment, I save only the bar size.


May 09 2020

abc2midi, abc2abc, yaps -- compatibility with abcm2ps.
The %%beginps and %%endps enclose text which should not
be processed by abc2midi or abc2abc.   The flag ignore_line is set
to 1 when parseline() encounters "%%beginps" and is reset to 0
when %%endps" is encountered. If ignore_line is 1, the rest of
the code in parseline() is ignored when abc2midi is running.


May 10 2020

abc2midi: the following file causes a core dump.

X:1
T:Autumn Ale
C:Chance Thomas, Stephen DiGregorio, Geoff Scott and/or Brad Spear
R:Jig
S:The Lord of the Rings Online Soundtrack
O:Turbine's Middle Earth
Z:Northman
N:This is not intended for percussion instruments.
Q:333
M:6/8
L:1/8
K:D
AGA BA/3B/3A/3G | FE/3F/3E/3D EFG |

abc2midi notpowerof2.abc
4.53 May 09 2021 abc2midi
Error in line-char 13-5 : 3 b is not a power of 2
Error in line-char 13-8 : 3 b is not a power of 2
Floating point exception (core dumped)

Analysis: the crash occurs in the function reduce (0)
which cannot handle a division by zero. The function
check_power_of_two(3) in parseabc.c returns 0 when the
argument is not a power of 2. Fix: changed the return
to -1. The program does not crash but the midi file
is not created correctly.



May 19 2020

abc2midi: the following file causes abc2midi to hang.

X:1
T: Hangs abc2midi
L:1/4
K:C
2c/2fac'/c'/c'/c'/c'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

James Allwright intoduced a fix in readlen() in parseabc.c


May 22 2021

abc2midi: treble-8 not applied in K: or V: commands after October 19 2020
update. For example,

X:1
T: transposition
L:1/2
M:C
K:none clef=treble-8 
V:1
cz
V:2
zc

The note c should be played with midi pitch 60 instead of 72.
James Allwright made minor fixes to parseabc.c and store.c, in order
to get these options working again.



May 25 2021

James Allwright added more security checks to stop the
parser from reading numbers beyond the largest integer. Changes
were made to parserabc.c and midi2abc.c

The abc2abc -s spacing function was modified to ignore certain
time signatures like M: none or M:7/8. The code for dealing with
3/2, 3/4, 3/8 ... time signatures was improved.


June 24 2021

abc2midi bug: in the following sample

X:1
T: octave
M: 2/4
L: 1/8
K: none octave=1
V:1
C4|
V:2
C4|

The octave=1 applies only to voice 1 and does not
act as global variable applying to both voices.

Analysis: event_octave either sets global.octaveshift or
v.octaveshift depending upon the variable pastheader. Pastheader
was set to 1 by headerprocess() in event_key() prior to calling
event_octave which prevented global.octaveshift from being set.

Fix: moved headerprocess(), getvoicecontext(), etc to after
calling event_octave().


June 27 2021

midi2abc: bug
For some midi files midi2abc returns something like this
X: 1
T: from gchordbreakdown1.mid
M: 4/4
L: 1/8
Q:1/4=120
K:C % 0 sharps
V:1
K:E % 16 sharps
=c=d e=g e4| \


Analysis, in the function handletext(), the local variable sf is
declared as an integer but not initialized. The function
sscanf(str,"%d %d",&sf,&mi);
attempts to read sf and mi from str, but str does not contain
any integers, and sf is not changed.
Temporary fix: initialized sf to 0.


June 27 2021

abc2midi: %%MIDI gchordoff produces garbage. In the following file

X:1
T: gchord breakdown
M: 4/4
L: 1/8
Q:1/4=120
K:C
%%MIDI gchord ghi2ihi2
%%MIDI gchordoff
"C" cd eg e4 |"Am" ag ag e4 |
%%MIDI gchordon
"Dm" defe d4 | "G7" g6z2 |

The output in track 2 as seen by midi2abc looks like this.
X: 1
T: from gchordbreakdown1.mid
M: 4/4
L: 1/8
Q:1/4=120
K:C % 0 sharps
V:1
cd eg e4| \
ag ag e4| \
de fe d4| \
g6 
V:2
F,,,,F,,,, F,,,,2 F,,,,F,,,, F,,,,2| \
F,,,,F,,,, F,,,,2 F,,,,F,,,, F,,,,2| \
D,F, A,2 A,F, A,2| \
G,B, D2 DB, D2|

instead of

X: 1
T: from gchordbreakdown1.mid
M: 4/4
L: 1/8
Q:1/4=120
K:C % 0 sharps
V:1
cd eg e4| \
ag ag e4| \
de fe d4| \
g6 
V:2
z8| \
z8| \
D,F, A,2 A,F, A,2| \
G,B, D2 DB, D2|

Analysis: abc2midi works correctly without the
%%MIDI gchord ghi2ihi2
declaration. The problem occurs in the function dogchords().
This function was expanded to handle alberti starting from May 1 2004.
Unfortunately, the fix introduced in 2016-01-03 introduced this
problem when %%MIDI gchordoff sets gchords to 0. The else branch
outputs gchordnotes[gchordnotes_size] when in fact, no note should
be queued out.

Fix: prefixed the switch(action) statement with the line
 if (gchords) /* [SS] 2021-06-27 */
preventing any note output when gchords is 0.

In addition, the case 'b' was missing a break, allowing the switch statement
to continue to case 'c' and causing a different problem when
%%MIDI gchord ffbb


September 15 2021

abc2midi bug:
The last fix in June 27 2021 inserting a break introduced a new bug.
The chord associated with the 'b' gchord code was missing. b and f
codes were indistinguishable. Fix: removed the break in the switch
statement for case b:


October 11 2021

abc2midi new feature:
In compliance with the ABC draft standard 2.2, I introduced additional
K: and V: options for transposition. You can now indicate the number
of semitones to transpose by giving the original note and the 
corresponding transposed note in the K: or V: field using either
shift = note1note2
sound = note1note2
instrument = note1/note2
The number of semitones is determined by the difference note2 - note1.

Abcm2ps and abc2svg recognize this command, but abc2abc, yaps, and
abcmatch ignore this new option.

http://abcnotation.com/wiki/abc:standard:v2.2#transposition

Here is a test sample:

X:1
T: standard 2.2 transposition
M: 4/4
L: 1/4
K: C  
V:1 
Bcde|Bcde|
V:2
Bcde|Bcde|
V:1 shift = Bc
Bcde|Bcde|
V:2
Bcde|Bcde|
V:1 sound = dc
Bcde|Bcde|
V:2
Bcde|Bcde|
V:1 instrument = c/^D
Bcde|Bcde|
V:2
Bcde|Bcde|
V:1 transpose = 0
Bcde|Bcde|
V:2 shift=DE,
Bcde|Bcde|


October 15 2021

Abc2abc -P bug



X:1
T: P bug
M:4/4
L:1/4
V:1 clef=treble
V:2 clef=bass
%%staves [1 2]
K:C
V:1
C2 D2  |  C4 |
V:2
C,2 G,2 | C,4|

The command
abc2abc t.abc -t 3 -P 1
fails to transpose voice 1

This bug has been around since this option was introduced in June 7 2011.
Fortunately, it has not bothered anyone until recently.
If you add another K:c after the first V:1 command in the body as
shown below.

X:1
T: P bug
M:4/4
L:1/4
V:1 clef=treble
V:2 clef=bass
%%staves [1 2]
K:C
V:1
K:C
C2 D2  |  C4 |
V:2
C,2 G,2 | C,4|

then voice 1 will be transposed correctly. Unfortunately, there is
no easy fix. When the -P option is present, abc2abc ignores the
first K: field command. (In toabc.c line 1643 event_key aborts
prior to setting up the arrays for a key transpose. Commenting
out this return statement introduces another problem.)

The main issue is that abc2abc only does one pass through the
input file. It does not know whether there is a K: field command
following V:1. If it assumes that there is none and forces a
call to event_key in event_voice, there may be another problem
when a different K: field command is found eventually. I have
decided to suspend support to the -P option because it would be
too complicated to fix this.


November 25 2021

abcmatch bug. The fix on 2021-03-27 made abcmatch non-operable. The
number of bars *nbars is never incremented. The line was replaced
with
if (*nnotes > 0) { /* [SS] 2021-11-25 */
in the function make_note_representation(...)


December 05 2021

abc2midi new feature. Abc2midi did not recognize double flats or double sharps
in the gchord. For example

X:1
T: Double flat gchord
M: 4/4
L: 1/4
K: C
"Dbb" C4| C4 |

returns the error message
Error in line-char 6-0 : Unrecognized chord name "b"
(Hint: use %MIDI chordname to define it. eg %MIDI chordname sus4 0 4 7).

Fix: in event_handle_gchord in store.c, now check for a double accidental.


December 10 2021

abc2midi: introduced gchord elements k and K. A gchord string can
contain and of the letters in zcfbghijkGHIJKx. Note that the chord
elements j,J,k,K are only defined for gchords with 4 or 5 notes like
M9 or M11. Here is a test example.

X:1
T: Gchord string
M: 4/4
L: 1/4
K: C
%%MIDI chordname x 0 3 5 7 9
%%MIDI gchord fGHIJK
"C11" C4 | C4 |
"Cx"  C4 | C4|
"C11/E" C4 | C4|
"C11/G" C4 | C4|
"C11/B" C4 | C4|


December 12 2021

abcmidi: changed bar length warning as suggested by James Allwright.


January 13 2022

abc2midi: stack overflow bugs reported by Kolja Grassmann
<koljagrassman@mailbox.org>

static int getword(place,w) in genmidi.c
check that the syllable[200] array is not overrun
in the while loop ((syllastus != postword)...) add && (i<199)

static void karaokestarttrack in genmidi.c
replace strcpy(atitle+2,atext[pitch[j]])
with strncpy(atitle+2,atext[pitch[j]], 197)
to prevent overflowing the atitle[200] array
in three places.

static int inlist(place, passno) in genmidi.c
To prevent stack overflow in msg[100];
use snprintf instead of sprintf
snprintf(msg, 100, "Bad variant list : %s", atext[pitch[place]]);

void event_handle_instruction(s) in store.c
To prevent overrunning the array buff[MAXLINE]
used snprintf instead of sprintf
 snprintf(buff, MAXLINE, "instruction !%s! ignored", s);

void event_info_key(key, value) in store.c
To prevent overrunning the array errmsg[80]
used snprintf instead of sprintf
snprintf(errmsg, 80, "I: key \' %s\' not recognized", key);


January 27 2022

abcmidi: new feature
%%MIDI pitchbendrange semi
maps the pitchwheel 0 to 16383 to semi semitones. By default semi
is set to 2. If you change it to 4, then the pitchwheel maps into
+/-4 semitones. This effects all microtones in the active channel
when semi is not 2. %%MIDI temperament commands may not work
correctly. Here is an example.

X:1
T: pitch bend with RPN
M: 4/4
L: 1/4
K: G
%%MIDI program 70
G2 B2 |\
%%MIDI bendstring 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500
!bend! G4 |\
%%MIDI pitchbendrange 7
!bend! G4 |

February 12 2022
Midi2abc -mftext: adjusted the pitchbend sensitivity bend2cents when
a RPN control command is received (in function mftxt_parameter).

February 13 2022
abc2midi: added an optional third parameter to %%MIDI bendvelocity
which specifies the number of MIDI pitchbend messages to create.
If this parameter is missing, the default is 8 as before.


February 18 2022
abc2midi bug: the K: and V: score option transposes the music in the
wrong direction. eg

X:1
T: transpose
M: 4/4
L: 1/4
K: G sound = DC
CDEF|GABc|

CDEF... converted to BbCDE.. instead of DEF#G...

Fix: swapped p2 and p1 in
          *transpose = p2 - p1;
in parsesound() in parseabc.c

February 21 2022
abc2abc mangles text. eg
input:

X:1
T: Text mangled by abc2abc 
Q:1/2=120
M:4/4
L:1/8
K:G bass octave=-2
%%begintext center
this text is mangled
%%endtext
%%
!f! g2 z d g2 z d | gdgb d'2 z2 | c'2 z a c'2 z a | cafa d2 z2 | gggg gggg | [I:repeat] |

abc2abc text.abc -t 2 >output.abc

output:

X:1
T:Text mangled by abc2abc 
Q:1/2=120
M:4/4
L:1/8
K:Amaj clef=bass octave=-2
%%begintext center
this tfxt is mbnalfe
%%endtext
%%
!f! a2 z e a2 z e | aeac' e'2 z2 | d'2 z b d'2 z b | dbgb e2 z2 | aaaa aaaa | [I:repeat] |

Analysis:
Parseline (line) in parseabc.c checks the line for %%begintext using strcmp.
Unfortunately, it does not find a match because the line also contains
the word 'center'.

Fix: replaced 
if (strcmp(line,"%%begintext") == 0) {
with
if (strstr(line,"%%begintext") != NULL) {
which returns the pointer to %%begintext in the line.


March 20 2022

abc2midi bug: I could not demonstrate this bug on my own system.

When abc2midi is compiled on a Debian linux system using the -O2 compilation
flag (by default), it produces a faulty midi file for abc files containing
gchords. Here is a sample file.

%abc-2.2
X:1
T:Test
M:C
L:1/4
Q:1/4=135
V:S clef=treble
V:s clef=treble
K:C
%%score (s S)
%
[V:s] "C" x2 "a" x2 |
[V:S]  C  C   A A   |

The problem occurs with the bass accompaniment generated by "a". The
bass accompaniment creates a long string of A,, notes.

This problem disappears when abc2midi is compiled without the
-O2 optimizer.

Analysis: the bug was traced to the code gchord_configure in genmidi.c.
The limit of the loops
 for (j=0; j<chordlen[chordnum]; j++)
contain bad data when chordnum is set to -1 (for bass accompaniment).

Fix: exit from gchord_configure function when chordnum is less than
zero.

The problem was identified to me by Jakob Englhauser. Jakob verified
that this fix works.


April 06 2022 midi2abc: removal of spaces in text strings for control
messages.


April 27 2022 abc2midi: Recanting change from February 18 2022.
The swap was incorrect.
Fix: swapped p2 and p1 in
          *transpose = p2 - p1;
in parsesound() in parseabc.c
abc2midi now transposes this file correctly.


X:1
T: transposition
M: 4/4
L: 1/4
K:Cm
V:1 shift=cF
cdef|gabc'|
V:2 sound=cF
cdef|gabc'|
V:3 score=cF
cdef|gabc'|
V:4 instrument=cF
cdef|gabc'|

Note that the command instrument=cF is not part of the abc standard
and abc2svg does not recognize it.


April 28 2022

midi2abc: minor change for -stats function


May 05 2022

midicopy: introduced new options -nopressure and -nocntrl


May 20 2022

Improvements in parsing umlaut characters in the T: Q: commands
and guitar chords in compliance with section 8.2 of the 2.2 Abc standard
(mnemonics). Here are examples where the mnemonics occur.

X:7
T:Slurs and Ties
T: Title with f\"unny chars like \005 Çéñô Àçäßö © …
M:C|
K:Ebm
[| (CDEF) ((3efg) ((3gag)| "_demit\"asse" (C2 EF) (ef(ga)) | ((c2 (3(d)ef) e2)\
 A2-|A4 c4-|(c4(e4)|a8) |]

X: 1
T: Traveller's Joy
R: polka
M: 2/4
L: 1/8
Q: "bl\"oop" 1/4=90
K: Gmaj
"^Duggie" f>g ag/2f/2 | "<G\"odel" gG B/2c/2d | "C" ee "G" dg/2B/2 | B/2A/2G/2B/2 "D" A2 |
"D" f>g ag/2f/2 | "G" gG B/2c/2d | "C" ee "G"dg/2g/2 | "D" af "G" g2 :|
%

X: 2
T: Tempo example
M: 4/4
L: 1/4
Q: 1/4=90 "c\"ah\"o\"ots"
K: G
abcd|efga

James Allwright added new functions to do the umlaut handling:
umlaut_get_buffer()
umlaut_build_string()
and parsename/parsesname were combined into one function.

June 14 2022

James Allwright has added support to the w:+ and +: lyric fields
as defined in the 2.3 abc standard. The following examples tests
the new feature.

X:1
T: Strange w: field example from abc 2.2 standard
N: This example appears in section 3.3 of the standard, which says :
N: The following is a legal continuation of the w: field, 
N: although the usage not recommended
M: 4/4
L:1/4
K:G
abcd|efgz|
%%vocalfont Times-Roman 14
w:nor-mal
% legal, but not recommended
%%vocalfont Times-Italic *
+:i-ta-lic
%%vocalfont Times-Roman *
+:nor-mal

X:2
T: Continuation Example
M:4/4
L:1/8
K:G
% legacy style continuation
B3A | "G"G2D2 B,2D2 | G4 z2G2 | "D7"A2A2 A2A2 | A4 ||
w: Oh, the Grand Old Duke of York, \
w: he had ten thou-sand men.
% + field style continuation
B3A | "G"G2D2 B,2D2 | G4 z2G2 | "D7"A2A2 A2A2 | A4 || 
w: Oh, the Grand Old Duke of York,
+: he had ten thou-sand men.
% w: + style continuation
B3A | "G"G2D2 B,2D2 | G4 z2G2 | "D7"A2A2 A2A2 | A4 z2 ||
w: Oh, the Grand Old Duke of York,
w: + he had ten thou-sand men.

There are numerous small changes.
In abc.h, added WORDEXTEND feature type.
In parseabc.h defined W_PLUS_FIELD and PLUS_FIELD
 and added a new integer parameter 'append' to the
 function event_word
In structs.h added lyrics_end
In parseabc.c preparse_words() has been split into two
 new functions preparse2_words() and preparse1_words()
 new input parameter in the function event_words()
In store.c, toabc.c, matchsup.c, and yapstree.c, modified
 the function event_words.
In genmidi.c introduced function check_wordextend()
In drawtune.c added the case WORDEXTEND in functions sizevoice()
 and printvoiceline().

July 31 2022

The abcmidi package creates a new voice when it sees
V: T clef=tab
where tab indicates tablature. As a result abc2midi
creates a separate track for this voice which can cause some
problems.

Fix: parseabc.c and music_utils.c was modified to ignore
the clef=tab indication.


August 1 2022

Fixed the abc parser so it does not report a malformed note
when it encounters a dotted bar line .|  -- (in parsemusic() in parseabc.c).
The dotted bar line is treated as a regular bar line.


August 23 2022, September 01 2022

midi2abc -midistats introducing quietTime.

December 5 2022

Midi2abc has been getting too big and it is time to split it into
separate applications.  Midistats is a new application that will replace
the midi2abc -midistats option.


December 9 2022

Cleaning out -stats code in midi2abc.


December 21 2022

abc2midi:
Wnen <note1> equals <note2> in the instrument=<note1>/<note2>  directive,
note2 should be treated as c (midi pitch 72).  Fix: parsesound in
parseabc.c was modified to return a midi pitch of 72 when the two
notes are equal.

test file:

X:1
T: transpose
M: 4/4
L: 1/4
K: C instrument=F/F
FGAB|cdef|

produces a midi file which looks like

X: 1
T: from h1.mid
M: 4/4
L: 1/8
Q:1/4=120
K:C % 0 sharps
V:1
c2 d2 e2 ^f2| \
g2 a2 b2 c'2|

when it was translated back to abc using midi2abc.

Note that this change also applies to sound= and shift= even though
this may not be specified in the standard
http://abcnotation.com/wiki/abc:standard:v2.2#transposing_instrument_examples


December 22 2022

abcmidi: segementation fault. The following file produced a
segmentation fault.

X:1
T: transpose
M: 4/4
L: 1/4
K: C instrument=F 
FGAB|cdef|

Analysis: there is an invisible space following F in the
line K: C instrument=F . As a result the function note2midi
called pitch2midi with an invalid note (a space). The line
p = (int) ((long) strchr(anoctave, note) - (long) anoctave);
returned a bad index into the scale array.

Fix: tested that p is in the range 0 to 7.


December 27 2022

abcmidi: The instrument=<note1>/<note2> is defined as a shorthand
for score=<note1><note2> sound=c<note2>. For instrument=,<note1>
indicates the key of the instrument and  <note2> is either c or C.
The sound= directive specifies the note and how it is played.
For example, sound=c_B indicates that the note c is played as
_B on the instrument. Every note is transposed down by two semitones.
The problem is that, the notes in the instrument directive are
in the opposite order of the sound= and score= directives.
The function parsesound() in parseabc.c treats takes care of
the directives sound =, shift = and instrument =.
Unfortunately, all these directives are treated in the same
manner causing the instrument= directive to transpose
in the wrong direction.

Fix: for the special case, instrument=, transpose is set to
p1 - p2 instead of p2 - p1.

The '/' is only part of the instrument= syntax. Note2midi has
an extra parameter, word, indicating the type of directive.
It will issue a warning if it detects a '/' in the sound= or
shift= directives.

December 30 2022

abcmidi: The instrument=*/c is a special directive that suppresses
a transpose.  For example:

X:2
T: transpose using instrument=_B/c
T: clarinet coded in concert pitch, displayed in Bb (as in player part)
M: 4/4
L: 1/4
K: C 
V:1 nm="Flute"
CDEF|GABc|cBAG|FEDC|
V:2 instrument=_B/c  nm="Clarinet\nin Bb"
CDEF|GABc|cBAG|FEDC|

The notes in V:2 are displayed up using score=_Bc, but they are still
played as written (sound=cc does nothing).
Fix: the code in the block 
if (casecmp(word,"instrument") == 0 {
...
}
in parsesound() (parseabc.c) was rewritten.


January 05 2023

abc2midi: instrument =F/D transposes cdec up by 3 semitones instead of
down by 10 semitones in the following example.

X:5
T: wrong octave
M: 4/4
K:C
V:1 instrument=F/D
cdec z4
V:2
z4 c4

Fix: Hudson Lacerda supplied me with pseudo-code (doc/hudsonshift.txt)
which describes how all the transpose directives should work.
This code was implemented in parseSoundScore() which now replaces
parseSound(). It also fixes yaps.


January 06 2023

abcmidi ignores sound=cD in the following example.

X:2
T: sound + score
M: 4/4
K:C
V:1 sound=cD score=FD
cdec z4
V:2
z4 c4

Analysis: *transpose is set to -10 by parseSoundScore when it
processes sound=CD but when parseSoundScore is called again
with score=FD it sets *transpose to 0, the initialized value
of transp_sound. The last value of *transpose is used by
event_voice.

Fix: if parseSoundScore is called by the abc2midi executable,
then *transpose is not set to transp_sound when the score=
directive is processed. There is a similar issue when
parseSoundScore is called by yaps. We do not want to set
*transpose to transp_score when the sound= is processed.

January 08 2023

abc2abc should replicate the score=, shift=, sound=, and instrument=
directives but otherwise ignore them.

Fix:  parseSoundScore() in parseabc.c does nothing if it is
called from abc2abc and return 0. The function parseother(),
which is called from parsevoice() or parsekey(), will output
all other directives in the K: or V: command.

January 10 2023

abcmidi: in event_handle_instruction(s), added code to recognize
!ped(! and !ped)! in addition to !ped! and !ped-up!


January 20 2023

abc2midi: as remarked around June 04-06 2005, split bars and
parts were never fully working. For example,

%%quiet
X:1
T: split-part
M:5/4
L:1/8
Q:1/4=132
P:A6
K:none
%%MIDI channel 10
P:A
CDCDC CDCDC & [I:MIDI channel 10] z2E3 E5 |

does not convert correctly to a midi file.

Fix: the code in partbreak() seems to have been at fault.
The program returns the wrong position of the voice in the
feature array, causing the wrong notes to be sent to the
active midi track. Permanently eliminating the function
fillvoice and always calling findvoice, fixed one of the
problems. The second fix was to replace findpart() with
findvoice() when the PART feature is encountered. Findvoice()
automatically calls findpart(). The external integer array,
dependent_voice(), is no longer used and is also eliminated.
(See this file December 12 2006.) These changes also appear
to fix the bug addressed at the same date.


February 07 2023
abc2abc: in toabc.c, James Allwright has introduced a new option -c
which replaces /2 with /. He also fixed the -h output in
event_init() so that all options are listed.


February 08 2023
midi2abc, mftext, midistats: modified midifile.c so that it indicates where
it encounters an unexpected byte in the input midi file.


March 24 2023
More functions for the percussion track was added to midistats.c to
support some future analysis.


June 25 2023
Midistats runs incorrectly if the midi file has no program channel
commands. When a program channel command is missing, the program should
be the acoutic piano (0) by default.

If more than one channel with the same program color, they should be
added together.


August 22 2023

Midistats improved the calculation of the number of rhythm patterns
in a channel (barChn[chan].rhythmPattern) by allowing for dithering
of note onset. Introduced dithermargin variable in function
stats_noteon(). In function, output_track_summary(), suppressed
notemeanpitch for percussion channel.


October 25 2023

Midistats returns track activity (note on/off) for every track.


November 1 2023

Midistats returns the control volume settings for every track,
identifies midi files whose note timings are not quantized.


November 2 2023

abc2midi bug: In the following example, not all notes are
tied correctly.

X:1
T: tied note
M: 2/4
L: 1/4
K: C
D2-|:D2 |[1CD-:|[2CD|

No fix is available.


November 8 2023

midistats: extended the size of arrays (midievents and pulsecounter) to
handle certain midi files. The function stats_interpret_pulseCounter()
can detect midi files containing triplets and nonquantized notes.

midicopy: extended to handle midi files with up to 150 tracks.


December 17 2023

midicopy: The midi program number is not set properly for a few the
midi files where the channel program numbers are set in a separate
track. Midicopy processes and copies the tracks sequentially, and
by the time it sees the channel program numbers in the separate
track it is already too late. It would be necessary to rewrite
midicopy so that it stores the entire midi file in memory prior to
copying it to disk.

midistats: Introducing a new option -nseqfor n where is a channel
number. See drums.txt for a description.


December 23 2023

abc2midi: gchord bug

The following example produces some strange artefacts on starting
the midi file for some players.

X:1
T:Test
L:1/8
Q:1/2=30
M:2/2
%%MIDI gchord GHIc
K:C
GAB | "C"c4 C4 |

Explanation: the output midi file plays a note with midi pitch 0
in the accompaniment channel. The problem originates in the dogchords()
function for switch case 'G': in genmidi.c. Since g_started is 0,
the second branch of the if statement is executed, but the pitch
value in gchordnotes[gchordnotes_size] contains 0.

Fix: the switch statement should not be executed since g_started is
0 (i.e. the gchord accompaniment does not start till "C" is encountered).
The switch statement is now bypassed when either g_started 
or gchords is 0. The tests for gchords and g_started in all the
case statements were removed since they are unnecessary.



December 28 2023

abc2midi: tuplet bug

The following example produces the error

Warning in line-char 7-8 : Different length notes in tuple

X:1
T:Test
L:1/4
Q:1/4=90
M:3/4
K:D
(3[ac']/d'/[ac']/ [ac']/z/ |

Analysis: though it is legal to have different length notes (and
rests) in a tuple, this is clearly a bug. The message occurs in the
function event_note() in store.c. tnote_num and tnote_denom should
contain the expected length of the note in the tuple based on the
first note encountered in the tuple. The value of tnote_denom was
not adjusted by event_chordoff to compensate by the length value
specified at the end of the [ac'] chord, resulting in the problem.


January 15 2024

abc2midi bug: the following example produces a warning, but the
the output midi file is correct.

Warning in line-char 7-23 : Track 1 Bar 1 has 1 time units while the time signature has 2

X:1
T:Test trill
L:1/4
M:2/2
Q:1/2=60
K:Dm
 !trill!"C"g4- | g2^c2 |

Analysis: this warning is produced by checkbar() in genmidi.c. This problem was
reported in this file on November 23 2012. The code for handling tied notes is
quite intricate and I do not understand it. I am hesitant in tampering with the code.
 

February 14 2024

abc2midi: repeat bug

For the following example:

X:1
T: Repeat bug 
M: 1/4
L: 1/4
P:A
K:C
P:A
A | B & C :|

Abc2midi produces a midi file which looks like this
V:1
A | B |
V:2
Z | C | Z | C|

the second voice is repeated by the first voice is not.

Removing the P:A prior to K:C fixes the problem.
Alternatively, inserting the missing left repeat |:
(eg) |: A | B & C :|
also resolves the problem.

Apparently, abc2midi does not insert the left repeat in the
correct position.

Analysis: abc2midi produces an internal representation of the
music using the feature[] array. Since this tune uses split
voices using the & character, the internal representation now
contains two voices. abc2midi then calls scan_for_missing_repeats()
and add_missing_repeats() in store.c in order to insert the missing
left repeats in the internal representation. Unfortunately,
scan_for_missing_repeats puts the left repeat in the wrong place where
it is ineffective. 

The code in scan_for_missing_repeats is quite complicated
because it has to work for either voices or parts. It searches
for either VOICE or PART code in the feature array and inserts
the left repeat immediately following this code. If both
VOICE and PART are present, VOICE should immediately follow PART
in order that scan_for_missing_repeats works correctly. Unfortunately,
they occur in the opposite order. The function event_split_voice()
inserts the VOICE code in the wrong position, mainly because
the v1index address is incorrect.

Fix: event_part() in store.c, I added the line
v1index = notes; /* [SS] 2024-02-14 */
following
addfeature(PART, (int)*p, 0, 0);
 
This appears to resolve this issue.
 

abc2midi: another related repeat bug

For the following example:

X:1
T: A related repeat bug
P:A
M:3/4
L:1/4
K:D
P:X
Z | zzz & b'b'b' :|
P:A
CCC | DDD  :|

abc2midi produces incorrect output for this file. It does not
insert the left repeats in the right place in its internal
representation.

Fix: for the present time you need to put the left repeats in the
file like this.

|:Z | zzz & b'b'b' :|
P:A
|:CCC | DDD  :|



February 19 2024

abc2midi bug and fix submitted by James Allwright.

The parser recognizes |: but not |::
In the following example,

X:1
T: ||: bug
M: 2/4
L: 1/4
K: G
G||:AB|[1cz:||[2ed|

the repeat goes back to 0th bar (containing G) instead of
bar 1 (containing AB).

Fix: in parsemusic() in parseabc.c, the following lines were
added.

if (*(p+1) == ':') {
        /* handle ||: as a variant of |:  [JA] 2024-02-19 */
        check_and_call_bar (BAR_REP, "");
        p = p + 2;

The change also has impact on yaps, abc2abc, and abcmatch.


February 22 2024

abc2midi bug

Adding snm=something after a clef= declaration
removes the offset from the clef. In the following
example,

X:1
T: with snm
M:4/4
L:1/4
V:1 clef=treble-8
V:2 clef=treble-8 snm=anything
K:C
[V:1] z z C z |
[V:2] z z z C |

C in voice 1 is shifted down an octave but C in voice 2
is untouched.

Analysis: parsevoice attempts to parse each token (clef=, octave=,
transpose=, sound=, name= and etc.) by calling various functions
parseclef(), parsetranspose(), parseoctave(), and etc.) until it
succeeds. parseclef is thus called on every token and returns either
1 or 0 depending whether it was successful or not. parseclef calls
the function isclef() to do the work. Unfortunately, isclef()
zeros the variable new_clef->octave_offset whether or not a
clef is declared in the token. Therefore the token snm=...
causes new_clef->octave_offset to be zeroed. The next function
which follows, get_extended_clef_details does set the octave_offset, but
it is only called if the token was a clef.

Fix: commented out the line in isclef() which zeros the octave_offset.


February 25 2024

abc2midi note:

Besides clef=treble-8, the abcmidi 2.2 standard also recognizes
clef=treble_8, clef=treble^8 and etc. These clefs do not transpose
the notes in the midi file but merely put the appropriate symbol
on the clef. Abc2midi presently ignores these endings in the
function get_clef_octave_offset() in music_utils.c.  When it is
necessary for the parseclef to see these endings the following fix
is necessary.

Fix: readword() called by parseclef breaks the clef string
when it encounters either a ^ or _ in order to handle sharps
and flats in the K: declaration. (See note above April 8 2015.)
It is necessary to use the new function, readword_with_()
which does not break the string on encountering either
the underscore _ or caret ^.


March 02 2024

abc2midi deviance from abc standard 2.2

The clef=, octave=, and transpose= in the V: command are
expected to be persistant and independent of each other. They
are changed independently any time a new clef=, octave=,
or transpose= appears.  These are stored in 3 variables.
And the pitch of a note is assigned the sum of these values.

Analysis:
event_note computes the midi pitch from note (one of a,b,c,d,e,f,g),
the xoctave, clef, accidental, and mult which are all input
parameters to that function. In addition it accesses the global
voice structure v of the active voice to get the octaveshift
for that voice. The function computes the local variable octave
from xoctave, clef->octave_offset and v->octaveshift. 

Prior to this fix and since May 21 2021, the local variable
octave was either assigned to the value of
clef->octave_offset + xoctave or to v->octaveshift + xoctave when
v->octaveshift is nonzero. In addition, event_voice also changes
v->octaveshift when it encounters a new clef=.

Fix:

In order to comply with this standard, the code in event_voice
was modified to prevent clef= from modifying v->octaveshift. In
addition event_note now computes octave as below.
 octave = clef->octave_offset + v->octaveshift + xoctave;  /*[SS] 2024-03-02*/

Note this is a significant change as it could break some abc
files. For example, if the user put clef=treble+8 and also
octave=+1, just to be safe, then the resulting octave would be higher
than expected. Fortunately, octave= is still rarely used.

Here is the test file for verifying this fix.

X:1
T:Test for octave shifts in sound
M:4/4
K:C
% The following seven notes should have equal sound
V:1 clef=treble
d8 |\
[V:1 clef=treble+8] D8 |\ 
[V:1 octave=-1] d8 |\  
[V:1 transpose=12] D8 |\
[V:1 clef=treble] d8 |\
[V:1 octave=0] D8 |\
[V:1 transpose=0] d8 |]


April 30 2024

According to the abc standards 2.1 and 2.2 the %% (pseudo comment)
and the I: (stylesheet directive) should access the same functionality
in the same way. Thus if
%%MIDI program 10
should appear in an I: command as I:MIDI program 10 and not as
I:MIDI= program 10. James Allwright has updated abcMIDI C code
to comply with the standards. If you need to run some of the older
abc files that do not obey this standard and you do not want
to edit these files, then you should use an older version of
the abcMIDI package. 

The following files were updated: matchsup.c, parseabc.h, pareseabc.c
parser2.c, store.c, toabc.c. and yapstree.c. Look for the comments
[JA] 2024-04-30.


June 11 2024

abc2midi: corrected the sus4 chord in store.c

August 11 2024
midicopy: introduced -transpose option

August 13 2024
abc2midi: in event_handle_gchord() in store.c increased the size
of variable name to char name[10] to avoid potential buffer overflow.

December 06 2024
abc2midi: process_midix(s) in store.c can cause a segmentation error
if it cannot match MIDIx with the corresponding MIDIdef. Fix:
added a return statement after reporting the problem in event_error(msg).

December 16 2024
December 22 2024
abc2midi: corrections to the sus, sus4, sus2 and sus9 chords provided
by Avik Topchyan were incorporated in the function setup_chordnames()
into store.c


January 3 2025
abc2midi: it was recently discovered that abc2midi does not respect
the microtone key signature when dealing with Turkish makams.
In the sample file

X:1
T: Microtone key signature
M: 4/4
L: 1/4
%%MIDI temperamentequal 53
K: C
B,2 D2|\
_1B,2 _4D2|
K: C _1B _4D
B,2 D2|

The last bar B,2 D2 should be played as _1B,2 _4D.

Fix: most of the code dealing with the microtone key signature
was already present in the function pitchof_b, however the
implementation was not complete. In order to complete the
implementation, the pitchof_b detects whether the note is
under the influence of the key signature and invokes event_microtone()
when necessary. The pitch shift is then applied just as if
the microtone was already present in the note.

Comment: the code dealing with microtones is very messy. The
function pitchof_b is more than 120 lines of code because it
also handles trills, and other note decorations. Information
is passed around through global variables like workmic, workmap,
note, pitchbend, microtone, setmicrotone. event_microtone
is called before event_note. It is hard to determine what is
going on. Many people have worked on this code.

 
January 07 2025

abc2midi: works correctly with microtone shortcuts but does not
handle the fraction expression of microtones. eg.

X:1
T: equaltempered 53
M: 4/4
L: 1/4
%%MIDI temperamentequal 53
K: none
C ^12/53C ^24/53C ^36/53C |^48/53C _48/53D _36/53D _24/53D |_12/53D =D ^12/53D ^24/53D| ^36/53D ^48/53D _48/53E _36/53E |
_24/53E _12/53E =E ^12/53E | ^24/53E ^36/53E F ^12/53F| ^24/53F ^36/53F ^48/53F _48/53G| _36/53G _24/53G _12/53G =G |
^12/53G ^24/53G ^36/53G ^48/53G| _48/53A _36/53A _24/53A _12/53A | A ^12/53A ^24/53A ^36/53A| ^48/53A _48/53B _36/53B _24/53B|
_12/53B =B ^12/53B ^24/53B _12/53c|

Fix: there were numerous minor fixes to ensure that the variable
setmicrotone.denom is initialized to 1 rather than 0 (to avoid division
by 0). New code was inserted in pitchof_b() in store.c.
 if (microtone) {
        /* [SS] 2025-01-03  2025-01-06*/
        if (setmicrotone.denom == 1)
          /* microtone shortcut (eg _1B,) */
          microtoneshift =  setmicrotone.num * microstep_size/100.0;
        else
          /* microtone fraction (eg _12/53B,) */
          microtoneshift =  (float) setmicrotone.num /(float) setmicrotone.denom;
In addition event_key was not receiving negative fractional microtones.
The problem was traced to a missing check in process_microtones()
in parseabc.c


January 12 2025

abc2midi ignores non-microtone accidentals. In the following example,

X:1
T: Non microtone accidentals
L:1/8
Q:1/4=60
M:8/8
%%MIDI temperamentequal 36
K:C
EF^FG^Gc^cd|

The accidentals in front of F, G, and c were
ignored.

Fix: in pitchof_b, for TEMPERLN or TEMPEREQ respect accidentals
occurring outside of microtones.


January 20 2025
January 22 2025

midi2abc

Added new options -midinotes and -midinotes-brief for listing the
notes (including pitchbends) present in the midi file. This is 
useful for checking the accuracy of abc2midi or the abc notation
representation.


February 02 2025

abc2midi 

X:2
T: treble bug
M:6/8
K:G treble-8
cCdDeE|

abc2midi shifts the notes down by 2 octaves instead of 1

Fix: in pitchof_b in store.c
recanted the replacement of
 if (v->octaveshift == 0) {   /*[JA] 2021-05-21 */
    octave = xoctave + clef->octave_offset;
  } else {
    octave = xoctave + v->octaveshift;
  }
for
  octave = clef->octave_offset + v->octaveshift + xoctave;  /*[SS] 2024-03-02*/

(clef->octave_offset and v->octaveshift are both -1. We want to apply
only one of those.)


February 15 2025

abc2midi ignores accidentals when converting to a temperamentequal scale.
In the following example:

X:1
T: temperamentequal 19
M: 4/4
L: 1/4
%%MIDI temperamentequal 19
K: none
C ^C _D D | ^D _E E F | ^F _G G ^G| _A A ^A _B| B c z z|

the accidentals were ignored when creating the midi file.

Fix:

Changed
 /* respect accidentals when they do not occur in a microtone */
    if (acc == '^' && !microtone) pitchvalue = pitchvalue + (float) mul; /* [SS] 2025-01-12 */
    if (acc == '_' && !microtone) pitchvalue = pitchvalue - (float) mul;

To

  /* respect accidentals when they do not occur in a microtone */
    if (acc == '^' && !microtone) pitchvalue = pitchvalue + (float) (mul*accidental_size); /* [SS] 2025-02-15 */
    if (acc == '_' && !microtone) pitchvalue = pitchvalue - (float) (mul*accidental_size);


February 16 2025

abc2midi produced the wrong results for temperamentequal 31

X:5
T: temperamentequal 31 
M:none
L:1/2
K:C
%
%%text \%\%MIDI temperamentequal 31
%%MIDI temperamentequal 31
"^Octave divided in 31 equal parts"\
=c ^/c ^c ^3/c ^^c =d _/d _d _3/d __d =c2  |
%

Fix:
In pitchof_b (store.c) it is necessary to scale the microtoneshift by the
accidental_size prior to adding it to the pitchvalue.

   pitchvalue += microtoneshift*accidental_size; /* [SS] 2025.02.16 */


February 13 2026

midistats: added new option -keystability.

February 24 2026

midistats: the summary includes ntimesig, triplets, unquantized when appropriate.

