4 enum { SAMPLE = 44100 };
14 typedef struct Tracker Tracker;
16 int fd, ofd, div, tempo = 500000, ntrack;
19 uchar out[8192], *outp = out;
28 sysfatal("malloc: %r");
39 if(read(fd, &c, 1) == 0)
40 sysfatal("unexpected eof");
60 return x | get16(src);
91 skip(Tracker *src, int x)
114 int samp, j, k, no[128];
122 memset(no, 0, sizeof no);
123 for(x = tr; x < tr + ntrack; x++){
126 for(j = 0; j < 16; j++)
127 for(k = 0; k < 128; k++)
128 no[k] += x->notes[j][k];
132 for(k = 0; k < 128; k++){
133 f = (T % freq[k]) >= freq[k]/2 ? 1 : 0;
137 outp[0] = outp[2] = u;
138 outp[1] = outp[3] = u >> 8;
140 if(outp == out + sizeof out){
141 write(ofd, out, sizeof out);
149 readevent(Tracker *src)
154 l = tconv(getvar(src));
161 sysfatal("invalid midi");
168 src->notes[t & 15][n] = 0;
172 src->notes[t & 15][n] = get8(src);
191 tempo = get16(src) << 8;
195 write(2, src->data, n);
199 fprint(2, "unknown meta event type %.2x\n", t);
200 case 3: case 1: case 2: case 0x58: case 0x59: case 0x21:
205 sysfatal("unknown event type %x", t>>4);
210 main(int argc, char **argv)
222 fd = open(*argv, OREAD);
224 ofd = open("/dev/audio", OWRITE);
225 if(fd < 0 || ofd < 0)
226 sysfatal("open: %r");
227 if(get32(nil) != 0x4D546864 || get32(nil) != 6)
228 sysfatal("invalid file header");
232 tr = emallocz(ntrack * sizeof(*tr));
233 for(i = 0; i < ntrack; i++){
234 if(get32(nil) != 0x4D54726B)
235 sysfatal("invalid track header");
237 tr[i].data = emallocz(size);
238 readn(fd, tr[i].data, size);
240 for(i = 0; i < 128; i++)
241 freq[i] = SAMPLE / (440 * pow(1.05946, i - 69));
245 for(x = tr; x < tr + ntrack; x++){
248 t = tconv(peekvar(x)) + x->t;
249 if(t < mint || minx == nil){
255 write(ofd, out, outp - out);