~kris/9p

9hist

1f460dd1a0a3981feb153cc385eab6cce62013a3 — David du Colombier 31 years ago 28e045c
Plan 9 from Bell Labs 1995-02-21
1 files changed, 157 insertions(+), 99 deletions(-)

M port/devaudio.c
M port/devaudio.c => port/devaudio.c +157 -99
@@ 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:;