mirror of https://github.com/0intro/conterm
add audio
This commit is contained in:
parent
b7aa0db730
commit
37ef30916c
|
@ -1 +1,2 @@
|
||||||
|
AUDIO=none
|
||||||
include $(ROOT)/Make.$(CONF)
|
include $(ROOT)/Make.$(CONF)
|
||||||
|
|
|
@ -13,6 +13,8 @@ GUI=x11
|
||||||
LDADD=-L$(X11)/lib -lX11 -ggdb
|
LDADD=-L$(X11)/lib -lX11 -ggdb
|
||||||
LDFLAGS=$(PTHREAD)
|
LDFLAGS=$(PTHREAD)
|
||||||
TARG=drawterm
|
TARG=drawterm
|
||||||
|
# AUDIO=none
|
||||||
|
AUDIO=unix
|
||||||
|
|
||||||
all: default
|
all: default
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ OFILES=\
|
||||||
chan.$O\
|
chan.$O\
|
||||||
data.$O\
|
data.$O\
|
||||||
dev.$O\
|
dev.$O\
|
||||||
|
devaudio.$O\
|
||||||
|
devaudio-$(AUDIO).$O\
|
||||||
devcons.$O\
|
devcons.$O\
|
||||||
devdraw.$O\
|
devdraw.$O\
|
||||||
devfs-$(OS).$O\
|
devfs-$(OS).$O\
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Linux and BSD
|
||||||
|
*/
|
||||||
|
#include "u.h"
|
||||||
|
#include "lib.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "devaudio.h"
|
||||||
|
|
||||||
|
/* maybe this should return -1 instead of sysfatal */
|
||||||
|
void
|
||||||
|
audiodevopen(void)
|
||||||
|
{
|
||||||
|
error("no audio support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
audiodevclose(void)
|
||||||
|
{
|
||||||
|
error("no audio support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
audiodevsetvol(int what, int left, int right)
|
||||||
|
{
|
||||||
|
error("no audio support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
audiodevgetvol(int what, int *left, int *right)
|
||||||
|
{
|
||||||
|
error("no audio support");
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
* 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");
|
||||||
|
}
|
|
@ -0,0 +1,372 @@
|
||||||
|
#include "u.h"
|
||||||
|
#include "lib.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "devaudio.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Qdir = 0,
|
||||||
|
Qaudio,
|
||||||
|
Qvolume,
|
||||||
|
|
||||||
|
Aclosed = 0,
|
||||||
|
Aread,
|
||||||
|
Awrite,
|
||||||
|
|
||||||
|
Speed = 44100,
|
||||||
|
Ncmd = 50, /* max volume command words */
|
||||||
|
};
|
||||||
|
|
||||||
|
Dirtab
|
||||||
|
audiodir[] =
|
||||||
|
{
|
||||||
|
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
|
||||||
|
"audio", {Qaudio}, 0, 0666,
|
||||||
|
"volume", {Qvolume}, 0, 0666,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
QLock lk;
|
||||||
|
Rendez vous;
|
||||||
|
int amode; /* Aclosed/Aread/Awrite for /audio */
|
||||||
|
} audio;
|
||||||
|
|
||||||
|
#define aqlock(a) qlock(&(a)->lk)
|
||||||
|
#define aqunlock(a) qunlock(&(a)->lk)
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
char* name;
|
||||||
|
int flag;
|
||||||
|
int ilval; /* initial values */
|
||||||
|
int irval;
|
||||||
|
} volumes[] =
|
||||||
|
{
|
||||||
|
[Vaudio] "audio", Fout, 50, 50,
|
||||||
|
[Vsynth] "synth", Fin|Fout, 0, 0,
|
||||||
|
[Vcd] "cd", Fin|Fout, 0, 0,
|
||||||
|
[Vline] "line", Fin|Fout, 0, 0,
|
||||||
|
[Vmic] "mic", Fin|Fout|Fmono, 0, 0,
|
||||||
|
[Vspeaker] "speaker", Fout|Fmono, 0, 0,
|
||||||
|
|
||||||
|
[Vtreb] "treb", Fout, 50, 50,
|
||||||
|
[Vbass] "bass", Fout, 50, 50,
|
||||||
|
|
||||||
|
[Vspeed] "speed", Fin|Fout|Fmono, Speed, Speed,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static char Emode[] = "illegal open mode";
|
||||||
|
static char Evolume[] = "illegal volume specifier";
|
||||||
|
|
||||||
|
static void
|
||||||
|
resetlevel(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; volumes[i].name; i++)
|
||||||
|
audiodevsetvol(i, volumes[i].ilval, volumes[i].irval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
audioinit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static Chan*
|
||||||
|
audioattach(char *param)
|
||||||
|
{
|
||||||
|
return devattach('A', param);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Walkqid*
|
||||||
|
audiowalk(Chan *c, Chan *nc, char **name, int nname)
|
||||||
|
{
|
||||||
|
return devwalk(c, nc, name, nname, audiodir, nelem(audiodir), devgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
audiostat(Chan *c, uchar *db, int n)
|
||||||
|
{
|
||||||
|
return devstat(c, db, n, audiodir, nelem(audiodir), devgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Chan*
|
||||||
|
audioopen(Chan *c, int omode)
|
||||||
|
{
|
||||||
|
int amode;
|
||||||
|
|
||||||
|
switch((ulong)c->qid.path) {
|
||||||
|
default:
|
||||||
|
error(Eperm);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qvolume:
|
||||||
|
case Qdir:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qaudio:
|
||||||
|
amode = Awrite;
|
||||||
|
if((omode&7) == OREAD)
|
||||||
|
amode = Aread;
|
||||||
|
aqlock(&audio);
|
||||||
|
if(waserror()){
|
||||||
|
aqunlock(&audio);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
if(audio.amode != Aclosed)
|
||||||
|
error(Einuse);
|
||||||
|
audiodevopen();
|
||||||
|
audio.amode = amode;
|
||||||
|
poperror();
|
||||||
|
aqunlock(&audio);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = devopen(c, omode, audiodir, nelem(audiodir), devgen);
|
||||||
|
c->mode = openmode(omode);
|
||||||
|
c->flag |= COPEN;
|
||||||
|
c->offset = 0;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
audioclose(Chan *c)
|
||||||
|
{
|
||||||
|
switch((ulong)c->qid.path) {
|
||||||
|
default:
|
||||||
|
error(Eperm);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qdir:
|
||||||
|
case Qvolume:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qaudio:
|
||||||
|
if(c->flag & COPEN) {
|
||||||
|
aqlock(&audio);
|
||||||
|
audiodevclose();
|
||||||
|
audio.amode = Aclosed;
|
||||||
|
aqunlock(&audio);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
audioread(Chan *c, void *v, long n, vlong off)
|
||||||
|
{
|
||||||
|
int liv, riv, lov, rov;
|
||||||
|
long m;
|
||||||
|
char buf[300];
|
||||||
|
int j;
|
||||||
|
ulong offset = off;
|
||||||
|
char *a;
|
||||||
|
|
||||||
|
a = v;
|
||||||
|
switch((ulong)c->qid.path) {
|
||||||
|
default:
|
||||||
|
error(Eperm);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qdir:
|
||||||
|
return devdirread(c, a, n, audiodir, nelem(audiodir), devgen);
|
||||||
|
|
||||||
|
case Qaudio:
|
||||||
|
if(audio.amode != Aread)
|
||||||
|
error(Emode);
|
||||||
|
aqlock(&audio);
|
||||||
|
if(waserror()){
|
||||||
|
aqunlock(&audio);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
n = audiodevread(v, n);
|
||||||
|
poperror();
|
||||||
|
aqunlock(&audio);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qvolume:
|
||||||
|
j = 0;
|
||||||
|
buf[0] = 0;
|
||||||
|
for(m=0; volumes[m].name; m++){
|
||||||
|
audiodevgetvol(m, &lov, &rov);
|
||||||
|
liv = lov;
|
||||||
|
riv = rov;
|
||||||
|
j += snprint(buf+j, sizeof(buf)-j, "%s", volumes[m].name);
|
||||||
|
if((volumes[m].flag & Fmono) || (liv==riv && lov==rov)){
|
||||||
|
if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) && liv==lov)
|
||||||
|
j += snprint(buf+j, sizeof(buf)-j, " %d", liv);
|
||||||
|
else{
|
||||||
|
if(volumes[m].flag & Fin)
|
||||||
|
j += snprint(buf+j, sizeof(buf)-j,
|
||||||
|
" in %d", liv);
|
||||||
|
if(volumes[m].flag & Fout)
|
||||||
|
j += snprint(buf+j, sizeof(buf)-j,
|
||||||
|
" out %d", lov);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) &&
|
||||||
|
liv==lov && riv==rov)
|
||||||
|
j += snprint(buf+j, sizeof(buf)-j,
|
||||||
|
" left %d right %d",
|
||||||
|
liv, riv);
|
||||||
|
else{
|
||||||
|
if(volumes[m].flag & Fin)
|
||||||
|
j += snprint(buf+j, sizeof(buf)-j,
|
||||||
|
" in left %d right %d",
|
||||||
|
liv, riv);
|
||||||
|
if(volumes[m].flag & Fout)
|
||||||
|
j += snprint(buf+j, sizeof(buf)-j,
|
||||||
|
" out left %d right %d",
|
||||||
|
lov, rov);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j += snprint(buf+j, sizeof(buf)-j, "\n");
|
||||||
|
}
|
||||||
|
return readstr(offset, a, n, buf);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
audiowrite(Chan *c, void *vp, long n, vlong off)
|
||||||
|
{
|
||||||
|
long m;
|
||||||
|
int i, v, left, right, in, out;
|
||||||
|
Cmdbuf *cb;
|
||||||
|
char *a;
|
||||||
|
|
||||||
|
USED(off);
|
||||||
|
a = vp;
|
||||||
|
switch((ulong)c->qid.path) {
|
||||||
|
default:
|
||||||
|
error(Eperm);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qvolume:
|
||||||
|
v = Vaudio;
|
||||||
|
left = 1;
|
||||||
|
right = 1;
|
||||||
|
in = 1;
|
||||||
|
out = 1;
|
||||||
|
cb = parsecmd(vp, n);
|
||||||
|
if(waserror()){
|
||||||
|
free(cb);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < cb->nf; i++){
|
||||||
|
/*
|
||||||
|
* a number is volume
|
||||||
|
*/
|
||||||
|
if(cb->f[i][0] >= '0' && cb->f[i][0] <= '9') {
|
||||||
|
m = strtoul(cb->f[i], 0, 10);
|
||||||
|
if(!out)
|
||||||
|
goto cont0;
|
||||||
|
if(left && right)
|
||||||
|
audiodevsetvol(v, m, m);
|
||||||
|
else if(left)
|
||||||
|
audiodevsetvol(v, m, -1);
|
||||||
|
else if(right)
|
||||||
|
audiodevsetvol(v, -1, m);
|
||||||
|
goto cont0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(m=0; volumes[m].name; m++) {
|
||||||
|
if(strcmp(cb->f[i], volumes[m].name) == 0) {
|
||||||
|
v = m;
|
||||||
|
in = 1;
|
||||||
|
out = 1;
|
||||||
|
left = 1;
|
||||||
|
right = 1;
|
||||||
|
goto cont0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strcmp(cb->f[i], "reset") == 0) {
|
||||||
|
resetlevel();
|
||||||
|
goto cont0;
|
||||||
|
}
|
||||||
|
if(strcmp(cb->f[i], "in") == 0) {
|
||||||
|
in = 1;
|
||||||
|
out = 0;
|
||||||
|
goto cont0;
|
||||||
|
}
|
||||||
|
if(strcmp(cb->f[i], "out") == 0) {
|
||||||
|
in = 0;
|
||||||
|
out = 1;
|
||||||
|
goto cont0;
|
||||||
|
}
|
||||||
|
if(strcmp(cb->f[i], "left") == 0) {
|
||||||
|
left = 1;
|
||||||
|
right = 0;
|
||||||
|
goto cont0;
|
||||||
|
}
|
||||||
|
if(strcmp(cb->f[i], "right") == 0) {
|
||||||
|
left = 0;
|
||||||
|
right = 1;
|
||||||
|
goto cont0;
|
||||||
|
}
|
||||||
|
error(Evolume);
|
||||||
|
break;
|
||||||
|
cont0:;
|
||||||
|
}
|
||||||
|
free(cb);
|
||||||
|
poperror();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qaudio:
|
||||||
|
if(audio.amode != Awrite)
|
||||||
|
error(Emode);
|
||||||
|
aqlock(&audio);
|
||||||
|
if(waserror()){
|
||||||
|
aqunlock(&audio);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
n = audiodevwrite(vp, n);
|
||||||
|
poperror();
|
||||||
|
aqunlock(&audio);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
audioswab(uchar *a, uint n)
|
||||||
|
{
|
||||||
|
ulong *p, *ep, b;
|
||||||
|
|
||||||
|
p = (ulong*)a;
|
||||||
|
ep = p + (n>>2);
|
||||||
|
while(p < ep) {
|
||||||
|
b = *p;
|
||||||
|
b = (b>>24) | (b<<24) |
|
||||||
|
((b&0xff0000) >> 8) |
|
||||||
|
((b&0x00ff00) << 8);
|
||||||
|
*p++ = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dev audiodevtab = {
|
||||||
|
'A',
|
||||||
|
"audio",
|
||||||
|
|
||||||
|
devreset,
|
||||||
|
audioinit,
|
||||||
|
devshutdown,
|
||||||
|
audioattach,
|
||||||
|
audiowalk,
|
||||||
|
audiostat,
|
||||||
|
audioopen,
|
||||||
|
devcreate,
|
||||||
|
audioclose,
|
||||||
|
audioread,
|
||||||
|
devbread,
|
||||||
|
audiowrite,
|
||||||
|
devbwrite,
|
||||||
|
devremove,
|
||||||
|
devwstat,
|
||||||
|
};
|
|
@ -14,6 +14,7 @@ extern Dev ipdevtab;
|
||||||
extern Dev fsdevtab;
|
extern Dev fsdevtab;
|
||||||
extern Dev mntdevtab;
|
extern Dev mntdevtab;
|
||||||
extern Dev lfddevtab;
|
extern Dev lfddevtab;
|
||||||
|
extern Dev audiodevtab;
|
||||||
|
|
||||||
Dev *devtab[] = {
|
Dev *devtab[] = {
|
||||||
&rootdevtab,
|
&rootdevtab,
|
||||||
|
@ -26,6 +27,7 @@ Dev *devtab[] = {
|
||||||
&fsdevtab,
|
&fsdevtab,
|
||||||
&mntdevtab,
|
&mntdevtab,
|
||||||
&lfddevtab,
|
&lfddevtab,
|
||||||
|
&audiodevtab,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
1
main.c
1
main.c
|
@ -56,6 +56,7 @@ main(int argc, char **argv)
|
||||||
panic("bind #I: %r");
|
panic("bind #I: %r");
|
||||||
if(bind("#U", "/", MAFTER) < 0)
|
if(bind("#U", "/", MAFTER) < 0)
|
||||||
panic("bind #U: %r");
|
panic("bind #U: %r");
|
||||||
|
bind("#A", "/dev", MAFTER);
|
||||||
|
|
||||||
if(open("/dev/cons", OREAD) != 0)
|
if(open("/dev/cons", OREAD) != 0)
|
||||||
panic("open0: %r");
|
panic("open0: %r");
|
||||||
|
|
Loading…
Reference in New Issue