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