mp3.c (1517B)
1 #include <sys/select.h> 2 3 #include <err.h> 4 #include <limits.h> 5 #include <mpg123.h> 6 #include <stdio.h> 7 8 #include "sad.h" 9 10 static mpg123_handle *hdl; 11 12 static int mp3open(Format *fmt, const char *name) { 13 int r; 14 long rate; 15 int channels, encoding; 16 17 if (mpg123_init() != MPG123_OK) { 18 warnx("mpg123_init: failed"); 19 return -1; 20 } 21 22 hdl = mpg123_new(NULL, NULL); 23 if (!hdl) { 24 warnx("mpg123_new: failed"); 25 goto err0; 26 } 27 28 r = mpg123_open(hdl, name); 29 if (r != MPG123_OK) { 30 warnx("mpg123_open: failed"); 31 goto err1; 32 } 33 34 r = mpg123_getformat(hdl, &rate, &channels, &encoding); 35 if (r != MPG123_OK) { 36 warnx("mpg123_getformat: failed"); 37 goto err2; 38 } 39 40 fmt->bits = mpg123_encsize(encoding) * 8; 41 fmt->rate = rate; 42 fmt->channels = channels; 43 44 if (initresamplers(fmt) < 0) 45 goto err2; 46 47 return 0; 48 49 err2: 50 mpg123_close(hdl); 51 err1: 52 mpg123_delete(hdl); 53 err0: 54 mpg123_exit(); 55 hdl = NULL; 56 return -1; 57 } 58 59 static int mp3decode(void *buf, int nbytes) { 60 size_t actual; 61 int r; 62 63 r = mpg123_read(hdl, buf, nbytes, &actual); 64 if (r == MPG123_DONE) 65 return 0; 66 else if (r != MPG123_OK) { 67 warnx("mpg123_read: failed"); 68 return -1; 69 } 70 return actual; 71 } 72 73 static int mp3close(void) { 74 int r = 0; 75 76 if (hdl) { 77 if (mpg123_close(hdl) != MPG123_OK) { 78 warnx("mpg123_close: failed"); 79 r = -1; 80 } 81 mpg123_delete(hdl); 82 mpg123_exit(); 83 } 84 hdl = NULL; 85 return r; 86 } 87 88 Decoder mp3decoder = {.open = mp3open, .decode = mp3decode, .close = mp3close};