devaudio-unix.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       devaudio-unix.c (3319B)
       ---
            1 /*
            2  * Linux and BSD
            3  */
            4 #include        "u.h"
            5 #include        <sys/ioctl.h>
            6 #ifdef __linux__
            7 #include        <linux/soundcard.h>
            8 #else
            9 #include        <sys/soundcard.h>
           10 #endif
           11 #include        "lib.h"
           12 #include        "mem.h"
           13 #include        "dat.h"
           14 #include        "fns.h"
           15 #include        "error.h"
           16 #include        "devaudio.h"
           17 
           18 enum
           19 {
           20         Channels = 2,
           21         Rate = 44100,
           22         Bits = 16,
           23 };
           24 
           25 typedef struct A A;
           26 struct A
           27 {
           28         int afd;
           29         int cfd;
           30         int speed;
           31 };
           32 
           33 static A a[MaxAudio];
           34 
           35 void
           36 audiodevopen(int dev)
           37 {
           38         int t;
           39         int afd, cfd;
           40         ulong ul;
           41         char adev[40], mixer[40];
           42         
           43         a[dev].afd = -1;
           44         a[dev].cfd = -1;
           45 
           46         if(dev == 0){
           47                 strcpy(adev, "/dev/dsp");
           48                 strcpy(mixer, "/dev/mixer");
           49         }else{
           50                 snprint(adev, sizeof adev, "/dev/dsp%d", dev);
           51                 snprint(mixer, sizeof mixer, "/dev/mixer%d", dev);
           52         }
           53 
           54         afd = -1;
           55         cfd = -1;
           56         if((afd = open(adev, OWRITE)) < 0 || (cfd = open(mixer, ORDWR)) < 0)
           57                 goto err;
           58 
           59         t = Bits;
           60         if(ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &t) < 0)
           61                 goto err;
           62 
           63         t = Channels-1;
           64         if(ioctl(afd, SNDCTL_DSP_STEREO, &t) < 0)
           65                 goto err;
           66         
           67         ul = Rate;
           68         if(ioctl(afd, SNDCTL_DSP_SPEED, &ul) < 0)
           69                 goto err;
           70 
           71         a[dev].afd = afd;
           72         a[dev].cfd = cfd;
           73         a[dev].speed = Rate;
           74         return;
           75 
           76 err:
           77         if(afd >= 0)
           78                 close(afd);
           79         afd = -1;
           80         oserror();
           81 }
           82 
           83 void
           84 audiodevclose(int dev)
           85 {
           86         close(a[dev].afd);
           87         close(a[dev].cfd);
           88         a[dev].afd = -1;
           89         a[dev].cfd = -1;
           90 }
           91 
           92 static struct {
           93         int id9;
           94         int id;
           95 } names[] = {
           96         Vaudio,        SOUND_MIXER_VOLUME,
           97         Vpcm,        SOUND_MIXER_PCM,
           98         Vbass,                 SOUND_MIXER_BASS,
           99         Vtreb,                 SOUND_MIXER_TREBLE,
          100         Vline,                 SOUND_MIXER_LINE,
          101         Vpcm,                 SOUND_MIXER_PCM,
          102         Vsynth,                 SOUND_MIXER_SYNTH,
          103         Vcd,                 SOUND_MIXER_CD,
          104         Vmic,                 SOUND_MIXER_MIC,
          105         Vspeaker,        SOUND_MIXER_SPEAKER
          106 //        "record",                 SOUND_MIXER_RECLEV,
          107 //        "mix",                SOUND_MIXER_IMIX,
          108 //        "pcm2",                SOUND_MIXER_ALTPCM,
          109 //        "line1",                SOUND_MIXER_LINE1,
          110 //        "line2",                SOUND_MIXER_LINE2,
          111 //        "line3",                SOUND_MIXER_LINE3,
          112 //        "digital1",        SOUND_MIXER_DIGITAL1,
          113 //        "digital2",        SOUND_MIXER_DIGITAL2,
          114 //        "digital3",        SOUND_MIXER_DIGITAL3,
          115 //        "phonein",                SOUND_MIXER_PHONEIN,
          116 //        "phoneout",                SOUND_MIXER_PHONEOUT,
          117 //        "radio",                SOUND_MIXER_RADIO,
          118 //        "video",                SOUND_MIXER_VIDEO,
          119 //        "monitor",        SOUND_MIXER_MONITOR,
          120 //        "igain",                SOUND_MIXER_IGAIN,
          121 //        "ogain",                SOUND_MIXER_OGAIN,
          122 };
          123 
          124 static int
          125 lookname(int id9)
          126 {
          127         int i;
          128         
          129         for(i=0; i<nelem(names); i++)
          130                 if(names[i].id9 == id9)
          131                         return names[i].id;
          132         return -1;
          133 }
          134 
          135 void
          136 audiodevsetvol(int dev, int what, int left, int right)
          137 {
          138         int id;
          139         ulong x;
          140         int v;
          141         
          142         if(a[dev].cfd < 0)
          143                 error("audio device not open");
          144         if(what == Vspeed){
          145                 x = left;
          146                 if(ioctl(a[dev].afd, SNDCTL_DSP_SPEED, &x) < 0)
          147                         oserror();
          148                 a[dev].speed = x;
          149                 return;
          150         }
          151         if((id = lookname(what)) < 0)
          152                 error("no such volume");
          153         v = left | (right<<8);
          154         if(ioctl(a[dev].cfd, MIXER_WRITE(id), &v) < 0)
          155                 oserror();
          156 }
          157 
          158 void
          159 audiodevgetvol(int dev, int what, int *left, int *right)
          160 {
          161         int id;
          162         int v;
          163         
          164         if(a[dev].cfd < 0)
          165                 error("audio device not open");
          166         if(what == Vspeed){
          167                 *left = *right = a[dev].speed;
          168                 return;
          169         }
          170         if((id = lookname(what)) < 0)
          171                 error("no such volume");
          172         if(ioctl(a[dev].cfd, MIXER_READ(id), &v) < 0)
          173                 oserror();
          174         *left = v&0xFF;
          175         *right = (v>>8)&0xFF;
          176 }
          177 
          178 int
          179 audiodevwrite(int dev, void *v, int n)
          180 {
          181         int m, tot;
          182         
          183         for(tot=0; tot<n; tot+=m)
          184                 if((m = write(a[dev].afd, (uchar*)v+tot, n-tot)) <= 0)
          185                         oserror();
          186         return tot;
          187 }
          188 
          189 int
          190 audiodevread(int dev, void *v, int n)
          191 {
          192         error("no reading");
          193         return -1;
          194 }