From ef2baf8076db297fbb979fde6c3e911a391bd15a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 20 Nov 2011 22:14:27 +0100 Subject: More stuff --- maestropond.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file 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; in_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; in_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; jn_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; in_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; jn_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; in_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); } -- cgit v1.2.3