FreeCalypso > hg > freecalypso-tools
changeset 176:2b38691076b9
fc-e1decode utility written, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 25 Mar 2017 20:31:01 +0000 |
parents | b002c7cf5d03 |
children | 2133c475f5bd |
files | .hgignore ringtools/Makefile ringtools/fc-e1decode.c |
diffstat | 3 files changed, 173 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Sat Mar 25 18:36:37 2017 +0000 +++ b/.hgignore Sat Mar 25 20:31:01 2017 +0000 @@ -27,6 +27,7 @@ ^miscutil/fc-vm2hex$ ^miscutil/imei-luhn$ +^ringtools/fc-e1decode$ ^ringtools/fc-e1gen$ ^rvinterf/asyncshell/fc-shell$
--- a/ringtools/Makefile Sat Mar 25 18:36:37 2017 +0000 +++ b/ringtools/Makefile Sat Mar 25 20:31:01 2017 +0000 @@ -1,10 +1,13 @@ CC= gcc CFLAGS= -O2 -PROGS= fc-e1gen +PROGS= fc-e1decode fc-e1gen INSTBIN=/opt/freecalypso/bin all: ${PROGS} +fc-e1decode: fc-e1decode.c + ${CC} ${CFLAGS} -o $@ $@.c + fc-e1gen: fc-e1gen.c ${CC} ${CFLAGS} -o $@ $@.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ringtools/fc-e1decode.c Sat Mar 25 20:31:01 2017 +0000 @@ -0,0 +1,168 @@ +/* + * This program decodes a binary Melody E1 file into the ASCII source format + * of our own invention which fc-e1gen accepts as input. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <strings.h> + +char *infname; +FILE *inf, *outf; + +static unsigned +get_word() +{ + u_char b[2]; + int i, c; + + for (i = 0; i < 2; i++) { + c = getc(inf); + if (c < 0) { + fprintf(stderr, "error: premature EOF in %s\n", + infname); + exit(1); + } + b[i] = c; + } + return((b[1] << 8) | b[0]); +} + +do_global_osc_set() +{ + unsigned word, osc; + + word = get_word(); + fprintf(outf, "osc-set (%u)", word & 0xFF); + for (osc = 0; osc < 8; osc++) + if (word & (1 << (osc + 8))) + fprintf(outf, " %u", osc); + putc('\n', outf); + putc('\n', outf); +} + +convert_signed_14bit(u) + unsigned u; +{ + int i; + + i = u; + if (i >= 8192) + i -= 16384; + return (i); +} + +convert_signed_5bit(u) + unsigned u; +{ + int i; + + i = u; + if (i >= 16) + i -= 32; + return (i); +} + +process_oscwords(osc, warnflags) + unsigned osc, *warnflags; +{ + unsigned word0, word1, extraword; + + word0 = get_word(); + word1 = get_word(); + if (word1 & 0xF) + *warnflags |= 1; + fprintf(outf, "osc %u (%u)", osc, word0 & 1); + if (word0 & 2) { + fprintf(outf, " df %d %u", convert_signed_14bit(word0 >> 2), + word1 >> 6); + } else { + if (word0 & 4) + fputs(" sq1", outf); + if (word0 & 8) + fputs(" sq2", outf); + fprintf(outf, " %u %u %u", (word0 >> 4) & 0x3F, word0 >> 10, + word1 >> 6); + } + if (word1 & 0x10) { + extraword = get_word(); + if (extraword & 0xFF) + *warnflags |= 2; + fprintf(outf, " trem %u %d", (extraword >> 8) & 7, + convert_signed_5bit(extraword >> 11)); + } + if (word1 & 0x20) { + extraword = get_word(); + fprintf(outf, " env %u %u %u %u %u", extraword & 0xF, + extraword >> 13, (extraword >> 10) & 7, + (extraword >> 7) & 7, (extraword >> 4) & 7); + } +} + +process_block(timeword) + unsigned timeword; +{ + unsigned osc, warnflags[8], anywarn; + + fprintf(outf, "time %u\n", timeword & 0xFF); + for (osc = 0; osc < 8; osc++) { + warnflags[osc] = 0; + if (timeword & (1 << (osc + 8))) + process_oscwords(osc, warnflags + osc); + } + putc('\n', outf); + anywarn = 0; + for (osc = 0; osc < 8; osc++) { + if (warnflags[osc] & 1) { + fprintf(outf, + "# warning: reserved bits set in osc %u word1 above\n", + osc); + anywarn = 1; + } + if (warnflags[osc] & 2) { + fprintf(outf, + "# warning: reserved bits set in osc %u word2 above\n", + osc); + anywarn = 1; + } + } + if (anywarn) + putc('\n', outf); +} + +main(argc, argv) + char **argv; +{ + unsigned timeword; + + if (argc < 2 || argc > 3) { + fprintf(stderr, "usage: %s infile [outfile]\n", argv[0]); + exit(1); + } + infname = argv[1]; + inf = fopen(infname, "r"); + if (!inf) { + perror(infname); + exit(1); + } + if (argc > 2) { + outf = fopen(argv[2], "w"); + if (!outf) { + perror(argv[2]); + exit(1); + } + } else + outf = stdout; + do_global_osc_set(); + for (;;) { + timeword = get_word(); + if (timeword == 0) + break; + process_block(timeword); + } + fputs("end\n", outf); + exit(0); +}