1Beta 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} 768