]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - Documentation/sound/oss/rme96xx
Linux-2.6.12-rc2
[mirror_ubuntu-artful-kernel.git] / Documentation / sound / oss / rme96xx
1 Beta release of the rme96xx (driver for RME 96XX cards like the
2 "Hammerfall" and the "Hammerfall light")
3
4 Important: The driver module has to be installed on a freshly rebooted system,
5 otherwise the driver might not be able to acquire its buffers.
6
7 features:
8
9 - OSS programming interface (i.e. runs with standard OSS soundsoftware)
10 - OSS/Multichannel interface (OSS multichannel is done by just aquiring
11 more than 2 channels). The driver does not use more than one device
12 ( yet .. this feature may be implemented later )
13 - more than one RME card supported
14
15 The driver uses a specific multichannel interface, which I will document
16 when the driver gets stable. (take a look at the defines in rme96xx.h,
17 which adds blocked multichannel formats i.e instead of
18 lrlrlrlr --> llllrrrr etc.
19
20 Use the "rmectrl" programm to look at the status of the card ..
21 or use xrmectrl, a GUI interface for the ctrl program.
22
23 What you can do with the rmectrl program is to set the stereo device for
24 OSS emulation (e.g. if you use SPDIF out).
25
26 You do:
27
28 ./ctrl offset 24 24
29
30 which makes the stereo device use channels 25 and 26.
31
32 Guenter Geiger <geiger@epy.co.at>
33
34 copy the first part of the attached source code into rmectrl.c
35 and the second part into xrmectrl (or get the program from
36 http://gige.xdv.org/pages/soft/pages/rme)
37
38 to compile: gcc -o rmectrl rmectrl.c
39 ------------------------------ snip ------------------------------------
40
41 #include <stdio.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <sys/ioctl.h>
45 #include <fcntl.h>
46 #include <linux/soundcard.h>
47 #include <math.h>
48 #include <unistd.h>
49 #include <stdlib.h>
50 #include "rme96xx.h"
51
52 /*
53 remctrl.c
54 (C) 2000 Guenter Geiger <geiger@debian.org>
55 HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
56 */
57
58 /* # define DEVICE_NAME "/dev/mixer" */
59 # define DEVICE_NAME "/dev/mixer1"
60
61
62 void usage(void)
63 {
64 fprintf(stderr,"usage: rmectrl [/dev/mixer<n>] [command [options]]\n\n");
65 fprintf(stderr,"where command is one of:\n");
66 fprintf(stderr," help show this help\n");
67 fprintf(stderr," status show status bits\n");
68 fprintf(stderr," control show control bits\n");
69 fprintf(stderr," mix show mixer/offset status\n");
70 fprintf(stderr," master <n> set sync master\n");
71 fprintf(stderr," pro <n> set spdif out pro\n");
72 fprintf(stderr," emphasis <n> set spdif out emphasis\n");
73 fprintf(stderr," dolby <n> set spdif out no audio\n");
74 fprintf(stderr," optout <n> set spdif out optical\n");
75 fprintf(stderr," wordclock <n> set sync wordclock\n");
76 fprintf(stderr," spdifin <n> set spdif in (0=optical,1=coax,2=intern)\n");
77 fprintf(stderr," syncref <n> set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n");
78 fprintf(stderr," adat1cd <n> set ADAT1 on internal CD\n");
79 fprintf(stderr," offset <devnr> <in> <out> set dev (0..3) offset (0..25)\n");
80 exit(-1);
81 }
82
83
84 int main(int argc, char* argv[])
85 {
86 int cards;
87 int ret;
88 int i;
89 double ft;
90 int fd, fdwr;
91 int param,orig;
92 rme_status_t stat;
93 rme_ctrl_t ctrl;
94 char *device;
95 int argidx;
96
97 if (argc < 2)
98 usage();
99
100 if (*argv[1]=='/') {
101 device = argv[1];
102 argidx = 2;
103 }
104 else {
105 device = DEVICE_NAME;
106 argidx = 1;
107 }
108
109 fprintf(stdout,"mixer device %s\n",device);
110 if ((fd = open(device,O_RDONLY)) < 0) {
111 fprintf(stdout,"opening device failed\n");
112 exit(-1);
113 }
114
115 if ((fdwr = open(device,O_WRONLY)) < 0) {
116 fprintf(stdout,"opening device failed\n");
117 exit(-1);
118 }
119
120 if (argc < argidx+1)
121 usage();
122
123 if (!strcmp(argv[argidx],"help"))
124 usage();
125 if (!strcmp(argv[argidx],"-h"))
126 usage();
127 if (!strcmp(argv[argidx],"--help"))
128 usage();
129
130 if (!strcmp(argv[argidx],"status")) {
131 ioctl(fd,SOUND_MIXER_PRIVATE2,&stat);
132 fprintf(stdout,"stat.irq %d\n",stat.irq);
133 fprintf(stdout,"stat.lockmask %d\n",stat.lockmask);
134 fprintf(stdout,"stat.sr48 %d\n",stat.sr48);
135 fprintf(stdout,"stat.wclock %d\n",stat.wclock);
136 fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint);
137 fprintf(stdout,"stat.syncmask %d\n",stat.syncmask);
138 fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed);
139 fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy);
140 fprintf(stdout,"stat.tc_out %d\n",stat.tc_out);
141 fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate);
142 fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error);
143 fprintf(stdout,"stat.bufid %d\n",stat.bufid);
144 fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid);
145 exit (0);
146 }
147
148 if (!strcmp(argv[argidx],"control")) {
149 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
150 fprintf(stdout,"ctrl.start %d\n",ctrl.start);
151 fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency);
152 fprintf(stdout,"ctrl.master %d\n",ctrl.master);
153 fprintf(stdout,"ctrl.ie %d\n",ctrl.ie);
154 fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48);
155 fprintf(stdout,"ctrl.spare %d\n",ctrl.spare);
156 fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed);
157 fprintf(stdout,"ctrl.pro %d\n",ctrl.pro);
158 fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis);
159 fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby);
160 fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out);
161 fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock);
162 fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in);
163 fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref);
164 fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset);
165 fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select);
166 fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock);
167 fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write);
168 fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd);
169 exit (0);
170 }
171
172 if (!strcmp(argv[argidx],"mix")) {
173 rme_mixer mix;
174 int i;
175
176 for (i=0; i<4; i++) {
177 mix.devnr = i;
178 ioctl(fd,SOUND_MIXER_PRIVATE1,&mix);
179 if (mix.devnr == i) {
180 fprintf(stdout,"devnr %d\n",mix.devnr);
181 fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset);
182 fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset);
183 }
184 }
185 exit (0);
186 }
187
188 /* the control flags */
189
190 if (argc < argidx+2)
191 usage();
192
193 if (!strcmp(argv[argidx],"master")) {
194 int val = atoi(argv[argidx+1]);
195 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
196 printf("master = %d\n",val);
197 ctrl.master = val;
198 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
199 exit (0);
200 }
201
202 if (!strcmp(argv[argidx],"pro")) {
203 int val = atoi(argv[argidx+1]);
204 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
205 printf("pro = %d\n",val);
206 ctrl.pro = val;
207 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
208 exit (0);
209 }
210
211 if (!strcmp(argv[argidx],"emphasis")) {
212 int val = atoi(argv[argidx+1]);
213 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
214 printf("emphasis = %d\n",val);
215 ctrl.emphasis = val;
216 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
217 exit (0);
218 }
219
220 if (!strcmp(argv[argidx],"dolby")) {
221 int val = atoi(argv[argidx+1]);
222 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
223 printf("dolby = %d\n",val);
224 ctrl.dolby = val;
225 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
226 exit (0);
227 }
228
229 if (!strcmp(argv[argidx],"optout")) {
230 int val = atoi(argv[argidx+1]);
231 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
232 printf("optout = %d\n",val);
233 ctrl.opt_out = val;
234 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
235 exit (0);
236 }
237
238 if (!strcmp(argv[argidx],"wordclock")) {
239 int val = atoi(argv[argidx+1]);
240 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
241 printf("wordclock = %d\n",val);
242 ctrl.wordclock = val;
243 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
244 exit (0);
245 }
246
247 if (!strcmp(argv[argidx],"spdifin")) {
248 int val = atoi(argv[argidx+1]);
249 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
250 printf("spdifin = %d\n",val);
251 ctrl.spdif_in = val;
252 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
253 exit (0);
254 }
255
256 if (!strcmp(argv[argidx],"syncref")) {
257 int val = atoi(argv[argidx+1]);
258 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
259 printf("syncref = %d\n",val);
260 ctrl.sync_ref = val;
261 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
262 exit (0);
263 }
264
265 if (!strcmp(argv[argidx],"adat1cd")) {
266 int val = atoi(argv[argidx+1]);
267 ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
268 printf("adat1cd = %d\n",val);
269 ctrl.adat1_cd = val;
270 ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
271 exit (0);
272 }
273
274 /* setting offset */
275
276 if (argc < argidx+4)
277 usage();
278
279 if (!strcmp(argv[argidx],"offset")) {
280 rme_mixer mix;
281
282 mix.devnr = atoi(argv[argidx+1]);
283
284 mix.i_offset = atoi(argv[argidx+2]);
285 mix.o_offset = atoi(argv[argidx+3]);
286 ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix);
287 fprintf(stdout,"devnr %d\n",mix.devnr);
288 fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset);
289 fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset);
290 exit (0);
291 }
292
293 usage();
294 exit (0); /* to avoid warning */
295 }
296
297
298 ---------------------------- <snip> --------------------------------
299 #!/usr/bin/wish
300
301 # xrmectrl
302 # (C) 2000 Guenter Geiger <geiger@debian.org>
303 # HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
304
305 #set defaults "-relief ridged"
306 set CTRLPROG "./rmectrl"
307 if {$argc} {
308 set CTRLPROG "$CTRLPROG $argv"
309 }
310 puts "CTRLPROG $CTRLPROG"
311
312 frame .butts
313 button .butts.exit -text "Exit" -command "exit" -relief ridge
314 #button .butts.state -text "State" -command "get_all"
315
316 pack .butts.exit -side left
317 pack .butts -side bottom
318
319
320 #
321 # STATUS
322 #
323
324 frame .status
325
326 # Sampling Rate
327
328 frame .status.sr
329 label .status.sr.text -text "Sampling Rate" -justify left
330 radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times
331 radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times
332 radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times
333 radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw -variable srate -value 96000 -font times
334
335 pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3
336
337 # Lock
338
339 frame .status.lock
340 label .status.lock.text -text "Lock" -justify left
341 checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times
342 checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times
343 checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times
344
345 pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3
346
347 # Sync
348
349 frame .status.sync
350 label .status.sync.text -text "Sync" -justify left
351 checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times
352 checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times
353 checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times
354
355 pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3
356
357 # Timecode
358
359 frame .status.tc
360 label .status.tc.text -text "Timecode" -justify left
361 checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times
362 checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times
363 checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times
364
365 pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3
366
367 # SPDIF In
368
369 frame .status.spdif
370 label .status.spdif.text -text "SPDIF In" -justify left
371 label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times
372 checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times
373
374 pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3
375
376 pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1
377
378
379 #
380 # CONTROL
381 #
382
383 proc setprof {} {
384 global CTRLPROG
385 global spprof
386 exec $CTRLPROG pro $spprof
387 }
388
389 proc setemph {} {
390 global CTRLPROG
391 global spemph
392 exec $CTRLPROG emphasis $spemph
393 }
394
395 proc setnoaud {} {
396 global CTRLPROG
397 global spnoaud
398 exec $CTRLPROG dolby $spnoaud
399 }
400
401 proc setoptical {} {
402 global CTRLPROG
403 global spoptical
404 exec $CTRLPROG optout $spoptical
405 }
406
407 proc setspdifin {} {
408 global CTRLPROG
409 global spdifin
410 exec $CTRLPROG spdifin [expr $spdifin - 1]
411 }
412
413 proc setsyncsource {} {
414 global CTRLPROG
415 global syncsource
416 exec $CTRLPROG syncref [expr $syncsource -1]
417 }
418
419
420 proc setmaster {} {
421 global CTRLPROG
422 global master
423 exec $CTRLPROG master $master
424 }
425
426 proc setwordclock {} {
427 global CTRLPROG
428 global wordclock
429 exec $CTRLPROG wordclock $wordclock
430 }
431
432 proc setadat1cd {} {
433 global CTRLPROG
434 global adat1cd
435 exec $CTRLPROG adat1cd $adat1cd
436 }
437
438
439 frame .control
440
441 # SPDIF In & SPDIF Out
442
443
444 frame .control.spdif
445
446 frame .control.spdif.in
447 label .control.spdif.in.text -text "SPDIF In" -justify left
448 radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times
449 radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times
450 radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times
451
452 checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times
453
454 pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd
455
456 label .control.spdif.space
457
458 frame .control.spdif.out
459 label .control.spdif.out.text -text "SPDIF Out" -justify left
460 checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times
461 checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times
462 checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times
463 checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times
464
465 pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom
466
467 pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1
468
469 # Sync Mode & Sync Source
470
471 frame .control.sync
472 frame .control.sync.mode
473 label .control.sync.mode.text -text "Sync Mode" -justify left
474 checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times
475 checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times
476
477 pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc
478
479 label .control.sync.space
480
481 frame .control.sync.src
482 label .control.sync.src.text -text "Sync Source" -justify left
483 radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times
484 radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times
485 radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times
486 radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times
487
488 pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom
489
490 pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1
491
492 label .control.space -text "" -width 10
493
494 # Buffer Size
495
496 frame .control.buf
497 label .control.buf.text -text "Buffer Size (Latency)" -justify left
498 radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times
499 radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times
500 radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times
501 radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times
502 radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times
503 radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times
504 radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times
505 radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times
506
507 pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3
508
509 # Offset
510
511 frame .control.offset
512
513 frame .control.offset.in
514 label .control.offset.in.text -text "Offset In" -justify left
515 label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
516 label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
517 label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
518 label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
519
520 pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3
521
522 label .control.offset.space
523
524 frame .control.offset.out
525 label .control.offset.out.text -text "Offset Out" -justify left
526 label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
527 label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
528 label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
529 label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
530
531 pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom
532
533 pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1
534
535
536 pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1
537
538
539 label .statustext -text Status -justify center -relief ridge
540 label .controltext -text Control -justify center -relief ridge
541
542 label .statusspace
543 label .controlspace
544
545 pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1
546
547
548 proc get_bit {output sstr} {
549 set idx1 [string last [concat $sstr 1] $output]
550 set idx1 [expr $idx1 != -1]
551 return $idx1
552 }
553
554 proc get_val {output sstr} {
555 set val [string wordend $output [string last $sstr $output]]
556 set val [string range $output $val [expr $val+1]]
557 return $val
558 }
559
560 proc get_val2 {output sstr} {
561 set val [string wordend $output [string first $sstr $output]]
562 set val [string range $output $val [expr $val+2]]
563 return $val
564 }
565
566 proc get_control {} {
567 global spprof
568 global spemph
569 global spnoaud
570 global spoptical
571 global spdifin
572 global ssrate
573 global master
574 global wordclock
575 global syncsource
576 global CTRLPROG
577
578 set f [open "| $CTRLPROG control" r+]
579 set ooo [read $f 1000]
580 close $f
581 # puts $ooo
582
583 set spprof [ get_bit $ooo "pro"]
584 set spemph [ get_bit $ooo "emphasis"]
585 set spnoaud [ get_bit $ooo "dolby"]
586 set spoptical [ get_bit $ooo "opt_out"]
587 set spdifin [ expr [ get_val $ooo "spdif_in"] + 1]
588 set ssrate [ expr [ get_val $ooo "latency"] + 1]
589 set master [ expr [ get_val $ooo "master"]]
590 set wordclock [ expr [ get_val $ooo "wordclock"]]
591 set syncsource [ expr [ get_val $ooo "sync_ref"] + 1]
592 }
593
594 proc get_status {} {
595 global srate
596 global ctrlcom
597
598 global adatlock1
599 global adatlock2
600 global adatlock3
601
602 global adatsync1
603 global adatsync2
604 global adatsync3
605
606 global tcbusy
607 global tcout
608 global tcvalid
609
610 global spdiferr
611 global crystal
612 global .status.spdif.text
613 global CTRLPROG
614
615
616 set f [open "| $CTRLPROG status" r+]
617 set ooo [read $f 1000]
618 close $f
619 # puts $ooo
620
621 # samplerate
622
623 set idx1 [string last "sr48 1" $ooo]
624 set idx2 [string last "doublespeed 1" $ooo]
625 if {$idx1 >= 0} {
626 set fact1 48000
627 } else {
628 set fact1 44100
629 }
630
631 if {$idx2 >= 0} {
632 set fact2 2
633 } else {
634 set fact2 1
635 }
636 set srate [expr $fact1 * $fact2]
637 # ADAT lock
638
639 set val [get_val $ooo lockmask]
640 set adatlock1 0
641 set adatlock2 0
642 set adatlock3 0
643 if {[expr $val & 1]} {
644 set adatlock3 1
645 }
646 if {[expr $val & 2]} {
647 set adatlock2 1
648 }
649 if {[expr $val & 4]} {
650 set adatlock1 1
651 }
652
653 # ADAT sync
654 set val [get_val $ooo syncmask]
655 set adatsync1 0
656 set adatsync2 0
657 set adatsync3 0
658
659 if {[expr $val & 1]} {
660 set adatsync3 1
661 }
662 if {[expr $val & 2]} {
663 set adatsync2 1
664 }
665 if {[expr $val & 4]} {
666 set adatsync1 1
667 }
668
669 # TC busy
670
671 set tcbusy [get_bit $ooo "busy"]
672 set tcout [get_bit $ooo "out"]
673 set tcvalid [get_bit $ooo "valid"]
674 set spdiferr [expr [get_bit $ooo "spdif_error"] == 0]
675
676 # 000=64kHz, 100=88.2kHz, 011=96kHz
677 # 111=32kHz, 110=44.1kHz, 101=48kHz
678
679 set val [get_val $ooo crystalrate]
680
681 set crystal "--.- kHz"
682 if {$val == 0} {
683 set crystal "64 kHz"
684 }
685 if {$val == 4} {
686 set crystal "88.2 kHz"
687 }
688 if {$val == 3} {
689 set crystal "96 kHz"
690 }
691 if {$val == 7} {
692 set crystal "32 kHz"
693 }
694 if {$val == 6} {
695 set crystal "44.1 kHz"
696 }
697 if {$val == 5} {
698 set crystal "48 kHz"
699 }
700 .status.spdif.sr configure -text $crystal
701 }
702
703 proc get_offset {} {
704 global inoffset
705 global outoffset
706 global CTRLPROG
707
708 set f [open "| $CTRLPROG mix" r+]
709 set ooo [read $f 1000]
710 close $f
711 # puts $ooo
712
713 if { [string match "*devnr*" $ooo] } {
714 set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
715 set val [get_val2 $ooo i_offset]
716 .control.offset.in.off0 configure -text "dev\#0: $val"
717 set val [get_val2 $ooo o_offset]
718 .control.offset.out.off0 configure -text "dev\#0: $val"
719 } else {
720 .control.offset.in.off0 configure -text "dev\#0: -"
721 .control.offset.out.off0 configure -text "dev\#0: -"
722 }
723 if { [string match "*devnr*" $ooo] } {
724 set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
725 set val [get_val2 $ooo i_offset]
726 .control.offset.in.off1 configure -text "dev\#1: $val"
727 set val [get_val2 $ooo o_offset]
728 .control.offset.out.off1 configure -text "dev\#1: $val"
729 } else {
730 .control.offset.in.off1 configure -text "dev\#1: -"
731 .control.offset.out.off1 configure -text "dev\#1: -"
732 }
733 if { [string match "*devnr*" $ooo] } {
734 set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
735 set val [get_val2 $ooo i_offset]
736 .control.offset.in.off2 configure -text "dev\#2: $val"
737 set val [get_val2 $ooo o_offset]
738 .control.offset.out.off2 configure -text "dev\#2: $val"
739 } else {
740 .control.offset.in.off2 configure -text "dev\#2: -"
741 .control.offset.out.off2 configure -text "dev\#2: -"
742 }
743 if { [string match "*devnr*" $ooo] } {
744 set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
745 set val [get_val2 $ooo i_offset]
746 .control.offset.in.off3 configure -text "dev\#3: $val"
747 set val [get_val2 $ooo o_offset]
748 .control.offset.out.off3 configure -text "dev\#3: $val"
749 } else {
750 .control.offset.in.off3 configure -text "dev\#3: -"
751 .control.offset.out.off3 configure -text "dev\#3: -"
752 }
753 }
754
755
756 proc get_all {} {
757 get_status
758 get_control
759 get_offset
760 }
761
762 # main
763 while {1} {
764 after 200
765 get_all
766 update
767 }