blob: 87d7b7b65fa1fcfc5f651b89005900a5ae477515 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001Beta release of the rme96xx (driver for RME 96XX cards like the
2"Hammerfall" and the "Hammerfall light")
3
4Important: The driver module has to be installed on a freshly rebooted system,
5otherwise the driver might not be able to acquire its buffers.
6
7features:
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
15The driver uses a specific multichannel interface, which I will document
16when the driver gets stable. (take a look at the defines in rme96xx.h,
17which adds blocked multichannel formats i.e instead of
18lrlrlrlr --> llllrrrr etc.
19
20Use the "rmectrl" programm to look at the status of the card ..
21or use xrmectrl, a GUI interface for the ctrl program.
22
23What you can do with the rmectrl program is to set the stereo device for
24OSS emulation (e.g. if you use SPDIF out).
25
26You do:
27
28./ctrl offset 24 24
29
30which makes the stereo device use channels 25 and 26.
31
32Guenter Geiger <geiger@epy.co.at>
33
34copy the first part of the attached source code into rmectrl.c
35and the second part into xrmectrl (or get the program from
36http://gige.xdv.org/pages/soft/pages/rme)
37
38to 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
62void 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
84int 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"
306set CTRLPROG "./rmectrl"
307if {$argc} {
308 set CTRLPROG "$CTRLPROG $argv"
309}
310puts "CTRLPROG $CTRLPROG"
311
312frame .butts
313button .butts.exit -text "Exit" -command "exit" -relief ridge
314#button .butts.state -text "State" -command "get_all"
315
316pack .butts.exit -side left
317pack .butts -side bottom
318
319
320#
321# STATUS
322#
323
324frame .status
325
326# Sampling Rate
327
328frame .status.sr
329label .status.sr.text -text "Sampling Rate" -justify left
330radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times
331radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times
332radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times
333radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw -variable srate -value 96000 -font times
334
335pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3
336
337# Lock
338
339frame .status.lock
340label .status.lock.text -text "Lock" -justify left
341checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times
342checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times
343checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times
344
345pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3
346
347# Sync
348
349frame .status.sync
350label .status.sync.text -text "Sync" -justify left
351checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times
352checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times
353checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times
354
355pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3
356
357# Timecode
358
359frame .status.tc
360label .status.tc.text -text "Timecode" -justify left
361checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times
362checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times
363checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times
364
365pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3
366
367# SPDIF In
368
369frame .status.spdif
370label .status.spdif.text -text "SPDIF In" -justify left
371label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times
372checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times
373
374pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3
375
376pack .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
383proc setprof {} {
384 global CTRLPROG
385 global spprof
386 exec $CTRLPROG pro $spprof
387}
388
389proc setemph {} {
390 global CTRLPROG
391 global spemph
392 exec $CTRLPROG emphasis $spemph
393}
394
395proc setnoaud {} {
396 global CTRLPROG
397 global spnoaud
398 exec $CTRLPROG dolby $spnoaud
399}
400
401proc setoptical {} {
402 global CTRLPROG
403 global spoptical
404 exec $CTRLPROG optout $spoptical
405}
406
407proc setspdifin {} {
408 global CTRLPROG
409 global spdifin
410 exec $CTRLPROG spdifin [expr $spdifin - 1]
411}
412
413proc setsyncsource {} {
414 global CTRLPROG
415 global syncsource
416 exec $CTRLPROG syncref [expr $syncsource -1]
417}
418
419
420proc setmaster {} {
421 global CTRLPROG
422 global master
423 exec $CTRLPROG master $master
424}
425
426proc setwordclock {} {
427 global CTRLPROG
428 global wordclock
429 exec $CTRLPROG wordclock $wordclock
430}
431
432proc setadat1cd {} {
433 global CTRLPROG
434 global adat1cd
435 exec $CTRLPROG adat1cd $adat1cd
436}
437
438
439frame .control
440
441# SPDIF In & SPDIF Out
442
443
444frame .control.spdif
445
446frame .control.spdif.in
447label .control.spdif.in.text -text "SPDIF In" -justify left
448radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times
449radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times
450radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times
451
452checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times
453
454pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd
455
456label .control.spdif.space
457
458frame .control.spdif.out
459label .control.spdif.out.text -text "SPDIF Out" -justify left
460checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times
461checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times
462checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times
463checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times
464
465pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom
466
467pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1
468
469# Sync Mode & Sync Source
470
471frame .control.sync
472frame .control.sync.mode
473label .control.sync.mode.text -text "Sync Mode" -justify left
474checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times
475checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times
476
477pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc
478
479label .control.sync.space
480
481frame .control.sync.src
482label .control.sync.src.text -text "Sync Source" -justify left
483radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times
484radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times
485radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times
486radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times
487
488pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom
489
490pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1
491
492label .control.space -text "" -width 10
493
494# Buffer Size
495
496frame .control.buf
497label .control.buf.text -text "Buffer Size (Latency)" -justify left
498radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times
499radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times
500radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times
501radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times
502radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times
503radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times
504radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times
505radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times
506
507pack .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
511frame .control.offset
512
513frame .control.offset.in
514label .control.offset.in.text -text "Offset In" -justify left
515label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
516label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
517label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
518label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
519
520pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3
521
522label .control.offset.space
523
524frame .control.offset.out
525label .control.offset.out.text -text "Offset Out" -justify left
526label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
527label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
528label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
529label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
530
531pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom
532
533pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1
534
535
536pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1
537
538
539label .statustext -text Status -justify center -relief ridge
540label .controltext -text Control -justify center -relief ridge
541
542label .statusspace
543label .controlspace
544
545pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1
546
547
548proc get_bit {output sstr} {
549 set idx1 [string last [concat $sstr 1] $output]
550 set idx1 [expr $idx1 != -1]
551 return $idx1
552}
553
554proc 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
560proc 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
566proc 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
594proc 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
703proc 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
756proc get_all {} {
757get_status
758get_control
759get_offset
760}
761
762# main
763while {1} {
764 after 200
765 get_all
766 update
767}