8 typedef struct Audio Audio;
17 int audiodelay = 1764; /* 40 ms */
18 int audiofreq = 44100;
22 char user[] = "audio";
36 if(dd == nil || dd->iface == nil || dd->altc == nil)
38 b = (uchar*)&dd->data;
39 if(Subclass(dd->iface->csp) != 2 || b[1] != 0x24 || b[2] != 0x02)
46 ap = (Audio**)&dd->altc->aux;
48 a = mallocz(sizeof(*a), 1);
49 a->minfreq = b[8] | b[9]<<8 | b[10]<<16;
50 a->maxfreq = b[11] | b[12]<<8 | b[13]<<16;
54 for(i=0; i<b[7]; i++){
55 a = mallocz(sizeof(*a), 1);
56 a->minfreq = b[8+3*i] | b[9+3*i]<<8 | b[10+3*i]<<16;
57 a->maxfreq = a->minfreq;
65 setupep(Dev *d, Ep *e, int speed)
72 for(i = 0; i < nelem(e->iface->altc); i++)
73 if(a = e->iface->altc[i])
74 for(x = a->aux; x; x = x->next)
75 if(speed >= x->minfreq && speed <= x->maxfreq)
78 werrstr("no altc found");
82 if(usbcmd(d, Rh2d|Rstd|Riface, Rsetiface, i, e->iface->id, nil, 0) < 0){
83 werrstr("set altc: %r");
90 if(usbcmd(d, Rh2d|Rclass|Rep, Rsetcur, 0x100, e->addr, b, 3) < 0)
91 fprint(2, "warning: set freq: %r\n");
93 if((d = openep(d, e->id)) == nil){
94 werrstr("openep: %r");
97 devctl(d, "pollival %d", a->interval);
98 devctl(d, "samplesz %d", audiochan*audiores/8);
99 devctl(d, "sampledelay %d", audiodelay);
100 devctl(d, "hz %d", speed);
102 devctl(d, "name audioin");
104 devctl(d, "name audio");
113 msg = smprint("master 100 100\nspeed %d\ndelay %d\n", audiofreq, audiodelay);
122 char msg[256], *f[4];
125 snprint(msg, sizeof(msg), "%.*s", r->ifcall.count, r->ifcall.data);
126 nf = tokenize(msg, f, nelem(f));
128 respond(r, "invalid ctl message");
131 if(strcmp(f[0], "speed") == 0){
136 if((d = setupep(audiodev, audioepout, speed)) == nil){
141 if(audioepin != nil && audioepin != audioepout){
142 if(d = setupep(audiodev, audioepin, speed))
146 } else if(strcmp(f[0], "delay") == 0){
147 audiodelay = atoi(f[1]);
151 r->ofcall.count = r->ifcall.count;
163 fprint(2, "%s devid\n", argv0);
168 main(int argc, char *argv[])
187 if((d = getdev(atoi(*argv))) == nil)
188 sysfatal("getdev: %r");
191 /* parse descriptors, mark valid altc */
192 for(i = 0; i < nelem(d->usb->ddesc); i++)
193 parsedescr(d->usb->ddesc[i]);
194 for(i = 0; i < nelem(d->usb->ep); i++){
196 if(e && e->iface && e->iface->csp == CSP(Claudio, 2, 0)){
204 if(audioepout != nil)
209 if(audioepin != nil && audioepout != nil)
213 if(audioepout == nil)
217 if((ed = setupep(audiodev, e, audiofreq)) == nil)
218 sysfatal("setupep: %r");
222 if(audioepout == nil)
223 sysfatal("no endpoints found");
225 fs.tree = alloctree(user, "usb", DMDIR|0555, nil);
226 createfile(fs.tree->root, "volume", user, 0666, nil);
228 snprint(buf, sizeof buf, "%d.audio", audiodev->id);
229 postsharesrv(&fs, nil, "usb", buf);