vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | 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 }