Compare commits

..

7 Commits

Author SHA1 Message Date
Seymour Shlien
e58956238a 2022.01.28 2022-01-28 07:43:41 -05:00
Seymour Shlien
0b83ee2c7b 2022.01.27 2022-01-27 12:46:08 -05:00
Seymour Shlien
fb5479e801 2022.01.13 2022-01-13 18:08:38 -05:00
Seymour Shlien
402f1ba212 2021.12.12 2021-12-12 15:59:49 -05:00
Seymour Shlien
3e1306aa26 2021.12.10 2021-12-10 12:08:42 -05:00
Seymour Shlien
fcae03ab71 2021.11.25 2021-11-25 13:00:06 -05:00
Seymour Shlien
e9c2aee88b 2021.10.11 2021-10-12 09:09:45 -04:00
7 changed files with 494 additions and 24 deletions

View File

@@ -1,2 +1,2 @@
2021 September 15 2021 2022 January 27 2022

View File

@@ -49,7 +49,7 @@ Matching:
#define VERSION "1.79 May 25 2021 abcmatch" #define VERSION "1.80 Novemeber 25 2021 abcmatch"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
@@ -274,7 +274,7 @@ make_note_representation (int *nnotes, int *nbars, int maxnotes, int maxbars,
these bar line indications. Note bar numbering starts these bar line indications. Note bar numbering starts
from 0. [SS] 2013-11-17 from 0. [SS] 2013-11-17
*/ */
if (*nbars >0 && *nnotes > 0) { /* 2021-03-27 */ if (*nnotes > 0) { /* [SS] 2021-11-25 */
midipitch[*nnotes] = BAR; midipitch[*nnotes] = BAR;
notelength[*nnotes] = BAR; notelength[*nnotes] = BAR;
(*nnotes)++; (*nnotes)++;

View File

@@ -14379,3 +14379,214 @@ The chord associated with the 'b' gchord code was missing. b and f
codes were indistinguishable. Fix: removed the break in the switch codes were indistinguishable. Fix: removed the break in the switch
statement for case b: 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 |

View File

@@ -1,10 +1,10 @@
abcMIDI : abc <-> MIDI conversion utilities abcMIDI : abc <-> MIDI conversion utilities
midi2abc version 3.48 June 27 2021 midi2abc version 3.48 June 27 2021
abc2midi version 4.60 September 15 2021 abc2midi version 4.66 January 27 2022
abc2abc version 2.15 May 25 2021 abc2abc version 2.15 May 25 2021
yaps version 1.87 May 25 2021 yaps version 1.87 May 25 2021
abcmatch version 1.79 May 25 2021 abcmatch version 1.80 November 25 2021
midicopy version 1.37 October 10 2020 midicopy version 1.37 October 10 2020
24th January 2002 24th January 2002
@@ -14,7 +14,7 @@ J.R.Allwright@westminster.ac.uk
University of Westminster, University of Westminster,
London, UK London, UK
June 2021 October 2021
Seymour Shlien Seymour Shlien
Ottawa, Canada Ottawa, Canada

View File

@@ -31,8 +31,11 @@
/* for Microsoft Visual C++ Ver 6 and higher */ /* for Microsoft Visual C++ Ver 6 and higher */
#ifdef _MSC_VER #ifdef _MSC_VER
#define ANSILIBS #define ANSILIBS
#define snprintf _snprintf
#define strncasecmp strnicmp
#endif #endif
#include "abc.h" #include "abc.h"
#include "parseabc.h" #include "parseabc.h"
#include "queues.h" #include "queues.h"
@@ -398,7 +401,8 @@ char* s;
p = s; p = s;
j = 0; j = 0;
seq_len = 0; seq_len = 0;
while ((strchr("zcfbghijGHIJx", *p) != NULL) && (j <39)) { /* [SS] 2021-12-10 */
while ((strchr("zcfbghijkGHIJKx", *p) != NULL) && (j <39)) {
if (*p == 0) break; if (*p == 0) break;
gchord_seq[j] = *p; gchord_seq[j] = *p;
p = p + 1; p = p + 1;
@@ -530,7 +534,7 @@ int pass;
if (bar_denom != 1) { if (bar_denom != 1) {
sprintf(msg+strlen(msg), "/%d", bar_denom); sprintf(msg+strlen(msg), "/%d", bar_denom);
}; };
sprintf(msg+strlen(msg), " units instead of %d", barsize); sprintf(msg+strlen(msg), " time units while the time signature has %d", barsize);
if (pass == 2) { if (pass == 2) {
strcat(msg, " in repeat"); strcat(msg, " in repeat");
}; };
@@ -810,17 +814,17 @@ int track;
if (feature[j] == TITLE) { if (feature[j] == TITLE) {
if (track != 2) if (track != 2)
mf_write_meta_event(0L, sequence_name, atext[pitch[j]], strlen (atext[pitch[j]])); mf_write_meta_event(0L, sequence_name, atext[pitch[j]], strlen (atext[pitch[j]]));
strcpy(atitle+2, atext[pitch[j]]); strncpy(atitle+2, atext[pitch[j]], 197); /* [KG] 2022-01-13 stack overflow bug */
text_data(atitle); text_data(atitle);
done--; done--;
} }
if (feature[j] == COMPOSER) { if (feature[j] == COMPOSER) {
strcpy(atitle+2, atext[pitch[j]]); strncpy(atitle+2, atext[pitch[j]], 197); /* [KG] 2022-01-13 stack overflow bug */
text_data(atitle); text_data(atitle);
done--; done--;
} }
if (feature[j] == COPYRIGHT) { if (feature[j] == COPYRIGHT) {
strcpy(atitle+2, atext[pitch[j]]); strcpy(atitle+2, atext[pitch[j]]); /* [KG] 2022-01-13 stack overflow bug */
text_data(atitle); text_data(atitle);
done--; done--;
} }
@@ -965,7 +969,8 @@ int w;
syllstatus = empty; syllstatus = empty;
c = *(words[w]+(*place)); c = *(words[w]+(*place));
isBig5 = 0; /* [BI] 2012-10-03 */ isBig5 = 0; /* [BI] 2012-10-03 */
while ((syllstatus != postword) && (syllstatus != failed)) { while ((syllstatus != postword) && (syllstatus != failed) && (i<199)) {
/* [KG] 2022-01-13 stack overflow bug fix */
syllable[i] = c; syllable[i] = c;
/* printf("syllstatus = %d c = %c i = %d place = %d row= %d \n",syllstatus,c,i,*place,w); */ /* printf("syllstatus = %d c = %c i = %d place = %d row= %d \n",syllstatus,c,i,*place,w); */
if (isBig5) { /* [BI] 2012-10-03 */ if (isBig5) { /* [BI] 2012-10-03 */
@@ -1251,7 +1256,8 @@ int passno;
found = 0; found = 0;
while ((found == 0) && (*p != '\0')) { while ((found == 0) && (*p != '\0')) {
if (!isdigit(*p)) { if (!isdigit(*p)) {
sprintf(msg, "Bad variant list : %s", atext[pitch[place]]); snprintf(msg, 100, "Bad variant list : %s", atext[pitch[place]]);
/* [KG] 2022-01-13 stack overflow bug */
event_error(msg); event_error(msg);
found = 1; found = 1;
}; };
@@ -1414,8 +1420,6 @@ static void midi_re_tune (int channel) {
this is done. this is done.
*/ */
char data[2]; char data[2];
data[0] = (char) (bend & 0x7f); /* least significant bits */
data[1] = (char) ((bend >>7) & 0x7f);
/* indicate that we are applying RPN fine and gross tuning using /* indicate that we are applying RPN fine and gross tuning using
the following two control commands. the following two control commands.
control 101 0 control 101 0
@@ -1438,6 +1442,29 @@ data[1] = (char) (bend & 0x7f); /* least significant bits */
write_event(control_change, channel, data, 2); write_event(control_change, channel, data, 2);
} }
/* [SS] 2022-01-27 */
static void midiPitchBendRange (int semis) {
/* by default the pitch wheel maps 0 to 16383 to a range of 4
* semitones. This function uses the RPN control command to
* expand the range to semis semitones.
*/
char data[2];
/* indicate that we are applying RPN fine and gross tuning using
the following two control commands.
control 101 0
control 100 0 */
data[0] = 101; /* RPN command */
data[1] = 0; /* type of command */
write_event(control_change, channel, data, 2);
data[0] = 6; /* contains most significant byte */
data[1] = semis;
write_event(control_change, channel, data, 2);
data[0] = 38; /* contains least significant byte (range in cents) */
data[1] = 0;
write_event(control_change, channel, data, 2);
}
/* [SS] 2011-07-04 */ /* [SS] 2011-07-04 */
@@ -2094,6 +2121,14 @@ int noteson;
else bendtype = 2; else bendtype = 2;
} }
/* [SS] 2022-01-27 */
else if (strcmp(command, "pitchbendrange") == 0) {
int semis;
semis = readsnump(&p);
midiPitchBendRange(semis);
done = 1;
}
else if (strcmp(command, "drone") == 0) { else if (strcmp(command, "drone") == 0) {
skipspace(&p); skipspace(&p);
@@ -2453,6 +2488,13 @@ int j;
save_note(g_num*len, g_denom, gchordnotes[gchordnotes_size], 8192, gchord.chan, gchord.vel); save_note(g_num*len, g_denom, gchordnotes[gchordnotes_size], 8192, gchord.chan, gchord.vel);
break; break;
/* [SS] 2021-12-10 */
case 'k':
if(gchordnotes_size >4 && g_started && gchords)
save_note(g_num*len, g_denom, gchordnotes[4], 8192, gchord.chan, gchord.vel);
else /* [SS] 2016-01-03 */
save_note(g_num*len, g_denom, gchordnotes[gchordnotes_size], 8192, gchord.chan, gchord.vel);
case 'G': case 'G':
if(gchordnotes_size>0 && g_started && gchords) if(gchordnotes_size>0 && g_started && gchords)
save_note(g_num*len, g_denom, gchordnotes[0]-12, 8192, gchord.chan, gchord.vel); save_note(g_num*len, g_denom, gchordnotes[0]-12, 8192, gchord.chan, gchord.vel);
@@ -2481,6 +2523,14 @@ int j;
save_note(g_num*len, g_denom, gchordnotes[gchordnotes_size], 8192, gchord.chan, gchord.vel); save_note(g_num*len, g_denom, gchordnotes[gchordnotes_size], 8192, gchord.chan, gchord.vel);
break; break;
/* [SS] 2021-12-10 */
case 'K':
if(gchordnotes_size >3 && g_started && gchords)
save_note(g_num*len, g_denom, gchordnotes[4]-12, 8192, gchord.chan, gchord.vel);
else /* [SS] 2016-01-03 */
save_note(g_num*len, g_denom, gchordnotes[gchordnotes_size], 8192, gchord.chan, gchord.vel);
break;
case 'x': case 'x':
if(!gchord_error) { if(!gchord_error) {
gchord_error++; gchord_error++;

View File

@@ -81,6 +81,7 @@ extern char *malloc ();
extern char *strchr (); extern char *strchr ();
#endif #endif
int note2midi (char** s);
int lineno; int lineno;
int parsing_started = 0; int parsing_started = 0;
int parsing, slur; int parsing, slur;
@@ -939,8 +940,8 @@ int interpret_voice_label (char *s, int num, int *is_new)
return num_voices; return num_voices;
} }
/* The following three functions parseclefs, parsetranspose, /* The following four functions parseclefs, parsetranspose,
* parseoctave are used to parse the K: field which not * parsesound, parseoctave are used to parse the K: field which not
* only specifies the key signature but also other descriptors * only specifies the key signature but also other descriptors
* used for producing a midi file or postscript file. * used for producing a midi file or postscript file.
* *
@@ -1019,6 +1020,49 @@ parsetranspose (s, word, gottranspose, transpose)
return 1; return 1;
}; };
/* [SS] 2021-10-11 */
int
parsesound (s, word, gottranspose, transpose)
/* parses string sound =
shift =
instrument = note1note2 or note1/note2
for parsekey() or parsevoice()
and returns the transpose value
*/
char **s;
char *word;
int *gottranspose;
int *transpose;
{
int p1,p2;
if (casecmp(word,"sound") != 0
&& casecmp(word,"shift") != 0
&& casecmp(word,"instrument") != 0
)
return 0;
skipspace (s);
if (**s != '=')
{
event_error ("sound must be followed by '='");
return 0;
} else {
*s = *s + 1;
skipspace (s);
p1 = note2midi (s);
/* printf("midi note = %d\n",p1); */
p2 = note2midi (s);
if (p2 == p1) {
*gottranspose = 0;
*transpose = 0;
} else {
/* printf("midi note = %d\n",p2); */
*transpose = p2 - p1;
/* printf("transpose = %d\n",*transpose); */
*gottranspose = 1;
}
}
return 1;
}
int int
parseoctave (s, word, gotoctave, octave) parseoctave (s, word, gotoctave, octave)
@@ -1382,6 +1426,9 @@ parsekey (str)
if (!parsed) if (!parsed)
parsed = parseoctave (&s, word, &gotoctave, &octave); parsed = parseoctave (&s, word, &gotoctave, &octave);
if (!parsed)
parsed = parsesound (&s, word, &gottranspose, &transpose);
if ((parsed == 0) && (casecmp (word, "Hp") == 0)) if ((parsed == 0) && (casecmp (word, "Hp") == 0))
{ {
sf = 2; sf = 2;
@@ -1623,6 +1670,8 @@ parsevoice (s)
&vparams.transpose); &vparams.transpose);
if (!parsed) if (!parsed)
parsed = parseoctave (&s, word, &vparams.gotoctave, &vparams.octave); parsed = parseoctave (&s, word, &vparams.gotoctave, &vparams.octave);
if (!parsed)
parsed = parsesound (&s, word, &vparams.gottranspose, &vparams.transpose);
if (!parsed) if (!parsed)
parsed = parsed =
parsename (&s, word, &vparams.gotname, vparams.namestring, parsename (&s, word, &vparams.gotname, vparams.namestring,
@@ -2661,6 +2710,156 @@ static void check_and_call_bar(int bar_type, char *replist)
event_bar (bar_type, replist); event_bar (bar_type, replist);
} }
/* [SS] 2021-10-11 */
static int pitch2midi(note, accidental, mult, octave )
/* computes MIDI pitch for note.
*/
char note, accidental;
int mult, octave;
{
int p;
char acc;
int mul, noteno;
int pitch;
static int scale[7] = {0, 2, 4, 5, 7, 9, 11};
static const char *anoctave = "cdefgab";
acc = accidental;
mul = mult;
noteno = (int)note - 'a';
p = (int) ((long) strchr(anoctave, note) - (long) anoctave);
p = scale[p];
if (acc == '^') p = p + mul;
if (acc == '_') p = p - mul;
p = p + 12*octave + 60;
return p;
}
/* [SS] 2021-10-11 */
int
note2midi (char** s)
{
/* for implementing sound=, shift= and instrument= key signature options */
/* check for accidentals */
char note, accidental;
char msg[80];
int octave;
int mult;
int pitch;
/*printf("note2midi: %c\n",**s); */
if (**s == '\0') return 72;
mult = 1;
accidental = ' ';
switch (**s)
{
case '_':
accidental = **s;
*s = *s + 1;
if (**s == '_')
{
*s = *s + 1;
mult = 2;
};
break;
case '^':
accidental = **s;
*s = *s + 1;
if (**s == '^')
{
*s = *s + 1;
mult = 2;
};
break;
case '=':
accidental = **s;
*s = *s + 1;
break;
default:
break;
};
if ((**s >= 'a') && (**s <= 'g'))
{
note = **s;
octave = 1;
*s = *s + 1;
while ((**s == '\'') || (**s == ',') || (**s == '/'))
{
if (**s == '\'')
{
octave = octave + 1;
*s = *s + 1;
};
if (**s == ',')
{
sprintf (msg, "Bad pitch specifier , after note %c", note);
event_error (msg);
octave = octave - 1;
*s = *s + 1;
};
if (**s == '/')
{
/* skip / which occurs in instrument = command */
*s = *s + 1;
/* printf("note = %c accidental = %c mult = %d octave= %d \n",note,accidental,mult,octave); */
pitch = pitch2midi(note, accidental, mult, octave);
return pitch;
}
};
}
else
{
octave = 0;
if ((**s >= 'A') && (**s <= 'G'))
{
note = **s + 'a' - 'A';
*s = *s + 1;
while ((**s == '\'') || (**s == ',') || (**s == '/'))
{
if (**s == ',')
{
octave = octave - 1;
*s = *s + 1;
};
if (**s == '\'')
{
sprintf (msg, "Bad pitch specifier ' after note %c",
note + 'A' - 'a');
event_error (msg);
octave = octave + 1;
*s = *s + 1;
};
if (**s == '/')
{
/* skip / which occurs in instrument = command */
*s = *s + 1;
/* printf("note = %c accidental = %c mult = %d octave= %d \n",note,accidental,mult,octave); */
pitch = pitch2midi(note, accidental, mult, octave);
return pitch;
};
};
};
/* printf("note = %c accidental = %c mult = %d octave= %d \n",note,accidental,mult,octave); */
}
if (note == ' ')
{
event_error ("Malformed note : expecting a-g or A-G");
}
pitch = pitch2midi(note, accidental, mult, octave);
return pitch;
}
void void
parsemusic (field) parsemusic (field)
char *field; char *field;

24
store.c
View File

@@ -186,7 +186,7 @@ int main()
*/ */
#define VERSION "4.60 September 15 2021 abc2midi" #define VERSION "4.66 January 27 2022 abc2midi"
/* enables reading V: indication in header */ /* enables reading V: indication in header */
#define XTEN1 1 #define XTEN1 1
@@ -3171,7 +3171,8 @@ char* value;
else if (is_abcm2ps_option (key)) return; else if (is_abcm2ps_option (key)) return;
else { else {
sprintf(errmsg,"I: key \' %s\' not recognized", key); /* [KG] 2022-01-13 stack overflow */
snprintf(errmsg, 80, "I: key \' %s\' not recognized", key);
if (quiet == -1 && silent == 0) event_error(errmsg); /* [SS] 2018-04-01 */ if (quiet == -1 && silent == 0) event_error(errmsg); /* [SS] 2018-04-01 */
} }
} }
@@ -4494,13 +4495,15 @@ void event_handle_gchord(s)
char* s; char* s;
{ {
int basepitch; int basepitch;
char accidental, note; char accidental, accidental2, note; /* [SS] 2021-12-05 */
char* p; char* p;
char name[9]; char name[9];
int i; int i;
int chordno; int chordno;
int bassnote; int bassnote;
int inversion; int inversion;
int mult; /* [SS] 2021-12-05 */
mult = 1;
if (ignore_guitarchords == 1) return; /* [SS] 2019-12-09 */ if (ignore_guitarchords == 1) return; /* [SS] 2019-12-09 */
if ((*s >= '0') && (*s <= '5')) { if ((*s >= '0') && (*s <= '5')) {
@@ -4527,7 +4530,9 @@ char* s;
}; };
}; };
p = get_accidental(p, &accidental); p = get_accidental(p, &accidental);
basepitch = pitchof(note, accidental, 1, 0, 0) - middle_c; p = get_accidental(p, &accidental2); /* [SS] 2021-12-05 */
if (accidental2 != '=') mult = 2; /* [SS] 2021-12-05 */
basepitch = pitchof(note, accidental, mult, 0, 0) - middle_c;
i = 0; i = 0;
while ((i<9) && (*p != ' ') && (*p != '\0') && (*p != '(') while ((i<9) && (*p != ' ') && (*p != '\0') && (*p != '(')
&& (*p != '/') && (*p != ')')) { && (*p != '/') && (*p != ')')) {
@@ -4543,12 +4548,16 @@ char* s;
note = (int)*p - 'A' + 'a'; note = (int)*p - 'A' + 'a';
p = p + 1; p = p + 1;
p = get_accidental(p, &accidental); p = get_accidental(p, &accidental);
inversion = pitchof(note, accidental, 1, 0, 0) - middle_c; p = get_accidental(p, &accidental2); /* [SS] 2021-12-05 */
if (accidental2 != '=') mult = 2; /* [SS] 2021-12-05 */
inversion = pitchof(note, accidental, mult, 0, 0) - middle_c;
} else if ((*p >= 'a') && (*p <= 'g')) { } else if ((*p >= 'a') && (*p <= 'g')) {
note = (int)*p; note = (int)*p;
p = p + 1; p = p + 1;
p = get_accidental(p, &accidental); p = get_accidental(p, &accidental);
inversion = pitchof(note, accidental, 1, 0, 0) - middle_c; p = get_accidental(p, &accidental2); /* [SS] 2021-12-05 */
if (accidental2 != '=') mult = 2; /* [SS] 2021-12-05 */
inversion = pitchof(note, accidental, mult, 0, 0) - middle_c;
} else if (!silent) { } else if (!silent) {
event_error(" / must be followed by A-G or a-g in gchord"); event_error(" / must be followed by A-G or a-g in gchord");
}; };
@@ -4739,7 +4748,8 @@ if (nofnop == 0) {
}; };
if (done == 0 && quiet == -1) { /* [SS] 2013-11-02 */ if (done == 0 && quiet == -1) { /* [SS] 2013-11-02 */
sprintf(buff, "instruction !%s! ignored", s); snprintf(buff, MAXLINE, "instruction !%s! ignored", s);
/* [KG] 2022-01-13 static overflow */
event_warning(buff); event_warning(buff);
}; };
} }