From 1f460dd1a0a3981feb153cc385eab6cce62013a3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 21 Feb 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-02-21 --- port/devaudio.c | 256 +++++++++++++++++++++++++++++------------------- 1 file changed, 157 insertions(+), 99 deletions(-) diff --git a/port/devaudio.c b/port/devaudio.c index bdb546cb31c0252a4221d460d07833f87329c6e8..827dfcd66b26a99d83154f1da886970f007b6898 100644 --- a/port/devaudio.c +++ b/port/devaudio.c @@ -15,7 +15,6 @@ typedef struct AQueue AQueue; typedef struct Buf Buf; -typedef struct Level Level; enum { @@ -24,11 +23,24 @@ enum Qvolume, Fmono = 1, + Fin = 2, + Fout = 4, Aclosed = 0, Aread, Awrite, + Vaudio = 0, + Vsynth, + Vcd, + Vline, + Vmic, + Vspeaker, + Vtreb, + Vbass, + Vspeed, + Nvol, + Speed = 44100, Ncmd = 50, /* max volume command words */ }; @@ -40,19 +52,6 @@ audiodir[] = "volume", {Qvolume}, 0, 0666, }; -struct Level -{ - int master; /* mixer output volume control */ - int ogain; /* extra gain after master */ - int pcm; /* mixer volume on D/A (voice) */ - int synth; /* mixer volume on synthesizer (MIDI) */ - int cd; /* mixer volume on cd */ - int line; /* mixer volume on line */ - int igain; /* mixer volume to A/D */ - int treb; /* treb control */ - int bass; /* bass control */ - int iswitch; /* input on/off switches */ -}; struct Buf { uchar* virt; @@ -74,12 +73,10 @@ static struct int active; /* boolean dma running */ int intr; /* boolean an interrupt has happened */ int amode; /* Aclosed/Aread/Awrite for /audio */ - Level left; /* all of left volumes */ - Level right; /* all of right volumes */ - int mic; /* mono level */ - int speaker; /* mono level */ - int oswitch; /* output on/off switches */ - int speed; /* pcm sample rate, doesnt change w stereo */ + int rivol[Nvol]; /* right/left input/output volumes */ + int livol[Nvol]; + int rovol[Nvol]; + int lovol[Nvol]; int major; /* SB16 major version number (sb 4) */ int minor; /* SB16 minor version number */ @@ -93,31 +90,22 @@ static struct static struct { char* name; - int* ptr1; - int* ptr2; int flag; - int ilval; + int ilval; /* initial values */ int irval; } volumes[] = { - "master", &audio.left.master, &audio.right.master, 0, 50, 50, - "ogain", &audio.left.ogain, &audio.right.ogain, 0, 0, 0, - "igain", &audio.left.igain, &audio.right.igain, 0, 0, 0, - - "treb", &audio.left.treb, &audio.right.treb, 0, 50, 50, - "bass", &audio.left.bass, &audio.right.bass, 0, 50, 50, - - "pcm", &audio.left.pcm, &audio.right.pcm, 0, 90, 90, - "synth", &audio.left.synth, &audio.right.synth, 0, 90, 90, - "cd", &audio.left.cd, &audio.right.cd, 0, 81, 81, - "line", &audio.left.line, &audio.right.line, 0, 65, 65, +[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, - "mic", &audio.mic, &audio.mic, Fmono, 0, 0, - "speaker", &audio.speaker, &audio.speaker, Fmono, 0, 0, - "oswitch", &audio.oswitch, &audio.oswitch, Fmono, 31, 31, - "iswitch", &audio.left.iswitch, &audio.right.iswitch, 0, 85, 43, +[Vtreb] "treb", Fout, 50, 50, +[Vbass] "bass", Fout, 50, 50, - "speed", &audio.speed, &audio.speed, Fmono, Speed, Speed, +[Vspeed] "speed", Fin|Fout|Fmono, Speed, Speed, 0 }; @@ -229,39 +217,68 @@ mxcmdu(int s, int v) static void mxvolume(void) { - ilock(&blaster); - mxcmds(0x30, audio.left.master); - mxcmds(0x31, audio.right.master); - - mxcmdt(0x32, audio.left.pcm); - mxcmdt(0x33, audio.right.pcm); - - mxcmdt(0x34, audio.left.synth); - mxcmdt(0x35, audio.right.synth); - - mxcmdt(0x36, audio.left.cd); - mxcmdt(0x37, audio.right.cd); + int *left, *right; + int source; - mxcmdt(0x38, audio.left.line); - mxcmdt(0x39, audio.right.line); - - mxcmdt(0x3a, audio.mic); - mxcmdt(0x3b, audio.speaker); - - mxcmds(0x3f, audio.left.igain); - mxcmds(0x40, audio.right.igain); - mxcmds(0x41, audio.left.ogain); - mxcmds(0x42, audio.right.ogain); - - mxcmdu(0x44, audio.left.treb); - mxcmdu(0x45, audio.right.treb); + if(audio.amode == Aread){ + left = audio.livol; + right = audio.rivol; + }else{ + left = audio.lovol; + right = audio.rovol; + } - mxcmdu(0x46, audio.left.bass); - mxcmdu(0x47, audio.right.bass); + ilock(&blaster); - mxcmd(0x3c, audio.oswitch); - mxcmd(0x3d, audio.left.iswitch); - mxcmd(0x3e, audio.right.iswitch); + mxcmd(0x30, 255); /* left master */ + mxcmd(0x31, 255); /* right master */ + mxcmd(0x3f, 0); /* left igain */ + mxcmd(0x40, 0); /* right igain */ + mxcmd(0x41, 0); /* left ogain */ + mxcmd(0x42, 0); /* right ogain */ + + mxcmds(0x32, left[Vaudio]); + mxcmds(0x33, right[Vaudio]); + + mxcmds(0x34, left[Vsynth]); + mxcmds(0x35, right[Vsynth]); + + mxcmds(0x36, left[Vcd]); + mxcmds(0x37, right[Vcd]); + + mxcmds(0x38, left[Vline]); + mxcmds(0x39, right[Vline]); + + mxcmds(0x3a, left[Vmic]); + mxcmds(0x3b, left[Vspeaker]); + + mxcmdu(0x44, left[Vtreb]); + mxcmdu(0x45, right[Vtreb]); + + mxcmdu(0x46, left[Vbass]); + mxcmdu(0x47, right[Vbass]); + + source = 0; + if(left[Vsynth]) + source |= 1<<6; + if(right[Vsynth]) + source |= 1<<5; + if(left[Vaudio]) + source |= 1<<4; + if(right[Vaudio]) + source |= 1<<3; + if(left[Vcd]) + source |= 1<<2; + if(right[Vcd]) + source |= 1<<1; + if(left[Vmic]) + source |= 1<<0; + if(audio.amode == Aread) + mxcmd(0x3c, 0); /* output switch */ + else + mxcmd(0x3c, source); + mxcmd(0x3d, source); /* input left switch */ + mxcmd(0x3e, source); /* input right switch */ iunlock(&blaster); } @@ -337,15 +354,19 @@ static void startdma(void) { ulong count; + int speed; ilock(&blaster); dmaend(Dma); - if(audio.amode == Aread) + if(audio.amode == Aread) { sbcmd(0x42); /* input sampling rate */ - else + speed = audio.livol[Vspeed]; + } else { sbcmd(0x41); /* output sampling rate */ - sbcmd(audio.speed>>8); - sbcmd(audio.speed); + speed = audio.lovol[Vspeed]; + } + sbcmd(speed>>8); + sbcmd(speed); count = (Bufsize >> 1) - 1; if(audio.amode == Aread) @@ -479,8 +500,10 @@ resetlevel(void) int i; for(i=0; volumes[i].name; i++) { - *volumes[i].ptr1 = volumes[i].ilval; - *volumes[i].ptr2 = volumes[i].irval; + audio.lovol[i] = volumes[i].ilval; + audio.rovol[i] = volumes[i].irval; + audio.livol[i] = volumes[i].ilval; + audio.rivol[i] = volumes[i].irval; } } @@ -629,6 +652,7 @@ audioopen(Chan *c, int omode) setempty(); audio.curcount = 0; qunlock(&audio); + mxvolume(); break; } c = devopen(c, omode, audiodir, NPORT, devgen); @@ -684,8 +708,9 @@ audioclose(Chan *c) long audioread(Chan *c, char *a, long n, ulong offset) { - long m, o, n0, bn; - char buf[256]; + int liv, riv, lov, rov; + long m, n0; + char buf[300]; Buf *b; int j; @@ -737,18 +762,36 @@ audioread(Chan *c, char *a, long n, ulong offset) case Qvolume: j = 0; - for(m=0; volumes[m].name; m++) { - o = *volumes[m].ptr1; - if(volumes[m].flag & Fmono) - j += snprint(buf+j, sizeof(buf)-j, "%s %d\n", volumes[m].name, o); - else { - bn = *volumes[m].ptr2; - if(o == bn) - j += snprint(buf+j, sizeof(buf)-j, "%s both %d\n", volumes[m].name, o); - else - j += snprint(buf+j, sizeof(buf)-j, "%s left %d right %d\n", - volumes[m].name, o, bn); + buf[0] = 0; + for(m=0; volumes[m].name; m++){ + liv = audio.livol[m]; + riv = audio.rivol[m]; + lov = audio.lovol[m]; + rov = audio.rovol[m]; + 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); @@ -766,7 +809,7 @@ long audiowrite(Chan *c, char *a, long n, ulong offset) { long m, n0; - int i, nf, v, left, right; + int i, nf, v, left, right, in, out; char buf[255], *field[Ncmd]; Buf *b; @@ -779,9 +822,11 @@ audiowrite(Chan *c, char *a, long n, ulong offset) break; case Qvolume: - v = 0; + v = Vaudio; left = 1; right = 1; + in = 1; + out = 1; if(n > sizeof(buf)-1) n = sizeof(buf)-1; memmove(buf, a, n); @@ -794,10 +839,14 @@ audiowrite(Chan *c, char *a, long n, ulong offset) */ if(field[i][0] >= '0' && field[i][0] <= '9') { m = strtoul(field[i], 0, 10); - if(left) - *volumes[v].ptr1 = m; - if(right) - *volumes[v].ptr2 = m; + if(left && out) + audio.lovol[v] = m; + if(left && in) + audio.livol[v] = m; + if(right && out) + audio.rovol[v] = m; + if(right && in) + audio.rivol[v] = m; mxvolume(); goto cont0; } @@ -805,6 +854,10 @@ audiowrite(Chan *c, char *a, long n, ulong offset) for(m=0; volumes[m].name; m++) { if(strcmp(field[i], volumes[m].name) == 0) { v = m; + in = 1; + out = 1; + left = 1; + right = 1; goto cont0; } } @@ -814,6 +867,16 @@ audiowrite(Chan *c, char *a, long n, ulong offset) mxvolume(); goto cont0; } + if(strcmp(field[i], "in") == 0) { + in = 1; + out = 0; + goto cont0; + } + if(strcmp(field[i], "out") == 0) { + in = 0; + out = 1; + goto cont0; + } if(strcmp(field[i], "left") == 0) { left = 1; right = 0; @@ -824,11 +887,6 @@ audiowrite(Chan *c, char *a, long n, ulong offset) right = 1; goto cont0; } - if(strcmp(field[i], "both") == 0) { - left = 1; - right = 1; - goto cont0; - } error(Evolume); break; cont0:;