Vigain,
Vogain,
Vspeed,
+ Vdelay,
Nvol,
Blocksize = 4096,
int active; /* boolean dma running */
int major; /* SB16 major version number (sb 4) */
int minor; /* SB16 minor version number */
- ulong totcount; /* how many bytes processed since open */
- vlong tottime; /* time at which totcount bytes were processed */
Ring ring; /* dma ring buffer */
Blaster blaster;
[Vigain] "recgain", 0x3f, 0xff, Stereo, 0,
[Vogain] "outgain", 0x41, 0xff, Stereo, 0,
[Vspeed] "speed", 0, 0, Absolute, 0,
+ [Vdelay] "delay", 0, 0, Absolute, 0,
0,
};
Ctlr *ctlr = adev->ctlr;
Volume *vol;
- if(x == Vspeed){
- ctlr->lvol[x] = ctlr->rvol[x] = a[0];
- return 0;
- }
-
vol = voltab+x;
blaster = &ctlr->blaster;
ilock(blaster);
switch(vol->type){
+ case Absolute:
+ switch(x){
+ case Vdelay:
+ adev->delay = a[0];
+ break;
+ case Vspeed:
+ adev->speed = a[0];
+ break;
+ }
+ ctlr->lvol[x] = ctlr->rvol[x] = a[0];
+ break;
case Stereo:
ctlr->rvol[x] = a[1];
mxcmd(blaster, vol->reg+1, a[1]);
blaster = &ctlr->blaster;
ring = &ctlr->ring;
- if(buffered(ring) >= Blocksize){
+ if(buffered(ring) >= Blocksize)
ring->ri = ring->nbuf - dmacount(ctlr->conf.dma);
-
- ctlr->totcount += Blocksize;
- ctlr->tottime = todget(nil);
- }else{
+ else{
dmaend(ctlr->conf.dma);
sbcmd(blaster, 0xd9); /* exit at end of count */
sbcmd(blaster, 0xd5); /* pause */
sbcmd(blaster, 0x42); /* input sampling rate */
else
sbcmd(blaster, 0x41); /* output sampling rate */
- speed = ctlr->lvol[Vspeed];
+ speed = ctlr->adev->speed;
sbcmd(blaster, speed>>8);
sbcmd(blaster, speed);
/*
* Set the speed.
*/
- speed = ctlr->lvol[Vspeed];
+ speed = ctlr->adev->speed;
if(speed < 4000)
speed = 4000;
else if(speed > 48000)
ilock(&ctlr->blaster);
ctlr->ring.ri = 0;
ctlr->ring.wi = 0;
- ctlr->totcount = 0;
- ctlr->tottime = 0LL;
iunlock(&ctlr->blaster);
}
audiostatus(Audio *adev, void *a, long n, vlong)
{
Ctlr *ctlr = adev->ctlr;
-
- return snprint((char*)a, n,
- "bufsize %6d buffered %6ld "
- "offset %10lud time %19lld\n",
- Blocksize, buffered(&ctlr->ring),
- ctlr->totcount, ctlr->tottime);
+ return snprint((char*)a, n, "bufsize %6d buffered %6ld\n",
+ Blocksize, buffered(&ctlr->ring));
}
static int
inactive(void *arg)
{
Ctlr *ctlr = arg;
-
return !ctlr->active;
}
anybuf(void *arg)
{
Ctlr *ctlr = arg;
-
return available(&ctlr->ring) || inactive(ctlr);
}
+static int
+ratebuf(void *arg)
+{
+ Ctlr *ctlr = arg;
+ int delay = ctlr->adev->delay*4;
+ return (delay <= 0) || (buffered(&ctlr->ring) <= delay) || inactive(ctlr);
+}
+
static long
audiowrite(Audio *adev, void *vp, long n, vlong)
{
}
p += n;
}
+ while(ratebuf(ctlr) == 0)
+ sleep(&ctlr->vous, ratebuf, ctlr);
return p - (uchar*)vp;
}
static void
-audioclose(Audio *adev)
+audioclose(Audio *adev, int mode)
{
Ctlr *ctlr;
+ if(mode == OREAD)
+ return;
ctlr = adev->ctlr;
sleep(&ctlr->vous, inactive, ctlr);
setempty(ctlr);
/* make a list of audio isa cards if not already done */
if(cards == nil){
for(i=0; i<nelem(irq); i++){
- ctlr = malloc(sizeof(Ctlr));
- memset(ctlr, 0, sizeof(Ctlr));
+ ctlr = mallocz(sizeof(Ctlr), 1);
+ if(ctlr == nil){
+ print("sb16: can't allocate memory\n");
+ break;
+ }
ctlr->conf.port = 0x220 + i*0x10;
ctlr->conf.irq = irq[i];
ctlr->conf.dma = 0;