Compare commits

...

4 Commits

Author SHA1 Message Date
sshlien
6db6eb0979 2024.03.02 2024-03-02 19:10:18 -05:00
sshlien
4d51b779bf 2024.02.25 2024-02-25 07:53:27 -05:00
sshlien
bf013dc428 2024.02.23 2024-02-23 14:26:37 -05:00
sshlien
6441b47841 2024.02.22 2024-02-22 21:08:16 -05:00
6 changed files with 172 additions and 16 deletions

View File

@@ -1,2 +1,2 @@
February 19 2024
March 03 2024

View File

@@ -15340,3 +15340,113 @@ if (*(p+1) == ':') {
The change also has impact on yaps, abc2abc, and abcmatch.
February 22 2024
abc2midi bug
Adding snm=something after a clef= declaration
removes the offset from the clef. In the following
example,
X:1
T: with snm
M:4/4
L:1/4
V:1 clef=treble-8
V:2 clef=treble-8 snm=anything
K:C
[V:1] z z C z |
[V:2] z z z C |
C in voice 1 is shifted down an octave but C in voice 2
is untouched.
Analysis: parsevoice attempts to parse each token (clef=, octave=,
transpose=, sound=, name= and etc.) by calling various functions
parseclef(), parsetranspose(), parseoctave(), and etc.) until it
succeeds. parseclef is thus called on every token and returns either
1 or 0 depending whether it was successful or not. parseclef calls
the function isclef() to do the work. Unfortunately, isclef()
zeros the variable new_clef->octave_offset whether or not a
clef is declared in the token. Therefore the token snm=...
causes new_clef->octave_offset to be zeroed. The next function
which follows, get_extended_clef_details does set the octave_offset, but
it is only called if the token was a clef.
Fix: commented out the line in isclef() which zeros the octave_offset.
February 25 2024
abc2midi note:
Besides clef=treble-8, the abcmidi 2.2 standard also recognizes
clef=treble_8, clef=treble^8 and etc. These clefs do not transpose
the notes in the midi file but merely put the appropriate symbol
on the clef. Abc2midi presently ignores these endings in the
function get_clef_octave_offset() in music_utils.c. When it is
necessary for the parseclef to see these endings the following fix
is necessary.
Fix: readword() called by parseclef breaks the clef string
when it encounters either a ^ or _ in order to handle sharps
and flats in the K: declaration. (See note above April 8 2015.)
It is necessary to use the new function, readword_with_()
which does not break the string on encountering either
the underscore _ or caret ^.
March 02 2024
abc2midi deviance from abc standard 2.2
The clef=, octave=, and transpose= in the V: command are
expected to be persistant and independent of each other. They
are changed independently any time a new clef=, octave=,
or transpose= appears. These are stored in 3 variables.
And the pitch of a note is assigned the sum of these values.
Analysis:
event_note computes the midi pitch from note (one of a,b,c,d,e,f,g),
the xoctave, clef, accidental, and mult which are all input
parameters to that function. In addition it accesses the global
voice structure v of the active voice to get the octaveshift
for that voice. The function computes the local variable octave
from xoctave, clef->octave_offset and v->octaveshift.
Prior to this fix and since May 21 2021, the local variable
octave was either assigned to the value of
clef->octave_offset + xoctave or to v->octaveshift + xoctave when
v->octaveshift is nonzero. In addition, event_voice also changes
v->octaveshift when it encounters a new clef=.
Fix:
In order to comply with this standard, the code in event_voice
was modified to prevent clef= from modifying v->octaveshift. In
addition event_note now computes octave as below.
octave = clef->octave_offset + v->octaveshift + xoctave; /*[SS] 2024-03-02*/
Note this is a significant change as it could break some abc
files. For example, if the user put clef=treble+8 and also
octave=+1, just to be safe, then the resulting octave would be higher
than expected. Fortunately, octave= is still rarely used.
Here is the test file for verifying this fix.
X:1
T:Test for octave shifts in sound
M:4/4
K:C
% The following seven notes should have equal sound
V:1 clef=treble
d8 |\
[V:1 clef=treble+8] D8 |\
[V:1 octave=-1] d8 |\
[V:1 transpose=12] D8 |\
[V:1 clef=treble] d8 |\
[V:1 octave=0] D8 |\
[V:1 transpose=0] d8 |]

View File

@@ -1,7 +1,7 @@
abcMIDI : abc <-> MIDI conversion utilities
midi2abc version 3.59 February 08 2023
abc2midi version 4.87 February 19 2024
abc2midi version 4.91 March 02 2024
abc2abc version 2.21 February 19 2024
yaps version 1.93 February 19 2024
abcmatch version 1.83 February 19 2024

View File

@@ -205,6 +205,26 @@ static int get_clef_octave_offset (char *clef_ending)
if (strncmp (clef_ending, "-15", 2) == 0) {
return -2;
}
/* ^8, ^15, _8, _15 does not transpose the notes in
the midi output according to the abc standard 2.2;
though it should display the appropriate symbol in
the clef. For the time being I am commenting
the other endings so abc2midi runs correctly.
[SS] 2024.02.24
if (strncmp (clef_ending, "^8", 2) == 0) {
return 1;
}
if (strncmp (clef_ending, "^15", 2) == 0) {
return 2;
}
if (strncmp (clef_ending, "_8", 2) == 0) {
return -1;
}
if (strncmp (clef_ending, "_15", 2) == 0) {
return -2;
}
*/
return 0;
}

View File

@@ -688,7 +688,7 @@ int isclef (char *s, cleftype_t * new_clef,
int gotclef;
gotclef = 0;
new_clef->octave_offset = 0;
/*new_clef->octave_offset = 0; [SS] 2024-02.22 */
gotclef = get_standard_clef (s, new_clef);
if (!gotclef && expect_clef) {
/* do we have a clef in letter format ? e.g. C1, F3, G3 */
@@ -742,6 +742,33 @@ readword (word, s)
return (p);
}
char *
readword_with_ (word, s)
/* This version allows ^ and _ characters to be embedded in*/
/* the string. It is needed to parse clef=treble_8 or
/* clef=treble^8 . [SS] 2024-02-23 */
char word[];
char *s;
{
char *p;
int i;
p = s;
i = 0;
/* [SS] 2015-04-08 */
while ((*p != '\0') && (*p != ' ') && (*p != '\t') && ((i == 0) ||
((*p != '='))))
{
if (i < 29)
{
word[i] = *p;
i = i + 1;
};
p = p + 1;
};
word[i] = '\0';
return (p);
}
void
lcase (s)
/* convert word to lower case */
@@ -965,7 +992,7 @@ parseclef (s, word, gotclef, clefstr, newclef, gotoctave, octave)
{
int successful;
skipspace (s);
*s = readword (word, *s);
*s = readword_with_ (word, *s);
successful = 0;
if (casecmp (word, "clef") == 0)
{
@@ -978,7 +1005,7 @@ parseclef (s, word, gotclef, clefstr, newclef, gotoctave, octave)
{
*s = *s + 1;
skipspace (s);
*s = readword (clefstr, *s);
*s = readword_with_ (clefstr, *s);
if (isclef (clefstr, newclef, gotoctave, octave, 1))
{
*gotclef = 1;
@@ -1743,13 +1770,6 @@ parsevoice (s)
}
event_voice (num, s, &vparams);
/*
if (gottranspose) printf("transpose = %d\n", vparams.transpose);
if (gotoctave) printf("octave= %d\n", vparams.octave);
if (gotclef) printf("clef= %s\n", vparams.clefstr);
if (gotname) printf("parsevoice: name= %s\n", vparams.namestring);
if(gotmiddle) printf("parsevoice: middle= %s\n", vparams.middlestring);
*/
}

14
store.c
View File

@@ -186,7 +186,7 @@ int main()
*/
#define VERSION "4.87 February 19 2024 abc2midi"
#define VERSION "4.91 March 02 2024 abc2midi"
/* enables reading V: indication in header */
#define XTEN1 1
@@ -2976,10 +2976,11 @@ struct voice_params *vp;
v = getvoicecontext(n);
addfeature(VOICE, v->indexno, 0, 0);
if (vp->gotclef)
/*****if (vp->gotclef)
{
event_octave(vp->new_clef.octave_offset, 1);
}
}*** [SS] 2024-03.02 */
if (vp->gotoctave) {
event_octave(vp->octave,1);
};
@@ -4304,11 +4305,16 @@ int xoctave, n, m;
event_fatal_error("Internal error - no voice allocated");
};
if (gracenotes && ignore_gracenotes) return; /* [SS] 2010-01-08 */
if (v->octaveshift == 0) { /* [JA] 2021-05-21 */
/* [SS] 2024-03-02
printf("clef->octave_offset = %d v->octaveshift = %d\n",clef->octave_offset,v->octaveshift);
if (v->octaveshift == 0) { [JA] 2021-05-21
octave = xoctave + clef->octave_offset;
} else {
octave = xoctave + v->octaveshift;
}
*/
octave = clef->octave_offset + v->octaveshift + xoctave; /*[SS] 2024-03-02*/
num = n;
denom = m;
if (v->inchord) v->chordcount = v->chordcount + 1;