rme96xx 24 KB

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