123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /*
- * Linux and BSD
- */
- #include <sys/ioctl.h>
- #ifdef __linux__
- #include <linux/soundcard.h>
- #else
- #include <sys/soundcard.h>
- #endif
- #include "u.h"
- #include "lib.h"
- #include "dat.h"
- #include "fns.h"
- #include "error.h"
- #include "devaudio.h"
- enum
- {
- Channels = 2,
- Rate = 44100,
- Bits = 16,
- Bigendian = 1,
- };
- static int afd = -1;
- static int cfd= -1;
- static int speed;
- /* maybe this should return -1 instead of sysfatal */
- void
- audiodevopen(void)
- {
- int t;
- ulong ul;
- afd = -1;
- cfd = -1;
- if((afd = open("/dev/dsp", OWRITE)) < 0)
- goto err;
- if((cfd = open("/dev/mixer", ORDWR)) < 0)
- goto err;
-
- t = Bits;
- if(ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &t) < 0)
- goto err;
-
- t = Channels-1;
- if(ioctl(afd, SNDCTL_DSP_STEREO, &t) < 0)
- goto err;
-
- speed = Rate;
- ul = Rate;
- if(ioctl(afd, SNDCTL_DSP_SPEED, &ul) < 0)
- goto err;
- return;
- err:
- if(afd >= 0)
- close(afd);
- afd = -1;
- oserror();
- }
- void
- audiodevclose(void)
- {
- close(afd);
- close(cfd);
- afd = -1;
- cfd = -1;
- }
- static struct {
- int id9;
- int id;
- } names[] = {
- Vaudio, SOUND_MIXER_VOLUME,
- Vbass, SOUND_MIXER_BASS,
- Vtreb, SOUND_MIXER_TREBLE,
- Vline, SOUND_MIXER_LINE,
- Vpcm, SOUND_MIXER_PCM,
- Vsynth, SOUND_MIXER_SYNTH,
- Vcd, SOUND_MIXER_CD,
- Vmic, SOUND_MIXER_MIC,
- // "record", SOUND_MIXER_RECLEV,
- // "mix", SOUND_MIXER_IMIX,
- // "pcm2", SOUND_MIXER_ALTPCM,
- Vspeaker, SOUND_MIXER_SPEAKER
- // "line1", SOUND_MIXER_LINE1,
- // "line2", SOUND_MIXER_LINE2,
- // "line3", SOUND_MIXER_LINE3,
- // "digital1", SOUND_MIXER_DIGITAL1,
- // "digital2", SOUND_MIXER_DIGITAL2,
- // "digital3", SOUND_MIXER_DIGITAL3,
- // "phonein", SOUND_MIXER_PHONEIN,
- // "phoneout", SOUND_MIXER_PHONEOUT,
- // "radio", SOUND_MIXER_RADIO,
- // "video", SOUND_MIXER_VIDEO,
- // "monitor", SOUND_MIXER_MONITOR,
- // "igain", SOUND_MIXER_IGAIN,
- // "ogain", SOUND_MIXER_OGAIN,
- };
- static int
- lookname(int id9)
- {
- int i;
-
- for(i=0; i<nelem(names); i++)
- if(names[i].id9 == id9)
- return names[i].id;
- return -1;
- }
- void
- audiodevsetvol(int what, int left, int right)
- {
- int id;
- ulong x;
- int can, v;
-
- if(cfd < 0)
- error("audio device not open");
- if(what == Vspeed){
- x = left;
- if(ioctl(afd, SNDCTL_DSP_SPEED, &x) < 0)
- oserror();
- speed = x;
- return;
- }
- if((id = lookname(what)) < 0)
- return;
- if(ioctl(cfd, SOUND_MIXER_READ_DEVMASK, &can) < 0)
- can = ~0;
- if(!(can & (1<<id)))
- return;
- v = left | (right<<8);
- if(ioctl(cfd, MIXER_WRITE(id), &v) < 0)
- oserror();
- }
- void
- audiodevgetvol(int what, int *left, int *right)
- {
- int id;
- int can, v;
-
- if(cfd < 0)
- error("audio device not open");
- if(what == Vspeed){
- *left = *right = speed;
- return;
- }
- if((id = lookname(what)) < 0)
- return;
- if(ioctl(cfd, SOUND_MIXER_READ_DEVMASK, &can) < 0)
- can = ~0;
- if(!(can & (1<<id)))
- return;
- if(ioctl(cfd, MIXER_READ(id), &v) < 0)
- oserror();
- *left = v&0xFF;
- *right = (v>>8)&0xFF;
- }
- int
- audiodevwrite(void *v, int n)
- {
- int m, tot;
-
- for(tot=0; tot<n; tot+=m)
- if((m = write(afd, (uchar*)v+tot, n-tot)) <= 0)
- oserror();
- return tot;
- }
- int
- audiodevread(void *v, int n)
- {
- error("no reading");
- return -1;
- }
|