mirror of
https://github.com/sshlien/abcmidi.git
synced 2026-02-04 04:38:10 +00:00
2020.10.12
This commit is contained in:
@@ -49,7 +49,7 @@ Matching:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define VERSION "1.75 October 01 2020 abcmatch"
|
#define VERSION "1.75 October 12 2020 abcmatch"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|||||||
20
doc/CHANGES
20
doc/CHANGES
@@ -13918,3 +13918,23 @@ and applying an appropriate pitchbend to each of these channels.
|
|||||||
This may pose a problem for some software which attempts to render the
|
This may pose a problem for some software which attempts to render the
|
||||||
midi file in music notation.
|
midi file in music notation.
|
||||||
|
|
||||||
|
|
||||||
|
October 12 2020
|
||||||
|
James Allwright has made significant improvements to parseabc.c, toabc.c,
|
||||||
|
and yapstree.c related to repeat checking. In parseabc.c, new functions
|
||||||
|
were introduced: init_voice_contexts, reset_parser_status,
|
||||||
|
interpret_voice_label, check_bar_repeats, and check_and_call_bar().
|
||||||
|
The functions isnumberp(), init_voicecode(), and interpret_voicestring()
|
||||||
|
have been retired. Reset_parser_status() is called each time a new
|
||||||
|
X: reference field command is encountered. Check_bar_repeats() replaces
|
||||||
|
a lot of the code that appears in event_bar() defined in toabc.c and
|
||||||
|
yapstree.c. parsemusic() calls event_bar indirectly through the
|
||||||
|
function check_and_call_bar(). Minor changes were made to toabc.c, store.c
|
||||||
|
and yapstree.c to accommodate the changes to parseabc. In particular,
|
||||||
|
a new flag repcheck is introduced and connected to parseabc.c as
|
||||||
|
an extern (in parseabc.h). In addition a new struct (voice_context)
|
||||||
|
has been introduced in parseabc.h.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
abcMIDI : abc <-> MIDI conversion utilities
|
abcMIDI : abc <-> MIDI conversion utilities
|
||||||
|
|
||||||
midi2abc version 3.46 June 22 2020
|
midi2abc version 3.46 June 22 2020
|
||||||
abc2midi version 4.42 October 01 2020
|
abc2midi version 4.43 October 12 2020
|
||||||
abc2abc version 2.10 October 01 2020
|
abc2abc version 2.11 October 12 2020
|
||||||
yaps version 1.80 October 07 2020
|
yaps version 1.81 October 12 2020
|
||||||
abcmatch version 1.74 October 01 2020
|
abcmatch version 1.75 October 12 2020
|
||||||
midicopy version 1.37 October 10 2020
|
midicopy version 1.37 October 10 2020
|
||||||
|
|
||||||
24th January 2002
|
24th January 2002
|
||||||
|
|||||||
@@ -824,6 +824,7 @@ void event_octave(num, local)
|
|||||||
/* used internally by other routines when octave=N is encountered */
|
/* used internally by other routines when octave=N is encountered */
|
||||||
/* in I: or K: fields */
|
/* in I: or K: fields */
|
||||||
int num;
|
int num;
|
||||||
|
int local;
|
||||||
{
|
{
|
||||||
if (dotune) {
|
if (dotune) {
|
||||||
if (pastheader || local) {
|
if (pastheader || local) {
|
||||||
|
|||||||
317
parseabc.c
317
parseabc.c
@@ -90,10 +90,12 @@ int chorddecorators[DECSIZE];
|
|||||||
char decorations[] = ".MLRH~Tuv'OPS"; /* 2020-05-01 */
|
char decorations[] = ".MLRH~Tuv'OPS"; /* 2020-05-01 */
|
||||||
char *abbreviation[SIZE_ABBREVIATIONS];
|
char *abbreviation[SIZE_ABBREVIATIONS];
|
||||||
|
|
||||||
int voicecodes = 0;
|
int num_voices = 0; /* [JA] 2020-10-12 */
|
||||||
/* [SS] 2015-03-16 allow 24 voices */
|
int repcheck = 1; /* enables/ disables repeat checking */
|
||||||
/*char voicecode[16][30]; for interpreting V: string */
|
/* abc2midi disables repeat checking because it does its own thing */
|
||||||
char voicecode[24][30]; /*for interpreting V: string */
|
voice_context_t voicecode[MAX_VOICES];
|
||||||
|
int voicenum; /* current voice number */
|
||||||
|
int has_voice_fields = 0;
|
||||||
|
|
||||||
int decorators_passback[DECSIZE];
|
int decorators_passback[DECSIZE];
|
||||||
/* this global array is linked as an external to store.c and
|
/* this global array is linked as an external to store.c and
|
||||||
@@ -329,30 +331,6 @@ skiptospace (p)
|
|||||||
*p = *p + 1;
|
*p = *p + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
isnumberp (p)
|
|
||||||
char **p;
|
|
||||||
/* returns 1 if positive number, returns 0 if not a positive number */
|
|
||||||
/* ie -4 or 1A both return 0. This function is needed to get the */
|
|
||||||
/* voice number. */
|
|
||||||
{
|
|
||||||
char **c;
|
|
||||||
c = p;
|
|
||||||
while (( **c != ' ') && ( **c != TAB) && **c != '\0')
|
|
||||||
{
|
|
||||||
if (( **c >= 0) && (**c <= 9)) /*[SDG] 2020-06-03 */
|
|
||||||
*c = *c + 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
/* could use isdigit(**c) */
|
|
||||||
/* is zero a positive number? is V:0 ok? [SS] */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
readnumf (num)
|
readnumf (num)
|
||||||
char *num;
|
char *num;
|
||||||
@@ -788,72 +766,137 @@ lcase (s)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [JA] 2020-10-12 */
|
||||||
void
|
void init_voice_contexts (void)
|
||||||
init_voicecode ()
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 24; i++) /* [SS} 2015-03-15 */
|
for (i = 0; i < MAX_VOICES; i++) { /* [SS} 2015-03-15 */
|
||||||
voicecode[i][0] = 0;
|
voicecode[i].label[0] = '\0';
|
||||||
voicecodes = 0;
|
voicecode[i].expect_repeat = 0;
|
||||||
|
voicecode[i].repeat_count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [JA] 2020-10-12 */
|
||||||
|
/* called at the start of each tune */
|
||||||
|
static void reset_parser_status (void)
|
||||||
|
{
|
||||||
|
voicenum = 0;
|
||||||
|
has_voice_fields = 0;
|
||||||
|
num_voices = 1;
|
||||||
|
parserinchord = 0;
|
||||||
|
ingrace = 0;
|
||||||
|
slur = 0;
|
||||||
|
init_voice_contexts ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
print_voicecodes ()
|
print_voicecodes ()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (voicecodes == 0)
|
if (num_voices == 0)
|
||||||
return;
|
return;
|
||||||
printf ("voice mapping:\n");
|
printf ("voice mapping:\n");
|
||||||
for (i = 0; i < voicecodes; i++)
|
for (i = 0; i < num_voices; i++)
|
||||||
{
|
{
|
||||||
if (i % 4 == 3)
|
if (i % 4 == 3)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("%s %d ", voicecode[i], i + 1);
|
printf ("%s %d ", voicecode[i].label, i + 1);
|
||||||
}
|
}
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
/* [JA] 2020-10-12 */
|
||||||
interpret_voicestring (char *s)
|
int interpret_voice_label (char *s, int num)
|
||||||
{
|
/* We expect a numeric value indicating the voice number.
|
||||||
/* if V: is followed by a string instead of a number
|
* The assumption is that these will ocuur in the order in which voices
|
||||||
* we check to see if we have encountered this string
|
* appear, so that we have V:1, V:2, ... V:N if there are N voices.
|
||||||
* before. We assign the number associated with this
|
* The abc standard 2.2 allows strings instead of these numbers to
|
||||||
* string and add it to voicecode if it was not encountered
|
* represent voices.
|
||||||
* before. If more than 16 distinct strings were encountered
|
* This function should be called with either
|
||||||
* we report an error -1.
|
* an empty string and a valid num or
|
||||||
|
* a valid string and num set to 0.
|
||||||
|
*
|
||||||
|
* If num is non-zero, we check that it is valid and return it.
|
||||||
|
* If the number is one above the number of voices currently in use,
|
||||||
|
* we allocate a new voice.
|
||||||
|
*
|
||||||
|
* If num is zero and the string is not empty, we check if string
|
||||||
|
* has been assigned to one of the existing voices. If not, we
|
||||||
|
* allocate a new voice and assign the string to it.
|
||||||
|
*
|
||||||
|
* If we exceed MAX_VOICES voices, we report an error.
|
||||||
|
*
|
||||||
|
* we return a voice number in the range 1 - num_voices
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
char code[32];
|
char code[32];
|
||||||
char msg[80]; /* [PHDM] 2012-11-22 */
|
char msg[80]; /* [PHDM] 2012-11-22 */
|
||||||
char *c;
|
char *c;
|
||||||
c = readword (code, s);
|
c = readword (code, s);
|
||||||
|
|
||||||
/* [PHDM] 2012-11-22 */
|
if (num > 0)
|
||||||
if (*c != '\0' && *c != ' ' && *c != ']')
|
{
|
||||||
|
if (num > num_voices + 1)
|
||||||
{
|
{
|
||||||
sprintf (msg, "invalid character `%c' in Voice ID", *c);
|
char error_message[80];
|
||||||
event_error (msg);
|
|
||||||
|
snprintf(error_message, 80, "V:%d out of sequence, treating as V:%d",
|
||||||
|
num, num_voices);
|
||||||
|
event_warning(error_message);
|
||||||
|
num = num_voices + 1;
|
||||||
}
|
}
|
||||||
|
/* declaring a new voice */
|
||||||
|
if (num == num_voices + 1)
|
||||||
|
{
|
||||||
|
if (num_voices >= MAX_VOICES)
|
||||||
|
{
|
||||||
|
event_warning("Number of available voices exceeded");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
num_voices = num_voices + 1;
|
||||||
|
voicecode[num_voices - 1].label[0] = '\0';
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
/* [PHDM] 2012-11-22 */
|
||||||
|
if (*c != '\0' && *c != ' ' && *c != ']') {
|
||||||
|
sprintf (msg, "invalid character `%c' in Voice ID", *c);
|
||||||
|
event_error (msg);
|
||||||
|
}
|
||||||
/* [PHDM] 2012-11-22 */
|
/* [PHDM] 2012-11-22 */
|
||||||
|
|
||||||
if (code[0] == '\0')
|
if (code[0] == '\0')
|
||||||
return 0;
|
{
|
||||||
if (voicecodes == 0)
|
event_warning("Empty V: field, treating as V:1");
|
||||||
{
|
return 1;
|
||||||
strcpy (voicecode[voicecodes], code);
|
}
|
||||||
voicecodes++;
|
/* Has supplied label been used for one of the existing voices ? */
|
||||||
return voicecodes;
|
if (has_voice_fields)
|
||||||
|
{
|
||||||
|
for (i = 0; i < num_voices; i++) {
|
||||||
|
if (strcmp (code, voicecode[i].label) == 0) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < voicecodes; i++)
|
}
|
||||||
if (stringcmp (code, voicecode[i]) == 0)
|
/* if we have got here, we have a new voice */
|
||||||
return (i + 1);
|
if ((num_voices + 1) > MAX_VOICES) {/* [SS] 2015-03-16 */
|
||||||
if ((voicecodes + 1) > 23) /* [SS] 2015-03-16 */
|
event_warning("Number of available voices exceeded");
|
||||||
return -1;
|
return 1;
|
||||||
strcpy (voicecode[voicecodes], code);
|
}
|
||||||
voicecodes++;
|
/* First V: field is a special case. We are already on voice 1,
|
||||||
return voicecodes;
|
* so we don't increment the number of voices, but we will set
|
||||||
|
* status->has_voice_fields on returning from this function.
|
||||||
|
*/
|
||||||
|
if (has_voice_fields)
|
||||||
|
{
|
||||||
|
num_voices++;
|
||||||
|
}
|
||||||
|
strncpy (voicecode[num_voices - 1].label, code, 31);
|
||||||
|
return num_voices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following three functions parseclefs, parsetranspose,
|
/* The following three functions parseclefs, parsetranspose,
|
||||||
@@ -1479,22 +1522,14 @@ parsevoice (s)
|
|||||||
vparams.other[0] = '\0'; /* [SS] 2011-04-18 */
|
vparams.other[0] = '\0'; /* [SS] 2011-04-18 */
|
||||||
|
|
||||||
skipspace (&s);
|
skipspace (&s);
|
||||||
if (isnumberp (&s) == 1)
|
num = 0;
|
||||||
{
|
if (isdigit(*s)) { /* [JA] 2020-10-12 */
|
||||||
num = readnump (&s);
|
num = readnump (&s);
|
||||||
}
|
}
|
||||||
else
|
num = interpret_voice_label (s, num);
|
||||||
{
|
has_voice_fields = 1;
|
||||||
num = interpret_voicestring (s);
|
skiptospace (&s);
|
||||||
if (num == 0)
|
voicenum = num;
|
||||||
event_error ("No voice number or string in V: field");
|
|
||||||
if (num == -1)
|
|
||||||
{
|
|
||||||
event_error ("More than 16 voices encountered in V: fields");
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
skiptospace (&s);
|
|
||||||
};
|
|
||||||
skipspace (&s);
|
skipspace (&s);
|
||||||
while (*s != '\0')
|
while (*s != '\0')
|
||||||
{
|
{
|
||||||
@@ -2115,9 +2150,14 @@ parsefield (key, field)
|
|||||||
{
|
{
|
||||||
event_error ("second X: field in header");
|
event_error ("second X: field in header");
|
||||||
};
|
};
|
||||||
|
if (inbody)
|
||||||
|
{
|
||||||
|
/* [JA] 2020-10-14 */
|
||||||
|
event_error ("Missing blank line before new tune");
|
||||||
|
}
|
||||||
event_refno (x);
|
event_refno (x);
|
||||||
ignore_line =0; /* [SS] 2017-04-12 */
|
ignore_line =0; /* [SS] 2017-04-12 */
|
||||||
init_voicecode (); /* [SS] 2011-01-01 */
|
reset_parser_status(); /* [JA] 2020-10-12 */
|
||||||
inhead = 1;
|
inhead = 1;
|
||||||
inbody = 0;
|
inbody = 0;
|
||||||
parserinchord = 0;
|
parserinchord = 0;
|
||||||
@@ -2376,6 +2416,99 @@ print_inputline ()
|
|||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [JA] 2020-10-12 */
|
||||||
|
/* Look for problems in the use of repeats */
|
||||||
|
static void check_bar_repeats (int bar_type, char *replist)
|
||||||
|
{
|
||||||
|
voice_context_t *cv = &voicecode[voicenum];
|
||||||
|
|
||||||
|
switch (bar_type) {
|
||||||
|
case SINGLE_BAR:
|
||||||
|
break;
|
||||||
|
case DOUBLE_BAR:
|
||||||
|
break;
|
||||||
|
case THIN_THICK:
|
||||||
|
break;
|
||||||
|
case THICK_THIN:
|
||||||
|
break;
|
||||||
|
case BAR_REP:
|
||||||
|
if (cv->expect_repeat) {
|
||||||
|
event_warning ("Expecting repeat, found |:");
|
||||||
|
};
|
||||||
|
cv->expect_repeat = 1;
|
||||||
|
cv->repeat_count = cv->repeat_count + 1;
|
||||||
|
break;
|
||||||
|
case REP_BAR:
|
||||||
|
if (!cv->expect_repeat) {
|
||||||
|
char error_message[80];
|
||||||
|
|
||||||
|
if (cv->repeat_count == 0)
|
||||||
|
{
|
||||||
|
snprintf(error_message, 80, "Missing repeat at start ? Unexpected :|%s found", replist);
|
||||||
|
event_warning (error_message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(error_message, 80, "Unexpected :|%s found", replist);
|
||||||
|
event_warning (error_message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cv->expect_repeat = 0;
|
||||||
|
cv->repeat_count = cv->repeat_count + 1;
|
||||||
|
break;
|
||||||
|
case BAR1:
|
||||||
|
if (!cv->expect_repeat) {
|
||||||
|
if (cv->repeat_count == 0)
|
||||||
|
{
|
||||||
|
event_warning ("Missing repeat at start ? found |1");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
event_warning ("found |1 in non-repeat section");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case REP_BAR2:
|
||||||
|
if (!cv->expect_repeat) {
|
||||||
|
if (cv->repeat_count == 0)
|
||||||
|
{
|
||||||
|
event_warning ("Missing repeat at start ? found :|2");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
event_warning ("No repeat expected, found :|2");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cv->expect_repeat = 0;
|
||||||
|
cv->repeat_count = cv->repeat_count + 1;
|
||||||
|
break;
|
||||||
|
case DOUBLE_REP:
|
||||||
|
if (!cv->expect_repeat) {
|
||||||
|
if (cv->repeat_count == 0)
|
||||||
|
{
|
||||||
|
event_warning ("Missing repeat at start ? found ::");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
event_warning ("No repeat expected, found ::");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cv->expect_repeat = 1;
|
||||||
|
cv->repeat_count = cv->repeat_count + 1;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [JA] 2020-10-12 */
|
||||||
|
static void check_and_call_bar(int bar_type, char *replist)
|
||||||
|
{
|
||||||
|
if (repcheck)
|
||||||
|
{
|
||||||
|
check_bar_repeats (bar_type, replist);
|
||||||
|
}
|
||||||
|
event_bar (bar_type, replist);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
parsemusic (field)
|
parsemusic (field)
|
||||||
char *field;
|
char *field;
|
||||||
@@ -2459,20 +2592,20 @@ parsemusic (field)
|
|||||||
switch (*p)
|
switch (*p)
|
||||||
{
|
{
|
||||||
case ':':
|
case ':':
|
||||||
event_bar (BAR_REP, "");
|
check_and_call_bar (BAR_REP, "");
|
||||||
p = p + 1;
|
p = p + 1;
|
||||||
break;
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
event_bar (DOUBLE_BAR, "");
|
check_and_call_bar (DOUBLE_BAR, "");
|
||||||
p = p + 1;
|
p = p + 1;
|
||||||
break;
|
break;
|
||||||
case ']':
|
case ']':
|
||||||
event_bar (THIN_THICK, "");
|
check_and_call_bar (THIN_THICK, "");
|
||||||
p = p + 1;
|
p = p + 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
p = getrep (p, playonrep_list);
|
p = getrep (p, playonrep_list);
|
||||||
event_bar (SINGLE_BAR, playonrep_list);
|
check_and_call_bar (SINGLE_BAR, playonrep_list);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
@@ -2480,20 +2613,20 @@ parsemusic (field)
|
|||||||
switch (*p)
|
switch (*p)
|
||||||
{
|
{
|
||||||
case ':':
|
case ':':
|
||||||
event_bar (DOUBLE_REP, "");
|
check_and_call_bar (DOUBLE_REP, "");
|
||||||
p = p + 1;
|
p = p + 1;
|
||||||
break;
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
p = p + 1;
|
p = p + 1;
|
||||||
p = getrep (p, playonrep_list);
|
p = getrep (p, playonrep_list);
|
||||||
event_bar (REP_BAR, playonrep_list);
|
check_and_call_bar (REP_BAR, playonrep_list);
|
||||||
if (*p == ']')
|
if (*p == ']')
|
||||||
p = p + 1; /* [SS] 2013-10-31 */
|
p = p + 1; /* [SS] 2013-10-31 */
|
||||||
break;
|
break;
|
||||||
/* [JM] 2018-02-22 dotted bar line ... this is legal */
|
/* [JM] 2018-02-22 dotted bar line ... this is legal */
|
||||||
default:
|
default:
|
||||||
/* [SS] 2018-02-08 introducing DOTTED_BAR */
|
/* [SS] 2018-02-08 introducing DOTTED_BAR */
|
||||||
event_bar (DOTTED_BAR,"");
|
check_and_call_bar (DOTTED_BAR,"");
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
@@ -2558,9 +2691,9 @@ parsemusic (field)
|
|||||||
{
|
{
|
||||||
case '|':
|
case '|':
|
||||||
p = p + 1;
|
p = p + 1;
|
||||||
event_bar (THICK_THIN, "");
|
check_and_call_bar (THICK_THIN, "");
|
||||||
if (*p == ':') { /* [SS] 2015-04-13 [SDG] 2020-06-04 */
|
if (*p == ':') { /* [SS] 2015-04-13 [SDG] 2020-06-04 */
|
||||||
event_bar (BAR_REP, "");
|
check_and_call_bar (BAR_REP, "");
|
||||||
p = p + 1;
|
p = p + 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2596,7 +2729,7 @@ parsemusic (field)
|
|||||||
/*if (!inchordflag && *p == '|') { [SS] 2018-12-21 not THICK_THIN bar line*/
|
/*if (!inchordflag && *p == '|') { [SS] 2018-12-21 not THICK_THIN bar line*/
|
||||||
if (!parserinchord && *p == '|') { /* [SS] 2019-06-06 not THICK_THIN bar line*/
|
if (!parserinchord && *p == '|') { /* [SS] 2019-06-06 not THICK_THIN bar line*/
|
||||||
p = p + 1; /* skip over | */
|
p = p + 1; /* skip over | */
|
||||||
event_bar (THIN_THICK, "");}
|
check_and_call_bar (THIN_THICK, "");}
|
||||||
else {
|
else {
|
||||||
readlen (&chord_n, &chord_m, &p); /* [SS] 2019-06-06 */
|
readlen (&chord_n, &chord_m, &p); /* [SS] 2019-06-06 */
|
||||||
event_chordoff (chord_n, chord_m);
|
event_chordoff (chord_n, chord_m);
|
||||||
|
|||||||
10
parseabc.h
10
parseabc.h
@@ -32,12 +32,22 @@ struct voice_params {
|
|||||||
char other[V_STRLEN+1]; /* [SS] 2011-04-18 */
|
char other[V_STRLEN+1]; /* [SS] 2011-04-18 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct voice_context {
|
||||||
|
char label[31];
|
||||||
|
int expect_repeat;
|
||||||
|
int repeat_count;
|
||||||
|
} voice_context_t;
|
||||||
|
|
||||||
|
#define MAX_VOICES 30
|
||||||
|
|
||||||
/* holds a fraction */
|
/* holds a fraction */
|
||||||
struct fraction {
|
struct fraction {
|
||||||
int num;
|
int num;
|
||||||
int denom;
|
int denom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern int repcheck; /* allows backend to enable/disable repeat checking */
|
||||||
|
extern voice_context_t voicecode[MAX_VOICES];
|
||||||
|
|
||||||
#ifndef KANDR
|
#ifndef KANDR
|
||||||
extern int readnump(char **p);
|
extern int readnump(char **p);
|
||||||
|
|||||||
6
store.c
6
store.c
@@ -185,7 +185,7 @@ int main()
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VERSION "4.42 Ocober 01 2020 abc2midi"
|
#define VERSION "4.43 Ocober 12 2020 abc2midi"
|
||||||
|
|
||||||
/* enables reading V: indication in header */
|
/* enables reading V: indication in header */
|
||||||
#define XTEN1 1
|
#define XTEN1 1
|
||||||
@@ -892,6 +892,10 @@ char **filename;
|
|||||||
} else {
|
} else {
|
||||||
check = 0;
|
check = 0;
|
||||||
};
|
};
|
||||||
|
/* disable repeat checking because abc2midi does its own workaround
|
||||||
|
* attempting to fix various repeat errors.
|
||||||
|
*/
|
||||||
|
repcheck = 0;
|
||||||
/* look for filename-from-tune-titles option */
|
/* look for filename-from-tune-titles option */
|
||||||
namelimit = 252;
|
namelimit = 252;
|
||||||
titlenames = 0;
|
titlenames = 0;
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ struct voice {
|
|||||||
struct fract barcount;
|
struct fract barcount;
|
||||||
int barno;
|
int barno;
|
||||||
int barchecking;
|
int barchecking;
|
||||||
int expect_repeat;
|
|
||||||
int brokentype, brokenmult, brokenpending;
|
int brokentype, brokenmult, brokenpending;
|
||||||
int tiespending;
|
int tiespending;
|
||||||
struct feature* tie_place[MAX_TIES];
|
struct feature* tie_place[MAX_TIES];
|
||||||
|
|||||||
81
toabc.c
81
toabc.c
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
/* back-end for outputting (possibly modified) abc */
|
/* back-end for outputting (possibly modified) abc */
|
||||||
|
|
||||||
#define VERSION "2.10 October 06 2020 abc2abc"
|
#define VERSION "2.11 October 12 2020 abc2abc"
|
||||||
|
|
||||||
/* for Microsoft Visual C++ 6.0 or higher */
|
/* for Microsoft Visual C++ 6.0 or higher */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@@ -66,7 +66,7 @@ struct fract chordfactor; /* factor of the first note in a chord [PHDM] 2013-03-
|
|||||||
struct fract breakpoint; /* used to break bar into beamed sets of notes */
|
struct fract breakpoint; /* used to break bar into beamed sets of notes */
|
||||||
int barno; /* number of bar within tune */
|
int barno; /* number of bar within tune */
|
||||||
int newspacing; /* was -s option selected ? */
|
int newspacing; /* was -s option selected ? */
|
||||||
int barcheck, repcheck; /* indicate -b and -r options selected */
|
int barcheck; /* indicate -b and -r options selected */
|
||||||
int echeck; /* was error-checking turned off ? (-e option) */
|
int echeck; /* was error-checking turned off ? (-e option) */
|
||||||
int newbreaks; /* was -n option selected ? */
|
int newbreaks; /* was -n option selected ? */
|
||||||
int nodouble_accidentals;
|
int nodouble_accidentals;
|
||||||
@@ -105,8 +105,6 @@ char* clef = ""; /* [SS] 2020-01-22 */
|
|||||||
|
|
||||||
extern int nokey; /* signals no key signature assumed */
|
extern int nokey; /* signals no key signature assumed */
|
||||||
extern int nokeysig; /* signals -nokeys or -nokeysf option */
|
extern int nokeysig; /* signals -nokeys or -nokeysf option */
|
||||||
extern int voicecodes ; /* from parseabc.c */
|
|
||||||
extern char voicecode[16][30]; /*for interpreting V: string */
|
|
||||||
|
|
||||||
struct voicetype { /* information needed for each voice */
|
struct voicetype { /* information needed for each voice */
|
||||||
int number; /* voice number from V: field */
|
int number; /* voice number from V: field */
|
||||||
@@ -115,7 +113,6 @@ struct voicetype { /* information needed for each voice */
|
|||||||
struct abctext* currentline;
|
struct abctext* currentline;
|
||||||
int bars_remaining;
|
int bars_remaining;
|
||||||
int bars_complete;
|
int bars_complete;
|
||||||
int expect_repeat; /* [SS] 2018-12-01 */
|
|
||||||
int drumchan;
|
int drumchan;
|
||||||
} voice[MAX_VOICES];
|
} voice[MAX_VOICES];
|
||||||
int voicecount, this_voice, next_voice;
|
int voicecount, this_voice, next_voice;
|
||||||
@@ -1206,7 +1203,6 @@ int num;
|
|||||||
voice[voice_index].bars_complete = 0;
|
voice[voice_index].bars_complete = 0;
|
||||||
voice[voice_index].bars_remaining = bars_per_line;
|
voice[voice_index].bars_remaining = bars_per_line;
|
||||||
voice[voice_index].drumchan = 0;
|
voice[voice_index].drumchan = 0;
|
||||||
voice[voice_index].expect_repeat = -1; /* [SS] 2018-12-01 */
|
|
||||||
};
|
};
|
||||||
voice[voice_index].currentline = NULL;
|
voice[voice_index].currentline = NULL;
|
||||||
return(voice_index);
|
return(voice_index);
|
||||||
@@ -1236,38 +1232,26 @@ struct voice_params *vp;
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (strlen(s) == 0) {
|
if (strlen(voicecode[n-1].label) > 0) {
|
||||||
if(voicecodes >= n) emit_string_sprintf("V:%s",voicecode[n-1]);
|
emit_string_sprintf("V:%s",voicecode[n-1].label);
|
||||||
else emit_int_sprintf("V:%d", n);
|
|
||||||
if (vp->gotclef) {sprintf(output," clef=%s", vp->clefname);
|
|
||||||
emit_string(output);}
|
|
||||||
if (vp->gotoctave) {sprintf(output," octave=%d", vp->octave);
|
|
||||||
emit_string(output);}
|
|
||||||
if (vp->gottranspose) {sprintf(output," transpose=%d", vp->transpose);
|
|
||||||
emit_string(output);}
|
|
||||||
if (vp->gotname) {sprintf(output," name=%s", vp->namestring);
|
|
||||||
emit_string(output);}
|
|
||||||
if (vp->gotsname) {sprintf(output," sname=%s", vp->snamestring);
|
|
||||||
emit_string(output);}
|
|
||||||
if( vp->gotmiddle ) { sprintf(output, " middle=%s", vp->middlestring);
|
|
||||||
emit_string(output);}
|
|
||||||
if( vp->gotother ) { sprintf(output, " %s", vp->other);
|
|
||||||
emit_string(output);} /* [SS] 2011-04-18 */
|
|
||||||
} else {
|
} else {
|
||||||
if(voicecodes >= n) emit_string_sprintf("V:%s",voicecode[n-1]);
|
emit_int_sprintf("V:%d", n);
|
||||||
emit_int_sprintf("V:%d ", n);
|
}
|
||||||
if (vp->gotclef) {sprintf(output," clef=%s", vp->clefname);
|
if (vp->gotclef) {sprintf(output," clef=%s", vp->clefname);
|
||||||
emit_string(output);}
|
emit_string(output);}
|
||||||
if (vp->gotoctave) {sprintf(output," octave=%d", vp->octave);
|
if (vp->gotoctave) {sprintf(output," octave=%d", vp->octave);
|
||||||
emit_string(output);}
|
emit_string(output);}
|
||||||
if (vp->gottranspose) {sprintf(output," transpose=%d", vp->transpose);
|
if (vp->gottranspose) {sprintf(output," transpose=%d", vp->transpose);
|
||||||
emit_string(output);}
|
emit_string(output);}
|
||||||
if (vp->gotname) {sprintf(output," name=%s", vp->namestring);
|
if (vp->gotname) {sprintf(output," name=%s", vp->namestring);
|
||||||
emit_string(output);}
|
emit_string(output);}
|
||||||
if( vp->gotmiddle ) { sprintf(output, " middle=%s", vp->middlestring);
|
if (vp->gotsname) {sprintf(output," sname=%s", vp->snamestring);
|
||||||
emit_string(output);}
|
emit_string(output);}
|
||||||
if( vp->gotother ) { sprintf(output, " %s", vp->other);
|
if( vp->gotmiddle ) { sprintf(output, " middle=%s", vp->middlestring);
|
||||||
emit_string(output);} /* [SS] 2011-04-18 */
|
emit_string(output);}
|
||||||
|
if( vp->gotother ) { sprintf(output, " %s", vp->other);
|
||||||
|
emit_string(output);} /* [SS] 2011-04-18 */
|
||||||
|
if (strlen(s) != 0) {
|
||||||
emit_string(s);
|
emit_string(s);
|
||||||
};
|
};
|
||||||
inmusic = 0;
|
inmusic = 0;
|
||||||
@@ -1426,8 +1410,6 @@ static void start_tune()
|
|||||||
count.denom = 1;
|
count.denom = 1;
|
||||||
barno = 0;
|
barno = 0;
|
||||||
tuplenotes = 0;
|
tuplenotes = 0;
|
||||||
/* expect_repeat is now a voice struct variable [SS] 2018-12-01 */
|
|
||||||
/* expect_repeat = -1; repeat from start may occur [J-FM] 2012-06-04 */
|
|
||||||
inlinefield = 0;
|
inlinefield = 0;
|
||||||
if (barlen.num == 0) {
|
if (barlen.num == 0) {
|
||||||
/* generate missing time signature */
|
/* generate missing time signature */
|
||||||
@@ -1741,39 +1723,18 @@ char* replist;
|
|||||||
break;
|
break;
|
||||||
case BAR_REP:
|
case BAR_REP:
|
||||||
emit_string("|:");
|
emit_string("|:");
|
||||||
if (voice[this_voice].expect_repeat > 0 && repcheck)
|
|
||||||
{
|
|
||||||
/* no error if first repeat [J-FM] 2012-06-04 */
|
|
||||||
event_error("Expecting repeat, found |:");
|
|
||||||
};
|
|
||||||
voice[this_voice].expect_repeat = 1;
|
|
||||||
break;
|
break;
|
||||||
case REP_BAR:
|
case REP_BAR:
|
||||||
emit_string_sprintf(":|%s", replist);
|
emit_string_sprintf(":|%s", replist);
|
||||||
if ((!voice[this_voice].expect_repeat) && (repcheck)) {
|
|
||||||
event_warning("No repeat expected, found :|");
|
|
||||||
};
|
|
||||||
voice[this_voice].expect_repeat = 0;
|
|
||||||
break;
|
break;
|
||||||
case BAR1:
|
case BAR1:
|
||||||
emit_string("|1");
|
emit_string("|1");
|
||||||
if ((!voice[this_voice].expect_repeat) && (repcheck)) {
|
|
||||||
event_warning("found |1 in non-repeat section");
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
case REP_BAR2:
|
case REP_BAR2:
|
||||||
emit_string(":|2");
|
emit_string(":|2");
|
||||||
if ((!voice[this_voice].expect_repeat) && (repcheck)) {
|
|
||||||
event_warning("No repeat expected, found :|2");
|
|
||||||
};
|
|
||||||
voice[this_voice].expect_repeat = 0;
|
|
||||||
break;
|
break;
|
||||||
case DOUBLE_REP:
|
case DOUBLE_REP:
|
||||||
emit_string("::");
|
emit_string("::");
|
||||||
if ((voice[this_voice].expect_repeat) && (repcheck)) {
|
|
||||||
event_error("No repeat expected, found ::");
|
|
||||||
};
|
|
||||||
voice[this_voice].expect_repeat = 1;
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
if ((count.num*barlen.denom != barlen.num*count.denom) &&
|
if ((count.num*barlen.denom != barlen.num*count.denom) &&
|
||||||
|
|||||||
43
yapstree.c
43
yapstree.c
@@ -22,7 +22,7 @@
|
|||||||
/* yapstree.c - back-end for abc parser. */
|
/* yapstree.c - back-end for abc parser. */
|
||||||
/* generates a data structure suitable for typeset music */
|
/* generates a data structure suitable for typeset music */
|
||||||
|
|
||||||
#define VERSION "1.80 October 07 2020 yaps"
|
#define VERSION "1.81 October 12 2020 yaps"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef USE_INDEX
|
#ifdef USE_INDEX
|
||||||
#define strchr index
|
#define strchr index
|
||||||
@@ -64,7 +64,6 @@ char outputroot[256];
|
|||||||
char matchstring[256];
|
char matchstring[256];
|
||||||
int fileopen;
|
int fileopen;
|
||||||
|
|
||||||
int repcheck;
|
|
||||||
int xinhead;
|
int xinhead;
|
||||||
int xinbody;
|
int xinbody;
|
||||||
int suppress;
|
int suppress;
|
||||||
@@ -792,7 +791,6 @@ static struct voice* newvoice(int n)
|
|||||||
v->inslur = 0;
|
v->inslur = 0;
|
||||||
v->ingrace = 0;
|
v->ingrace = 0;
|
||||||
v->inchord = 0;
|
v->inchord = 0;
|
||||||
v->expect_repeat = 0;
|
|
||||||
v->tuplenotes = 0;
|
v->tuplenotes = 0;
|
||||||
v->thistuple = NULL;
|
v->thistuple = NULL;
|
||||||
v->tuple_count = 0;
|
v->tuple_count = 0;
|
||||||
@@ -2195,45 +2193,6 @@ char* playonrep_list;
|
|||||||
checkbar(type); /* increment bar number if bar complete */
|
checkbar(type); /* increment bar number if bar complete */
|
||||||
/* [SS] 2015-11-15 * changed (void*) to (int *) */
|
/* [SS] 2015-11-15 * changed (void*) to (int *) */
|
||||||
addfeature(type, (int *)cv->barno); /* save bar number */
|
addfeature(type, (int *)cv->barno); /* save bar number */
|
||||||
switch(type) {
|
|
||||||
case SINGLE_BAR:
|
|
||||||
break;
|
|
||||||
case DOUBLE_BAR:
|
|
||||||
break;
|
|
||||||
case THIN_THICK:
|
|
||||||
break;
|
|
||||||
case THICK_THIN:
|
|
||||||
break;
|
|
||||||
case BAR_REP:
|
|
||||||
if ((cv->expect_repeat) && (repcheck)) {
|
|
||||||
event_error("Expecting repeat, found |:");
|
|
||||||
};
|
|
||||||
cv->expect_repeat = 1;
|
|
||||||
break;
|
|
||||||
case REP_BAR:
|
|
||||||
if ((!cv->expect_repeat) && (repcheck)) {
|
|
||||||
event_error("No repeat expected, found :|");
|
|
||||||
};
|
|
||||||
cv->expect_repeat = 0;
|
|
||||||
break;
|
|
||||||
case BAR1:
|
|
||||||
if ((!cv->expect_repeat) && (repcheck)) {
|
|
||||||
event_error("found |1 in non-repeat section");
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case REP_BAR2:
|
|
||||||
if ((!cv->expect_repeat) && (repcheck)) {
|
|
||||||
event_error("No repeat expected, found :|2");
|
|
||||||
};
|
|
||||||
cv->expect_repeat = 0;
|
|
||||||
break;
|
|
||||||
case DOUBLE_REP:
|
|
||||||
if ((!cv->expect_repeat) && (repcheck)) {
|
|
||||||
event_error("No repeat expected, found ::");
|
|
||||||
};
|
|
||||||
cv->expect_repeat = 1;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if ((playonrep_list != NULL) && (strlen(playonrep_list) > 0)) {
|
if ((playonrep_list != NULL) && (strlen(playonrep_list) > 0)) {
|
||||||
event_playonrep(playonrep_list);
|
event_playonrep(playonrep_list);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user