2 * Simple mp3 player. Derived from libmad's example minimad.c.
8 /* Current input file */
14 int vfd; /* /dev/volume */
17 input(void *data, struct mad_stream *stream)
20 static uchar buf[32768];
23 n = stream->bufend - stream->next_frame;
24 memmove(buf, stream->next_frame, n);
25 m = read(fd, buf+n, sizeof buf-n);
28 sysfatal("reading input: %r");
32 mad_stream_buffer(stream, buf, n);
33 return MAD_FLOW_CONTINUE;
37 * Dither 28-bit down to 16-bit. From mpg321.
38 * I'm skeptical, but it's supposed to make the
39 * samples sound better than just truncation.
41 typedef struct Dither Dither;
48 #define PRNG(x) (((x)*0x19660dL + 0x3c6ef35fL) & 0xffffffffL)
52 FracBits = MAD_F_FRACBITS,
54 Round = 1 << (FracBits+1-OutBits-1), // sic
55 ScaleBits = FracBits + 1 - OutBits,
56 LowMask = (1<<ScaleBits) - 1,
62 audiodither(mad_fixed_t v, Dither *d)
68 v += d->error[0] - d->error[1] + d->error[2];
69 d->error[2] = d->error[1];
70 d->error[1] = d->error[0] / 2;
76 random = PRNG(d->random);
77 out += (random & LowMask) - (d->random & LowMask);
95 d->error[0] = v - out;
98 return out >> ScaleBits;
102 output(void *data, struct mad_header const* header, struct mad_pcm *pcm)
105 mad_fixed_t const *left, *right;
107 static uchar buf[16384], *p;
109 if(pcm->samplerate != rate){
110 rate = pcm->samplerate;
112 fprint(2, "warning: audio sample rate is %d Hz\n", rate);
114 fprint(vfd, "speed %d", rate);
117 memset(&d, 0, sizeof d);
119 switch(pcm->channels){
121 left = pcm->samples[0];
123 v = audiodither(*left++, &d);
132 left = pcm->samples[0];
133 right = pcm->samples[1];
135 v = audiodither(*left++, &d);
138 v = audiodither(*right++, &d);
144 assert(p<=buf+sizeof buf);
145 write(1, buf, p-buf);
146 return MAD_FLOW_CONTINUE;
150 error(void *data, struct mad_stream *stream, struct mad_frame *frame)
152 if(stream->error == MAD_ERROR_LOSTSYNC)
153 return MAD_FLOW_CONTINUE;
154 sysfatal("%s:#%lld: %s",
155 name, offset-(stream->bufend-stream->next_frame),
156 mad_stream_errorstr(stream));
161 play(int fd, char *nam)
163 struct mad_decoder decoder;
166 mad_decoder_init(&decoder, (void*)fd, input, nil, nil, output, error, nil);
167 mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
168 mad_decoder_finish(&decoder);
174 fprint(2, "usage: mp3dec [-o outfile] [file...]\n");
179 main(int argc, char **argv)
186 outfile = EARGF(usage());
193 if((fd = create(outfile, OWRITE, 0666)) < 0)
194 sysfatal("create %s: %r", outfile);
196 if((fd = open("/dev/audio", OWRITE)) < 0)
197 sysfatal("open /dev/audio: %r");
198 vfd = open("/dev/volume", OWRITE);
206 play(0, "standard input");
208 for(i=0; i<argc; i++){
209 if((fd = open(argv[i], OREAD)) < 0)
210 sysfatal("open %s: %r", argv[i]);