diff options
author | Thomas White <taw@bitwiz.org.uk> | 2011-11-12 21:19:25 +0100 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2011-11-12 21:19:25 +0100 |
commit | 0327cf8217900174041d4f14a19aace4098dd8a6 (patch) | |
tree | 6636e7ef5cdb056382a2a810667614da15b73eac |
Initial import
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | maestropond.c | 282 |
3 files changed, 297 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f6f12a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +maestropond +maestropond.o + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..facb0e4 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +OBJS=maestropond.o + +maestropond: ${OBJS} + gcc -g ${OBJS} -o maestropond + +maestropond.o: maestropond.c + gcc -g -W -Wall -c maestropond.c -o maestropond.o + +clean: + rm -f ${OBJS} maestropond + +.PHONY: clean diff --git a/maestropond.c b/maestropond.c new file mode 100644 index 0000000..0ac0de6 --- /dev/null +++ b/maestropond.c @@ -0,0 +1,282 @@ +/* + * maestropond.c + * + * Convert Acorn Maestro files to LilyPond files + * + * (c) 2011 Thomas White <taw@physics.org> + * + */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <getopt.h> +#include <sys/types.h> +#include <sys/stat.h> + +static void show_syntax(const char *s) +{ + printf("Syntax: %s [options]\n", s); +} + + +static void show_help(const char *s) +{ + show_syntax(s); + printf( +"\nConvert Acorn Maestro files to LilyPond files.\n" +"\n" +" -h, --help Display this help message.\n" +"\n" +); +} + + +static unsigned int get_basic_int(unsigned char *f, size_t *pptr) +{ + unsigned int v; + size_t ptr = *pptr; + int sig; + + v = 0; + sig = f[ptr++]; + if ( sig != 0x40 ) { + fprintf(stderr, "Not a BASIC integer (sig %i, val %i)\n", + sig, v); + goto out; + } + + v += f[ptr++] << 24; + v += f[ptr++] << 16; + v += f[ptr++] << 8; + v += f[ptr++]; + +out: + *pptr = ptr; + return v; +} + + +static size_t process_music_data(unsigned char *f, size_t ptr, size_t len) +{ + unsigned int n_gates; + unsigned int i; + unsigned int lengths[8]; + + n_gates = get_basic_int(f, &ptr); + printf("%i gates\n", n_gates); + + for ( i=0; i<8; i++ ) { + lengths[i] = get_basic_int(f, &ptr); + printf("Channel %i, length %i\n", i+1, lengths[i]); + } + + for ( i=0; i<n_gates; i++ ) { + unsigned char gd; + gd = f[ptr++]; + } + + for ( i=0; i<8; i++ ) { + unsigned int j; + for ( j=0; j<lengths[i]; j++ ) { + unsigned char d; + d = f[ptr++]; + } + } + + return ptr; +} + + +static size_t process_stave_data(unsigned char *f, size_t ptr) +{ + int n_staves, n_perc; + + n_staves = f[ptr++]; + n_perc = f[ptr++]; + + printf("%i staves, %i percussion\n", n_staves, n_perc); + + return ptr; +} + + +static size_t process_instrument_data(unsigned char *f, size_t ptr) +{ + int i; + + for ( i=0; i<8; i++ ) { + int ch, v; + ch = f[ptr++]; v = f[ptr++]; + printf("Channel %i, voice %i\n", ch+1, v); + } + + return ptr; +} + + +static size_t process_volume_data(unsigned char *f, size_t ptr) +{ + int i; + + for ( i=0; i<8; i++ ) { + int v; + v = f[ptr++]; + printf("Channel %i, volume %i\n", i+1, v); + } + + return ptr; +} + + +static size_t process_stereo_data(unsigned char *f, size_t ptr) +{ + int i; + + for ( i=0; i<8; i++ ) { + int st; + st = f[ptr++]; + printf("Channel %i, stereo %i\n", i+1, st); + } + + return ptr; +} + + +static size_t process_tempo_data(unsigned char *f, size_t ptr) +{ + int tempo; + + tempo = f[ptr++]; + printf("Tempo = %i\n", tempo); + + return ptr; +} + + +static void convert_file(const char *filename) +{ + struct stat statbuf; + FILE *fh; + unsigned char *f; + size_t r, ptr; + + if ( stat(filename, &statbuf) == -1 ) { + fprintf(stderr, "Couldn't file file '%s'\n", filename); + return; + } + f = malloc(statbuf.st_size); + if ( f == NULL ) { + fprintf(stderr, "Couldn't allocate memory.\n"); + return; + } + + /* Load data */ + fh = fopen(filename, "rb"); + if ( fh == NULL ) { + fprintf(stderr, "Failed to open file '%s'\n", filename); + return; + } + r = fread(f, 1, statbuf.st_size, fh); + if ( r != (size_t)statbuf.st_size ) { + fprintf(stderr, "Failed to read file" + " (got %lli out of %lli bytes).\n", + (long long int)r, + (long long int)statbuf.st_size); + fclose(fh); + free(f); + return; + } + fclose(fh); + + if ( memcmp(f, "Maestro\n", 8) != 0 ) { + fprintf(stderr, "Not a Maestro file.\n"); + free(f); + return; + } + + if ( f[8] != 2 ) { + fprintf(stderr, "Unrecognised Maestro file type (%i)\n", f[8]); + free(f); + return; + } + + ptr = 9; + while ( ptr < r ) { + switch ( f[ptr++] ) { + + case 1 : + ptr = process_music_data(f, ptr, r); + break; + + case 2 : + ptr = process_stave_data(f, ptr); + break; + + case 3 : + ptr = process_instrument_data(f, ptr); + break; + + case 4 : + ptr = process_volume_data(f, ptr); + break; + + case 5 : + ptr = process_stereo_data(f, ptr); + break; + + case 6 : + ptr = process_tempo_data(f, ptr); + break; + + } + } +} + + +int main(int argc, char *argv[]) +{ + int c; + char *infile; + + /* Long options */ + const struct option longopts[] = { + {"help", 0, NULL, 'h'}, + {0, 0, NULL, 0} + }; + + /* Short options */ + while ((c = getopt_long(argc, argv, "h", + longopts, NULL)) != -1) { + + switch (c) { + case 'h' : + show_help(argv[0]); + return 0; + + case 0 : + break; + + default : + return 1; + } + + } + if ( optind >= argc ) { + show_syntax(argv[0]); + return 1; + } + + infile = argv[optind++]; + printf("Input: '%s'\n", infile); + convert_file(infile); + + return 0; +} |