Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / Documentation / sound / oss / rme96xx
blob87d7b7b65fa1fcfc5f651b89005900a5ae477515
1 Beta release of the rme96xx (driver for RME 96XX cards like the 
2 "Hammerfall" and the "Hammerfall light") 
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.
7 features:
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
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.
20 Use the "rmectrl" programm to look at the status of the card .. 
21 or use xrmectrl, a GUI interface for the ctrl program.
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).
26 You do:
28 ./ctrl offset 24 24
30 which makes the stereo device use channels 25 and 26.
32 Guenter Geiger <geiger@epy.co.at>
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)
38 to compile: gcc -o rmectrl rmectrl.c
39 ------------------------------ snip ------------------------------------
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"
53   remctrl.c
54   (C) 2000 Guenter Geiger <geiger@debian.org>
55   HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
58 /* # define DEVICE_NAME "/dev/mixer" */
59 # define DEVICE_NAME "/dev/mixer1"
62 void usage(void)
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);
84 int main(int argc, char* argv[])
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;
97      if (argc < 2)
98           usage();
100      if (*argv[1]=='/') {
101           device = argv[1];
102           argidx = 2;
103      }
104      else {
105           device = DEVICE_NAME;
106           argidx = 1;
107      }
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      }
115      if ((fdwr = open(device,O_WRONLY)) < 0) {
116           fprintf(stdout,"opening device failed\n");
117           exit(-1);
118      }
120      if (argc < argidx+1)
121           usage();
123      if (!strcmp(argv[argidx],"help"))
124         usage();
125      if (!strcmp(argv[argidx],"-h"))
126         usage();
127      if (!strcmp(argv[argidx],"--help"))
128         usage();
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      }
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      }
172      if (!strcmp(argv[argidx],"mix")) {
173           rme_mixer mix;
174           int i;
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      }
188 /* the control flags */
190      if (argc < argidx+2)
191           usage();
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      }
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      }
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      }
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      }
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      }
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      }
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      }
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      }
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      }
274 /* setting offset */
276      if (argc < argidx+4)
277           usage();
279      if (!strcmp(argv[argidx],"offset")) {
280           rme_mixer mix;
282           mix.devnr = atoi(argv[argidx+1]);
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      }
293      usage();
294      exit (0); /* to avoid warning */
298 ---------------------------- <snip> --------------------------------
299 #!/usr/bin/wish
301 # xrmectrl
302 # (C) 2000 Guenter Geiger <geiger@debian.org>
303 # HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
305 #set defaults "-relief ridged"
306 set CTRLPROG "./rmectrl"
307 if {$argc} {
308     set CTRLPROG "$CTRLPROG $argv"
310 puts "CTRLPROG $CTRLPROG"
312 frame .butts
313 button .butts.exit -text "Exit" -command "exit" -relief ridge
314 #button .butts.state -text "State" -command "get_all"
316 pack .butts.exit -side left
317 pack .butts -side bottom
321 # STATUS
324 frame .status
326 # Sampling Rate
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
335 pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3
337 # Lock
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
345 pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 
347 # Sync
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
355 pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 
357 # Timecode
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
365 pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 
367 # SPDIF In
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
374 pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 
376 pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1
380 # CONTROL 
383 proc setprof {} {
384     global CTRLPROG
385     global spprof
386     exec $CTRLPROG pro $spprof
389 proc setemph {} {
390     global CTRLPROG
391     global spemph
392     exec $CTRLPROG emphasis $spemph
395 proc setnoaud {} {
396     global CTRLPROG
397     global spnoaud
398     exec $CTRLPROG dolby $spnoaud
401 proc setoptical {} {
402     global CTRLPROG
403     global spoptical
404     exec $CTRLPROG optout $spoptical
407 proc setspdifin {} {
408     global CTRLPROG
409     global spdifin
410     exec $CTRLPROG spdifin [expr $spdifin - 1]
413 proc setsyncsource {} {
414     global CTRLPROG
415     global syncsource
416     exec $CTRLPROG syncref [expr $syncsource -1]
420 proc setmaster {} {
421     global CTRLPROG
422     global master
423     exec $CTRLPROG master $master
426 proc setwordclock {} {
427     global CTRLPROG
428     global wordclock
429     exec $CTRLPROG wordclock $wordclock
432 proc setadat1cd {} {
433     global CTRLPROG
434     global adat1cd
435     exec $CTRLPROG adat1cd $adat1cd
439 frame .control
441 # SPDIF In & SPDIF Out
444 frame .control.spdif
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
452 checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times
454 pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd
456 label .control.spdif.space
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
465 pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom
467 pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1
469 # Sync Mode & Sync Source
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
477 pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc
479 label .control.sync.space
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
488 pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom
490 pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1
492 label .control.space -text "" -width 10
494 # Buffer Size
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
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 
509 # Offset
511 frame .control.offset
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
520 pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3
522 label .control.offset.space
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
531 pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom
533 pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1
536 pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1
539 label .statustext -text Status -justify center -relief ridge
540 label .controltext -text Control -justify center -relief ridge
542 label .statusspace
543 label .controlspace
545 pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1
548 proc get_bit {output sstr} {
549     set idx1 [string last [concat $sstr 1] $output]
550     set idx1 [expr $idx1 != -1]
551     return $idx1
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
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
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
578     set f [open "| $CTRLPROG control" r+]
579     set ooo [read $f 1000]
580     close $f
581 #    puts $ooo
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]
594 proc get_status {} {
595     global srate
596     global ctrlcom
598     global adatlock1
599     global adatlock2
600     global adatlock3
602     global adatsync1
603     global adatsync2
604     global adatsync3
606     global tcbusy
607     global tcout
608     global tcvalid
610     global spdiferr
611     global crystal
612     global .status.spdif.text
613     global CTRLPROG
616     set f [open "| $CTRLPROG status" r+]
617     set ooo [read $f 1000]
618     close $f
619 #    puts $ooo
621 # samplerate
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     }
631     if {$idx2 >= 0} {
632         set fact2 2
633     } else {
634         set fact2 1
635     }
636     set srate [expr $fact1 * $fact2]
637 #   ADAT lock
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     }
653 #  ADAT sync
654     set val [get_val $ooo syncmask]
655     set adatsync1 0
656     set adatsync2 0
657     set adatsync3 0
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     }
669 # TC busy
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]
676 #  000=64kHz, 100=88.2kHz, 011=96kHz
677 #  111=32kHz, 110=44.1kHz, 101=48kHz
679     set val [get_val $ooo crystalrate]
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
703 proc get_offset {} {
704     global inoffset
705     global outoffset
706     global CTRLPROG
708     set f [open "| $CTRLPROG mix" r+]
709     set ooo [read $f 1000]
710     close $f
711 #    puts $ooo
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     }
756 proc get_all {} {
757 get_status
758 get_control
759 get_offset
762 # main
763 while {1} {
764   after 200
765   get_all
766   update