]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/nusb/audio/audio.c
merge
[plan9front.git] / sys / src / cmd / nusb / audio / audio.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "usb.h"
5
6 int audiofreq = 44100;
7 int audiochan = 2;
8 int audiores = 16;
9
10 char validaltc[] = "";
11
12 void
13 parsedescr(Desc *dd)
14 {
15         uchar *b;
16         int i;
17
18         if(dd == nil || dd->iface == nil || dd->altc == nil)
19                 return;
20         b = (uchar*)&dd->data;
21         if(Subclass(dd->iface->csp) != 2 || b[1] != 0x24 || b[2] != 0x02)
22                 return;
23         if(b[4] != audiochan)
24                 return;
25         if(b[6] != audiores)
26                 return;
27         if(b[7] == 0){
28                 int minfreq, maxfreq;
29
30                 minfreq = b[8] | b[9]<<8 | b[10]<<16;
31                 maxfreq = b[11] | b[12]<<8 | b[13]<<16;
32                 if(minfreq > audiofreq || maxfreq < audiofreq)
33                         return;
34         } else {
35                 int freq;
36
37                 for(i=0; i<b[7]; i++){
38                         freq = b[8+3*i] | b[9+3*i]<<8 | b[10+3*i]<<16;
39                         if(freq == audiofreq)
40                                 break;
41                 }
42                 if(i == b[7])
43                         return;
44         }
45         dd->altc->aux = validaltc;
46 }
47
48 void
49 usage(void)
50 {
51         fprint(2, "%s devid\n", argv0);
52         exits("usage");
53 }
54
55 void
56 main(int argc, char *argv[])
57 {
58         Dev *d, *ed;
59         Usbdev *ud;
60         uchar b[4];
61         Altc *a;
62         Ep *e;
63         int i;
64
65         ARGBEGIN {
66         } ARGEND;
67
68         if(argc == 0)
69                 usage();
70
71         if((d = getdev(atoi(*argv))) == nil)
72                 sysfatal("getdev: %r");
73         if(configdev(d) < 0)
74                 sysfatal("configdev: %r");
75
76         ud = d->usb;
77
78         /* parse descriptors, mark valid altc */
79         for(i = 0; i < nelem(ud->ddesc); i++)
80                 parsedescr(ud->ddesc[i]);
81
82         for(i = 0; i < nelem(ud->ep); i++){
83                 e = ud->ep[i];
84                 if(e && e->iface && e->iface->csp == CSP(Claudio, 2, 0) && e->dir == Eout)
85                         goto Foundendp;
86         }
87         sysfatal("no endpoints found");
88         return;
89
90 Foundendp:
91         for(i = 0; i < nelem(e->iface->altc); i++){
92                 a = e->iface->altc[i];
93                 if(a && a->aux == validaltc)
94                         goto Foundaltc;
95         }
96         sysfatal("no altc found");
97
98 Foundaltc:
99         if(usbcmd(d, Rh2d|Rstd|Riface, Rsetiface, i, e->iface->id, nil, 0) < 0)
100                 sysfatal("usbcmd: set altc: %r");
101
102         b[0] = audiofreq;
103         b[1] = audiofreq >> 8;
104         b[2] = audiofreq >> 16;
105         if(usbcmd(d, Rh2d|Rclass|Rep, Rsetcur, 0x100, e->addr, b, 3) < 0)
106                 fprint(2, "warning: set freq: %r");
107
108         if((ed = openep(d, e->id)) == nil)
109                 sysfatal("openep: %r");
110         devctl(ed, "pollival %d", 1);
111         devctl(ed, "samplesz %d", audiochan*audiores/8);
112         devctl(ed, "hz %d", audiofreq);
113
114         /* rename endpoint to #u/audio */
115         devctl(ed, "name audio");
116
117         exits(0);
118 }