static long audioread(Chan *c, void *a, long n, vlong off) { Audiochan *ac; Audio *adev; long (*fn)(Audio *, void *, long, vlong); ac = c->aux; adev = ac->adev; fn = nil; switch((ulong)c->qid.path){ case Qdir: audiodir[Qaudio].length = adev->buffered ? adev->buffered(adev) : 0; return devdirread(c, a, n, audiodir, nelem(audiodir), devgen); case Qaudio: fn = adev->read; break; case Qaudiostat: fn = adev->status; break; case Qvolume: fn = adev->volread; break; } if(fn == nil) error(Egreg); eqlock(ac); if(waserror()){ qunlock(ac); nexterror(); } switch((ulong)c->qid.path){ case Qaudiostat: case Qvolume: /* generate the text on first read */ if(ac->data == nil || off == 0){ long l; ac->data = nil; l = fn(adev, ac->buf, sizeof(ac->buf)-1, 0); if(l < 0) l = 0; ac->buf[l] = 0; ac->data = ac->buf; } /* then serve all requests from buffer */ n = readstr(off, a, n, ac->data); break; default: n = fn(adev, a, n, off); } qunlock(ac); poperror(); return n; }
static int audiostat(Chan *c, uchar *dp, int n) { Audiochan *ac; Audio *adev; ac = c->aux; adev = ac->adev; if((ulong)c->qid.path == Qaudio) audiodir[Qaudio].length = adev->buffered ? adev->buffered(adev) : 0; return devstat(c, dp, n, audiodir, nelem(audiodir), devgen); }