wav.c (1366B)
1 #include <sys/select.h> 2 3 #include <err.h> 4 #include <limits.h> 5 #include <sndfile.h> 6 #include <stdio.h> 7 8 #include "sad.h" 9 10 static SNDFILE *sf; 11 12 static int wavopen(Format *fmt, const char *name) { 13 SF_INFO sfinfo; 14 int bits; 15 16 sf = sf_open(name, SFM_READ, &sfinfo); 17 if (!sf) { 18 warnx("sf_open_fd: failed"); 19 return -1; 20 } 21 22 if (sfinfo.channels < 1 || sfinfo.channels > 2) { 23 warnx("sfinfo: unsupported number of channels %d", sfinfo.channels); 24 goto err0; 25 } 26 27 switch (sfinfo.format & 0xff) { 28 case SF_FORMAT_PCM_S8: 29 bits = 8; 30 break; 31 case SF_FORMAT_PCM_16: 32 bits = 16; 33 break; 34 case SF_FORMAT_PCM_24: 35 bits = 24; 36 break; 37 case SF_FORMAT_PCM_32: 38 bits = 32; 39 break; 40 default: 41 warnx("sfinfo: unsupported format"); 42 goto err0; 43 } 44 45 fmt->bits = bits; 46 fmt->rate = sfinfo.samplerate; 47 fmt->channels = sfinfo.channels; 48 49 if (initresamplers(fmt) < 0) 50 goto err0; 51 52 return 0; 53 err0: 54 sf_close(sf); 55 sf = NULL; 56 return -1; 57 } 58 59 static int wavdecode(void *buf, int nbytes) { 60 return sf_read_short(sf, buf, nbytes / sizeof(short)) * sizeof(short); 61 } 62 63 static int wavclose(void) { 64 int r = 0; 65 66 if (sf) { 67 r = sf_close(sf); 68 if (r != 0) { 69 warnx("sf_close: failed"); 70 r = -1; 71 } 72 } 73 sf = NULL; 74 return r; 75 } 76 77 Decoder wavdecoder = {.open = wavopen, .decode = wavdecode, .close = wavclose};