summaryrefslogtreecommitdiff
path: root/sys/src/cmd/audio/mixfs
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-01-10 14:51:29 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2014-01-10 14:51:29 +0100
commitfc88896fc1f7a1849e8f4e8c372b1e06ea836384 (patch)
tree75a9f523cf3aea808d3f2a42a5e1566f679d85b1 /sys/src/cmd/audio/mixfs
parentf4550c4d6ae277a5ee96fac110fdd306b3e3ac40 (diff)
mixfs: make mixbuffer addition atomic
serialize mixing with spinlock to make the addition on the mixbuffer samples atomic.
Diffstat (limited to 'sys/src/cmd/audio/mixfs')
-rw-r--r--sys/src/cmd/audio/mixfs/mixfs.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/sys/src/cmd/audio/mixfs/mixfs.c b/sys/src/cmd/audio/mixfs/mixfs.c
index 537bfca8f..15a082e24 100644
--- a/sys/src/cmd/audio/mixfs/mixfs.c
+++ b/sys/src/cmd/audio/mixfs/mixfs.c
@@ -23,6 +23,7 @@ struct Stream
ulong mixrp;
int mixbuf[NBUF][NCHAN];
+Lock mixlock;
Stream streams[16];
int
@@ -163,33 +164,44 @@ fswrite(Req *r)
p = (uchar*)r->ifcall.data;
n = r->ifcall.count;
- m = n/(NCHAN*2);
+ r->ofcall.count = n;
+ n /= (NCHAN*2);
srv = r->srv;
srvrelease(srv);
s = r->fid->aux;
qlock(s);
- if(s->run == 0){
- s->wp = mixrp;
- s->run = 1;
- }
- for(i=0; i<m; i++){
- while((long)(s->wp - mixrp) >= NBUF-1){
+ while(n > 0){
+ if(s->run == 0){
+ s->wp = mixrp;
+ s->run = 1;
+ }
+ m = NBUF-1 - (long)(s->wp - mixrp);
+ if(m <= 0){
s->run = 1;
rsleep(s);
+ continue;
}
- for(j=0; j<NCHAN; j++){
- mixbuf[s->wp % NBUF][j] += s16(p);
- p += 2;
+ if(m > n)
+ m = n;
+
+ lock(&mixlock);
+ for(i=0; i<m; i++){
+ for(j=0; j<NCHAN; j++){
+ mixbuf[s->wp % NBUF][j] += s16(p);
+ p += 2;
+ }
+ s->wp++;
}
- s->wp++;
+ unlock(&mixlock);
+
+ n -= m;
}
if((long)(s->wp - mixrp) >= NDELAY){
s->run = 1;
rsleep(s);
}
qunlock(s);
- r->ofcall.count = n;
respond(r, nil);
srvacquire(srv);
}