summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2011-11-20 22:14:27 +0100
committerThomas White <taw@bitwiz.org.uk>2011-11-20 22:14:27 +0100
commitef2baf8076db297fbb979fde6c3e911a391bd15a (patch)
treeeaf0e708c966dc0476592efe41e56c49b64723d9
parent91cd3b6586021d867d0265c0a2283d4d8e447e40 (diff)
More stuff
-rw-r--r--maestropond.c176
1 files changed, 167 insertions, 9 deletions
diff --git a/maestropond.c b/maestropond.c
index 3a0ae4d..6cf1ca0 100644
--- a/maestropond.c
+++ b/maestropond.c
@@ -53,8 +53,11 @@ enum clef
enum chord_type
{
+ CHORD_UNDEFINED,
CHORD_MUSIC,
- CHORD_CLEF
+ CHORD_CLEF,
+ CHORD_BARLINE,
+ CHORD_TIMESIG
};
struct note
@@ -73,6 +76,8 @@ struct chord
int length;
enum clef clef;
+ int timesig_num;
+ int timesig_den;
};
struct stave
@@ -147,6 +152,7 @@ out:
static struct chord *add_chord(struct music *mus, int stave)
{
struct stave *st = &mus->staves[stave];
+ struct chord *c;
if ( st->n_chords >= st->max_chords ) {
struct chord *n;
@@ -159,7 +165,16 @@ static struct chord *add_chord(struct music *mus, int stave)
st->chords = n;
}
- return &st->chords[st->n_chords++];
+ c = &st->chords[st->n_chords++];
+ c->n_notes = 0;
+ c->type = CHORD_UNDEFINED;
+ return c;
+}
+
+
+static int maestro_to_beat(int n)
+{
+ return pow(2, n-1);
}
@@ -171,7 +186,12 @@ static void music_attribute(unsigned char ma, struct music *mus)
} else if ( (ma & 0x3f) == 0x20 ) {
- //fprintf(ofh, "|\n ");
+ unsigned int i;
+ for ( i=0; i<mus->n_staves; i++ ) {
+ struct chord *c = add_chord(mus, i);
+ c->type = CHORD_BARLINE;
+ }
+ printf("\n");
} else if ( (ma & 0x1f) == 0x10 ) {
@@ -227,10 +247,17 @@ static void music_attribute(unsigned char ma, struct music *mus)
} else if ( (ma & 0x1) == 0x1 ) {
int tn, td;
+ unsigned int i;
tn = 1 + ((ma & 0x1e) >> 1);
td = 1 + ((ma & 0xe0) >> 5);
- //fprintf(ofh, "\\time %i/%i\n", tn, td);
+
+ for ( i=0; i<mus->n_staves; i++ ) {
+ struct chord *c = add_chord(mus, i);
+ c->type = CHORD_TIMESIG;
+ c->timesig_num = tn;
+ c->timesig_den = maestro_to_beat(td-1);
+ }
}
}
@@ -247,6 +274,7 @@ static enum note_tone note_letter(int n)
case 6 : return NOTE_G;
}
+ fprintf(stderr, "Tone number %i not recognised.\n", n);
return NOTE_SILENCE;
}
@@ -258,13 +286,13 @@ static struct note pitch_to_note(int pos, int acc, enum clef cl)
switch ( cl ) {
case CLEF_BASS :
- n.octave = (pos+1) / 8;
- n.nt = note_letter((pos+1) % 8);
+ n.octave = (pos+1) / 7;
+ n.nt = note_letter((pos+1) % 7);
break;
case CLEF_TREBLE :
- n.octave = 2+ ((pos-1) / 8);
- n.nt = note_letter((pos-1) % 8);
+ n.octave = 2+ ((pos-1) / 7);
+ n.nt = note_letter((pos-1) % 7);
break;
default:
@@ -347,9 +375,11 @@ static void process_gate(struct music *mus, int i, int *nptrs)
{
unsigned int l, j;
+ printf("(");
while ( mus->gates[i] != 0 ) {
l = find_max_length(mus->gates[i], mus->notes, nptrs);
+ printf("%i ", l);
for ( j=0; j<mus->n_staves; j++ ) {
@@ -357,7 +387,7 @@ static void process_gate(struct music *mus, int i, int *nptrs)
int k;
n = add_chord(mus, j);
- n->length = l;
+ n->length = maestro_to_beat(l);
n->type = CHORD_MUSIC;
/* Find the notes of this length on this stave */
@@ -379,6 +409,7 @@ static void process_gate(struct music *mus, int i, int *nptrs)
}
}
+ printf(")");
}
@@ -514,6 +545,131 @@ static size_t process_tempo_data(unsigned char *f, size_t ptr, size_t len,
}
+static char letter(enum note_tone t)
+{
+ switch ( t ) {
+ case NOTE_A : return 'a';
+ case NOTE_B : return 'b';
+ case NOTE_C : return 'c';
+ case NOTE_D : return 'd';
+ case NOTE_E : return 'e';
+ case NOTE_F : return 'f';
+ case NOTE_G : return 'g';
+ case NOTE_SILENCE : return 's';
+ }
+
+ return '?';
+}
+
+
+static const char *note_to_ly(struct note n, char *t)
+{
+ int i;
+ int lyo = n.octave - 3;
+
+ t[0] = letter(n.nt);
+ t[1] = '\0';
+
+ if ( lyo > 0 ) {
+ for ( i=0; i<lyo; i++ ) {
+ strcat(t, "'");
+ }
+ } else if ( lyo < 0 ) {
+ for ( i=0; i<lyo; i++ ) {
+ strcat(t, ",");
+ }
+ }
+
+ return t;
+}
+
+
+static const char *clef_to_ly(enum clef c)
+{
+ switch ( c ) {
+ case CLEF_TREBLE : return "treble";
+ case CLEF_ALTO : return "alto";
+ case CLEF_TENOR : return "tenor";
+ case CLEF_BASS : return "bass";
+ }
+
+ return "unknown";
+}
+
+
+static void write_stave(FILE *ofh, struct stave *st)
+{
+ int i;
+ char t[32];
+ for ( i=0; i<st->n_chords; i++ ) {
+
+ int j;
+ struct chord *c = &st->chords[i];
+
+ if ( c->type == CHORD_CLEF ) {
+ fprintf(ofh, "\\clef \"%s\"\n", clef_to_ly(c->clef));
+ continue;
+ }
+
+ if ( c->type == CHORD_BARLINE ) {
+ fprintf(ofh, "| ");
+ continue;
+ }
+
+ if ( c->type == CHORD_TIMESIG ) {
+ fprintf(ofh, "\\time %i/%i\n", c->timesig_num,
+ c->timesig_den);
+ continue;
+ }
+
+ if ( c->type != CHORD_MUSIC ) {
+ fprintf(stderr, "Unknown chord type.\n");
+ continue;
+ }
+
+ if ( c->n_notes == 0 ) {
+ fprintf(stderr, "I don't understand this chord.\n");
+ continue;
+ }
+
+ if ( c->n_notes == 1 ) {
+ fprintf(ofh, "%s%i ", note_to_ly(c->notes[0], t),
+ c->length);
+ continue;
+ }
+
+ fprintf(ofh, "<");
+ for ( j=0; j<c->n_notes; j++ ) {
+ fprintf(ofh, "%s ", note_to_ly(c->notes[0], t));
+ }
+ fprintf(ofh, ">%i ", c->length);
+
+ }
+}
+
+static void write_lilypond(struct music *mus, FILE *ofh)
+{
+ unsigned int i;
+
+ fprintf(ofh, "\\score {\n");
+ fprintf(ofh, " <<\n");
+
+ for ( i=0; i<mus->n_staves; i++ ) {
+
+ fprintf(ofh, "\\new Staff {\n");
+ write_stave(ofh, &mus->staves[i]);
+ fprintf(ofh, "}\n");
+
+ }
+
+ fprintf(ofh, ">>\n");
+
+ fprintf(ofh, "\\layout { }\n");
+ fprintf(ofh, "\\midi { }\n");
+ fprintf(ofh, "}\n");
+}
+
+
static void convert_file(const char *filename)
{
struct stat statbuf;
@@ -614,6 +770,8 @@ static void convert_file(const char *filename)
}
interpret_gates(&mus);
+ write_lilypond(&mus, ofh);
+ fclose(ofh);
}