4 enum { SAMPLE = 44100 };
14 typedef struct Tracker Tracker;
16 int fd, ofd, div, tempo = 500000, ntrack;
27 sysfatal("malloc: %r");
38 if(read(fd, &c, 1) == 0)
39 sysfatal("unexpected eof");
59 return x | get16(src);
90 skip(Tracker *src, int x)
113 int samp, j, k, l, 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];
130 s = emallocz(samp * 4);
131 for(l = 0; l < samp; l++){
133 for(k = 0; k < 128; k++){
134 f = (T % freq[k]) >= freq[k]/2 ? 1 : 0;
138 s[4 * l] = s[4 * l + 2] = u;
139 s[4 * l + 1] = s[4 * l + 3] = u >> 8;
142 write(ofd, s, samp * 4);
147 readevent(Tracker *src)
152 l = tconv(getvar(src));
159 sysfatal("invalid midi");
166 src->notes[t & 15][n] = 0;
170 src->notes[t & 15][n] = get8(src);
186 tempo = get16(src) << 8;
190 write(1, src->data, n);
194 print("unknown meta event type %.2x\n", t);
195 case 3: case 1: case 2: case 0x58: case 0x59: case 0x21:
200 sysfatal("unknown event type %x", t>>4);
205 main(int argc, char **argv)
212 sysfatal("invalid arguments");
213 fd = open(argv[1], OREAD);
215 sysfatal("open: %r");
216 ofd = open("/dev/audio", OWRITE);
219 if(get32(nil) != 0x4D546864 || get32(nil) != 6)
220 sysfatal("invalid file header");
224 tr = emallocz(ntrack * sizeof(*tr));
225 for(i = 0; i < ntrack; i++){
226 if(get32(nil) != 0x4D54726B)
227 sysfatal("invalid track header");
229 tr[i].data = emallocz(size);
230 read(fd, tr[i].data, size);
232 for(i = 0; i < 128; i++)
233 freq[i] = SAMPLE / (440 * pow(1.05946, i - 69));
237 for(x = tr; x < tr + ntrack; x++){
240 t = tconv(peekvar(x)) + x->t;
241 if(t < mint || minx == nil){