vorbis.c (1125B)
1 #include <sys/select.h> 2 3 #include <err.h> 4 #include <limits.h> 5 #include <stdio.h> 6 #include <vorbis/vorbisfile.h> 7 8 #include "sad.h" 9 10 static OggVorbis_File vf; 11 static int cursect; 12 13 static int vorbisopen(Format *fmt, const char *name) { 14 int r; 15 vorbis_info *vi; 16 17 r = ov_fopen(name, &vf); 18 if (r < 0) { 19 warnx("ov_fopen: failed"); 20 return -1; 21 } 22 23 vi = ov_info(&vf, -1); 24 if (!vi) { 25 warnx("ov_info: failed"); 26 goto err0; 27 } 28 29 fmt->bits = 16; 30 fmt->rate = vi->rate; 31 fmt->channels = vi->channels; 32 33 if (initresamplers(fmt) < 0) 34 goto err0; 35 36 return 0; 37 38 err0: 39 ov_clear(&vf); 40 return -1; 41 } 42 43 static int vorbisdecode(void *buf, int nbytes) { 44 int r, decoded; 45 char *p = buf; 46 47 decoded = 0; 48 while (nbytes > 0) { 49 r = ov_read(&vf, &p[decoded], nbytes, 0, 2, 1, &cursect); 50 if (r < 0) { 51 warnx("ov_read: failed"); 52 return -1; 53 } else if (r == 0) { 54 break; 55 } 56 decoded += r; 57 nbytes -= r; 58 } 59 return decoded; 60 } 61 62 static int vorbisclose(void) { return ov_clear(&vf); } 63 64 Decoder vorbisdecoder = { 65 .open = vorbisopen, .decode = vorbisdecode, .close = vorbisclose};