summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2011-11-12 21:19:25 +0100
committerThomas White <taw@bitwiz.org.uk>2011-11-12 21:19:25 +0100
commit0327cf8217900174041d4f14a19aace4098dd8a6 (patch)
tree6636e7ef5cdb056382a2a810667614da15b73eac
Initial import
-rw-r--r--.gitignore3
-rw-r--r--Makefile12
-rw-r--r--maestropond.c282
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;
+}