comparison ringtools/fc-e1decode.c @ 176:2b38691076b9

fc-e1decode utility written, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 25 Mar 2017 20:31:01 +0000
parents
children c8806a5d4a6a
comparison
equal deleted inserted replaced
175:b002c7cf5d03 176:2b38691076b9
1 /*
2 * This program decodes a binary Melody E1 file into the ASCII source format
3 * of our own invention which fc-e1gen accepts as input.
4 */
5
6 #include <sys/types.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <ctype.h>
10 #include <string.h>
11 #include <strings.h>
12
13 char *infname;
14 FILE *inf, *outf;
15
16 static unsigned
17 get_word()
18 {
19 u_char b[2];
20 int i, c;
21
22 for (i = 0; i < 2; i++) {
23 c = getc(inf);
24 if (c < 0) {
25 fprintf(stderr, "error: premature EOF in %s\n",
26 infname);
27 exit(1);
28 }
29 b[i] = c;
30 }
31 return((b[1] << 8) | b[0]);
32 }
33
34 do_global_osc_set()
35 {
36 unsigned word, osc;
37
38 word = get_word();
39 fprintf(outf, "osc-set (%u)", word & 0xFF);
40 for (osc = 0; osc < 8; osc++)
41 if (word & (1 << (osc + 8)))
42 fprintf(outf, " %u", osc);
43 putc('\n', outf);
44 putc('\n', outf);
45 }
46
47 convert_signed_14bit(u)
48 unsigned u;
49 {
50 int i;
51
52 i = u;
53 if (i >= 8192)
54 i -= 16384;
55 return (i);
56 }
57
58 convert_signed_5bit(u)
59 unsigned u;
60 {
61 int i;
62
63 i = u;
64 if (i >= 16)
65 i -= 32;
66 return (i);
67 }
68
69 process_oscwords(osc, warnflags)
70 unsigned osc, *warnflags;
71 {
72 unsigned word0, word1, extraword;
73
74 word0 = get_word();
75 word1 = get_word();
76 if (word1 & 0xF)
77 *warnflags |= 1;
78 fprintf(outf, "osc %u (%u)", osc, word0 & 1);
79 if (word0 & 2) {
80 fprintf(outf, " df %d %u", convert_signed_14bit(word0 >> 2),
81 word1 >> 6);
82 } else {
83 if (word0 & 4)
84 fputs(" sq1", outf);
85 if (word0 & 8)
86 fputs(" sq2", outf);
87 fprintf(outf, " %u %u %u", (word0 >> 4) & 0x3F, word0 >> 10,
88 word1 >> 6);
89 }
90 if (word1 & 0x10) {
91 extraword = get_word();
92 if (extraword & 0xFF)
93 *warnflags |= 2;
94 fprintf(outf, " trem %u %d", (extraword >> 8) & 7,
95 convert_signed_5bit(extraword >> 11));
96 }
97 if (word1 & 0x20) {
98 extraword = get_word();
99 fprintf(outf, " env %u %u %u %u %u", extraword & 0xF,
100 extraword >> 13, (extraword >> 10) & 7,
101 (extraword >> 7) & 7, (extraword >> 4) & 7);
102 }
103 }
104
105 process_block(timeword)
106 unsigned timeword;
107 {
108 unsigned osc, warnflags[8], anywarn;
109
110 fprintf(outf, "time %u\n", timeword & 0xFF);
111 for (osc = 0; osc < 8; osc++) {
112 warnflags[osc] = 0;
113 if (timeword & (1 << (osc + 8)))
114 process_oscwords(osc, warnflags + osc);
115 }
116 putc('\n', outf);
117 anywarn = 0;
118 for (osc = 0; osc < 8; osc++) {
119 if (warnflags[osc] & 1) {
120 fprintf(outf,
121 "# warning: reserved bits set in osc %u word1 above\n",
122 osc);
123 anywarn = 1;
124 }
125 if (warnflags[osc] & 2) {
126 fprintf(outf,
127 "# warning: reserved bits set in osc %u word2 above\n",
128 osc);
129 anywarn = 1;
130 }
131 }
132 if (anywarn)
133 putc('\n', outf);
134 }
135
136 main(argc, argv)
137 char **argv;
138 {
139 unsigned timeword;
140
141 if (argc < 2 || argc > 3) {
142 fprintf(stderr, "usage: %s infile [outfile]\n", argv[0]);
143 exit(1);
144 }
145 infname = argv[1];
146 inf = fopen(infname, "r");
147 if (!inf) {
148 perror(infname);
149 exit(1);
150 }
151 if (argc > 2) {
152 outf = fopen(argv[2], "w");
153 if (!outf) {
154 perror(argv[2]);
155 exit(1);
156 }
157 } else
158 outf = stdout;
159 do_global_osc_set();
160 for (;;) {
161 timeword = get_word();
162 if (timeword == 0)
163 break;
164 process_block(timeword);
165 }
166 fputs("end\n", outf);
167 exit(0);
168 }