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);
185 while(get8(src) != 0xF7)
196 tempo = get16(src) << 8;
200 write(2, src->data, n);
204 fprint(2, "unknown meta event type %.2x\n", t);
205 case 3: case 1: case 2: case 0x58: case 0x59: case 0x21:
210 sysfatal("unknown event type %x", t>>4);
215 main(int argc, char **argv)
227 fd = open(*argv, OREAD);
229 ofd = open("/dev/audio", OWRITE);
230 if(fd < 0 || ofd < 0)
231 sysfatal("open: %r");
232 if(get32(nil) != 0x4D546864 || get32(nil) != 6)
233 sysfatal("invalid file header");
237 tr = emallocz(ntrack * sizeof(*tr));
238 for(i = 0; i < ntrack; i++){
239 if(get32(nil) != 0x4D54726B)
240 sysfatal("invalid track header");
242 tr[i].data = emallocz(size);
243 readn(fd, tr[i].data, size);
245 for(i = 0; i < 128; i++)
246 freq[i] = SAMPLE / (440 * pow(1.05946, i - 69));
250 for(x = tr; x < tr + ntrack; x++){
253 t = tconv(peekvar(x)) + x->t;
254 if(t < mint || minx == nil){
260 write(ofd, out, outp - out);