]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/audiosb16.c
pc/ether*: use 64-bit physical addresses and check pci membar types and sizes
[plan9front.git] / sys / src / 9 / pc / audiosb16.c
index 3f6d8d682bed52732fae9661446d0b6e4c803e10..a38483aed93bdf4a9b6451adca96a8bd6c0236b3 100644 (file)
@@ -28,6 +28,7 @@ enum
        Vigain,
        Vogain,
        Vspeed,
+       Vdelay,
        Nvol,
 
        Blocksize       = 4096,
@@ -67,8 +68,6 @@ struct Ctlr
        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;
 
@@ -94,6 +93,7 @@ static Volume voltab[] = {
        [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,
 };
 
@@ -239,15 +239,21 @@ mxsetvol(Audio *adev, int x, int a[2])
        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]);
@@ -280,12 +286,9 @@ contindma(Ctlr *ctlr)
 
        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 */
@@ -314,7 +317,7 @@ sb16startdma(Ctlr *ctlr)
                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);
 
@@ -380,7 +383,7 @@ ess1688startdma(Ctlr *ctlr)
        /*
         * Set the speed.
         */
-       speed = ctlr->lvol[Vspeed];
+       speed = ctlr->adev->speed;
        if(speed < 4000)
                speed = 4000;
        else if(speed > 48000)
@@ -485,8 +488,6 @@ setempty(Ctlr *ctlr)
        ilock(&ctlr->blaster);
        ctlr->ring.ri = 0;
        ctlr->ring.wi = 0;
-       ctlr->totcount = 0;
-       ctlr->tottime = 0LL;
        iunlock(&ctlr->blaster);
 }
 
@@ -500,19 +501,14 @@ static long
 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;
 }
 
@@ -520,10 +516,17 @@ static int
 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)
 {
@@ -546,14 +549,18 @@ 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);
@@ -678,8 +685,11 @@ audioprobe(Audio *adev)
        /* 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;