FreeCalypso > hg > freecalypso-tools
view ringtools/fc-e1decode.c @ 888:b8ecdf54a957
fc-imyplay script
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 03 Apr 2022 04:28:44 +0000 |
parents | c8806a5d4a6a |
children |
line wrap: on
line source
/* * 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); } putc('\n', outf); } 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); }