diff --git a/VERSION b/VERSION index 4b29c29..f17a1b2 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -December 30 2022 +January 05 2022 diff --git a/doc/CHANGES b/doc/CHANGES index 408ee96..561a2cd 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -14976,3 +14976,22 @@ 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. + diff --git a/doc/hudsonshift.txt b/doc/hudsonshift.txt new file mode 100755 index 0000000..247760f --- /dev/null +++ b/doc/hudsonshift.txt @@ -0,0 +1,57 @@ +init: + transp_sound = transp_score = 0; + +ABC2MIDI: use transp_sound; +YAPS: use transp_score; +ABC2ABC: ignore and replicate instructions to output; + + +/******************************************/ + +if (p1==0) error(); + + + sound: + if (p2==0) + error(); + transp_sound = p2-p1; +/* + sound= transposes the playback according to the + specified interval (the typeset score is not affected) +*/ + + + score: + if (p2==0) + p2 = ( 72 ); + transp_score = p2-p1; +/* + score= transposes the typeset score according to the + specified interval (the playback is not affected); if the second note + is omitted it is assumed to be a c (see writing abc code for + transposing instruments) +*/ + + + instrument: + if (p2==0) + p2 = p1; + transp_score = p2-p1; + transp_sound = p2-( 72 ); +/* + instrument=/ is defined as score= sound=c +*/ + + + shift: + if (p2==0) + error(); + transp_score = transp_sound = p2-p1; +/* + shift= transposes the typeset score and the playback + according to the specified interval +*/ + + +/******************************************/ + diff --git a/parseabc.c b/parseabc.c index 58c4558..f6d18b4 100644 --- a/parseabc.c +++ b/parseabc.c @@ -942,7 +942,7 @@ int interpret_voice_label (char *s, int num, int *is_new) } /* The following four functions parseclefs, parsetranspose, - * parsesound, parseoctave are used to parse the K: field which not + * parseSoundScore, parseoctave are used to parse the K: field which not * only specifies the key signature but also other descriptors * used for producing a midi file or postscript file. * @@ -1021,6 +1021,97 @@ parsetranspose (s, word, gottranspose, transpose) return 1; }; +int parseSoundScore (char **s, + char *word, + int *gottranspose, + int *transpose) +/* parses sound, score, instrument, and shift + * according to Hudson Lacerda's pseudo code file + * doc/hudsonshift.txt. + */ +{ +int p1,p2; +int transp_sound; +int transp_score; + +transp_sound = 0; +transp_score = 0; + +if (casecmp(word,"sound") != 0 + && casecmp(word,"shift") != 0 + && casecmp(word,"instrument") != 0 + && casecmp(word,"score") != 0 + ) + return 0; + +skipspace (s); +if (**s != '=') + { + event_error ("expecting '=' after sound, score, instrument or shift"); + return 0; + } else { + *s = *s + 1; + skipspace (s); + p1 = note2midi (s,word); + p2 = note2midi (s,word); + if (p1 == 0) { + event_error (" missing. cannot do anything"); + } + /* p2 = 0 implies that is not given */ + + if (casecmp(word,"sound") == 0) { + if (p2 == 0) event_error("sound = requires "); + transp_sound = p2-p1; + /* + sound= transposes the playback according to the + specified interval (the typeset score is not affected) + */ + } + + if (casecmp(word,"score") == 0) { + if (p2 == 0) p2 = 72; + transp_score = p2 - p1; + /* + score= transposes the typeset score according to the + specified interval (the playback is not affected); if the second note + is omitted it is assumed to be a c (see writing abc code for + transposing instruments) + */ + } + + if (casecmp(word,"instrument") == 0) { + if (p2 == 0) p2 = p1; + transp_score = p2 - p1; + transp_sound = p2 - 72; + + /* + instrument=/ is defined as + score= sound=c + */ + } + + if (casecmp(word,"shift") == 0) { + if (p2 == 0) event_error("shift = requires "); + transp_score = p2 - p1; + transp_sound = p2 - p1; + /* + shift= transposes the typeset score and the playback + according to the specified interval + */ + } + + *gottranspose = 1; + + if (fileprogram == ABC2MIDI) *transpose = transp_sound; + if (fileprogram == YAPS) *transpose = transp_score; + return(1); + } +} + + + + +/* parsesound has been replaced with parseSoundScore */ /* [SS] 2021-10-11 */ int parsesound (s, word, gottranspose, transpose) /* parses string sound = @@ -1049,9 +1140,9 @@ int parsesound (s, word, gottranspose, transpose) *s = *s + 1; skipspace (s); p1 = note2midi (s,word); - /*printf("p1 midi note = %d\n",p1);*/ + printf("p1 midi note = %d\n",p1); p2 = note2midi (s,word); - /*printf("p2 midi note = %d\n",p2);*/ + printf("p2 midi note = %d\n",p2); if (p2 == p1 || p2 == 0) { *transpose = 72 - p1; /* [SS] 2022.12.30 */ @@ -1071,7 +1162,7 @@ int parsesound (s, word, gottranspose, transpose) *transpose = p2 - p1; /* [SS] 2022.02.18 2022.04.27 */ } *gottranspose = 1; - /*printf("p1 = %d p2 = %d transpose = %d\n",p1,p2,*transpose);*/ + printf("p1 = %d p2 = %d transpose = %d\n",p1,p2,*transpose); } return 1; } @@ -1421,7 +1512,7 @@ parsekey (str) parsed = parseoctave (&s, word, &gotoctave, &octave); if (!parsed) - parsed = parsesound (&s, word, &gottranspose, &transpose); + parsed = parseSoundScore (&s, word, &gottranspose, &transpose); if ((parsed == 0) && (casecmp (word, "Hp") == 0)) { @@ -1668,7 +1759,7 @@ parsevoice (s) if (!parsed) parsed = parseoctave (&s, word, &vparams.gotoctave, &vparams.octave); if (!parsed) - parsed = parsesound (&s, word, &vparams.gottranspose, &vparams.transpose); + parsed = parseSoundScore (&s, word, &vparams.gottranspose, &vparams.transpose); /* Code changed JA 20 May 2022 */ if ((!parsed) && (strcasecmp (word, "name") == 0)) { parsed = diff --git a/store.c b/store.c index ef3aab3..afdc0c2 100644 --- a/store.c +++ b/store.c @@ -186,7 +186,7 @@ int main() */ -#define VERSION "4.80 December 30 2022 abc2midi" +#define VERSION "4.81 January 05 2023 abc2midi" /* enables reading V: indication in header */ #define XTEN1 1 diff --git a/yapstree.c b/yapstree.c index 9ea6a3e..5ab20e5 100644 --- a/yapstree.c +++ b/yapstree.c @@ -22,7 +22,7 @@ /* yapstree.c - back-end for abc parser. */ /* generates a data structure suitable for typeset music */ -#define VERSION "1.90 June 14 2022 yaps" +#define VERSION "1.91 January 05 2023 yaps" #include #ifdef USE_INDEX #define strchr index