Compare commits

...

4 Commits

Author SHA1 Message Date
Seymour Shlien
d73b3682e1 2023.01.08 2023-01-08 11:10:49 -05:00
Seymour Shlien
c981535a2a 2023.01.06 2023-01-06 14:22:28 -05:00
Seymour Shlien
7fae7302c3 2022.01.05 2023-01-05 15:53:13 -05:00
Seymour Shlien
166a28d182 2022.12.30 2022-12-30 11:08:38 -05:00
8 changed files with 238 additions and 49 deletions

View File

@@ -1,2 +1,2 @@
December 27 2022
January 08 2023

View File

@@ -14951,6 +14951,85 @@ 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.

57
doc/hudsonshift.txt Executable file
View File

@@ -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=<note1><note2> 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=<note1><note2> 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=<note1>/<note2> is defined as score=<note1><note2> sound=c<note2>
*/
shift:
if (p2==0)
error();
transp_score = transp_sound = p2-p1;
/*
shift=<note1><note2> transposes the typeset score and the playback
according to the specified interval
*/
/******************************************/

View File

@@ -1,9 +1,9 @@
abcMIDI : abc <-> MIDI conversion utilities
midi2abc version 3.58 December 09 2022
abc2midi version 4.78 December 27 2022
abc2abc version 2.18 June 14 2022
yaps version 1.90 June 14 2022
abc2midi version 4.82 January 06 2023
abc2abc version 2.19 January 08 2023
yaps version 1.92 January 06 2023
abcmatch version 1.82 June 14 2022
midicopy version 1.38 May 06 2022
midistats version 0.58 December 09 2022

View File

@@ -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,51 +1021,105 @@ parsetranspose (s, word, gottranspose, transpose)
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 != '=')
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;
if ( fileprogram == ABC2ABC) {
return 0;
}
skipspace (s);
if (**s != '=')
{
event_error ("sound must be followed by '='");
event_error ("expecting '=' after sound, score, instrument or shift");
return 0;
} else {
*s = *s + 1;
skipspace (s);
p1 = note2midi (s,word);
/*printf("p1 midi note = %d\n",p1);*/
p2 = note2midi (s,word);
/*printf("p2 midi note = %d\n",p2);*/
if (p1 == 0) {
event_error ("<note1> missing. cannot do anything");
}
/* p2 = 0 implies that <note2> is not given */
if (p2 == p1) {
p2 = 72; /* [SS] 2022.12.21 */
}
if (casecmp(word,"instrument") == 0) { /*2022.12.27 */
*transpose = p1 - p2; /* [SS] 2022.02.18 2022.04.27 */
} else {
*transpose = p2 - p1; /* [SS] 2022.02.18 2022.04.27 */
}
*gottranspose = 1;
if (casecmp(word,"sound") == 0) {
if (p2 == 0) event_error("sound = requires <note2>");
transp_sound = p2-p1;
/*
sound=<note1><note2> 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=<note1><note2> 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=<note1>/<note2> is defined as
score=<note1><note2> sound=c<note2>
*/
}
if (casecmp(word,"shift") == 0) {
if (p2 == 0) event_error("shift = requires <note2>");
transp_score = p2 - p1;
transp_sound = p2 - p1;
/*
shift=<note1><note2> transposes the typeset score and the playback
according to the specified interval
*/
}
*gottranspose = 1;
if (fileprogram == ABC2MIDI) {
/* [SS] 2023.01.06 */
if (casecmp(word,"score") != 0) *transpose = transp_sound;
}
if (fileprogram == YAPS) {
/* [SS] 2023.01.06 */
if (casecmp(word,"sound") != 0) *transpose = transp_score;
}
return(1);
}
return 1;
}
}
int
parseoctave (s, word, gotoctave, octave)
@@ -1412,7 +1466,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))
{
@@ -1659,7 +1713,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 =
@@ -2752,8 +2806,7 @@ return p;
/* [SS] 2021-10-11 */
int
note2midi (char** s, char *word)
int note2midi (char** s, char *word)
{
/* for implementing sound=, shift= and instrument= key signature options */
@@ -2865,7 +2918,7 @@ switch (**s)
}
if (note == ' ')
{
event_error ("Malformed note : expecting a-g or A-G");
return 0;
}
pitch = pitch2midi(note, accidental, mult, octave);
return pitch;

View File

@@ -186,7 +186,7 @@ int main()
*/
#define VERSION "4.78 December 27 2022 abc2midi"
#define VERSION "4.82 January 06 2023 abc2midi"
/* enables reading V: indication in header */
#define XTEN1 1

View File

@@ -21,7 +21,7 @@
/* back-end for outputting (possibly modified) abc */
#define VERSION "2.18 June 14 2022 abc2abc"
#define VERSION "2.19 Jan 08 2022 abc2abc"
/* for Microsoft Visual C++ 6.0 or higher */
#ifdef _MSC_VER

View File

@@ -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.92 January 06 2023 yaps"
#include <stdio.h>
#ifdef USE_INDEX
#define strchr index