3
bag -- A quick hack to buffer audio data between TiMidity and an
4
external player program.
6
This program is in the Public Domain. It is distributed without
7
much hope that it will be useful, and WITHOUT ANY WARRANTY;
8
definitely without any implied warranty of MERCHANTABILITY or
9
FITNESS FOR ANY PURPOSE.
11
bag may enable you to play complex files at higher output rates,
12
but it's a bit of a pain to use.
14
Here's a usage example for Linux. splay is a program that (with
15
this invocation) plays audio data from stdin. Your flag
16
requirements may vary.
18
timidity -id -Or1lsS -o- -s22 -p48 filenames |
19
bag -b 2M -t 1M -c 4k |
29
#include <sys/types.h>
33
static int bytes(char *s)
37
while (*s>='0' && *s<='9')
52
int main(int argc, char **argv)
54
int bs=1024*1024, rs=4*1024, ws=4*1024, cs=4*1024, thresh=64*1024;
55
int c, junk=0, verbosity=0, flush_and_go=0;
56
char *bag, *head, *tail;
57
extern char *optarg; /* for Sun's gcc */
59
fd_set readfds, writefds, brokefds;
62
while ((c=getopt(argc, argv, "b:t:r:w:c:hv"))>0)
65
case 'b': bs=bytes(optarg); break;
66
case 't': thresh=bytes(optarg); break;
67
case 'r': rs=bytes(optarg); break;
68
case 'w': ws=bytes(optarg); break;
69
case 'c': rs=ws=bytes(optarg); break;
70
case 'v': verbosity++; break;
73
printf("\nBag usage:\n\n"
74
" timidity -id -Or[format options] -o- [options and filenames] |\n"
75
" bag [bag options] | audio_player [player options]\n\n"
77
" -b size Set buffer size (default %d)\n"
78
" -r size Set read chunk size (default %d)\n"
79
" -w size Set write chunk size (default %d)\n"
80
" -c size Set read/write chunk size\n"
81
" -t size Set start threshold for writing (default %d)\n"
83
" -h This help screen\n\n"
93
fprintf(stderr, "bag: Buffer size increased to %d bytes\n", bs);
98
fprintf(stderr, "bag: Threshold lowered to %d bytes\n", bs);
101
head=tail=bag=malloc(bs);
103
while (!flush_and_go)
110
FD_SET(STDIN_FILENO, &readfds);
112
if (junk>ws && junk>thresh)
114
FD_SET(STDOUT_FILENO, &writefds);
118
FD_SET(STDIN_FILENO, &brokefds);
119
FD_SET(STDOUT_FILENO, &brokefds);
124
if ((c=select(FD_SETSIZE,(int *) &readfds,(int *) &writefds, (int *) &brokefds, &tmo))<0)
126
if ((c=select(FD_SETSIZE, &readfds, &writefds, &brokefds, &tmo))<0)
128
perror("\nbag: select");
131
fprintf(stderr, "\rbag: %8d bytes", junk);
133
if (FD_ISSET(STDOUT_FILENO, &brokefds))
135
fprintf(stderr, "\nbag: Elvis has left the building\n");
139
if (FD_ISSET(STDIN_FILENO, &readfds))
141
if ((c=read(STDIN_FILENO, head,
142
(head+rs >= bag+bs) ? (bag+bs-head) : rs))<=0)
144
if (c==0 || errno!=EAGAIN)
155
else if (FD_ISSET(STDIN_FILENO, &brokefds))
158
if (flush_and_go || FD_ISSET(STDOUT_FILENO, &writefds))
161
c=(tail+ws >= bag+bs) ? (bag+bs-tail) : ws;
164
if (flush_and_go && verbosity)
165
fprintf(stderr, "\rbag: Flushing, %8d bytes", junk);
167
c=write(STDOUT_FILENO, tail, c);
172
} while (flush_and_go && junk);
175
fprintf(stderr, "\nbag: All done\n");