1 #include <errno.h> 2 #include <fcntl.h> 3 #include <poll.h> 4 #include <stdio.h> 5 #include <string.h> 6 #include <stdlib.h> 7 #include <unistd.h> 8 #include <sndio.h> 9 #include "tools.h" 10 11 #define BUFSZ 0x100 12 13 void cb(void *, int); 14 void usage(void); 15 16 unsigned char buf[BUFSZ]; 17 struct sio_par par; 18 char *xstr[] = SIO_XSTRINGS; 19 20 long long realpos = 0, playpos = 0; 21 22 void 23 cb(void *addr, int delta) 24 { 25 int bytes = delta * (int)(par.bps * par.pchan); 26 27 realpos += bytes; 28 29 fprintf(stderr, 30 "cb: bytes = %+7d, latency = %+7lld, " 31 "realpos = %+7lld, bufused = %+7lld\n", 32 bytes, playpos - realpos, 33 realpos, (realpos < 0) ? playpos : playpos - realpos); 34 } 35 36 void 37 usage(void) { 38 fprintf(stderr, "usage: play [-r rate] [-c nchan] [-e enc]\n"); 39 } 40 41 int 42 main(int argc, char **argv) { 43 int ch; 44 struct sio_hdl *hdl; 45 ssize_t n, len; 46 47 /* 48 * defaults parameters 49 */ 50 sio_initpar(&par); 51 par.sig = 1; 52 par.bits = 16; 53 par.pchan = 2; 54 par.rate = 44100; 55 56 while ((ch = getopt(argc, argv, "r:c:e:b:x:")) != -1) { 57 switch(ch) { 58 case 'r': 59 if (sscanf(optarg, "%u", &par.rate) != 1) { 60 fprintf(stderr, "%s: bad rate\n", optarg); 61 exit(1); 62 } 63 break; 64 case 'c': 65 if (sscanf(optarg, "%u", &par.pchan) != 1) { 66 fprintf(stderr, "%s: bad channels\n", optarg); 67 exit(1); 68 } 69 break; 70 case 'e': 71 if (!sio_strtoenc(&par, optarg)) { 72 fprintf(stderr, "%s: bad encoding\n", optarg); 73 exit(1); 74 } 75 break; 76 case 'b': 77 if (sscanf(optarg, "%u", &par.appbufsz) != 1) { 78 fprintf(stderr, "%s: bad buf size\n", optarg); 79 exit(1); 80 } 81 break; 82 case 'x': 83 for (par.xrun = 0;; par.xrun++) { 84 if (par.xrun == sizeof(xstr) / sizeof(char *)) { 85 fprintf(stderr, 86 "%s: bad xrun mode\n", optarg); 87 exit(1); 88 } 89 if (strcmp(xstr[par.xrun], optarg) == 0) 90 break; 91 } 92 break; 93 default: 94 usage(); 95 exit(1); 96 break; 97 } 98 } 99 100 hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0); 101 if (hdl == NULL) { 102 fprintf(stderr, "sio_open() failed\n"); 103 exit(1); 104 } 105 sio_onmove(hdl, cb, NULL); 106 if (!sio_setpar(hdl, &par)) { 107 fprintf(stderr, "sio_setpar() failed\n"); 108 exit(1); 109 } 110 if (!sio_getpar(hdl, &par)) { 111 fprintf(stderr, "sio_getpar() failed\n"); 112 exit(1); 113 } 114 if (!sio_start(hdl)) { 115 fprintf(stderr, "sio_start() failed\n"); 116 exit(1); 117 } 118 fprintf(stderr, "using %u bytes per buffer, rounding to %u\n", 119 par.bufsz * par.bps * par.pchan, 120 par.round * par.bps * par.pchan); 121 for (;;) { 122 len = read(STDIN_FILENO, buf, BUFSZ); 123 if (len < 0) { 124 perror("stdin"); 125 exit(1); 126 } 127 if (len == 0) 128 break; 129 n = sio_write(hdl, buf, len); 130 if (n == 0) { 131 fprintf(stderr, "sio_write: failed\n"); 132 exit(1); 133 } 134 playpos += n; 135 } 136 sio_close(hdl); 137 return 0; 138 } 139