⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbaudioctl.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <thread.h>#include "usb.h"#include "usbaudio.h"#include "usbaudioctl.h"int endpt[2] =		{-1, -1};int interface[2] =	{-1, -1};int featureid[2] =	{-1, -1};int selectorid[2] =	{-1, -1};int mixerid[2] =	{-1, -1};int curalt[2] =		{-1, -1};int buttonendpt =	-1;int id;Device *ad;Audiocontrol controls[2][Ncontrol] = {	{	[Speed_control] = {		"speed",	0, {0}, 0,	44100,	Undef},	[Mute_control] = {		"mute",		0, {0}, 0,	0,	Undef},	[Volume_control] = {		"volume",	0, {0}, 0,	0,	Undef},	[Bass_control] = {		"bass",		0, {0}, 0,	0,	Undef},	[Mid_control] = {		"mid",		0, {0}, 0,	0,	Undef},	[Treble_control] = {		"treble",	0, {0}, 0,	0,	Undef},	[Equalizer_control] = {		"equalizer",	0, {0}, 0,	0,	Undef},	[Agc_control] = {		"agc",		0, {0}, 0,	0,	Undef},	[Delay_control] = {		"delay",	0, {0}, 0,	0,	Undef},	[Bassboost_control] = {		"bassboost",	0, {0}, 0,	0,	Undef},	[Loudness_control] = {		"loudness",	0, {0}, 0,	0,	Undef},	[Channel_control] = {		"channels",	0, {0}, 0,	2,	Undef},	[Resolution_control] = {	"resolution",	0, {0}, 0,	16,	Undef},//	[Selector_control] = {		"selector",	0, {0}, 0,	0,	Undef},	}, {	[Speed_control] = {		"speed",	0, {0}, 0,	44100,	Undef},	[Mute_control] = {		"mute",		0, {0}, 0,	0,	Undef},	[Volume_control] = {		"volume",	0, {0}, 0,	0,	Undef},	[Bass_control] = {		"bass",		0, {0}, 0,	0,	Undef},	[Mid_control] = {		"mid",		0, {0}, 0,	0,	Undef},	[Treble_control] = {		"treble",	0, {0}, 0,	0,	Undef},	[Equalizer_control] = {		"equalizer",	0, {0}, 0,	0,	Undef},	[Agc_control] = {		"agc",		0, {0}, 0,	0,	Undef},	[Delay_control] = {		"delay",	0, {0}, 0,	0,	Undef},	[Bassboost_control] = {		"bassboost",	0, {0}, 0,	0,	Undef},	[Loudness_control] = {		"loudness",	0, {0}, 0,	0,	Undef},	[Channel_control] = {		"channels",	0, {0}, 0,	2,	Undef},	[Resolution_control] = {	"resolution",	0, {0}, 0,	16,	Undef},//	[Selector_control] = {		"selector",	0, {0}, 0,	0,	Undef},	}};intsetaudioalt(int rec, Audiocontrol *c, int control){	if (debug & Dbgcontrol)		fprint(2, "setcontrol %s: Set alt %d\n", c->name, control);	curalt[rec] = control;	if (setupcmd(ad->ep[0], RH2D|Rstandard|Rinterface, SET_INTERFACE, control, interface[rec], nil, 0) < 0){		if (debug & Dbgcontrol) fprint(2, "setcontrol: setupcmd %s failed\n", c->name);			return -1;	}	return control;}intfindalt(int rec, int nchan, int res, int speed){	Endpt *ep;	Audioalt *a;	Dalt *da;	int i, j, k, retval;	retval = -1;	controls[rec][Channel_control].min = 1000000;	controls[rec][Channel_control].max = 0;	controls[rec][Channel_control].step = Undef;	controls[rec][Resolution_control].min = 1000000;	controls[rec][Resolution_control].max = 0;	controls[rec][Resolution_control].step = Undef;	for (i = 0; i < Nendpt; i++) {		if ((ep = ad->ep[i]) == nil)			continue;		if(ep->csp != CSP(CL_AUDIO, 2, 0))			continue;		if (ep->iface == nil) {			fprint(2, "\tno interface\n");			return 0;		}		if ((rec == Play && (ep->addr &  0x80))		|| (rec == Record && (ep->addr &  0x80) == 0))			continue;		for (j = 0; j < 16; j++) {			if ((da = ep->iface->dalt[j]) == nil || (a = da->devspec) == nil)				continue;			if (a->nchan < controls[rec][Channel_control].min)				controls[rec][Channel_control].min = a->nchan;			if (a->nchan > controls[rec][Channel_control].max)				controls[rec][Channel_control].max = a->nchan;			if (a->res < controls[rec][Resolution_control].min)				controls[rec][Resolution_control].min = a->res;			if (a->res > controls[rec][Resolution_control].max)				controls[rec][Resolution_control].max = a->res;			controls[rec][Channel_control].settable = 1;			controls[rec][Channel_control].readable = 1;			controls[rec][Resolution_control].settable = 1;			controls[rec][Resolution_control].readable = 1;			controls[rec][Speed_control].settable = 1;			controls[rec][Speed_control].readable = 1;			if (a->nchan == nchan && a->res == res){				if(speed == Undef)					retval = j;				else if(a->caps & (has_discfreq|onefreq)){					for(k = 0; k < nelem(a->freqs); k++){						if(a->freqs[k] == speed){							retval = j;							break;						}					}				} else {					if(speed >= a->minfreq && speed <= a->maxfreq)						retval = j;				}			}		}	}	if ((debug & Dbgcontrol) && retval < 0){		fprint(2, "findalt(%d, %d, %d, %d) failed\n", rec, nchan, res, speed);	}	return retval;}intsetspeed(int rec, int speed){	int ps, n, no, dist, i;	Audioalt *a;	Dalt *da;	Endpt *ep;	char cmdbuf[32];	uchar buf[3];	if (curalt[rec] < 0){		fprint(2, "Must set channels and resolution before speed\n");		return Undef;	}	if (endpt[rec] < 0)		sysfatal("endpt[%s] not set\n", rec?"Record":"Playback");	ep = ad->ep[endpt[rec]];	if (ep->iface == nil)		sysfatal("no interface");	if (curalt[rec] < 0)		sysfatal("curalt[%s] not set\n", rec?"Record":"Playback");	da = ep->iface->dalt[curalt[rec]];	a = da->devspec;	if (a->caps & onefreq){		if (debug & Dbgcontrol)			fprint(2, "setspeed %d: onefreq\n", speed);		speed = a->freqs[0];		/* speed not settable, but packet size must still be set */	}else if (a->caps & has_contfreq){		if (debug & Dbgcontrol)			fprint(2, "setspeed %d: contfreq\n", speed);		if (speed < a->minfreq)			speed = a->minfreq;		else if (speed > a->maxfreq)			speed = a->maxfreq;		if (debug & Dbgcontrol)			fprint(2, "Setting continuously variable %s speed to %d\n",				rec?"record":"playback", speed);	}else if (a->caps & has_discfreq){		if (debug & Dbgcontrol)			fprint(2, "setspeed %d: discfreq\n", speed);		dist = 1000000;		no = -1;		for (i = 0; a->freqs[i] > 0; i++)			if (abs(a->freqs[i] - speed) < dist){				dist = abs(a->freqs[i] - speed);				no = i;			}		if (no == -1){			if (debug & Dbgcontrol)				fprint(2, "no = -1\n");			return Undef;		}		speed = a->freqs[no];		if (debug & Dbgcontrol)			fprint(2, "Setting discreetly variable %s speed to %d\n",				rec?"record":"playback", speed);	}else{		if (debug & Dbgcontrol)			fprint(2, "can't happen\n?");		return Undef;	}	if (a->caps & has_setspeed){		if (debug & Dbgcontrol)			fprint(2, "Setting %s speed to %d Hz;", rec?"record":"playback", speed);		buf[0] = speed;		buf[1] = speed >> 8;		buf[2] = speed >> 16;		if(setupcmd(ad->ep[0], RH2D|Rclass|Rendpt, SET_CUR, sampling_freq_control<<8, endpt[rec], buf, 3) < 0){			fprint(2, "Error in setupcmd\n");			return Undef;		}		if (setupreq(ad->ep[0], RD2H|Rclass|Rendpt, GET_CUR, sampling_freq_control<<8, endpt[rec], 3) < 0){			fprint(2, "Error in setupreq\n");			return Undef;		}		n = setupreply(ad->ep[0], buf, 3);		if (n != 3)			fprint(2, "Error in setupreply: %d\n", n);		else if (buf[2]){			if (debug & Dbgcontrol)				fprint(2, "Speed out of bounds %d (0x%x)\n",					buf[0] | buf[1] << 8 | buf[2] << 16,					buf[0] | buf[1] << 8 | buf[2] << 16);		}else			speed = buf[0] | buf[1] << 8 | buf[2] << 16;		if (debug & Dbgcontrol)			fprint(2, " speed now %d Hz;", speed);	}	ps = ((speed * da->interval + 999) / 1000)		* controls[rec][Channel_control].value[0]		* controls[rec][Resolution_control].value[0]/8;	if(ps > ep->maxpkt){		fprint(2, "packet size %d > maximum packet size %d\n",			ps, ep->maxpkt);		return Undef;	}	if (debug & Dbgcontrol)		fprint(2, "Configuring %s endpoint for %d Hz\n",				rec?"record":"playback", speed);	sprint(cmdbuf, "ep %d %d %c %ld %d", endpt[rec], da->interval, rec?'r':'w', 		controls[rec][Channel_control].value[0]*controls[rec][Resolution_control].value[0]/8,		speed);	if (write(ad->ctl, cmdbuf, strlen(cmdbuf)) != strlen(cmdbuf)){		fprint(2, "writing %s to #U/usb/%d/ctl: %r\n", cmdbuf, id);		return Undef;	}	if (debug & Dbgcontrol) fprint(2, "sent `%s' to /dev/usb/%d/ctl\n", cmdbuf, id);	return speed;}longgetspeed(int rec, int which){	int i, n;	Audioalt *a;	Dalt *da;	Endpt *ep;	uchar buf[3];	if (curalt[rec] < 0){		fprint(2, "Must set channels and resolution before getspeed\n");		return Undef;	}	if (endpt[rec] < 0)		sysfatal("endpt[%s] not set\n", rec?"Record":"Playback");	if(debug & Dbgcontrol)		fprint(2, "getspeed: curalt[%d] == %d\n", rec, endpt[rec]);	ep = ad->ep[endpt[rec]];	if (ep->iface == nil)		sysfatal("no interface");	if (curalt[rec] < 0)		sysfatal("curalt[%s] not set\n", rec?"Record":"Playback");	da = ep->iface->dalt[curalt[rec]];	a = da->devspec;	if (a->caps & onefreq){		if(debug & Dbgcontrol)			fprint(2, "getspeed: onefreq\n");		if (which == GET_RES)			return Undef;		return a->freqs[0];		/* speed not settable */	}	if (a->caps & has_setspeed){		if(debug & Dbgcontrol)			fprint(2, "getspeed: has_setspeed, ask\n");		if (setupreq(ad->ep[0], RD2H|Rclass|Rendpt, which, sampling_freq_control<<8, endpt[rec], 3) < 0)			return Undef;		n = setupreply(ad->ep[0], buf, 3);		if(n == 3){			if(buf[2]){				if (debug & Dbgcontrol)					fprint(2, "Speed out of bounds\n");				if ((a->caps & has_discfreq) && (buf[0] | buf[1] << 8) < 8)					return a->freqs[buf[0] | buf[1] << 8];			}			return buf[0] | buf[1] << 8 | buf[2] << 16;		}		if(debug & Dbgcontrol)			fprint(2, "getspeed: n = %d\n", n);	}	if (a->caps & has_contfreq){		if(debug & Dbgcontrol)			fprint(2, "getspeed: has_contfreq\n");		if (which == GET_CUR)			return controls[rec][Speed_control].value[0];		if (which == GET_MIN)			return a->minfreq;		if (which == GET_MAX)			return a->maxfreq;		if (which == GET_RES)			return 1;	}	if (a->caps & has_discfreq){		if(debug & Dbgcontrol)			fprint(2, "getspeed: has_discfreq\n");		if (which == GET_CUR)			return controls[rec][Speed_control].value[0];		if (which == GET_MIN)			return a->freqs[0];		for (i = 0; i < 8 && a->freqs[i] > 0; i++)			;		if (which == GET_MAX)			return a->freqs[i-1];		if (which == GET_RES)			return Undef;	}	if (debug & Dbgcontrol)		fprint(2, "can't happen\n?");	return Undef;}intsetcontrol(int rec, char *name, long *value){	int i, ctl, m;	byte buf[3];	int type, req, control, index, count;	Audiocontrol *c;	c = nil;	for (ctl = 0; ctl < Ncontrol; ctl++){		c = &controls[rec][ctl];		if (strcmp(name, c->name) == 0)			break;	}	if (ctl == Ncontrol){		if (debug & Dbgcontrol) fprint(2, "setcontrol: control not found\n");		return -1;	}	if (c->settable == 0) {		if (debug & Dbgcontrol) fprint(2, "setcontrol: control %d.%d not settable\n", rec, ctl);		if (c->chans){			for (i = 0; i < 8; i++)				if ((c->chans & 1 << i) && c->value[i] != value[i])

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -