[PATCH] v4l: common part Updates and tuner additions
[linux-2.6] / 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 }