mirror of
https://github.com/sshlien/abcmidi.git
synced 2025-12-08 19:01:02 +00:00
Compare commits
4 Commits
2021.05.09
...
2021.05.24
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62506f6ac3 | ||
|
|
538896e1b9 | ||
|
|
dcfa5cc7ad | ||
|
|
96570dbb2d |
68
doc/CHANGES
68
doc/CHANGES
@@ -14172,3 +14172,71 @@ to 1 when parseline() encounters "%%beginps" and is reset to 0
|
|||||||
when %%endps" is encountered. If ignore_line is 1, the rest of
|
when %%endps" is encountered. If ignore_line is 1, the rest of
|
||||||
the code in parseline() is ignored when abc2midi is running.
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
Guide to writing abc for abc2midi
|
Guide to writing abc for abc2midi - minor revision [JA] 2021-05-24
|
||||||
---------------------------------
|
--------------------------------------------------------------
|
||||||
|
|
||||||
Updated June 1 2017. %%MIDI program ranges from 0 to 127 not 1 to 128.
|
Updated June 1 2017. %%MIDI program ranges from 0 to 127 not 1 to 128.
|
||||||
|
|
||||||
The defining document for abc is the abc version 1.6 specification which can
|
The abc notation language is described by the version 1.6 specification
|
||||||
be found at http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt . This document
|
document and later modifications to this document referred to as
|
||||||
is a description of abc as interpreted by abc2midi.
|
version 2.1 and version 2.2. These can be found at abcnotation.com .
|
||||||
|
|
||||||
An abc tune consists of a header followed by a body. Each line in the
|
An abc tune consists of a header followed by a body. Each line in the
|
||||||
header is a different field starting with a letter immediately followed
|
header is a different field starting with a letter immediately followed
|
||||||
@@ -160,15 +161,43 @@ K:G clef=soprano octave=-1 transpose=-1
|
|||||||
The clef is recognized by typesetting programs such as yaps and abc2mps
|
The clef is recognized by typesetting programs such as yaps and abc2mps
|
||||||
and in some situations it will cause abc2midi to transpose the notes
|
and in some situations it will cause abc2midi to transpose the notes
|
||||||
up or down by an octave. Recognized clefs are treble,
|
up or down by an octave. Recognized clefs are treble,
|
||||||
bass, baritone, tenor, alto, mezzo and soprano. There are also variants
|
bass, baritone, tenor, alto, mezzo and soprano.
|
||||||
of these clefs; treble-8, tenor-8, treble+8 covering ranges which are an
|
|
||||||
octave below and an octave above the normal treble clef. Other
|
|
||||||
variants are not recognized at this time. No transposition is
|
|
||||||
assumed for the bass clef since many abc files enter the notes
|
|
||||||
with all the commas.
|
|
||||||
|
|
||||||
The octave specifier is a convenience to make entering music easier.
|
Clefs with +8, -8:
|
||||||
It allows the user to avoid repeatedly entering commas or apostrophes
|
|
||||||
|
Sometimes, you will find written music where there is a treble clef (or
|
||||||
|
some other clef) with a small 8. The meaning is that every note is to
|
||||||
|
be played an octave higher than shown. Suppose you notate the abc note A
|
||||||
|
using a treble clef. This appears as a note between the second and third
|
||||||
|
lines from the bottom of the stave. Then with a treble+8 clef (which looks
|
||||||
|
exactly the same except that it has a small 8), a note at the same position
|
||||||
|
on the stave lines is now played as abc note a (which is normally put on
|
||||||
|
a line one line up from the top line of the stave). Similarly, the
|
||||||
|
treble-8 clef indicates that every note is to be played an octave lower
|
||||||
|
than shown, so note A would be played as A, .
|
||||||
|
|
||||||
|
The abc standard versions 2.1 and 2.2 support this idea, but the way
|
||||||
|
the abc notation is interpreted changes when you have clef=treble+8.
|
||||||
|
With clef=treble+8, every stave position is interpreted as being an
|
||||||
|
octave higher than if you had clef=treble e.g. the note that sounds as
|
||||||
|
a does in normal abc is written as A in abc with clef=treble+8.
|
||||||
|
The overall effect of this is that when you change a passage from
|
||||||
|
clef=treble to clef=treble+8, without editing any of the notes, every
|
||||||
|
note appears at exactly the same place on the stave lines as it did
|
||||||
|
before, but it is played an octave higher.
|
||||||
|
|
||||||
|
The benefit of this change in interpretation is that you can notate
|
||||||
|
very high or very low passages in abc without having to use lots of
|
||||||
|
' or , characters.
|
||||||
|
|
||||||
|
The octave specifier is a convenience to make entering music easier,
|
||||||
|
developed before the +8/-8 clef modifier and still supported. However,
|
||||||
|
to be compatible with other abc programs, it is recommended that you
|
||||||
|
use the clef modifier. The syntax
|
||||||
|
|
||||||
|
I:octave=<offset in octaves>
|
||||||
|
|
||||||
|
allows the user to avoid repeatedly entering commas or apostrophes
|
||||||
when entering a sequence of low or high notes. Both yaps and abc2midi
|
when entering a sequence of low or high notes. Both yaps and abc2midi
|
||||||
will transpose the notes by the specified number of octaves during
|
will transpose the notes by the specified number of octaves during
|
||||||
the parsing stage.
|
the parsing stage.
|
||||||
@@ -180,9 +209,10 @@ e.g. the passage B,,, C,, D,, E,, F,, could be written more compactly as
|
|||||||
I:octave=0
|
I:octave=0
|
||||||
|
|
||||||
|
|
||||||
Some instruments such as the Bb clarinet automatically transpose the
|
Some instruments such as the Bb clarinet are by classical convention
|
||||||
written music. For example in the case of the clarinet, the music is
|
considered to transpose the written music. For example in the case of
|
||||||
written in the key of C but the instrument plays it in the key of Bb.
|
the clarinet, the music is written in the key of C but the instrument
|
||||||
|
plays it in the key of Bb.
|
||||||
For multivoiced tunes, the %%MIDI transpose indication is not that useful
|
For multivoiced tunes, the %%MIDI transpose indication is not that useful
|
||||||
since it transposes all the voices by the specified amount. The
|
since it transposes all the voices by the specified amount. The
|
||||||
transpose=n subcommand in the K: field tells abc2midi to transpose
|
transpose=n subcommand in the K: field tells abc2midi to transpose
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
abcMIDI : abc <-> MIDI conversion utilities
|
abcMIDI : abc <-> MIDI conversion utilities
|
||||||
|
|
||||||
midi2abc version 3.47 November 01 2020
|
midi2abc version 3.47 November 01 2020
|
||||||
abc2midi version 4.53 May 08 2021
|
abc2midi version 4.56 May 21 2021
|
||||||
abc2abc version 2.13 May 08 2021
|
abc2abc version 2.13 May 08 2021
|
||||||
yaps version 1.86 December 10 2020
|
yaps version 1.86 December 10 2020
|
||||||
abcmatch version 1.78 March 27 2021
|
abcmatch version 1.78 March 27 2021
|
||||||
|
|||||||
74
parseabc.c
74
parseabc.c
@@ -420,7 +420,7 @@ int check_power_of_two(int denom)
|
|||||||
if (t % 2 != 0) {
|
if (t % 2 != 0) {
|
||||||
snprintf(error_message, 80, "%d b is not a power of 2", denom);
|
snprintf(error_message, 80, "%d b is not a power of 2", denom);
|
||||||
event_error (error_message);
|
event_error (error_message);
|
||||||
return 0;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
t = t / 2;
|
t = t / 2;
|
||||||
}
|
}
|
||||||
@@ -543,37 +543,37 @@ void readsig (char **sig, timesig_details_t *timesig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
readlen (a, b, p)
|
void readlen (int *a, int *b, char **p)
|
||||||
int *a, *b;
|
|
||||||
char **p;
|
|
||||||
/* read length part of a note and advance character pointer */
|
/* read length part of a note and advance character pointer */
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
*a = readnump (p);
|
*a = readnump (p);
|
||||||
if (*a == 0)
|
if (*a == 0) {
|
||||||
{
|
*a = 1;
|
||||||
*a = 1;
|
}
|
||||||
};
|
|
||||||
*b = 1;
|
*b = 1;
|
||||||
if (**p == '/')
|
if (**p == '/') {
|
||||||
{
|
*p = *p + 1;
|
||||||
*p = *p + 1;
|
*b = readnump (p);
|
||||||
*b = readnump (p);
|
if (*b == 0) {
|
||||||
if (*b == 0)
|
*b = 2;
|
||||||
{
|
/* [JA] 2021-05-19 prevent infinite loop */
|
||||||
*b = 2;
|
/* limit the number of '/'s we support */
|
||||||
while (**p == '/')
|
while ((**p == '/') && (*b < 1024)) {
|
||||||
{
|
*b = *b * 2;
|
||||||
*b = *b * 2;
|
*p = *p + 1;
|
||||||
*p = *p + 1;
|
}
|
||||||
};
|
if (*b >= 1024) {
|
||||||
};
|
event_warning ("Exceeded maximum note denominator");
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
*b = check_power_of_two(*b);
|
*b = check_power_of_two(*b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* [JA] 2020-12-10 */
|
/* [JA] 2020-12-10 */
|
||||||
static void read_L_unitlen(int *num, int *denom, char **place)
|
static void read_L_unitlen(int *num, int *denom, char **place)
|
||||||
{
|
{
|
||||||
@@ -1261,7 +1261,17 @@ static void process_microtones (int *parsed, char word[],
|
|||||||
modmicrotone[j].denom = b;
|
modmicrotone[j].denom = b;
|
||||||
/* printf("%c microtone = %d/%d\n",modmap[j],modmicrotone[j].num,modmicrotone[j].denom); */
|
/* printf("%c microtone = %d/%d\n",modmap[j],modmicrotone[j].num,modmicrotone[j].denom); */
|
||||||
}
|
}
|
||||||
} /* finished ^ = _ */
|
} /* finished ^ = _ */
|
||||||
|
|
||||||
|
static void set_voice_from_master(int voice_num)
|
||||||
|
{
|
||||||
|
voice_context_t *current_voice;
|
||||||
|
|
||||||
|
current_voice = &voicecode[voice_num - 1];
|
||||||
|
copy_timesig(¤t_voice->timesig, &master_timesig);
|
||||||
|
copy_clef(¤t_voice->clef, &master_clef);
|
||||||
|
current_voice->unitlen = master_unitlen;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
parsekey (str)
|
parsekey (str)
|
||||||
@@ -1345,7 +1355,7 @@ parsekey (str)
|
|||||||
while (*s != '\0')
|
while (*s != '\0')
|
||||||
{
|
{
|
||||||
parsed = parseclef (&s, word, &gotclef, clefstr, &newclef, &cgotoctave, &coctave);
|
parsed = parseclef (&s, word, &gotclef, clefstr, &newclef, &cgotoctave, &coctave);
|
||||||
if (gotclef) {
|
if (parsed) { /* [JA] 2021-05-21 changed (gotclef) to (parsed) */
|
||||||
/* make clef an attribute of current voice */
|
/* make clef an attribute of current voice */
|
||||||
if (inhead) {
|
if (inhead) {
|
||||||
copy_clef (&master_clef, &newclef);
|
copy_clef (&master_clef, &newclef);
|
||||||
@@ -1550,16 +1560,6 @@ parsekey (str)
|
|||||||
return (gotkey);
|
return (gotkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_voice_from_master(int voice_num)
|
|
||||||
{
|
|
||||||
voice_context_t *current_voice;
|
|
||||||
|
|
||||||
current_voice = &voicecode[voice_num - 1];
|
|
||||||
copy_timesig(¤t_voice->timesig, &master_timesig);
|
|
||||||
copy_clef(¤t_voice->clef, &master_clef);
|
|
||||||
current_voice->unitlen = master_unitlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
parsevoice (s)
|
parsevoice (s)
|
||||||
char *s;
|
char *s;
|
||||||
@@ -2306,10 +2306,12 @@ parsefield (key, field)
|
|||||||
* if L: fields was missing in the header.
|
* if L: fields was missing in the header.
|
||||||
*/
|
*/
|
||||||
resolve_unitlen();
|
resolve_unitlen();
|
||||||
|
}
|
||||||
|
foundkey = parsekey (place); /* [JA] 2021.05.21 parsekey called before set_voice_from_master(1) */
|
||||||
|
if (inhead) {
|
||||||
/* set voice parameters using values from header */
|
/* set voice parameters using values from header */
|
||||||
set_voice_from_master(1);
|
set_voice_from_master(1);
|
||||||
}
|
}
|
||||||
foundkey = parsekey (place);
|
|
||||||
if (inhead || inbody) {
|
if (inhead || inbody) {
|
||||||
if (foundkey)
|
if (foundkey)
|
||||||
{
|
{
|
||||||
|
|||||||
8
store.c
8
store.c
@@ -186,7 +186,7 @@ int main()
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VERSION "4.53 May 09 2021 abc2midi"
|
#define VERSION "4.56 May 21 2021 abc2midi"
|
||||||
|
|
||||||
/* enables reading V: indication in header */
|
/* enables reading V: indication in header */
|
||||||
#define XTEN1 1
|
#define XTEN1 1
|
||||||
@@ -4300,7 +4300,11 @@ int xoctave, n, m;
|
|||||||
event_fatal_error("Internal error - no voice allocated");
|
event_fatal_error("Internal error - no voice allocated");
|
||||||
};
|
};
|
||||||
if (gracenotes && ignore_gracenotes) return; /* [SS] 2010-01-08 */
|
if (gracenotes && ignore_gracenotes) return; /* [SS] 2010-01-08 */
|
||||||
octave = xoctave + v->octaveshift;
|
if (v->octaveshift == 0) { /* [JA] 2021-05-21 */
|
||||||
|
octave = xoctave + clef->octave_offset;
|
||||||
|
} else {
|
||||||
|
octave = xoctave + v->octaveshift;
|
||||||
|
}
|
||||||
num = n;
|
num = n;
|
||||||
denom = m;
|
denom = m;
|
||||||
if (v->inchord) v->chordcount = v->chordcount + 1;
|
if (v->inchord) v->chordcount = v->chordcount + 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user