summaryrefslogtreecommitdiff
path: root/sys/src/cmd/unix/drawterm/kern/devaudio-unix.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/kern/devaudio-unix.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/kern/devaudio-unix.c')
-rwxr-xr-xsys/src/cmd/unix/drawterm/kern/devaudio-unix.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/kern/devaudio-unix.c b/sys/src/cmd/unix/drawterm/kern/devaudio-unix.c
new file mode 100755
index 000000000..ad5af7458
--- /dev/null
+++ b/sys/src/cmd/unix/drawterm/kern/devaudio-unix.c
@@ -0,0 +1,183 @@
+/*
+ * 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;
+}