14 typedef struct Stream Stream;
26 int mixbuf[NBUF][NCHAN];
27 int lbbuf[NBUF][NCHAN];
36 v = p[0]<<(sizeof(int)-2)*8 | p[1]<<(sizeof(int)-1)*8;
37 v >>= (sizeof(int)-2)*8;
56 if(strcmp(r->fid->file->name, "audio") != 0){
60 for(s = streams; s < streams+nelem(streams); s++){
62 if(s->used == 0 && s->run == 0){
66 s->rd = (r->ifcall.mode&OWRITE) == 0;
73 respond(r, "all streams in use");
81 if(f->file != nil && strcmp(f->file->name, "audio") == 0 && (s = f->aux) != nil){
90 static uchar buf[NBUF*NCHAN*2];
91 int sweep, fd, i, j, n, m, v;
95 threadsetname("audioproc");
101 for(s = streams; s < streams+nelem(streams); s++){
104 n = (long)(s->wp - mixrp);
105 if(n <= 0 && (s->used == 0 || sweep))
125 /* attempt to sleep just shortly before buffer underrun */
140 if((fd = open("/dev/audio", OWRITE)) < 0){
141 fprint(2, "%s: open /dev/audio: %r\n", argv0);
148 for(j=0; j<NCHAN; j++){
149 v = clip16(mixbuf[mixrp % NBUF][j]);
150 lbbuf[mixrp % NBUF][j] = v;
151 mixbuf[mixrp % NBUF][j] = 0;
157 write(fd, buf, p - buf);
169 p = (uchar*)r->ofcall.data;
184 m = NBUF-1 - (long)(s->wp - mixrp);
195 for(j=0; j<NCHAN; j++){
196 v = lbbuf[s->wp % NBUF][j];
219 p = (uchar*)r->ifcall.data;
233 m = NBUF-1 - (long)(s->wp - mixrp);
244 for(j=0; j<NCHAN; j++){
245 mixbuf[s->wp % NBUF][j] += s16(p);
254 if((long)(s->wp - mixrp) >= NDELAY){
268 if(r->fid->file == nil){
272 if(strcmp(r->fid->file->name, "audio") == 0 && (s = r->fid->aux) != nil){
275 r->d.length = (long)(s->wp - mixrp);
276 r->d.length *= NCHAN*2;
290 for(s=streams; s < streams+nelem(streams); s++){
291 s->used = s->run = s->rd = 0;
292 s->Rendez.l = &s->QLock;
294 proccreate(audioproc, nil, 16*1024);
308 .destroyfid= fsclunk,
316 fprint(2, "usage: %s [-D] [-s srvname] [-m mtpt]\n", argv0);
321 threadmain(int argc, char **argv)
324 char *mtpt = "/mnt/mix";
331 srv = EARGF(usage());
334 mtpt = EARGF(usage());
343 fs.tree = alloctree(nil, nil, DMDIR|0777, nil);
344 createfile(fs.tree->root, "audio", nil, 0666, nil);
345 threadpostmountsrv(&fs, srv, mtpt, MREPL);
347 mtpt = smprint("%s/audio", mtpt);
348 if(bind(mtpt, "/dev/audio", MREPL) < 0)
349 sysfatal("bind: %r");