mirror of
https://github.com/sshlien/abcmidi.git
synced 2025-12-06 06:55:06 +00:00
15072 lines
454 KiB
Plaintext
15072 lines
454 KiB
Plaintext
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.
|
|
|
|
|