root/rat/trunk/ui_audiotool.tcl @ 2155

Revision 2155, 82.8 KB (checked in by ucacoxh, 15 years ago)

- Added message response to WM_DESTROY_WINDOW for reception chart and file windows
so that closing window now just hides it. Otherwise participant may click to close window
and thereby destroy it. Further attempts to show/hide window cause error. [oth]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#
2# Copyright (c) 1995-99 University College London
3# All rights reserved.
4#
5# $Revision$
6#
7# Full terms and conditions of the copyright appear below.
8#
9
10wm withdraw .
11
12if {[string compare [info commands registry] "registry"] == 0} {
13        set win32 1
14} else {
15        set win32 0
16        option add *Menu*selectColor            forestgreen
17        option add *Radiobutton*selectColor     forestgreen
18        option add *Checkbutton*selectColor     forestgreen
19        option add *Entry.background            gray70
20}
21
22set statsfont     {helvetica 10}
23set titlefont     {helvetica 10}
24set infofont      {helvetica 10}
25set smallfont     {helvetica  8}
26set verysmallfont {helvetica  8}
27
28option add *Entry.relief       sunken
29option add *borderWidth        1
30option add *highlightThickness 0
31option add *Button*padX        4         
32option add *Button*padY        0         
33option add *font               $infofont
34option add *Menu*tearOff       0
35
36set V(class) "Mbone Applications"
37set V(app)   "rat"
38
39set iht                 16
40set iwd                 250
41set cancel_info_timer   0
42set num_cname           0
43set fw                  .l.t.list.f
44
45proc init_source {cname} {
46        global CNAME NAME EMAIL LOC PHONE TOOL NOTE num_cname
47        global CODEC DURATION PCKTS_RECV PCKTS_LOST PCKTS_MISO PCKTS_DUP JITTER \
48                LOSS_TO_ME LOSS_FROM_ME INDEX JIT_TOGED BUFFER_SIZE PLAYOUT_DELAY
49
50        if {[array names INDEX $cname] != [list $cname]} {
51                # This is a source we've not seen before...
52                set        CNAME($cname) $cname
53                set         NAME($cname) $cname
54                set        EMAIL($cname) ""
55                set        PHONE($cname) ""
56                set          LOC($cname) ""
57                set         TOOL($cname) ""
58                set         NOTE($cname) ""
59                set        CODEC($cname) unknown
60                set     DURATION($cname) ""
61                set  BUFFER_SIZE($cname) 0
62                set PLAYOUT_DELAY($cname) 0
63                set   PCKTS_RECV($cname) 0
64                set   PCKTS_LOST($cname) 0
65                set   PCKTS_MISO($cname) 0
66                set   PCKTS_DUP($cname)  0
67                set       JITTER($cname) 0
68                set    JIT_TOGED($cname) 0
69                set   LOSS_TO_ME($cname) 101
70                set LOSS_FROM_ME($cname) 101
71                set        INDEX($cname) $num_cname
72                incr num_cname
73                chart_enlarge $num_cname 
74                chart_label   $cname
75        }
76}
77
78proc window_plist {cname} {
79        global fw
80        regsub -all {@|\.} $cname {-} foo
81        return $fw.source-$foo
82}
83
84proc window_stats {cname} {
85        regsub -all {[\. ]} $cname {-} foo
86        return .stats$foo
87}
88
89# Commands to send message over the conference bus...
90proc output_mute {state} {
91    mbus_send "R" "audio.output.mute" "$state"
92    if {$state} {
93        .r.c.vol.t1 configure -relief sunken
94        pack forget .r.c.vol.b1 .r.c.vol.s1
95        pack .r.c.vol.ml -side top -fill both -expand 1
96    } else {
97        .r.c.vol.t1 configure -relief raised
98        pack forget .r.c.vol.ml
99        pack .r.c.vol.b1 -side top  -fill x -expand 1
100        pack .r.c.vol.s1 -side top  -fill x -expand 1
101    }
102}
103
104proc input_mute {state} {
105    mbus_send "R" "audio.input.mute" "$state"
106    if {$state} {
107        .r.c.gain.t2 configure -relief sunken
108        pack forget .r.c.gain.b2 .r.c.gain.s2
109        pack .r.c.gain.ml -side top -fill both -expand 1
110    } else {
111        .r.c.gain.t2 configure -relief raised
112        pack forget .r.c.gain.ml
113        pack .r.c.gain.b2 -side top  -fill x -expand 1
114        pack .r.c.gain.s2 -side top  -fill x -expand 1
115    }
116}
117
118proc set_vol {new_vol} {
119    global volume
120    set volume $new_vol
121    mbus_send "R" "audio.output.gain" $volume
122}
123
124proc set_gain {new_gain} {
125    global gain
126    set gain $new_gain
127    mbus_send "R" "audio.input.gain" $gain
128}
129
130proc toggle_input_port {} {
131  global input_port
132       
133  switch $input_port {
134        microphone {set input_port "line_in"}
135        line_in    {set input_port "cd"}
136        cd         {set input_port "microphone"}
137        *          {error "unknown port $input_port"}
138  }
139 
140  mbus_send "R" "audio.input.port" [mbus_encode_str $input_port]
141}
142 
143
144proc toggle_output_port {} {
145  global output_port
146 
147  switch $output_port {
148        speaker   {set output_port "line_out"}
149        line_out  {set output_port "headphone"}
150        headphone {set output_port "speaker"}
151        *         {error "unknown port $output_port"}
152  }
153
154  mbus_send "R" "audio.output.port" [mbus_encode_str $output_port]
155}
156
157proc mbus_heartbeat {} {
158}
159
160#############################################################################################################
161# Reception of Mbus messages...
162
163proc mbus_recv {cmnd args} {
164        # This is not the most efficient way of doing this, since we could call mbus_recv_...
165        # directly from the C code. It does, however, make it explicit which Mbus commands we
166        # understand.
167        switch $cmnd {
168                mbus.waiting                    {eval mbus_recv_mbus.waiting $args}
169                mbus.go                         {eval mbus_recv_mbus.go $args}
170                mbus.hello                      {eval mbus_recv_mbus.hello $args}
171                mbus.quit                       {eval mbus_recv_mbus.quit $args}
172                tool.rat.load.settings          {eval mbus_recv_tool.rat.load.settings $args}
173                tool.rat.sampling.supported     {eval mbus_recv_tool.rat.sampling.supported $args}
174                tool.rat.codec.supported        {eval mbus_recv_tool.rat.codec.supported $args}
175                tool.rat.redundancy.supported   {eval mbus_recv_tool.rat.redundancy.supported $args}
176                tool.rat.converter.supported    {eval mbus_recv_tool.rat.converter.supported $args}
177                tool.rat.repair.supported       {eval mbus_recv_tool.rat.repair.supported $args}
178                tool.rat.agc                    {eval mbus_recv_tool.rat.agc $args}
179                tool.rat.sync                   {eval mbus_recv_tool.rat.sync $args}
180                tool.rat.format.in              {eval mbus_recv_tool.rat.format.in $args}
181                tool.rat.format.out              {eval mbus_recv_tool.rat.format.out $args}
182                tool.rat.codec                  {eval mbus_recv_tool.rat.codec $args}
183                tool.rat.rate                   {eval mbus_recv_tool.rat.rate $args}
184                tool.rat.lecture.mode           {eval mbus_recv_tool.rat.lecture.mode $args}
185                tool.rat.disable.audio.ctls     {eval mbus_recv_tool.rat.disable.audio.ctls $args}
186                tool.rat.enable.audio.ctls      {eval mbus_recv_tool.rat.enable.audio.ctls $args}
187                tool.rat.audio.buffered         {eval mbus_recv_tool.rat.audio.buffered $args}
188                tool.rat.audio.delay            {eval mbus_recv_tool.rat.audio.delay $args}
189                tool.rat.3d.enabled             {eval mbus_recv_tool.rat.3d.enabled $args}
190                tool.rat.3d.azimuth.min         {eval mbus_recv_tool.rat.3d.azimuth.min $args}
191                tool.rat.3d.azimuth.max         {eval mbus_recv_tool.rat.3d.azimuth.max $args}
192                tool.rat.3d.filter.types        {eval mbus_recv_tool.rat.3d.filter.types   $args}
193                tool.rat.3d.filter.lengths      {eval mbus_recv_tool.rat.3d.filter.lengths $args}
194                tool.rat.3d.user.settings       {eval mbus_recv_tool.rat.3d.user.settings  $args}
195                audio.suppress.silence          {eval mbus_recv_audio.suppress.silence $args}
196                audio.channel.coding            {eval mbus_recv_audio.channel.coding $args}
197                audio.channel.repair            {eval mbus_recv_audio.channel.repair $args}
198                audio.input.gain                {eval mbus_recv_audio.input.gain $args}
199                audio.input.port                {eval mbus_recv_audio.input.port $args}
200                audio.input.mute                {eval mbus_recv_audio.input.mute $args}
201                audio.input.powermeter          {eval mbus_recv_audio.input.powermeter $args}
202                audio.output.gain               {eval mbus_recv_audio.output.gain $args}
203                audio.output.port               {eval mbus_recv_audio.output.port $args}
204                audio.output.mute               {eval mbus_recv_audio.output.mute $args}
205                audio.output.powermeter         {eval mbus_recv_audio.output.powermeter $args}
206                audio.file.play.ready           {eval mbus_recv_audio.file.play.ready   $args}
207                audio.file.play.alive           {eval mbus_recv_audio.file.play.alive $args}
208                audio.file.record.ready         {eval mbus_recv_audio.file.record.ready $args}
209                audio.file.record.alive         {eval mbus_recv_audio.file.record.alive $args}
210                audio.devices               {eval mbus_recv_audio_devices $args}
211                audio.device                {eval mbus_recv_audio_device $args}
212                session.title                   {eval mbus_recv_session.title $args}
213                session.address                 {eval mbus_recv_session.address $args}
214                rtp.cname                       {eval mbus_recv_rtp.cname $args}
215                rtp.source.exists               {eval mbus_recv_rtp.source.exists $args}
216                rtp.source.remove               {eval mbus_recv_rtp.source.remove $args}
217                rtp.source.name                 {eval mbus_recv_rtp.source.name $args}
218                rtp.source.email                {eval mbus_recv_rtp.source.email $args}
219                rtp.source.phone                {eval mbus_recv_rtp.source.phone $args}
220                rtp.source.loc                  {eval mbus_recv_rtp.source.loc $args}
221                rtp.source.tool                 {eval mbus_recv_rtp.source.tool $args}
222                rtp.source.note                 {eval mbus_recv_rtp.source.note $args}
223                rtp.source.codec                {eval mbus_recv_rtp.source.codec $args}
224                rtp.source.packet.duration      {eval mbus_recv_rtp.source.packet.duration $args}
225                rtp.source.packet.loss          {eval mbus_recv_rtp.source.packet.loss $args}
226                rtp.source.reception            {eval mbus_recv_rtp.source.reception $args}
227                rtp.source.active               {eval mbus_recv_rtp.source.active $args}
228                rtp.source.inactive             {eval mbus_recv_rtp.source.inactive $args}
229                rtp.source.mute                 {eval mbus_recv_rtp.source.mute $args}
230                security.encryption.key         {eval mbus_recv_security.encryption.key $args}
231                default                         {puts "Unknown mbus command $cmnd"}
232        }
233}
234
235proc mbus_recv_mbus.waiting {condition} {
236        if {$condition == "rat.ui.init"} {
237                mbus_send "U" "mbus.go" [mbus_encode_str rat.ui.init]
238        }
239}
240
241proc mbus_recv_mbus.go {condition} {
242}
243
244proc mbus_recv_mbus.hello {} {
245        # Ignore...
246}
247
248proc mbus_recv_tool.rat.load.settings {} {
249    load_settings
250    check_rtcp_name
251    sync_engine_to_ui
252    chart_show
253    file_show
254    toggle_plist
255}
256
257proc update_channels_displayed {} {
258    global freq channel_support
259
260    set m1 .prefs.pane.audio.dd.sampling.ch_in.mb.m
261    $m1 delete 0 last
262    set m2 .prefs.pane.audio.dd.sampling.ch_out.mb.m
263    $m2 delete 0 last
264   
265    set s [lsearch -glob $channel_support *$freq*]
266   
267    foreach i [lrange [split [lindex $channel_support $s] ","] 1 2] {
268         $m1 add command -label "$i" -command "set ichannels $i; change_sampling"
269         $m2 add command -label "$i" -command "set ochannels $i; change_sampling"
270    }
271}
272
273proc change_sampling { } {
274    global freq ichannels
275
276    update_channels_displayed
277
278    mbus_send "R" "tool.rat.sampling" "[mbus_encode_str $freq] [mbus_encode_str $ichannels]"
279}
280
281proc mbus_recv_tool.rat.sampling.supported {arg} {
282    global freq channel_support
283
284    #clear away old state of channel support
285    if [info exists channel_support] {
286        unset channel_support
287    }
288
289    set freqs [list]
290    set channel_support [list]
291
292    .prefs.pane.audio.dd.sampling.freq.mb.m delete 0 last
293
294    set mode [split $arg]
295    foreach m $mode {
296        lappend channel_support $m
297        set support [split $m ","]
298        set f [lindex $support 0]
299        lappend freqs $f
300        .prefs.pane.audio.dd.sampling.freq.mb.m add command -label $f -command "set freq $f; change_sampling"
301    }
302    set freq [lindex $freqs 0]
303    update_channels_displayed
304}
305
306proc mbus_recv_tool.rat.codec.supported {arg} {
307    # We now have a list of codecs which this RAT supports...
308    global prenc
309
310    .prefs.pane.transmission.dd.pri.m.menu delete 0 last
311
312    set codecs [split $arg]
313    foreach c $codecs {
314        .prefs.pane.transmission.dd.pri.m.menu    add command -label $c -command "set prenc $c; validate_red_codecs"
315    }   
316
317    set prenc [lindex $codecs 0]
318}
319
320proc mbus_recv_tool.rat.redundancy.supported {arg} {
321    global secenc
322
323    .prefs.pane.transmission.cc.red.fc.m.menu delete 0 last
324
325    set codecs [split $arg]
326    foreach c $codecs {
327        .prefs.pane.transmission.cc.red.fc.m.menu add command -label $c -command "set secenc \"$c\""
328    }
329
330    set secenc [lindex $codecs 0]
331}
332
333proc mbus_recv_tool.rat.converter.supported {arg} {
334    global convert_var
335   
336    .prefs.pane.reception.r.ms.menu delete 0 last
337   
338    set converters [split $arg ","]
339    foreach c $converters {
340        .prefs.pane.reception.r.ms.menu add command -label $c -command "set convert_var \"$c\""
341    }
342}
343
344proc mbus_recv_tool.rat.repair.supported {arg} {
345    .prefs.pane.reception.r.m.menu delete 0 last
346   
347    set schemes [split $arg ","]
348    foreach rep $schemes {
349        .prefs.pane.reception.r.m.menu add command -label $rep -command "set repair_var \"$rep\""
350    }
351}
352
353proc mbus_recv_audio_devices {arg} {
354        global audio_device
355       
356        set m .prefs.pane.audio.dd.device.mdev
357        set max_len 0
358       
359        $m.menu delete 0 last
360        set devices [split $arg ","]
361        foreach d $devices {
362                $m.menu add command -label "$d" -command "set audio_device \"$d\""
363                set len [string length "$d"]
364                if [expr $len > $max_len] {
365                        set max_len $len
366                }
367        }
368        $m configure -width $max_len
369}
370
371proc mbus_recv_audio_device {arg} {
372        global audio_device
373
374        set audio_device $arg
375}
376
377proc mbus_recv_tool.rat.agc {arg} {
378  global agc_var
379  set agc_var $arg
380}
381
382proc mbus_recv_tool.rat.sync {arg} {
383  global sync_var
384  set sync_var $arg
385}
386
387proc mbus_recv_security.encryption.key {new_key} {
388        global key_var key
389        set key_var 1
390        set key     $new_key
391}
392
393proc mbus_recv_tool.rat.format.in {arg} {
394    global freq ichannels
395#expect arg to be <sample_type>,<sample rate>,<mono/stereo>
396    set e [split $arg ","]
397   
398    set freq      [lindex $e 1]
399    set ichannels [lindex $e 2]
400    puts "tool.rat.format.in \"$freq\" \"$ichannels\""
401}
402
403proc mbus_recv_tool.rat.format.out {arg} {
404    global freq ochannels
405    set e [split $arg ","]
406   
407    set freq      [lindex $e 1]
408    set ochannels [lindex $e 2]
409    puts "tool.rat.format.out \"$freq\" \"$ochannels\""
410}
411
412proc mbus_recv_tool.rat.codec {arg} {
413  global prenc
414  set prenc $arg
415}
416
417proc mbus_recv_tool.rat.rate {arg} {
418    global upp
419    set upp $arg
420}
421
422proc mbus_recv_audio.channel.coding {channel args} {
423    global channel_var secenc red_off int_units int_gap
424    set channel_var $channel
425    switch $channel {
426        redundant {
427                set secenc  [lindex $args 0]
428                set red_off [lindex $args 1]
429        }
430        interleaved {
431                set int_units [lindex $args 0]
432                set int_gap   [lindex $args 1]
433        }
434    }
435}
436
437proc mbus_recv_audio.channel.repair {arg} {
438  global repair_var
439  set repair_var $arg
440}
441
442proc mbus_recv_audio.input.powermeter {level} {
443        global bargraphTotalHeight
444        bargraphSetHeight .r.c.gain.b2 [expr ($level * $bargraphTotalHeight) / 100]
445}
446
447proc mbus_recv_audio.output.powermeter {level} {
448        global bargraphTotalHeight
449        bargraphSetHeight .r.c.vol.b1  [expr ($level * $bargraphTotalHeight) / 100]
450}
451
452proc mbus_recv_audio.input.gain {new_gain} {
453    global gain
454    set gain $new_gain
455    .r.c.gain.s2 set $gain
456}
457
458proc mbus_recv_audio.input.port {device} {
459        global input_port
460        set input_port $device
461        .r.c.gain.l2 configure -bitmap $device
462        puts "set iport $input_port"
463}
464
465proc mbus_recv_audio.input.mute {val} {
466    global in_mute_var
467    set in_mute_var $val
468    if {$val} {
469        .r.c.gain.t2 configure -relief sunken
470        pack forget .r.c.gain.b2 .r.c.gain.s2
471        pack .r.c.gain.ml -side top -fill both -expand 1
472    } else {
473        .r.c.gain.t2 configure -relief raised
474        pack forget .r.c.gain.ml
475        pack .r.c.gain.b2 -side top  -fill x -expand 1
476        pack .r.c.gain.s2 -side top  -fill x -expand 1
477    }
478}
479
480proc mbus_recv_audio.output.gain {gain} {
481        .r.c.vol.s1 set $gain
482}
483
484proc mbus_recv_audio.output.port {device} {
485        global output_port
486        set output_port $device
487        .r.c.vol.l1 configure -bitmap $device
488}
489
490proc mbus_recv_audio.output.mute {val} {
491    global out_mute_var
492    set out_mute_var $val
493    if {$val} {
494        .r.c.vol.t1 configure -relief sunken
495    } else {
496        .r.c.vol.t1 configure -relief raised
497    }
498}
499
500proc mbus_recv_session.title {title} {
501    global session_title
502    set session_title $title
503    wm title . "RAT: $title"
504}
505
506proc mbus_recv_session.address {addr port ttl} {
507    global session_address
508    set session_address "Address: $addr Port: $port TTL: $ttl"
509}
510
511proc mbus_recv_tool.rat.lecture.mode {mode} {
512        global lecture_var
513        set lecture_var $mode
514}
515
516proc mbus_recv_audio.suppress.silence {mode} {
517        global silence_var
518        set silence_var $mode
519}
520
521proc mbus_recv_rtp.cname {cname} {
522        global my_cname rtcp_name rtcp_email rtcp_phone rtcp_loc num_cname
523
524        set my_cname $cname
525        init_source  $cname
526        cname_update $cname
527}
528
529proc mbus_recv_rtp.source.exists {cname} {
530        init_source $cname
531        chart_label $cname
532        cname_update $cname
533}
534
535proc mbus_recv_rtp.source.name {cname name} {
536        global NAME
537        init_source $cname
538        set NAME($cname) $name
539        chart_label $cname
540        cname_update $cname
541}
542
543proc mbus_recv_rtp.source.email {cname email} {
544        global EMAIL
545        init_source $cname
546        set EMAIL($cname) $email
547}
548
549proc mbus_recv_rtp.source.phone {cname phone} {
550        global PHONE
551        init_source $cname
552        set PHONE($cname) $phone
553}
554
555proc mbus_recv_rtp.source.loc {cname loc} {
556        global LOC
557        init_source $cname
558        set LOC($cname) $loc
559}
560
561proc mbus_recv_rtp.source.tool {cname tool} {
562        global TOOL my_cname
563        init_source $cname
564        set TOOL($cname) $tool
565        if {[string compare $cname $my_cname] == 0} {
566            global tool_name
567            # tool name looks like RAT x.x.x platform ....
568            # lose the platform stuff
569            set tool_frag [split $tool]
570            set tool_name "UCL [lindex $tool_frag 0] [lindex $tool_frag 1]"
571            wm title . ""
572        }
573}
574
575proc mbus_recv_rtp.source.note {cname note} {
576        global NOTE
577        init_source $cname
578        set NOTE($cname) $note
579}
580
581proc mbus_recv_rtp.source.codec {cname codec} {
582        global CODEC
583        init_source $cname
584        set CODEC($cname) $codec
585}
586
587proc mbus_recv_rtp.source.packet.duration {cname packet_duration} {
588        global DURATION
589        init_source $cname
590        set DURATION($cname) $packet_duration
591}
592
593proc mbus_recv_tool.rat.audio.buffered {cname buffered} {
594        global BUFFER_SIZE
595        init_source $cname
596        set BUFFER_SIZE($cname) $buffered 
597# we don't update cname as source.packet.duration always follows
598}
599
600proc mbus_recv_tool.rat.audio.delay {cname len} {
601        global PLAYOUT_DELAY
602        init_source $cname
603        set PLAYOUT_DELAY($cname) $len 
604# we don't update cname as source.packet.duration always follows
605}
606
607proc mbus_recv_tool.rat.3d.enabled {mode} {
608        global 3d_audio_var
609        set 3d_audio_var $mode
610}
611
612proc mbus_recv_tool.rat.3d.azimuth.min {min} {
613    global 3d_azimuth
614    set 3d_azimuth(min) $min
615}
616
617proc mbus_recv_tool.rat.3d.azimuth.max {max} {
618    global 3d_azimuth
619    set 3d_azimuth(max) $max
620}
621
622proc mbus_recv_tool.rat.3d.filter.types {args} {
623    global 3d_filters
624    set 3d_filters [split $args ","]
625}
626
627proc mbus_recv_tool.rat.3d.filter.lengths {args} {
628    global 3d_filter_lengths
629    set 3d_filter_lengths [split $args ","]
630}
631
632proc mbus_recv_tool.rat.3d.user.settings {args} {
633    global filter_type filter_length azimuth
634    set cname                 [lindex $args 0]
635    set filter_type($cname)   [lindex $args 1]
636    set filter_length($cname) [lindex $args 2]
637    set azimuth($cname)       [lindex $args 3]
638}
639
640proc mbus_recv_rtp.source.packet.loss {dest srce loss} {
641        global losstimers my_cname LOSS_FROM_ME LOSS_TO_ME
642        init_source $srce
643        init_source $dest
644        catch {after cancel $losstimers($srce,$dest)}
645        chart_set $srce $dest $loss
646        set losstimers($srce,$dest) [after 7500 chart_set \"$srce\" \"$dest\" 101]
647        if {[string compare $dest $my_cname] == 0} {
648                set LOSS_TO_ME($srce) $loss
649        }
650        if {[string compare $srce $my_cname] == 0} {
651                set LOSS_FROM_ME($dest) $loss
652        }
653        cname_update $srce
654        cname_update $dest
655}
656
657proc mbus_recv_rtp.source.reception {cname packets_recv packets_lost packets_miso packets_dup jitter jit_tog} {
658        global PCKTS_RECV PCKTS_LOST PCKTS_MISO PCKTS_DUP JITTER JIT_TOGED
659        init_source $cname
660        set PCKTS_RECV($cname) $packets_recv
661        set PCKTS_LOST($cname) $packets_lost
662        set PCKTS_MISO($cname) $packets_miso
663        set PCKTS_DUP($cname)  $packets_dup
664        set JITTER($cname) $jitter
665        set JIT_TOGED($cname) $jit_tog
666}
667
668proc mbus_recv_rtp.source.active {cname} {
669    catch [[window_plist $cname] configure -background white]
670    cname_update $cname
671}
672
673proc mbus_recv_rtp.source.inactive {cname} {
674    catch [[window_plist $cname] configure -background grey90]
675    after 60 "catch {[window_plist $cname] configure -background grey88}"
676    after 120 "catch {[window_plist $cname] configure -background [.l.t.list cget -background]}"
677    cname_update $cname
678}
679
680proc mbus_recv_rtp.source.remove {cname} {
681    global CNAME NAME EMAIL LOC PHONE TOOL NOTE CODEC DURATION PCKTS_RECV PCKTS_LOST PCKTS_MISO \
682            PCKTS_DUP JITTER BUFFER_SIZE PLAYOUT_DELAY LOSS_TO_ME LOSS_FROM_ME INDEX JIT_TOGED \
683            num_cname loss_to_me_timer loss_from_me_timer
684
685    # Disable updating of loss diamonds. This has to be done before we destroy the
686    # window representing the participant, else the background update may try to
687    # access a window which has been destroyed...
688    catch {after cancel $loss_to_me_timer($cname)}
689    catch {after cancel $loss_from_me_timer($cname)}
690   
691    catch [destroy [window_plist $cname]]
692   
693    unset CNAME($cname) NAME($cname) EMAIL($cname) PHONE($cname) LOC($cname) TOOL($cname) NOTE($cname)
694    unset CODEC($cname) DURATION($cname) PCKTS_RECV($cname) PCKTS_LOST($cname) PCKTS_MISO($cname) PCKTS_DUP($cname)
695    unset JITTER($cname) LOSS_TO_ME($cname) LOSS_FROM_ME($cname) INDEX($cname) JIT_TOGED($cname) BUFFER_SIZE($cname)
696    unset PLAYOUT_DELAY($cname)
697
698    incr num_cname -1
699    chart_redraw $num_cname
700}
701
702proc mbus_recv_rtp.source.mute {cname val} {
703        global iht
704
705        if {$val} {
706                [window_plist $cname] create line [expr $iht + 2] [expr $iht / 2] 500 [expr $iht / 2] -tags a -width 2.0 -fill gray95
707        } else {
708                catch [[window_plist $cname] delete a]
709        }
710}
711
712proc mbus_recv_audio.file.play.ready {name} {
713        global play_file
714        set    play_file(name) $name
715        file_enable_play
716}
717
718proc mbus_recv_audio.file.play.alive {alive} {
719        global play_file
720       
721        puts "file_play_live"
722        if {$alive} {
723                after 200 file_play_live
724        } else {
725                set play_file(state) end
726                file_enable_play
727        }
728}
729
730proc mbus_recv_audio.file.record.ready {name} {
731        global record_file
732        set    record_file(name) $name
733        file_enable_record
734}
735
736proc mbus_recv_audio.file.record.alive {alive} {
737        global rec_file
738        if {$alive} {
739                after 200 file_rec_live
740        } else {
741                set rec_file(state) end
742                file_enable_record                                         
743        }
744}
745
746proc mbus_recv_mbus.quit {} {
747        save_settings
748        destroy .
749}
750
751#############################################################################################################
752
753proc set_loss_to_me {cname loss} {
754        global prev_loss_to_me loss_to_me_timer
755
756        catch {after cancel $loss_to_me_timer($cname)}
757        set loss_to_me_timer($cname) [after 7500 catch \"[window_plist $cname] itemconfigure h -fill grey\"]
758
759        if {$loss < 5} {
760                catch [[window_plist $cname] itemconfigure m -fill green]
761        } elseif {$loss < 10} {
762                catch [[window_plist $cname] itemconfigure m -fill orange]
763        } elseif {$loss <= 100} {
764                catch [[window_plist $cname] itemconfigure m -fill red]
765        } else {
766                catch [[window_plist $cname] itemconfigure m -fill grey]
767        }
768}
769
770proc set_loss_from_me {cname loss} {
771        global prev_loss_from_me loss_from_me_timer
772
773        catch {after cancel $loss_from_me_timer($cname)}
774        set loss_from_me_timer($cname) [after 7500 catch \"[window_plist $cname] itemconfigure h -fill grey\"]
775
776        if {$loss < 5} {
777                catch [[window_plist $cname] itemconfigure h -fill green]
778        } elseif {$loss < 10} {
779                catch [[window_plist $cname] itemconfigure h -fill orange]
780        } elseif {$loss <= 100} {
781                catch [[window_plist $cname] itemconfigure h -fill red]
782        } else {
783                catch [[window_plist $cname] itemconfigure h -fill grey]
784        }
785}
786
787proc cname_update {cname} {
788        # This procedure updates the on-screen representation of
789        # a participant.
790        global NAME LOSS_TO_ME LOSS_FROM_ME
791        global fw iht iwd my_cname
792
793        set cw [window_plist $cname]
794
795        if {[winfo exists $cw]} {
796                $cw itemconfigure t -text $NAME($cname)
797        } else {
798                # Add this participant to the list...
799                set thick 0
800                set l $thick
801                set h [expr $iht / 2 + $thick]
802                set f [expr $iht + $thick]
803                canvas $cw -width $iwd -height $f -highlightthickness $thick
804                $cw create text [expr $f + 2] $h -anchor w -text $NAME($cname) -fill black -tag t
805                $cw create polygon $l $h $h $l $h $f -outline black -fill grey50 -tag m
806                $cw create polygon $f $h $h $l $h $f -outline black -fill grey50 -tag h
807
808                bind $cw <Button-1>         "toggle_stats \"$cname\""
809                bind $cw <Button-2>         "toggle_mute $cw \"$cname\""
810                bind $cw <Control-Button-1> "toggle_mute $cw \"$cname\""
811
812                if {[info exists my_cname] && ([string compare $cname $my_cname] == 0) && ([pack slaves $fw] != "")} {
813                        pack $cw -before [lindex [pack slaves $fw] 0] -fill x
814                }
815                pack $cw -fill x
816                fix_scrollbar
817        }
818
819        set_loss_to_me $cname $LOSS_TO_ME($cname)
820        set_loss_from_me $cname $LOSS_FROM_ME($cname)
821}
822
823#power meters
824
825# number of elements in the bargraphs...
826set bargraphTotalHeight 24
827set bargraphRedHeight [expr $bargraphTotalHeight * 3 / 4]
828
829proc bargraphCreate {bgraph} {
830        global oh$bgraph bargraphTotalHeight
831
832        frame $bgraph -bg black
833        frame $bgraph.inner0 -width 8 -height 6 -bg green
834        pack $bgraph.inner0 -side left -padx 0 -fill both -expand true
835        for {set i 1} {$i < $bargraphTotalHeight} {incr i} {
836                frame $bgraph.inner$i -width 8 -height 8 -bg black
837                pack $bgraph.inner$i -side left -padx 0 -fill both -expand true
838        }
839        set oh$bgraph 0
840}
841
842proc bargraphSetHeight {bgraph height} {
843        upvar #0 oh$bgraph oh
844        global bargraphTotalHeight bargraphRedHeight
845
846        if {$oh > $height} {
847                for {set i [expr $height + 1]} {$i <= $oh} {incr i} {
848                        $bgraph.inner$i config -bg black
849                }
850        } else {
851                if {$bargraphRedHeight > $height} {
852                        for {set i [expr $oh + 1]} {$i <= $height} {incr i} {
853                                $bgraph.inner$i config -bg green
854                        }
855                } else {
856                        for {set i [expr $oh + 1]} {$i <= $bargraphRedHeight} {incr i} {
857                                $bgraph.inner$i config -bg green
858                        }
859                        for {set i $bargraphRedHeight} {$i <= $height} {incr i} {
860                                $bgraph.inner$i config -bg red
861                        }
862                }
863        }
864        set oh $height
865}
866
867proc toggle {varname} {
868    upvar 1 $varname local
869    set local [expr !$local]
870}
871
872proc toggle_plist {} {
873        global plist_on
874        if {$plist_on} {
875                pack .l.t  -side top -fill both -expand 1
876        } else {
877                pack forget .l.t
878        }
879        update
880        wm deiconify .
881}
882
883proc toggle_mute {cw cname} {
884        global iht
885        if {[$cw gettags a] == ""} {
886                mbus_send "R" "rtp.source.mute" "[mbus_encode_str $cname] 1"
887        } else {
888                mbus_send "R" "rtp.source.mute" "[mbus_encode_str $cname] 0"
889        }
890}
891
892proc fix_scrollbar {} {
893        global iht iwd fw
894
895        set ch [expr $iht * ([llength [pack slaves $fw]] + 2)]
896        set bh [winfo height .l.t.scr]
897        if {$ch > $bh} {set h $ch} else {set h $bh}
898        .l.t.list configure -scrollregion "0.0 0.0 $iwd $h"
899}
900
901proc info_timer {} {
902        global cancel_info_timer
903        if {$cancel_info_timer == 1} {
904                set cancel_info_timer 0
905        } else {
906                update_rec_info
907                after 1000 info_timer
908        }
909}
910
911proc stats_add_field {widget label watchVar} {
912    global statsfont
913    frame $widget -relief sunk
914    label $widget.l -text $label -font $statsfont -anchor w
915    label $widget.w -textvariable $watchVar -font $statsfont
916    pack $widget -side top -fill x -expand 1
917    pack $widget.l -side left  -fill x -expand 1
918    pack $widget.w -side right
919}
920
921set 3d_azimuth(min) 0
922set 3d_azimuth(max) 0
923set 3d_filters        [list "Not Available"]
924set 3d_filter_lengths [list "0"]
925
926proc toggle_stats {cname} {
927    global statsfont
928    set win [window_stats $cname]
929    if {[winfo exists $win]} {
930        destroy $win
931    } else {
932        global stats_pane
933        # Window does not exist so create it
934        toplevel $win 
935        frame $win.mf
936        pack $win.mf -padx 0 -pady 0
937        label $win.mf.l -text "Category:"
938       
939        menubutton $win.mf.mb -menu $win.mf.mb.menu -indicatoron 1 -textvariable stats_pane($win) -relief raised -width 16
940        pack $win.mf.l $win.mf.mb -side left
941        menu $win.mf.mb.menu -tearoff 0
942        $win.mf.mb.menu add command -label "Personal Details" -command "set_pane stats_pane($win) $win.df \"Personal Details\""
943        $win.mf.mb.menu add command -label "Reception"        -command "set_pane stats_pane($win) $win.df Reception"
944        $win.mf.mb.menu add command -label "3D Positioning"   -command "set_pane stats_pane($win) $win.df \"3D Positioning\""
945
946        set stats_pane($win) "Personal Details"
947        frame $win.df
948        frame $win.df.personal
949        pack  $win.df $win.df.personal -fill x
950
951        global NAME EMAIL PHONE LOC NOTE CNAME TOOL
952        stats_add_field $win.df.personal.1 "Name: "     NAME($cname)
953        stats_add_field $win.df.personal.2 "Email: "    EMAIL($cname)
954        stats_add_field $win.df.personal.3 "Phone: "    PHONE($cname)
955        stats_add_field $win.df.personal.4 "Location: " LOC($cname)
956        stats_add_field $win.df.personal.5 "Note: "     NOTE($cname)
957        stats_add_field $win.df.personal.6 "Tool: "     TOOL($cname)
958        stats_add_field $win.df.personal.7 "CNAME: "    CNAME($cname)
959
960        frame $win.df.reception
961        global CODEC DURATION BUFFER_SIZE PLAYOUT_DELAY PCKTS_RECV PCKTS_LOST PCKTS_MISO \
962               PCKTS_DUP LOSS_FROM_ME LOSS_TO_ME JITTER JIT_TOGED
963        stats_add_field $win.df.reception.1 "Audio encoding: "         CODEC($cname)
964        stats_add_field $win.df.reception.2 "Packet duration (ms): "   DURATION($cname)
965        stats_add_field $win.df.reception.3 "Playout delay (ms): "     PLAYOUT_DELAY($cname)
966        stats_add_field $win.df.reception.4 "Buffer length (ms): "     BUFFER_SIZE($cname)
967        stats_add_field $win.df.reception.5 "Arrival jitter (ms): "    JITTER($cname)
968        stats_add_field $win.df.reception.6 "Loss from me (%): "       LOSS_FROM_ME($cname)
969        stats_add_field $win.df.reception.7 "Loss to me (%): "         LOSS_TO_ME($cname)
970        stats_add_field $win.df.reception.8 "Packets received: "       PCKTS_RECV($cname)
971        stats_add_field $win.df.reception.9 "Packets lost: "           PCKTS_LOST($cname)
972        stats_add_field $win.df.reception.a "Packets misordered: "     PCKTS_MISO($cname)
973        stats_add_field $win.df.reception.b "Packets duplicated: "     PCKTS_DUP($cname)
974        stats_add_field $win.df.reception.c "Units dropped (jitter): " JIT_TOGED($cname)
975
976# 3D settings
977        # Trigger engine to send details for this participant
978        mbus_send "R" "tool.rat.3d.user.settings.request" [mbus_encode_str $cname]
979
980        frame $win.df.3d -relief sunk
981        label $win.df.3d.advice -text "These options allow the rendering of the\nparticipant to be altered when 3D\nrendering is enabled."
982        checkbutton $win.df.3d.ext -text "3D Audio Rendering" -variable 3d_audio_var
983        pack $win.df.3d.advice
984        pack $win.df.3d.ext
985
986        frame $win.df.3d.opts
987        pack $win.df.3d.opts -side top
988
989        frame $win.df.3d.opts.filters
990        label $win.df.3d.opts.filters.l -text "Filter Type:"
991        pack $win.df.3d.opts.filters.l -side top -fill x -expand 1 -anchor w
992        global 3d_filters 3d_filter_lengths
993       
994        global filter_type
995        set filter_type($cname) [lindex $3d_filters 0]
996
997        set cnt 0
998        foreach i $3d_filters {
999            radiobutton $win.df.3d.opts.filters.$cnt \
1000                    -value "$i" -variable filter_type($cname) \
1001                    -text "$i"
1002                pack $win.df.3d.opts.filters.$cnt -side top -anchor w
1003            incr cnt
1004        }
1005
1006        frame $win.df.3d.opts.lengths
1007        label $win.df.3d.opts.lengths.l -text "Filter Length:" -width 16
1008        pack $win.df.3d.opts.lengths.l -side top -fill x -expand 1
1009       
1010        global filter_length
1011        set filter_length($cname) [lindex $3d_filter_lengths 0]
1012       
1013        set cnt 0
1014        foreach i $3d_filter_lengths {
1015            radiobutton $win.df.3d.opts.lengths.$cnt \
1016                    -value "$i" -variable filter_length($cname) \
1017                    -text "$i"
1018            pack $win.df.3d.opts.lengths.$cnt -side top -anchor w
1019            incr cnt
1020        }
1021        pack $win.df.3d.opts.filters -side left -expand 1 -anchor n
1022        pack $win.df.3d.opts.lengths -side left -expand 1 -anchor n
1023       
1024        global 3d_azimuth azimuth
1025        scale $win.df.3d.azimuth -from $3d_azimuth(min) -to $3d_azimuth(max) \
1026                -orient horizontal -label "Azimuth" -variable azimuth($cname)
1027        pack  $win.df.3d.azimuth -fill x -expand 1
1028
1029        button $win.df.3d.apply -text "Apply" -command "3d_send_parameters $cname"
1030        pack   $win.df.3d.apply -side bottom  -anchor e -padx 2 -pady 2
1031
1032# Window Magic
1033        frame  $win.dis
1034        button $win.dis.b -text "Dismiss" -command "destroy $win; 3d_delete_parameters $cname"
1035        pack   $win.dis   -side bottom -anchor s -fill x -expand 1
1036        pack   $win.dis.b -side right -anchor e -padx 2 -pady 2
1037        wm title $win "Participant $NAME($cname)"
1038        wm resizable $win 1 0
1039        constrain_window $win 0 250 21 0
1040    }
1041}
1042
1043proc 3d_send_parameters {cname} {
1044    global azimuth filter_type filter_length 3d_audio_var
1045
1046    mbus_send "R" "tool.rat.3d.enabled"   $3d_audio_var
1047    mbus_send "R" "tool.rat.3d.user.settings" "[mbus_encode_str $cname] [mbus_encode_str $filter_type($cname)] $filter_length($cname) $azimuth($cname)"
1048}
1049
1050proc 3d_delete_parameters {cname} {
1051    global filter_type filter_length azimuth
1052   
1053# None of these should ever fail, but you can't be too defensive...
1054    catch {
1055        unset filter_type($cname)
1056        unset filter_length($cname)
1057        unset azimuth($cname)
1058    }
1059}
1060
1061proc do_quit {} {
1062        catch {
1063                profile off pdat
1064                profrep pdat cpu
1065        }
1066        save_settings
1067        destroy .
1068        mbus_send "R" "mbus.quit" ""
1069}
1070
1071# Initialise RAT MAIN window
1072frame .r
1073frame .l
1074frame .l.t -relief sunken
1075scrollbar .l.t.scr -relief flat -highlightthickness 0 -command ".l.t.list yview"
1076canvas .l.t.list -highlightthickness 0 -bd 0 -relief raised -width $iwd -height 160 -yscrollcommand ".l.t.scr set" -yscrollincrement $iht
1077frame .l.t.list.f -highlightthickness 0 -bd 0
1078.l.t.list create window 0 0 -anchor nw -window .l.t.list.f
1079
1080frame .l.f -relief flat
1081label .l.f.title -font $infofont  -textvariable session_title
1082label .l.f.addr  -font $smallfont -textvariable session_address
1083
1084frame  .l.s1 -bd 0
1085label  .l.s1.tool -textvariable tool_name
1086button .l.s1.opts  -text "Options"   -command {wm deiconify .prefs; raise .prefs}
1087button .l.s1.about -text "About"     -command {jiggle_credits; wm deiconify .about}
1088button .l.s1.quit  -text "Quit"      -command do_quit
1089
1090frame .r.c
1091frame .r.c.vol
1092frame .r.c.gain
1093
1094pack .r -side top -fill x
1095pack .r.c -side top -fill x -expand 1
1096pack .r.c.vol  -side top -fill x
1097pack .r.c.gain -side top -fill x
1098
1099pack .l -side top -fill both -expand 1
1100pack .l.f -side top -fill x -padx 2
1101pack .l.f.title .l.f.addr -side top -fill x -pady 2
1102pack .l.s1 -side bottom -fill x
1103pack .l.s1.tool -side left -anchor w
1104pack  .l.s1.quit .l.s1.about .l.s1.opts -side right -anchor w -padx 2 -pady 2
1105pack .l.t  -side top -fill both -expand 1 -padx 2
1106pack .l.t.scr -side left -fill y
1107pack .l.t.list -side left -fill both -expand 1
1108bind .l.t.list <Configure> {fix_scrollbar}
1109
1110# Device output controls
1111set out_mute_var 0
1112button .r.c.vol.t1 -highlightthickness 0 -pady 0 -padx 0 -text mute -command {toggle out_mute_var; output_mute $out_mute_var}
1113set output_port "speaker"
1114button .r.c.vol.l1 -pady 0 -padx 0 -highlightthickness 0 -command toggle_output_port
1115bargraphCreate .r.c.vol.b1
1116scale .r.c.vol.s1 -highlightthickness 0 -from 0 -to 99 -command set_vol -orient horizontal -relief raised -showvalue false -width 10 -variable volume
1117label .r.c.vol.ml -text "Reception is muted" -relief sunken
1118
1119pack .r.c.vol.l1 -side left -fill y
1120pack .r.c.vol.t1 -side left -fill y
1121pack .r.c.vol.b1 -side top  -fill x -expand 1
1122pack .r.c.vol.s1 -side top  -fill x -expand 1
1123
1124# Device input controls
1125set in_mute_var 1
1126button .r.c.gain.t2 -highlightthickness 0 -pady 0 -padx 0 -text mute -command {toggle in_mute_var; input_mute $in_mute_var}
1127set input_port "microphone"
1128button .r.c.gain.l2 -highlightthickness 0 -command toggle_input_port
1129bargraphCreate .r.c.gain.b2
1130scale .r.c.gain.s2 -highlightthickness 0 -from 0 -to 99 -command set_gain -orient horizontal -relief raised -showvalue false -width 10 -variable gain
1131label .r.c.gain.ml -text "Transmission is muted" -relief sunken
1132
1133pack .r.c.gain.l2 -side left -fill y
1134pack .r.c.gain.t2 -side left -fill y
1135pack .r.c.gain.ml -side top  -fill both -expand 1
1136
1137proc mbus_recv_tool.rat.disable.audio.ctls {} {
1138        .r.c.vol.t1 configure -state disabled
1139        .r.c.vol.l1 configure -state disabled
1140        .r.c.vol.s1 configure -state disabled
1141        .r.c.gain.t2 configure -state disabled
1142        .r.c.gain.l2 configure -state disabled
1143        .r.c.gain.s2 configure -state disabled
1144}
1145
1146proc mbus_recv_tool.rat.enable.audio.ctls {} {
1147        .r.c.vol.t1 configure -state normal
1148        .r.c.vol.l1 configure -state normal
1149        .r.c.vol.s1 configure -state normal
1150        .r.c.gain.t2 configure -state normal
1151        .r.c.gain.l2 configure -state normal
1152        .r.c.gain.s2 configure -state normal
1153}
1154bind all <ButtonPress-3>   {toggle in_mute_var; input_mute $in_mute_var}
1155bind all <ButtonRelease-3> {toggle in_mute_var; input_mute $in_mute_var}
1156bind all <q>               "do_quit"
1157
1158# Override default tk behaviour
1159wm protocol . WM_DELETE_WINDOW do_quit
1160
1161if {$win32 == 0} {
1162        wm iconbitmap . rat_small
1163}
1164wm resizable . 0 1
1165if ([info exists geometry]) {
1166        wm geometry . $geometry
1167}
1168
1169proc constrain_window {win maxstr xpad ylines ypad} {
1170    set fn [.prefs.buttons.apply cget -font]
1171    set w  [expr [font measure $fn $maxstr] + $xpad]
1172    set h  [expr $ylines * [font metrics $fn -linespace] + $ypad]
1173    wm geometry $win [format "%sx%s" $w $h]
1174}
1175
1176proc tk_optionCmdMenu {w varName firstValue args} {
1177    upvar #0 $varName var
1178 
1179    if ![info exists var] {
1180        set var $firstValue
1181    }
1182    menubutton $w -textvariable $varName -indicatoron 1 -menu $w.menu \
1183            -relief raised -bd 2 -highlightthickness 2 -anchor c
1184
1185    menu $w.menu -tearoff 0
1186    $w.menu add command -label $firstValue -command "set $varName \"$firstValue\""
1187    foreach i $args {
1188        $w.menu add command -label $i -command "set $varName \"$i\""
1189    }
1190    return $w.menu
1191}
1192
1193
1194###############################################################################
1195# Preferences Panel
1196#
1197
1198set prefs_pane "Personal"
1199toplevel .prefs
1200wm title .prefs "Preferences"
1201wm resizable .prefs 0 0
1202wm withdraw  .prefs
1203
1204frame .prefs.m
1205pack .prefs.m -side top -fill x -expand 0 -padx 2 -pady 2
1206frame .prefs.m.f
1207pack .prefs.m.f -padx 0 -pady 0
1208label .prefs.m.f.t -text "Category: "
1209pack .prefs.m.f.t -pady 2 -side left
1210menubutton .prefs.m.f.m -menu .prefs.m.f.m.menu -indicatoron 1 -textvariable prefs_pane -relief raised -width 14
1211pack .prefs.m.f.m -side top
1212menu .prefs.m.f.m.menu -tearoff 0
1213.prefs.m.f.m.menu add command -label "Personal"     -command {set_pane prefs_pane .prefs.pane "Personal"}
1214.prefs.m.f.m.menu add command -label "Transmission" -command {set_pane prefs_pane .prefs.pane "Transmission"}
1215.prefs.m.f.m.menu add command -label "Reception"    -command {set_pane prefs_pane .prefs.pane "Reception"}
1216.prefs.m.f.m.menu add command -label "Audio"        -command {set_pane prefs_pane .prefs.pane "Audio"}
1217.prefs.m.f.m.menu add command -label "Security"     -command {set_pane prefs_pane .prefs.pane "Security"}
1218.prefs.m.f.m.menu add command -label "Interface"    -command {set_pane prefs_pane .prefs.pane "Interface"}
1219
1220frame  .prefs.buttons
1221pack   .prefs.buttons       -side bottom -fill x
1222button .prefs.buttons.bye   -text "Cancel" -command {sync_ui_to_engine; wm withdraw .prefs}
1223button .prefs.buttons.apply -text "Apply" -command {wm withdraw .prefs; sync_engine_to_ui}
1224button .prefs.buttons.save  -text "Save & Apply" -command {save_settings; wm withdraw .prefs; sync_engine_to_ui}
1225pack   .prefs.buttons.bye .prefs.buttons.apply .prefs.buttons.save -side right -padx 2 -pady 2
1226
1227frame .prefs.pane -relief sunken
1228pack  .prefs.pane -side left -fill both -expand 1 -padx 4 -pady 2
1229
1230# setup width of prefs panel
1231constrain_window .prefs "XXXXXXXX48-kHzXXXStereoXXXLinear-16XXXUnitsXPerXPcktXXXXXXX" 0 12 128
1232
1233# Personal Info Pane
1234set i .prefs.pane.personal
1235frame $i
1236pack $i -fill both -expand 1 -pady 2 -padx 2
1237
1238frame $i.a -relief sunken
1239frame $i.a.f
1240pack $i.a -side top -fill both -expand 1
1241pack $i.a.f -side left -fill x -expand 1
1242
1243frame $i.a.f.f
1244pack $i.a.f.f
1245
1246label $i.a.f.f.l -width 40 -height 2 -text "The personal details below are conveyed\nto the other conference participants." -justify left -anchor w
1247pack $i.a.f.f.l -side top -anchor w -fill x
1248
1249frame $i.a.f.f.lbls
1250frame $i.a.f.f.ents
1251pack  $i.a.f.f.lbls -side left -fill y
1252pack  $i.a.f.f.ents -side right
1253
1254label $i.a.f.f.lbls.name  -text "Name:"     -anchor w
1255label $i.a.f.f.lbls.email -text "Email:"    -anchor w
1256label $i.a.f.f.lbls.phone -text "Phone:"    -anchor w
1257label $i.a.f.f.lbls.loc   -text "Location:" -anchor w
1258pack $i.a.f.f.lbls.name $i.a.f.f.lbls.email $i.a.f.f.lbls.phone $i.a.f.f.lbls.loc -fill x -anchor w -side top
1259
1260entry $i.a.f.f.ents.name  -width 28 -highlightthickness 0 -textvariable rtcp_name
1261entry $i.a.f.f.ents.email -width 28 -highlightthickness 0 -textvariable rtcp_email
1262entry $i.a.f.f.ents.phone -width 28 -highlightthickness 0 -textvariable rtcp_phone
1263entry $i.a.f.f.ents.loc   -width 28 -highlightthickness 0 -textvariable rtcp_loc
1264pack $i.a.f.f.ents.name $i.a.f.f.ents.email $i.a.f.f.ents.phone $i.a.f.f.ents.loc -anchor n -expand 0
1265
1266# Transmission Pane ###########################################################
1267set i .prefs.pane.transmission
1268frame $i 
1269frame $i.dd  -relief sunken
1270frame $i.cc  -relief sunken
1271frame $i.cc.van
1272frame $i.cc.red
1273frame $i.cc.int
1274
1275pack $i.dd -fill x
1276pack $i.cc $i.cc.van $i.cc.red -fill x -anchor w -pady 1
1277pack $i.cc.int -fill x -anchor w -pady 0
1278frame $i.dd.units
1279frame $i.dd.pri
1280
1281pack $i.dd.units $i.dd.pri -side right -fill x
1282
1283label $i.dd.pri.l -text "Encoding:"
1284menubutton $i.dd.pri.m -menu $i.dd.pri.m.menu -indicatoron 1 -textvariable prenc -relief raised -width 13
1285pack $i.dd.pri.l $i.dd.pri.m -side top
1286# fill in codecs
1287menu $i.dd.pri.m.menu -tearoff 0
1288
1289label $i.dd.units.l -text "Units:"
1290tk_optionCmdMenu $i.dd.units.m upp 1 2 4 8
1291$i.dd.units.m configure -width 13 -highlightthickness 0 -bd 1
1292pack $i.dd.units.l $i.dd.units.m -side top -fill x
1293
1294radiobutton $i.cc.van.rb -text "No Loss Protection" -justify right -value none        -variable channel_var
1295radiobutton $i.cc.red.rb -text "Redundancy"         -justify right -value redundant   -variable channel_var
1296radiobutton $i.cc.int.rb -text "Interleaving"       -justify right -value interleaved -variable channel_var
1297pack $i.cc.van.rb $i.cc.red.rb $i.cc.int.rb -side left -anchor nw -padx 2
1298
1299frame $i.cc.red.fc
1300label $i.cc.red.fc.l -text "Encoding:"
1301menubutton $i.cc.red.fc.m -textvariable secenc -indicatoron 1 -menu $i.cc.red.fc.m.menu -relief raised -width 13
1302menu $i.cc.red.fc.m.menu -tearoff 0
1303
1304frame $i.cc.red.u
1305label $i.cc.red.u.l -text "Offset in Pkts:"
1306tk_optionCmdMenu $i.cc.red.u.m red_off "1" "2" "4" "8" 
1307$i.cc.red.u.m configure -width 13 -highlightthickness 0 -bd 1
1308pack $i.cc.red.u -side right -anchor e -fill y
1309pack $i.cc.red.u.l $i.cc.red.u.m -fill x
1310pack $i.cc.red.fc -side right
1311pack $i.cc.red.fc.l $i.cc.red.fc.m
1312
1313frame $i.cc.int.zz
1314label $i.cc.int.zz.l -text "Units:"
1315tk_optionCmdMenu $i.cc.int.zz.m int_units 2 4 6 8
1316$i.cc.int.zz.m configure -width 13 -highlightthickness 0 -bd 1
1317
1318frame $i.cc.int.fc
1319label $i.cc.int.fc.l -text "Separation:"
1320tk_optionCmdMenu $i.cc.int.fc.m int_gap 2 4 6 8
1321$i.cc.int.fc.m configure -width 13 -highlightthickness 0 -bd 1
1322
1323pack $i.cc.int.fc $i.cc.int.zz -side right
1324pack $i.cc.int.fc.l $i.cc.int.fc.m -fill x -expand 1
1325pack $i.cc.int.zz.l $i.cc.int.zz.m -fill x -expand 1
1326
1327# Reception Pane ##############################################################
1328set i .prefs.pane.reception
1329frame $i 
1330frame $i.r -relief sunken
1331frame $i.o -relief sunken
1332frame $i.c -relief sunken
1333pack $i.r -side top -fill x -pady 0 -ipady 1
1334pack $i.o -side top -fill both  -pady 1
1335pack $i.c -side top -fill both  -pady 1 -expand 1
1336label $i.r.l -text "Repair Scheme:"
1337tk_optionCmdMenu $i.r.m repair_var {None}
1338
1339label $i.r.ls -text "Sample Rate Conversion"
1340tk_optionCmdMenu $i.r.ms convert_var {None}
1341
1342$i.r.m  configure -width 20 -bd 1
1343$i.r.ms configure -width 20 -bd 1
1344pack $i.r.l $i.r.m $i.r.ls $i.r.ms -side top
1345
1346frame $i.o.f
1347checkbutton $i.o.f.cb -text "Limit Playout Delay" -variable limit_var
1348frame $i.o.f.fl
1349label $i.o.f.fl.l1 -text "Minimum Delay (ms)" 
1350scale $i.o.f.fl.scmin -orient horizontal -from 0 -to 1000    -variable min_var -font $smallfont
1351frame $i.o.f.fr
1352label $i.o.f.fr.l2 -text "Maximum Delay (ms)"           
1353scale $i.o.f.fr.scmax -orient horizontal -from 1000 -to 2000 -variable max_var -font $smallfont
1354pack $i.o.f
1355pack $i.o.f.cb -side top -fill x
1356pack $i.o.f.fl $i.o.f.fr -side left
1357pack $i.o.f.fl.l1 $i.o.f.fl.scmin $i.o.f.fr.l2 $i.o.f.fr.scmax -side top -fill x -expand 1
1358
1359frame $i.c.f
1360frame $i.c.f.f
1361checkbutton $i.c.f.f.lec -text "Lecture Mode"       -variable lecture_var
1362checkbutton $i.c.f.f.ext -text "3D Audio Rendering" -variable 3d_audio_var
1363
1364pack $i.c.f -fill x -side left -expand 1
1365pack $i.c.f.f
1366pack $i.c.f.f.lec -side top  -anchor w
1367pack $i.c.f.f.ext -side top  -anchor w
1368
1369# Audio #######################################################################
1370set i .prefs.pane.audio
1371frame $i 
1372frame $i.dd -relief sunken
1373pack $i.dd -fill both -expand 1 -anchor w -pady 1
1374
1375frame $i.dd.device
1376pack $i.dd.device -side top -fill x
1377
1378label $i.dd.device.l -text "Audio Device:"
1379pack  $i.dd.device.l -side top -fill x
1380menubutton $i.dd.device.mdev -menu $i.dd.device.mdev.menu -indicatoron 1 \
1381                                -textvariable audio_device -relief raised -width 32
1382pack $i.dd.device.mdev
1383menu $i.dd.device.mdev.menu -tearoff 0
1384
1385frame $i.dd.sampling 
1386pack  $i.dd.sampling
1387
1388frame $i.dd.sampling.freq
1389frame $i.dd.sampling.ch_in
1390frame $i.dd.sampling.ch_out
1391pack $i.dd.sampling.freq $i.dd.sampling.ch_in $i.dd.sampling.ch_out -side left -fill x
1392
1393label $i.dd.sampling.freq.l   -text "Sample Rate:   "
1394label $i.dd.sampling.ch_in.l  -text "Input Channels:"
1395label $i.dd.sampling.ch_out.l -text "Output Channels:"
1396pack $i.dd.sampling.freq.l $i.dd.sampling.ch_in.l $i.dd.sampling.ch_out.l -fill x
1397
1398menubutton $i.dd.sampling.freq.mb -menu $i.dd.sampling.freq.mb.m -indicatoron 1 \
1399                                  -textvariable freq -relief raised
1400pack $i.dd.sampling.freq.mb -side left -fill x -expand 1
1401menu $i.dd.sampling.freq.mb.m
1402
1403menubutton $i.dd.sampling.ch_in.mb -menu $i.dd.sampling.ch_in.mb.m -indicatoron 1 \
1404                                  -textvariable ichannels -relief raised
1405pack $i.dd.sampling.ch_in.mb -side left -fill x -expand 1
1406menu $i.dd.sampling.ch_in.mb.m
1407
1408menubutton $i.dd.sampling.ch_out.mb -menu $i.dd.sampling.ch_out.mb.m -indicatoron 1 \
1409                                  -textvariable ochannels -relief raised
1410pack $i.dd.sampling.ch_out.mb -side left -fill x -expand 1
1411menu $i.dd.sampling.ch_out.mb.m
1412
1413frame $i.cks -relief sunken
1414pack $i.cks -fill both -expand 1 -anchor w -pady 1
1415frame $i.cks.f
1416frame $i.cks.f.f
1417checkbutton $i.cks.f.f.silence  -text "Silence Suppression"    -variable silence_var
1418checkbutton $i.cks.f.f.agc      -text "Automatic Gain Control" -variable agc_var
1419checkbutton $i.cks.f.f.loop     -text "Audio Loopback"         -variable audio_loop_var
1420checkbutton $i.cks.f.f.suppress -text "Echo Suppression"       -variable echo_var
1421pack $i.cks.f -fill x -side top -expand 1
1422pack $i.cks.f.f
1423pack $i.cks.f.f.silence $i.cks.f.f.agc $i.cks.f.f.loop $i.cks.f.f.suppress -side top -anchor w
1424
1425# Security Pane ###############################################################
1426set i .prefs.pane.security
1427frame $i 
1428frame $i.a -relief sunken
1429frame $i.a.f
1430frame $i.a.f.f
1431label $i.a.f.f.l -anchor w -justify left -text "Your communication can be secured with\nDES encryption.  Only conference participants\nwith the same key can receive audio data when\nencryption is enabled."
1432pack $i.a.f.f.l
1433pack $i.a -side top -fill both -expand 1
1434label $i.a.f.f.lbl -text "Key:"
1435entry $i.a.f.f.e -width 28 -textvariable key
1436checkbutton $i.a.f.f.cb -text "Enabled" -variable key_var
1437pack $i.a.f -fill x -side left -expand 1
1438pack $i.a.f.f
1439pack $i.a.f.f.lbl $i.a.f.f.e $i.a.f.f.cb -side left -pady 4 -padx 2 -fill x
1440
1441# Interface Pane ##############################################################
1442set i .prefs.pane.interface
1443frame $i 
1444frame $i.a -relief sunken
1445frame $i.a.f
1446frame $i.a.f.f
1447label $i.a.f.f.l -anchor w -justify left -text "The following features may be\ndisabled to conserve processing\npower."
1448pack $i.a -side top -fill both -expand 1
1449pack $i.a.f -fill x -side left -expand 1
1450checkbutton $i.a.f.f.power   -text "Powermeters active"       -variable meter_var
1451checkbutton $i.a.f.f.video   -text "Video synchronization"    -variable sync_var
1452checkbutton $i.a.f.f.balloon -text "Balloon help"             -variable help_on
1453checkbutton $i.a.f.f.matrix  -text "Reception quality matrix" -variable matrix_on -command chart_show
1454checkbutton $i.a.f.f.plist   -text "Participant list"         -variable plist_on  -command toggle_plist
1455checkbutton $i.a.f.f.fwin    -text "File Control Window"      -variable files_on  -command file_show
1456pack $i.a.f.f $i.a.f.f.l
1457pack $i.a.f.f.power $i.a.f.f.video $i.a.f.f.balloon $i.a.f.f.matrix $i.a.f.f.plist $i.a.f.f.fwin -side top -anchor w
1458
1459proc set_pane {p base desc} {
1460    upvar 1 $p pane
1461    set tpane [string tolower [lindex [split $pane] 0]]
1462    pack forget $base.$tpane
1463    set tpane [string tolower [lindex [split $desc] 0]]
1464    pack $base.$tpane -fill both -expand 1 -padx 2 -pady 2
1465    set pane $desc
1466}
1467
1468proc validate_red_codecs {} {
1469    # logic assumes codecs are sorted by b/w in menus
1470    global prenc secenc
1471
1472    set pri [.prefs.pane.transmission.dd.pri.m.menu index $prenc]
1473    if { [catch {set sec [.prefs.pane.transmission.cc.red.fc.m.menu index $secenc]}] } {
1474        set secenc $prienc
1475    }
1476
1477    if {$sec <= $pri} {
1478        for {set i 0} {$i < $pri} {incr i} {
1479            .prefs.pane.transmission.cc.red.fc.m.menu entryconfigure $i -state disabled
1480        }
1481        set secenc $prenc
1482    } else {
1483        for {set i $pri} {$i < $sec} {incr i} {
1484            .prefs.pane.transmission.cc.red.fc.m.menu entryconfigure $i -state normal
1485        }
1486    }
1487}
1488
1489# Initialise "About..." toplevel window
1490toplevel   .about
1491frame      .about.rim -relief sunken
1492frame      .about.m
1493frame      .about.rim.d
1494pack .about.m -fill x
1495pack .about.rim -padx 4 -pady 2 -side top -fill both -expand 1
1496pack .about.rim.d -side top -fill both -expand 1
1497
1498frame .about.m.f
1499label .about.m.f.l -text "Category:"
1500menubutton .about.m.f.mb -menu .about.m.f.mb.menu -indicatoron 1 -textvariable about_pane -relief raised -width 10
1501menu .about.m.f.mb.menu -tearoff 0
1502.about.m.f.mb.menu add command -label "Credits"   -command {set_pane about_pane .about.rim.d "Credits"   }
1503.about.m.f.mb.menu add command -label "Feedback"  -command {set_pane about_pane .about.rim.d "Feedback"  }
1504.about.m.f.mb.menu add command -label "Copyright" -command {set_pane about_pane .about.rim.d "Copyright" }
1505
1506pack .about.m.f
1507pack .about.m.f.l .about.m.f.mb -side left
1508
1509#label     .about.rim.t.d.logo  -highlightthickness 0 -bitmap rat_med
1510
1511frame     .about.rim.d.copyright
1512frame     .about.rim.d.copyright.f
1513frame     .about.rim.d.copyright.f.f
1514text      .about.rim.d.copyright.f.f.blurb -height 17 -yscrollcommand ".about.rim.d.copyright.f.f.scroll set"
1515scrollbar .about.rim.d.copyright.f.f.scroll -command ".about.rim.d.copyright.f.f.blurb yview"
1516
1517pack      .about.rim.d.copyright.f -expand 1 -fill both
1518pack      .about.rim.d.copyright.f.f
1519pack      .about.rim.d.copyright.f.f.scroll -side right -fill y -expand 1
1520pack      .about.rim.d.copyright.f.f.blurb -side left -expand 1
1521
1522frame     .about.rim.d.credits
1523frame     .about.rim.d.credits.f -relief sunken
1524frame     .about.rim.d.credits.f.f
1525pack      .about.rim.d.credits.f -fill both -expand 1
1526pack      .about.rim.d.credits.f.f -side left -fill x -expand 1
1527label     .about.rim.d.credits.f.f.1                  -text "The Robust-Audio Tool was developed in the Department of\nComputer Science, University College London.\n\nProject Supervision:"
1528label     .about.rim.d.credits.f.f.2 -foreground blue -text Good
1529label     .about.rim.d.credits.f.f.3                  -text "\nCore Development Team:"
1530label     .about.rim.d.credits.f.f.4 -foreground blue -text Bad
1531label     .about.rim.d.credits.f.f.5                  -text "Additional Contributions:"
1532label     .about.rim.d.credits.f.f.6 -foreground blue -text Ugly
1533for {set i 1} {$i<=6} {incr i} {
1534    pack  .about.rim.d.credits.f.f.$i -side top -fill x
1535}
1536
1537button    .about.dismiss -text Dismiss -command "wm withdraw .about"
1538pack      .about.dismiss -side bottom -anchor e -padx 2 -pady 2
1539
1540frame     .about.rim.d.feedback
1541frame     .about.rim.d.feedback.f -relief sunken
1542frame     .about.rim.d.feedback.f.f
1543pack      .about.rim.d.feedback.f -fill both -expand 1
1544pack      .about.rim.d.feedback.f.f -side left -fill x -expand 1
1545label     .about.rim.d.feedback.f.f.1                  -text "Comments, suggestions, and bug-reports should be sent to:"
1546label     .about.rim.d.feedback.f.f.2 -foreground blue -text "rat-trap@cs.ucl.ac.uk\n"
1547label     .about.rim.d.feedback.f.f.3                  -text "Further information is available on the world-wide web at:"
1548label     .about.rim.d.feedback.f.f.4 -foreground blue -text "http://www-mice.cs.ucl.ac.uk/multimedia/software/rat/\n"
1549for {set i 1} {$i<=4} {incr i} {
1550    pack  .about.rim.d.feedback.f.f.$i -side top -fill x
1551}
1552#pack .about.rim.t.logo .about.rim.t.blurb .about.rim.t.scroll -side right -fill y
1553
1554wm withdraw  .about
1555wm title     .about "About RAT"
1556wm resizable .about 0 0
1557set about_pane Copyright
1558set_pane about_pane .about.rim.d "Credits" 
1559constrain_window .about "XANDXFITNESSXFORXAXPARTICULARXPURPOSEXAREXDISCLAIMED.XINXNOXEVENTX" 0 21 28
1560
1561.about.rim.d.copyright.f.f.blurb insert end {
1562Copyright (C) 1995-1999 University College London
1563All rights reserved.
1564
1565Redistribution and use in source and binary forms, with or
1566without modification, is permitted, for non-commercial use
1567only, provided that the following conditions are met:
15681. Redistributions of source code must retain the above
1569   copyright notice, this list of conditions and the
1570   following disclaimer.
15712. Redistributions in binary form must reproduce the above
1572   copyright notice, this list of conditions and the
1573   following disclaimer in the documentation and/or other
1574   materials provided with the distribution.
15753. All advertising materials mentioning features or use of
1576   this software must display the following acknowledgement:
1577     "This product includes software developed by the
1578     Computer Science Department at University College
1579     London."
15804. Neither the name of the University nor of the Department
1581   may be used to endorse or promote products derived from
1582   this software without specific prior written permission.
1583Use of this software for commercial purposes is explicitly
1584forbidden unless prior written permission is obtained from
1585the authors.
1586
1587THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
1588"AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
1589BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
1590AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
1591SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
1592INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1593DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1594SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
1595OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1596LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1597(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
1598THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
1599OF SUCH DAMAGE.
1600
1601This software is derived, in part, from publically available
1602source code with the following copyright:
1603
1604Copyright (C) 1991-1993 Regents of the University of California
1605Copyright (C) 1992 Stichting Mathematisch Centrum, Amsterdam
1606Copyright (C) 1991-1992 RSA Data Security, Inc
1607Copyright (C) 1992 Jutta Degener and Carsten Bormann, TU Berlin
1608Copyright (C) 1994 Paul Stewart
1609Copyright (C) 1996 Regents of the University of California
1610
1611This product includes software developed by the Computer
1612Systems Engineering Group and by the Network Research Group
1613at Lawrence Berkeley Laboratory.
1614
1615The WB-ADPCM algorithm was developed by British Telecommunications
1616plc.  Permission has been granted to use it for non-commercial
1617research and development projects.  BT retain the intellectual
1618property rights to this algorithm.
1619
1620Encryption features of this software use the RSA Data
1621Security, Inc. MD5 Message-Digest Algorithm.
1622}
1623
1624proc shuffle_rats {args} {
1625    # This should really animate the movement and play fruit-machine sounds.... :-)
1626    set r ""
1627    set end [llength $args]
1628    set l 0
1629    while { $l < $end } {
1630        set toget [expr abs([clock clicks]) % [llength $args]]
1631        set r [format "%s%s  " $r [lindex $args $toget]]
1632        set args [lreplace $args $toget $toget]
1633        lappend used $toget
1634        if {$l >0 && [expr ($l + 1) % 3] == 0} {
1635            set r "$r\n"
1636        }
1637        incr l
1638    }
1639    return $r
1640}
1641
1642proc jiggle_credits {} {
1643# Software really developed by the Socialist Department of Computer Science
1644    .about.rim.d.credits.f.f.2 configure -text [shuffle_rats "Angela Sasse" "Vicky Hardman"]
1645    .about.rim.d.credits.f.f.4 configure -text [shuffle_rats "Colin Perkins" "Isidor Kouvelas" "Orion Hodson"]
1646    .about.rim.d.credits.f.f.6 configure -text [shuffle_rats "Darren Harris"  "Anna Watson" "Mark Handley" "Jon Crowcroft" "Anna Bouch" "Marcus Iken" "Kris Hasler"]
1647}
1648
1649proc sync_ui_to_engine {} {
1650    # the next time the display is shown, it needs to reflect the
1651    # state of the audio engine.
1652    mbus_send "R" "tool.rat.settings" ""
1653}
1654
1655proc sync_engine_to_ui {} {
1656    # make audio engine concur with ui
1657    global my_cname rtcp_name rtcp_email rtcp_phone rtcp_loc
1658    global prenc upp channel_var secenc red_off int_gap int_units
1659    global silence_var agc_var audio_loop_var echo_var
1660    global repair_var limit_var min_var max_var lecture_var 3d_audio_var convert_var 
1661    global meter_var sync_var gain volume input_port output_port
1662    global in_mute_var out_mute_var ichannels freq key key_var
1663    global audio_device
1664
1665    set my_cname_enc [mbus_encode_str $my_cname]
1666    #rtcp details
1667    mbus_send "R" "rtp.source.name"  "$my_cname_enc [mbus_encode_str $rtcp_name]"
1668    mbus_send "R" "rtp.source.email" "$my_cname_enc [mbus_encode_str $rtcp_email]"
1669    mbus_send "R" "rtp.source.phone" "$my_cname_enc [mbus_encode_str $rtcp_phone]"
1670    mbus_send "R" "rtp.source.loc"   "$my_cname_enc [mbus_encode_str $rtcp_loc]"
1671   
1672    #transmission details
1673    mbus_send "R" "tool.rat.codec"      "[mbus_encode_str $prenc] [mbus_encode_str $ichannels] [mbus_encode_str $freq]"
1674    mbus_send "R" "tool.rat.rate"         $upp
1675
1676    switch $channel_var {
1677        none        {mbus_send "R" "audio.channel.coding" "[mbus_encode_str $channel_var]"}
1678        redundant   {mbus_send "R" "audio.channel.coding" "[mbus_encode_str $channel_var] [mbus_encode_str $secenc] $red_off"}
1679        interleaved {mbus_send "R" "audio.channel.coding" "[mbus_encode_str $channel_var] $int_gap $int_units"}
1680        *           {error "unknown channel coding scheme $channel_var"}
1681    }
1682
1683    mbus_send "R" "tool.rat.silence"       $silence_var
1684    mbus_send "R" "tool.rat.agc"           $agc_var
1685    mbus_send "R" "tool.rat.loopback"      $audio_loop_var
1686    mbus_send "R" "tool.rat.echo.suppress" $echo_var
1687
1688    #Reception Options
1689    mbus_send "R" "audio.channel.repair"   [mbus_encode_str $repair_var]
1690    mbus_send "R" "tool.rat.playout.limit" $limit_var
1691    mbus_send "R" "tool.rat.playout.min"   $min_var
1692    mbus_send "R" "tool.rat.playout.max"   $max_var
1693    mbus_send "R" "tool.rat.lecture"       $lecture_var
1694    mbus_send "R" "tool.rat.3d.enabled"    $3d_audio_var
1695    mbus_send "R" "tool.rat.converter"     [mbus_encode_str $convert_var]
1696
1697    #Security
1698    if {$key_var==1 && [string length $key]!=0} {
1699        mbus_send "R" "security.encryption.key" [mbus_encode_str $key]
1700    } else {
1701        mbus_send "R" "security.encryption.key" [mbus_encode_str ""]
1702    }
1703
1704    #Interface
1705    mbus_send "R" "tool.rat.powermeter"   $meter_var
1706    mbus_send "R" "tool.rat.sync"         $sync_var
1707
1708    #device
1709    mbus_send "R" "audio.device"        [mbus_encode_str "$audio_device"]
1710    mbus_send "R" "audio.input.gain"    $gain
1711    mbus_send "R" "audio.output.gain"   $volume
1712    mbus_send "R" "audio.input.port"    [mbus_encode_str $input_port]
1713    mbus_send "R" "audio.output.port"   [mbus_encode_str $output_port]
1714    mbus_send "R" "audio.input.mute"    $in_mute_var
1715    mbus_send "R" "audio.output.mute"   $out_mute_var
1716}
1717
1718if {$win32 == 0 && [glob ~] == "/"} {
1719        set rtpfname /.RTPdefaults
1720} else {
1721        set rtpfname ~/.RTPdefaults
1722}
1723
1724proc save_setting {f field var} {
1725    global win32 V rtpfname
1726    upvar #0 $var value
1727    if {$win32 == 0} {
1728                catch { puts $f "*$field: $value" }
1729    } else {
1730                if {[string first "rtp" "$field"] == -1} {
1731                        set fail [catch {registry set "HKEY_CURRENT_USER\\Software\\$V(class)\\$V(app)" "*$field" "$value"} errmsg ]
1732                } else {
1733                        set fail [catch {registry set "HKEY_CURRENT_USER\\Software\\$V(class)\\common" "*$field" "$value"} errmsg ]
1734                }
1735                if {$fail} {
1736                        puts "registry set failed:\n$errmsg"
1737                }
1738        }
1739}
1740
1741proc save_settings {} {
1742    global rtpfname win32 TOOL my_cname
1743
1744    set f 0
1745    if {$win32 == 0} {
1746                set fail [catch {set f [open $rtpfname w]}]
1747                if {$fail} {
1748                        return
1749                }
1750    }
1751
1752    # personal
1753    save_setting $f rtpName     rtcp_name
1754    save_setting $f rtpEmail    rtcp_email
1755    save_setting $f rtpPhone    rtcp_phone
1756    save_setting $f rtpLoc      rtcp_loc
1757    save_setting $f audioTool   TOOL($my_cname)
1758
1759    # transmission
1760    save_setting $f audioFrequency         freq
1761    save_setting $f audioChannelsIn        ichannels
1762    save_setting $f audioChannelsOut       ochannels
1763    save_setting $f audioPrimary           prenc
1764    save_setting $f audioUnits             upp
1765    save_setting $f audioChannelCoding     channel_var
1766    save_setting $f audioRedundancy        secenc
1767    save_setting $f audioRedundancyOffset  red_off
1768    save_setting $f audioInterleavingGap   int_gap
1769    save_setting $f audioInterleavingUnits int_units
1770    save_setting $f audioSilence           silence_var
1771    save_setting $f audioAGC               agc_var
1772    save_setting $f audioLoopback          audio_loop_var
1773    save_setting $f audioEchoSuppress      echo_var
1774    # reception
1775    save_setting $f audioRepair           repair_var
1776    save_setting $f audioLimitPlayout     limit_var
1777    save_setting $f audioMinPlayout       min_var
1778    save_setting $f audioMaxPlayout       max_var
1779    save_setting $f audioLecture          lecture_var
1780    save_setting $f audio3dRendering      3d_audio_var
1781    save_setting $f audioAutoConvert      convert_var
1782    #security
1783   
1784    # ui bits
1785    save_setting $f audioPowermeters meter_var
1786    save_setting $f audioLipSync     sync_var
1787    save_setting $f audioHelpOn      help_on
1788    save_setting $f audioMatrixOn    matrix_on
1789    save_setting $f audioPlistOn     plist_on
1790    save_setting $f audioFilesOn     files_on
1791
1792    # device
1793        save_setting $f  audioDevice       audio_device
1794    save_setting $f  audioOutputGain   volume
1795    save_setting $f  audioInputGain    gain
1796    save_setting $f  audioOutputPort   output_port
1797    save_setting $f  audioInputPort    input_port
1798
1799    if {$win32 == 0} {
1800            close $f
1801    }
1802}
1803
1804proc load_setting {attrname field var default} {
1805    global V win32 $var
1806    upvar 1 $attrname attr
1807        set fail 0
1808    # who has the tcl manual? is the only way to pass arrays thru upvar...
1809        if {$win32} {
1810                if {[string first "rtp" "$field"] == -1} {
1811                        set fail [ catch { set tmp "[registry get HKEY_CURRENT_USER\\Software\\$V(class)\\$V(app) *$field]" } msg ]
1812                } else {
1813                        set fail [ catch { set tmp "[registry get HKEY_CURRENT_USER\\Software\\$V(class)\\common  *$field]" } msg ]
1814                }
1815                if {$fail} {
1816                        puts "Failed to get $field reason $msg\n";
1817                        set tmp ""
1818                } else {
1819                        puts "$field $var $tmp"
1820                }
1821    } else {
1822                set tmp [option get . $field rat]
1823                if {$tmp == ""} {
1824            # not in xresources...
1825                        if {[info exists attr($field)]} {
1826                        set tmp $attr($field)
1827                        }
1828                }
1829    }
1830    if {$tmp == ""} {
1831        # either not in rtp defaults, or registry...
1832        set tmp $default
1833    }
1834    set $var $tmp
1835}
1836
1837proc tool_version {tool} {
1838        if {![regexp {RAT v[0-9]+\.[0-9]+\.[0-9]+ [a-zA-Z]+} $tool]} {
1839                # Unknown tool version, so put out something which won't
1840                # match with the current version string to force a reset
1841                # of the saved parameters.
1842                return "RAT v0.0.0"
1843        }
1844        regsub {(RAT v[0-9]+\.[0-9]+\.[0-9]+) [a-zA-Z]+} $tool {\1} v
1845        return $v
1846}
1847
1848proc load_settings {} {
1849    global rtpfname win32 my_cname TOOL
1850
1851    set attr(zero) ""
1852    if {$win32 == 0} {
1853                if {[file readable $rtpfname]} {
1854                        set f [open $rtpfname]
1855                        while {[eof $f] == 0} {
1856                        gets $f line
1857                        set field [string trim [lindex $line 0] "*:"]
1858                        set value [lrange $line 1 end]
1859                        set attr($field) "$value"
1860                        }       
1861                        close $f
1862                }
1863    }
1864
1865    # personal
1866    load_setting attr rtpName   rtcp_name     "unknown"
1867    load_setting attr rtpEmail  rtcp_email    "unknown"
1868    load_setting attr rtpPhone  rtcp_phone    ""
1869    load_setting attr rtpLoc    rtcp_loc      ""
1870    load_setting attr audioTool audio_tool         ""
1871
1872    # If the version of the saved settings is different
1873    # from those the current version use defaults.
1874    global audio_tool
1875    if {[tool_version $audio_tool] != [tool_version $TOOL($my_cname)]} {
1876        foreach i [array names attr audio*] {
1877            unset attr($i)
1878        }
1879    }
1880    unset audio_tool
1881
1882    # reception
1883    load_setting attr audioRepair       repair_var    "Repetition"
1884
1885    load_setting attr audioLimitPlayout limit_var     "0"
1886    load_setting attr audioMinPlayout   min_var       "0"
1887    load_setting attr audioMaxPlayout   max_var       "2000"
1888    load_setting attr audioLecture      lecture_var   "0"
1889    load_setting attr audio3dRendering  3d_audio_var   "0"
1890    load_setting attr audioAutoConvert  convert_var   "None"
1891    #security
1892   
1893    # ui bits
1894    load_setting attr audioPowermeters  meter_var     "1"
1895    load_setting attr audioLipSync      sync_var      "0"
1896    load_setting attr audioHelpOn       help_on       "1"
1897    load_setting attr audioMatrixOn     matrix_on     "0"
1898    load_setting attr audioPlistOn      plist_on      "1"
1899    load_setting attr audioFilesOn      files_on      "0"
1900
1901    # device config
1902    load_setting attr audioOutputGain   volume       "50"
1903    load_setting attr audioInputGain    gain         "50"
1904    load_setting attr audioOutputPort   output_port  "speaker"
1905    load_setting attr audioInputPort    input_port   "microphone"
1906    # we don't save the following but we can set them so if people
1907    # want to start with mic open then they add following attributes
1908    load_setting attr audioOutputMute   out_mute_var "0"
1909    load_setting attr audioInputMute    in_mute_var  "1"
1910    # transmission
1911    load_setting attr audioSilence           silence_var   "1"
1912    load_setting attr audioAGC               agc_var       "0"
1913    load_setting attr audioLoopback          audio_loop_var "0"
1914    load_setting attr audioEchoSuppress      echo_var      "0"
1915    load_setting attr audioFrequency         freq          "8-kHz"
1916    load_setting attr audioChannelsIn        ichannels     "Mono"
1917    load_setting attr audioChannelsOut       ochannels     "Mono"
1918    load_setting attr audioPrimary           prenc         "GSM"
1919    load_setting attr audioUnits             upp           "2"
1920    load_setting attr audioChannelCoding     channel_var   "none"
1921    load_setting attr audioRedundancy        secenc        "GSM"
1922    load_setting attr audioRedundancyOffset  red_off       "1"
1923    load_setting attr audioInterleavingGap   int_gap       "4"
1924    load_setting attr audioInterleavingUnits int_units     "4"
1925    #device
1926    load_setting attr audioDevice            audio_device  "Unknown"
1927
1928    global prenc ichannels freq
1929    mbus_send "R" "tool.rat.codec" "[mbus_encode_str $prenc] [mbus_encode_str $ichannels] [mbus_encode_str $freq]"
1930       
1931    global      in_mute_var   out_mute_var
1932    input_mute  $in_mute_var
1933    output_mute $out_mute_var
1934}
1935
1936proc check_rtcp_name {} {
1937    global rtcp_name
1938    if {$rtcp_name == ""} {
1939        toplevel .name
1940        wm title .name "RAT User Information"
1941        message .name.m -width 1000 -text {
1942            Please enter the following details, for transmission
1943            to other conference participants.
1944        }
1945        frame  .name.b
1946        label  .name.b.res -text "Name:"
1947        entry  .name.b.e -highlightthickness 0 -width 20 -relief sunken -textvariable rtcp_name
1948        button .name.d -text Done -command {save_settings; sync_engine_to_ui; destroy .name}
1949        bind   .name.b.e <Return> {save_settings; sync_engine_to_ui; destroy .name}
1950       
1951        pack .name.m -side top -fill x -expand 1
1952        pack .name.b -side top -fill x -expand 1
1953        pack .name.b.res -side left
1954        pack .name.b.e -side right -fill x -expand 1
1955        pack .name.d -side bottom -fill x -expand 1
1956        wm resizable .name 0 0
1957        update
1958        raise .name .
1959    }
1960}
1961
1962#
1963# Routines to display the "chart" of RTCP RR statistics...
1964#
1965
1966set chart_font    6x10
1967set chart_size    1
1968set chart_boxsize 15
1969set chart_xoffset 180
1970set chart_yoffset 17
1971
1972toplevel  .chart
1973wm protocol .chart WM_DELETE_WINDOW    {set matrix_on 0; chart_show}
1974canvas    .chart.c  -background white  -xscrollcommand {.chart.sb set} -yscrollcommand {.chart.sr set}
1975scrollbar .chart.sr -orient vertical   -command {.chart.c yview}
1976scrollbar .chart.sb -orient horizontal -command {.chart.c xview}
1977button    .chart.d  -text "Dismiss"    -command {set matrix_on 0; chart_show}
1978
1979pack .chart.d  -side bottom -expand 0 -anchor e -padx 2 -pady 2
1980pack .chart.sb -side bottom -fill x    -expand 0 -anchor s
1981pack .chart.sr -side right  -fill y    -expand 0 -anchor e
1982pack .chart.c  -side left   -fill both -expand 1 -anchor n
1983
1984# Add a few labels to the chart...
1985.chart.c create text 2 [expr ($chart_boxsize / 2) + 2] -anchor w -text "Sender:" -font $chart_font 
1986.chart.c create line $chart_xoffset [expr $chart_boxsize + 2] $chart_xoffset 2
1987.chart.c create line $chart_xoffset 2 2 2
1988
1989proc chart_enlarge {new_size} {
1990  global chart_size
1991  global chart_boxsize
1992  global chart_xoffset
1993  global chart_yoffset
1994  global chart_font
1995
1996  if {$new_size < $chart_size} {
1997    return
1998  }
1999 
2000  for {set i 0} {$i <= $new_size} {incr i} {
2001    set s1 $chart_xoffset
2002    set s2 [expr $chart_yoffset + ($chart_boxsize * $i)]
2003    set s3 [expr $chart_xoffset + ($chart_boxsize * $new_size)]
2004    set s4 [expr $chart_xoffset + ($chart_boxsize * $i)]
2005    set s5 $chart_yoffset
2006    set s6 [expr $chart_yoffset + ($chart_boxsize * $new_size)]
2007    .chart.c create line $s1 $s2 $s3 $s2
2008    .chart.c create line $s4 $s5 $s4 $s6 
2009  }
2010
2011  for {set i 0} {$i < $new_size} {incr i} {
2012    set s1 $chart_xoffset
2013    set s2 [expr $chart_yoffset + ($chart_boxsize * $i)]
2014    set s3 [expr $chart_xoffset + ($chart_boxsize * $new_size)]
2015    set s4 [expr $chart_xoffset + ($chart_boxsize * $i)]
2016    set s5 $chart_yoffset
2017    set s6 [expr $chart_yoffset + ($chart_boxsize * $new_size)]
2018    .chart.c create text [expr $chart_xoffset - 2] [expr $s2 + ($chart_boxsize / 2)] -text $i -anchor e -font $chart_font
2019    .chart.c create text [expr $s4 + ($chart_boxsize / 2)] [expr $chart_yoffset - 2] -text $i -anchor s -font $chart_font
2020  }
2021  .chart.c configure -scrollregion "0 0 [expr $s3 + 1] [expr $s6 + 1]"
2022  set chart_size $new_size
2023}
2024
2025proc chart_set {dest srce val} {
2026  global INDEX chart_size chart_boxsize chart_xoffset chart_yoffset
2027
2028  if {[array names INDEX $srce] != [list $srce]} {
2029    return
2030  }
2031  if {[array names INDEX $dest] != [list $dest]} {
2032    return
2033  }
2034  set x $INDEX($srce)
2035  set y $INDEX($dest)
2036
2037  if {($x > $chart_size) || ($x < 0)} return
2038  if {($y > $chart_size) || ($y < 0)} return
2039  if {($val > 101) || ($val < 0)}     return
2040
2041  set xv [expr ($x * $chart_boxsize) + $chart_xoffset + 1]
2042  set yv [expr ($y * $chart_boxsize) + $chart_yoffset + 1]
2043
2044  if {$val < 5} {
2045    set colour green
2046  } elseif {$val < 10} {
2047    set colour orange
2048  } elseif {$val <= 100} {
2049    set colour red
2050  } else {
2051    set colour white
2052  }
2053
2054  .chart.c create rectangle $xv $yv [expr $xv + $chart_boxsize - 2] [expr $yv + $chart_boxsize - 2] -fill $colour -outline $colour
2055}
2056
2057proc chart_label {cname} {
2058  global CNAME NAME INDEX chart_size chart_boxsize chart_xoffset chart_yoffset chart_font
2059
2060  set pos $INDEX($cname)
2061  set val $NAME($cname)
2062  if {[string length $val] == 0} {
2063    set val $CNAME($cname)
2064  }
2065
2066  if {($pos > $chart_size) || ($pos < 0)} return
2067
2068  set ypos [expr $chart_yoffset + ($chart_boxsize * $pos) + ($chart_boxsize / 2)]
2069  .chart.c delete cname_$cname
2070  .chart.c create text 2 $ypos -text [string range $val 0 25] -anchor w -font $chart_font -tag cname_$cname
2071}
2072
2073proc chart_redraw {size} {
2074  # This is not very efficient... [csp]
2075  global CNAME NAME INDEX chart_size chart_boxsize chart_xoffset chart_yoffset chart_font
2076
2077  .chart.c delete all
2078  set chart_size 0
2079  chart_enlarge $size
2080  set j 0
2081  foreach i [array names CNAME] {
2082    set INDEX($i) $j
2083    chart_label $i
2084    incr j
2085  }
2086}
2087
2088proc chart_show {} {
2089        global matrix_on
2090        if {$matrix_on} {
2091                wm deiconify .chart
2092        } else {
2093                wm withdraw .chart
2094        }
2095}
2096
2097wm withdraw .chart
2098wm title    .chart "Reception quality matrix"
2099wm geometry .chart 320x200
2100
2101chart_enlarge 1
2102
2103#
2104# End of RTCP RR chart routines
2105#
2106
2107#
2108# File Control Window
2109#
2110
2111catch {
2112    toplevel .file
2113    wm protocol .file WM_DELETE_WINDOW {set files_on 0; file_show}
2114        frame .file.play
2115        frame .file.rec
2116        pack  .file.play -side left
2117        pack  .file.rec  -side right
2118
2119        label .file.play.l -text "Playback"
2120        pack  .file.play.l -side top -fill x
2121        label .file.rec.l -text "Record"
2122        pack  .file.rec.l -side top -fill x
2123
2124        wm withdraw .file
2125        wm title        .file "RAT File Control"
2126
2127        foreach action { play rec } {
2128                frame  .file.$action.buttons
2129                pack   .file.$action.buttons
2130                button .file.$action.buttons.disk -bitmap disk -command "fileDialog $action"
2131                pack   .file.$action.buttons.disk -side left
2132                foreach cmd "$action pause stop" {
2133                        button .file.$action.buttons.$cmd -bitmap $cmd -state disabled -command file_$action\_$cmd
2134                        pack   .file.$action.buttons.$cmd -side left
2135                }
2136        }
2137} fwinerr
2138
2139if {$fwinerr != {}} {
2140        puts stderr $fwinerr
2141}
2142
2143proc fileDialog {cmdbox} {
2144    global win32 tcl_platform
2145   
2146        set defaultExtension au
2147        set defaultLocation  .
2148
2149    switch -glob $tcl_platform(os) {
2150        SunOS    {
2151                if [file exists /usr/demo/SOUND/sounds] { set defaultLocation /usr/demo/SOUND/sounds }
2152                }
2153        Windows* {
2154                if [file exists C:/Windows/Media]       { set defaultLocation C:/Windows/Media }
2155                set defaultExtension wav
2156                }
2157        }
2158   
2159    set types {
2160                {"NeXT/Sun Audio files" "au"}
2161                {"Microsoft RIFF files" "wav"}
2162                {"All files"            "*"}
2163    }
2164   
2165    if {![string compare $cmdbox "play"]} {
2166                catch { asFileBox .playfilebox  -defaultextension $defaultExtension -command file_open_$cmdbox -directory $defaultLocation -extensions $types } asferror
2167    } else {
2168                catch { asFileBox .recfilebox   -defaultextension $defaultExtension -command file_open_$cmdbox  -extensions $types -force_extension 1 } asferror
2169    }
2170       
2171        if {$asferror != ""} {
2172                puts stderr asferror
2173        }
2174}
2175
2176proc file_show {} {
2177    global files_on
2178   
2179    if {$files_on} {
2180                wm deiconify .file
2181    } else {
2182                wm withdraw .file
2183    }
2184}
2185
2186proc file_play_live {} {
2187# Request heart beat to determine if file is valid
2188        mbus_send "R" audio.file.play.live ""
2189}
2190
2191proc file_rec_live {} {
2192# Request heart beat to determine if file is valid
2193        mbus_send "R" audio.file.record.live ""
2194}
2195
2196proc file_open_play {path} {
2197    global play_file
2198
2199    mbus_send "R" "audio.file.play.open" [mbus_encode_str $path]
2200    mbus_send "R" "audio.file.play.pause" 1
2201    set play_file(state) paused
2202    set play_file(name) $path
2203   
2204    # Test whether file is still playing/valid
2205    after 200 file_play_live
2206}
2207
2208proc file_open_rec {path} {
2209    global rec_file
2210
2211    mbus_send "R" "audio.file.record.open" [mbus_encode_str $path]
2212    mbus_send "R" "audio.file.record.pause" 1
2213
2214    set rec_file(state) paused
2215    set rec_file(name)  $path
2216
2217    # Test whether file is still recording/valid
2218    after 200 file_rec_live
2219}
2220
2221proc file_enable_play { } {
2222        .file.play.buttons.play   configure -state normal
2223        .file.play.buttons.pause  configure -state disabled
2224        .file.play.buttons.stop   configure -state disabled
2225}       
2226
2227proc file_enable_record { } {
2228        .file.rec.buttons.rec configure -state normal
2229        .file.rec.buttons.pause  configure -state disabled
2230        .file.rec.buttons.stop   configure -state disabled
2231}
2232
2233proc file_play_play {} {
2234        global play_file
2235       
2236        catch {
2237                puts stderr $play_file(state)
2238                if {$play_file(state) == "paused"} {
2239                        mbus_send "R" "audio.file.play.pause" 0
2240                        puts stderr "unpaused"
2241                } else {
2242                        mbus_send "R" "audio.file.play.open" [mbus_encode_str $play_file(name)]
2243                        puts stderr "re-opening"
2244                }
2245                set play_file(state) play
2246        } pferr
2247
2248        if { $pferr != "play" } { puts stderr "pferr: $pferr" }
2249
2250        .file.play.buttons.play   configure -state disabled
2251        .file.play.buttons.pause  configure -state normal
2252        .file.play.buttons.stop   configure -state normal
2253       
2254        after 200 file_play_live
2255}
2256
2257proc file_play_pause {} {
2258        global play_file
2259       
2260        .file.play.buttons.play   configure -state normal
2261        .file.play.buttons.pause  configure -state disabled
2262        .file.play.buttons.stop   configure -state normal
2263
2264        set play_file(state) paused
2265        mbus_send "R" "audio.file.play.pause" 1
2266}
2267
2268proc file_play_stop {} {
2269        global play_file
2270       
2271        set play_file(state) end
2272        file_enable_play
2273        mbus_send "R" "audio.file.play.stop" ""
2274}
2275
2276proc file_rec_rec {} {
2277        global rec_file
2278       
2279        catch {
2280                puts stderr $rec_file(state)
2281                if {$rec_file(state) == "paused"} {
2282                        mbus_send "R" "audio.file.record.pause" 0
2283                } else {
2284                        mbus_send "R" "audio.file.record.open" [mbus_encode_str $rec_file(name)]
2285                }
2286                set rec_file(state) record
2287        } prerr
2288
2289        if { $prerr != "record" } { puts stderr "prerr: $prerr" }
2290
2291        .file.rec.buttons.rec    configure -state disabled
2292        .file.rec.buttons.pause  configure -state normal
2293        .file.rec.buttons.stop   configure -state normal
2294
2295        after 200 file_rec_live
2296}
2297
2298proc file_rec_pause {} {
2299        global rec_file
2300
2301        .file.rec.buttons.rec    configure -state normal
2302        .file.rec.buttons.pause  configure -state disabled
2303        .file.rec.buttons.stop   configure -state normal
2304
2305        set rec_file(state) paused
2306        mbus_send "R" "audio.file.rec.pause" 1
2307}
2308
2309proc file_rec_stop {} {
2310        global rec_file
2311       
2312        set rec_file(state) end
2313        file_enable_record
2314        mbus_send "R" "audio.file.record.stop" ""
2315}
2316
2317#
2318# End of File Window routines
2319#
2320
2321bind . <t> {mbus_send "R" "toggle.input.port" ""}
2322
2323proc show_help {window} {
2324        global help_text help_on help_id
2325        if {$help_on} {
2326                .help.text  configure -text $help_text($window)
2327                # Beware! Don't put the popup under the cursor! Else we get window enter
2328                # for .help and leave for $window, making us hide_help which removes the
2329                # help window, giving us a window enter for $window making us popup the
2330                # help again.....
2331                if {[winfo width $window] > [winfo height $window]} {
2332                    set xpos [expr [winfo pointerx $window] + 10]
2333                    set ypos [expr [winfo rooty    $window] + [winfo height $window] + 4]
2334                } else {
2335                    set xpos [expr [winfo rootx    $window] + [winfo width $window] + 4]
2336                    set ypos [expr [winfo pointery $window] + 10]
2337                }
2338               
2339                wm geometry  .help +$xpos+$ypos
2340                set help_id [after 100 wm deiconify .help]
2341                raise .help $window
2342        }
2343}
2344
2345proc hide_help {window} {
2346        global help_id help_on
2347        if {[info exists help_id]} {
2348                after cancel $help_id
2349        }
2350        wm withdraw .help
2351}
2352
2353proc add_help {window text} {
2354        global help_text
2355        set help_text($window)  $text
2356        bind $window <Enter>    "+show_help $window"
2357        bind $window <Leave>    "+hide_help $window"
2358}
2359
2360bind Entry   <KeyPress> "+hide_help %W"
2361toplevel .help       -bg black
2362label    .help.text  -bg lavender -justify left
2363pack .help.text -side top -anchor w -fill x
2364wm transient        .help .
2365wm withdraw         .help
2366wm overrideredirect .help true
2367
2368add_help .r.c.gain.s2   "This slider controls the volume\nof the sound you send."
2369add_help .r.c.gain.l2   "Click to change input device."
2370add_help .r.c.gain.t2   "If this button is not pushed in, you are are transmitting,\nand may be\
2371                         heard by other participants. Holding down the\nright mouse button in\
2372                         any RAT window will temporarily\ntoggle the state of this button,\
2373                         allowing for easy\npush-to-talk operation."
2374add_help .r.c.gain.b2   "Indicates the loudness of the\nsound you are sending. If this\nis\
2375                         moving, you may be heard by\nthe other participants."
2376
2377add_help .r.c.vol.s1    "This slider controls the volume\nof the sound you hear."
2378add_help .r.c.vol.l1    "Click to change output device."
2379add_help .r.c.vol.t1    "If pushed in, reception is muted."
2380add_help .r.c.vol.b1    "Indicates the loudness of the\nsound you are hearing."
2381
2382add_help .l.f           "Name of the session, and the IP address, port\n&\
2383                         TTL used to transmit the audio data."
2384add_help .l.t           "The participants in this session with you at the top.\nClick on a name\
2385                         with the left mouse button to display\ninformation on that participant,\
2386                         and with the middle\nbutton to mute that participant (the right button\nwill\
2387                         toggle the transmission mute button, as usual)."
2388
2389add_help .l.s1.opts     "Brings up another window allowing\nthe control of various options."
2390add_help .l.s1.about    "Brings up another window displaying\ncopyright & author information."
2391add_help .l.s1.quit     "Press to leave the session."
2392
2393# preferences help
2394add_help .prefs.m.f.m  "Click here to change the preference\ncategory."
2395set i .prefs.buttons
2396add_help $i.bye         "Cancel changes."
2397add_help $i.apply       "Apply changes."
2398add_help $i.save        "Save and apply changes."
2399
2400# user help
2401set i .prefs.pane.personal.a.f.f.ents
2402add_help $i.name        "Enter your name for transmission\nto other participants."
2403add_help $i.email       "Enter your email address for transmission\nto other participants."
2404add_help $i.phone       "Enter your phone number for transmission\nto other participants."
2405add_help $i.loc         "Enter your location for transmission\nto other participants."
2406
2407#audio help
2408set i .prefs.pane.audio
2409add_help $i.dd.device.mdev "Selects preferred audio device."
2410add_help $i.dd.sampling.freq.mb \
2411                        "Sets the sampling rate of the audio device.\nThis changes the available codecs."
2412add_help $i.dd.sampling.ch_in.mb \
2413                        "Changes between mono and stereo audio input."
2414add_help $i.dd.sampling.ch_out.mb \
2415                        "Changes between mono and stereo audio output."
2416add_help $i.cks.f.f.silence\
2417                         "Prevents silence from being transmitted when the speaker is silent\n\
2418                          and the input is unmuted."
2419add_help $i.cks.f.f.agc  "Enables automatic control of the volume\nof the sound you send."
2420add_help $i.cks.f.f.loop "Enables hardware for loopback of audio input."
2421add_help $i.cks.f.f.suppress \
2422                         "Mutes microphone when playing audio."
2423
2424# transmission help
2425set i .prefs.pane.transmission
2426
2427add_help $i.dd.units.m  "Sets the duration of each packet sent.\nThere is a fixed per-packet\
2428                         overhead, so\nmaking this larger will reduce the total\noverhead.\
2429                         The effects of packet loss are\nmore noticable with large packets."
2430add_help $i.dd.pri.m    "Changes the primary audio compression\nscheme. The list is arranged\
2431                         with high-\nquality, high-bandwidth choices at the\ntop, and\
2432                         poor-quality, lower-bandwidth\nchoices at the bottom."
2433add_help $i.cc.van.rb   "Sets no channel coding."
2434add_help $i.cc.red.rb   "Piggybacks earlier units of audio into packets\n\
2435                         to protect against packet loss. Some audio\n\
2436                         tools (eg: vat-4.0) are not able to receive\n\
2437                         audio sent with this option."
2438add_help $i.cc.red.fc.m \
2439                        "Sets the format of the piggybacked data."
2440add_help $i.cc.red.u.m \
2441                        "Sets the offset of the piggybacked data."
2442add_help $i.cc.int.fc.m \
2443                        "Sets the separation of adjacent units within\neach packet. Larger values correspond\
2444                         to longer\ndelays."
2445add_help $i.cc.int.zz.m "Number of compound units per packet."
2446add_help $i.cc.int.rb   "Enables interleaving which exchanges latency\n\
2447                         for protection against burst losses.  No other\n\
2448                         audio tools can decode this format (experimental)."
2449
2450# Reception Help
2451set i .prefs.pane.reception
2452add_help $i.r.m         "Sets the type of repair applied when packets are\nlost. The schemes\
2453                         are listed in order of increasing\ncomplexity and quality of repair."
2454add_help $i.r.ms        "Sets the type of sample rate conversion algorithm\n\
2455                         that will be applied to streams that differ in rate\n\
2456                         to the audio device rate."
2457add_help $i.o.f.cb      "Enforce playout delay limits set below.\nThis is not usually desirable."
2458add_help $i.o.f.fl.scmin   "Sets the minimum playout delay that will be\napplied to incoming\
2459                         audio streams."
2460add_help $i.o.f.fr.scmax   "Sets the maximum playout delay that will be\napplied to incoming\
2461                         audio streams."
2462add_help $i.c.f.f.lec   "If enabled, extra delay is added at both sender and receiver.\nThis allows\
2463                         the receiver to better cope with host scheduling\nproblems, and the sender\
2464                         to perform better silence suppression.\nAs the name suggests, this option\
2465                         is intended for scenarios such\nas transmitting a lecture, where interactivity\
2466                         is less important\nthan quality."
2467
2468# security...too obvious for balloon help!
2469add_help .prefs.pane.security.a.f.f.e "Due to government export restrictions\nhelp\
2470                                       for this option is not available."
2471
2472# interface...ditto!
2473set i .prefs.pane.interface
2474add_help $i.a.f.f.power "Disable display of audio powermeters. This\nis only\
2475                         useful if you have a slow machine"
2476add_help $i.a.f.f.video "Enable lip-synchronisation, if\nyou\
2477                         have a compatible video tool"
2478add_help $i.a.f.f.balloon "If you can see this, balloon help\nis enabled. If not, it isn't."
2479add_help $i.a.f.f.matrix  "Displays a chart showing the reception\nquality reported by all participants"
2480add_help $i.a.f.f.plist   "Hides the list of participants"
2481
2482add_help .chart         "This chart displays the reception quality reported\n by all session\
2483                         participants. Looking along a row\n gives the quality with which that\
2484                         participant was\n received by all other participants in the session:\n green\
2485                         is good quality, orange medium quality, and\n red poor quality audio."
Note: See TracBrowser for help on using the browser.