diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-01-10 14:51:29 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-01-10 14:51:29 +0100 |
commit | fc88896fc1f7a1849e8f4e8c372b1e06ea836384 (patch) | |
tree | 75a9f523cf3aea808d3f2a42a5e1566f679d85b1 /sys/src/cmd/audio/mixfs | |
parent | f4550c4d6ae277a5ee96fac110fdd306b3e3ac40 (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.c | 36 |
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); } |