root/rat/trunk/ui_audiotool.tcl @ 3111

Revision 3111, 96.3 KB (checked in by ucaccsp, 15 years ago)

Update tcl/tk initialization sequence. The UI should now be ready before
we initialize our mbus interface, which should mean that rtp.ssrc cannot
fail.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1catch {
2#
3# Copyright (c) 1995-2000 University College London
4# All rights reserved.
5#
6# $Revision$
7#
8# Full terms and conditions of the copyright appear below.
9#
10
11wm withdraw .
12
13if {[string compare [info commands registry] "registry"] == 0} {
14    set win32 1
15} else {
16    set win32 0
17    option add *Menu*selectColor                forestgreen
18    option add *Radiobutton*selectColor         forestgreen
19    option add *Checkbutton*selectColor         forestgreen
20    option add *Entry.background                gray70
21}
22
23set statsfont     [font actual {helvetica 10}]
24set compfont      [font actual {helvetica 10}]
25set titlefont     [font actual {helvetica 10}]
26set infofont      [font actual {helvetica 10}]
27set smallfont     [font actual {helvetica  8}]
28set verysmallfont [font actual {helvetica  8}]
29
30set speaker_highlight white
31
32option add *Entry.relief       sunken
33option add *borderWidth        1
34option add *highlightThickness 0
35option add *font               $infofont
36option add *Menu*tearOff       0
37
38set V(class) "Mbone Applications"
39set V(app)   "rat"
40
41set iht                 16
42set iwd                 250
43set cancel_info_timer   0
44set num_ssrc            0
45set fw                  .l.t.list.f
46set iports             [list]
47set oports             [list]
48set bps_in              "0.0 b/s"
49set bps_out             $bps_in
50
51# Sliders use scale widget and this invokes it's -command option when
52# it is created (doh!)  We don't know what gain and volume settings
53# should be before we've received info from the audio engine.
54# Don't send our initial value if we've not heard anything from engine
55# first.  Otherwise we get catch-22 with both engine and ui queuing
56# messages of gains to each other and often UI wins, which it never
57# should do.
58
59set received(gain)      0
60set received(volume)    0
61
62###############################################################################
63#
64# Debugging Functions
65#
66###############################################################################
67
68# tvar - trace variable callback for watching changes to variables
69# e.g. to watch write events to myVar use:
70#                                          trace variable myVar w tvar
71
72proc tvar {name element op} {
73# Compose variable name and print out change
74    if {$element != ""} {
75        set name ${name}($element)
76    }
77    upvar $name x
78    puts stderr "Variable $name set to $x."
79
80# Unravel stack and display
81    puts "Stack trace:"
82    set depth [info level]
83    set l 0
84    while {$l < $depth} {
85        puts stderr "\tLevel $l: [info level $l]"
86        incr l
87    }
88}
89
90###############################################################################
91
92# trace variable gain w tvar
93
94proc init_source {ssrc} {
95        global CNAME NAME EMAIL LOC PHONE TOOL NOTE SSRC num_ssrc
96        global CODEC DURATION PCKTS_RECV PCKTS_LOST PCKTS_MISO PCKTS_DUP \
97               JITTER LOSS_TO_ME LOSS_FROM_ME INDEX JIT_TOGED BUFFER_SIZE \
98               PLAYOUT_DELAY GAIN MUTE SKEW SPIKE_EVENTS SPIKE_TOGED RTT
99
100        # This is a debugging test -- old versions of the mbus used the
101        # cname to identify participants, whilst the newer version uses
102        # the ssrc.  This check detects if old style commands are being
103        # used and raises an error if so.
104        if [regexp {.*@[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+} "$ssrc"] {
105                error "ssrc $ssrc invalid"
106        }
107
108        if {[array names INDEX $ssrc] != [list $ssrc]} {
109                # This is a source we've not seen before...
110                set         CNAME($ssrc) ""
111                set          NAME($ssrc) $ssrc
112                set         EMAIL($ssrc) ""
113                set         PHONE($ssrc) ""
114                set           LOC($ssrc) ""
115                set          TOOL($ssrc) ""
116                set          NOTE($ssrc) ""
117                set         CODEC($ssrc) unknown
118                set          GAIN($ssrc) 1.0
119                set          MUTE($ssrc) 0
120                set      DURATION($ssrc) ""
121                set   BUFFER_SIZE($ssrc) 0
122                set PLAYOUT_DELAY($ssrc) 0
123                set          SKEW($ssrc) 1.000
124                set   SPIKE_EVENTS($ssrc) 0         
125                set   SPIKE_TOGED($ssrc) 0         
126                set           RTT($ssrc) ""
127                set    PCKTS_RECV($ssrc) 0
128                set    PCKTS_LOST($ssrc) 0
129                set    PCKTS_MISO($ssrc) 0
130                set     PCKTS_DUP($ssrc) 0
131                set        JITTER($ssrc) 0
132                set     JIT_TOGED($ssrc) 0
133                set    LOSS_TO_ME($ssrc) 0
134                set  LOSS_FROM_ME($ssrc) 0
135                set  HEARD_LOSS_TO_ME($ssrc) 0
136                set  HEARD_LOSS_FROM_ME($ssrc) 0
137                set         INDEX($ssrc) $num_ssrc
138                set          SSRC($ssrc) $ssrc
139                incr num_ssrc
140                chart_add   $ssrc
141        }
142}
143
144proc window_plist {ssrc} {
145        global fw
146        regsub -all {@|\.} $ssrc {-} foo
147        return $fw.source-$foo
148}
149
150proc window_stats {ssrc} {
151        regsub -all {[\. ]} $ssrc {-} foo
152        return .stats$foo
153}
154
155# Commands to send message over the conference bus...
156proc output_mute {state} {
157    mbus_send "R" "audio.output.mute" "$state"
158    bargraphState .r.c.rx.au.pow.bar [expr ! $state]
159}
160
161proc input_mute {state} {
162    mbus_send "R" "audio.input.mute" "$state"
163    bargraphState .r.c.tx.au.pow.bar [expr ! $state]
164}
165
166proc set_vol {new_vol} {
167    global volume received
168    set volume $new_vol
169    if {$received(volume)} {
170        mbus_send "R" "audio.output.gain" $volume
171    }
172}
173
174proc set_gain {new_gain} {
175    global gain received
176    set gain $new_gain
177    if {$received(gain)} {
178        mbus_send "R" "audio.input.gain" $gain
179    }
180}
181
182proc toggle_iport {} {
183    global iport iports
184
185    set len [llength $iports]
186# lsearch returns -1 if not found, index otherwise
187    set idx [lsearch -exact $iports $iport]
188
189    if {$idx != -1} {
190        incr idx
191        set idx [expr $idx % $len]
192        set port [lindex $iports $idx]
193        mbus_send "R" "audio.input.port" [mbus_encode_str $port]
194    }
195}
196
197proc incr_port {varname listname delta} {
198    upvar $varname  port
199    upvar $listname ports
200    set len [llength $ports]
201# lsearch returns -1 if not found, index otherwise
202    set idx [lsearch -exact $ports $port]
203   
204    if {$idx != -1} {
205        incr idx $delta
206        if {$idx < 0} {
207            set idx [expr $len - 1]
208        } elseif {$idx >= $len} {
209            set idx 0
210        }
211        set port [lindex $ports $idx]
212# yuechh!
213        if {$varname == "iport"} {
214            mbus_send "R" "audio.input.port" [mbus_encode_str $port]
215        } else {
216            mbus_send "R" "audio.output.port" [mbus_encode_str $port]
217        }
218    }
219}
220
221proc mbus_heartbeat {} {
222}
223
224#############################################################################################################
225# Reception of Mbus messages...
226
227proc mbus_recv {cmnd args} {
228        # This is not the most efficient way of doing this, since we could call mbus_recv_...
229        # directly from the C code. It does, however, make it explicit which Mbus commands we
230        # understand.
231        switch $cmnd {
232                mbus.waiting                    {eval mbus_recv_mbus.waiting $args}
233                mbus.go                         {eval mbus_recv_mbus.go $args}
234                mbus.hello                      {eval mbus_recv_mbus.hello $args}
235                mbus.quit                       {eval mbus_recv_mbus.quit $args}
236                tool.rat.sampling.supported     {eval mbus_recv_tool.rat.sampling.supported $args}
237                tool.rat.converter              {eval mbus_recv_tool.rat.converter $args}
238                tool.rat.converters.flush       {eval mbus_recv_tool.rat.converters.flush $args}
239                tool.rat.converters.add         {eval mbus_recv_tool.rat.converters.add $args}
240                tool.rat.repairs.flush          {eval mbus_recv_tool.rat.repairs.flush $args}
241                tool.rat.repairs.add            {eval mbus_recv_tool.rat.repairs.add $args}
242                tool.rat.powermeter             {eval mbus_recv_tool.rat.powermeter $args}
243                tool.rat.agc                    {eval mbus_recv_tool.rat.agc $args}
244                tool.rat.format.in              {eval mbus_recv_tool.rat.format.in $args}
245                tool.rat.codec                  {eval mbus_recv_tool.rat.codec $args}
246                tool.rat.codec.details          {eval mbus_recv_tool.rat.codec.details $args}
247                tool.rat.rate                   {eval mbus_recv_tool.rat.rate $args}
248                tool.rat.lecture.mode           {eval mbus_recv_tool.rat.lecture.mode $args}
249                tool.rat.audio.buffered         {eval mbus_recv_tool.rat.audio.buffered $args}
250                tool.rat.audio.delay            {eval mbus_recv_tool.rat.audio.delay $args}
251                tool.rat.audio.skew             {eval mbus_recv_tool.rat.audio.skew $args}
252                tool.rat.spike.events           {eval mbus_recv_tool.rat.spike.events $args}
253                tool.rat.spike.toged            {eval mbus_recv_tool.rat.spike.toged $args}
254                tool.rat.rtt                    {eval mbus_recv_tool.rat.rtt $args}
255                tool.rat.3d.enabled             {eval mbus_recv_tool.rat.3d.enabled $args}
256                tool.rat.3d.azimuth.min         {eval mbus_recv_tool.rat.3d.azimuth.min $args}
257                tool.rat.3d.azimuth.max         {eval mbus_recv_tool.rat.3d.azimuth.max $args}
258                tool.rat.3d.filter.types        {eval mbus_recv_tool.rat.3d.filter.types   $args}
259                tool.rat.3d.filter.lengths      {eval mbus_recv_tool.rat.3d.filter.lengths $args}
260                tool.rat.3d.user.settings       {eval mbus_recv_tool.rat.3d.user.settings  $args}
261                tool.rat.playout.limit          {eval mbus_recv_tool.rat.playout.limit $args}
262                tool.rat.playout.min            {eval mbus_recv_tool.rat.playout.min   $args}
263                tool.rat.playout.max            {eval mbus_recv_tool.rat.playout.max   $args}
264                tool.rat.echo.suppress          {eval mbus_recv_tool.rat.echo.suppress $args}
265                tool.rat.loopback               {eval mbus_recv_tool.rat.loopback      $args}
266                tool.rat.bps.in                 {eval mbus_recv_tool.rat.bps.in        $args}
267                tool.rat.bps.out                {eval mbus_recv_tool.rat.bps.out       $args}
268                audio.suppress.silence          {eval mbus_recv_audio.suppress.silence $args}
269                audio.channel.coding            {eval mbus_recv_audio.channel.coding $args}
270                audio.channel.repair            {eval mbus_recv_audio.channel.repair $args}
271                audio.devices.flush             {eval mbus_recv_audio_devices_flush $args}
272                audio.devices.add               {eval mbus_recv_audio_devices_add $args}
273                audio.device                    {eval mbus_recv_audio_device $args}
274                audio.input.gain                {eval mbus_recv_audio.input.gain $args}
275                audio.input.port                {eval mbus_recv_audio.input.port $args}
276                audio.input.ports.add           {eval mbus_recv_audio.input.ports.add $args}
277                audio.input.ports.flush         {eval mbus_recv_audio.input.ports.flush $args}
278                audio.input.mute                {eval mbus_recv_audio.input.mute $args}
279                audio.input.powermeter          {eval mbus_recv_audio.input.powermeter $args}
280                audio.output.gain               {eval mbus_recv_audio.output.gain $args}
281                audio.output.port               {eval mbus_recv_audio.output.port $args}
282                audio.output.ports.add          {eval mbus_recv_audio.output.ports.add $args}
283                audio.output.ports.flush        {eval mbus_recv_audio.output.ports.flush $args}
284                audio.output.mute               {eval mbus_recv_audio.output.mute $args}
285                audio.output.powermeter         {eval mbus_recv_audio.output.powermeter $args}
286                audio.file.play.ready           {eval mbus_recv_audio.file.play.ready   $args}
287                audio.file.play.alive           {eval mbus_recv_audio.file.play.alive $args}
288                audio.file.record.ready         {eval mbus_recv_audio.file.record.ready $args}
289                audio.file.record.alive         {eval mbus_recv_audio.file.record.alive $args}
290                session.title                   {eval mbus_recv_session.title $args}
291                rtp.addr                        {eval mbus_recv_rtp.addr $args}
292                rtp.ssrc                        {eval mbus_recv_rtp.ssrc $args}
293                rtp.source.exists               {eval mbus_recv_rtp.source.exists $args}
294                rtp.source.remove               {eval mbus_recv_rtp.source.remove $args}
295                rtp.source.cname                {eval mbus_recv_rtp.source.cname $args}
296                rtp.source.name                 {eval mbus_recv_rtp.source.name $args}
297                rtp.source.email                {eval mbus_recv_rtp.source.email $args}
298                rtp.source.phone                {eval mbus_recv_rtp.source.phone $args}
299                rtp.source.loc                  {eval mbus_recv_rtp.source.loc $args}
300                rtp.source.tool                 {eval mbus_recv_rtp.source.tool $args}
301                rtp.source.note                 {eval mbus_recv_rtp.source.note $args}
302                rtp.source.codec                {eval mbus_recv_rtp.source.codec $args}
303                rtp.source.packet.duration      {eval mbus_recv_rtp.source.packet.duration $args}
304                rtp.source.packet.loss          {eval mbus_recv_rtp.source.packet.loss $args}
305                rtp.source.reception            {eval mbus_recv_rtp.source.reception $args}
306                rtp.source.active               {eval mbus_recv_rtp.source.active $args}
307                rtp.source.inactive             {eval mbus_recv_rtp.source.inactive $args}
308                rtp.source.mute                 {eval mbus_recv_rtp.source.mute $args}
309                rtp.source.gain                 {eval mbus_recv_rtp.source.gain $args}
310                security.encryption.key         {eval mbus_recv_security.encryption.key $args}
311                default                         {puts "Unknown mbus command $cmnd"}
312        }
313}
314
315proc mbus_recv_mbus.waiting {condition} {
316        if {$condition == "rat.ui.init"} {
317                mbus_send "U" "mbus.go" [mbus_encode_str rat.ui.init]
318        }
319}
320
321proc mbus_recv_mbus.go {condition} {
322}
323
324proc mbus_recv_mbus.hello {} {
325        # Ignore...
326}
327
328proc change_freq {new_freq} {
329    global freq
330
331    if {$freq != $new_freq} {
332        set freq $new_freq
333        update_channels_displayed
334        update_codecs_displayed
335        reset_encodings
336    }
337}
338
339proc change_channels {new_channels} {
340    global ichannels
341    if {$ichannels != $new_channels} {
342        set ichannels $new_channels
343        update_codecs_displayed
344        reset_encodings
345    }
346}
347
348proc update_channels_displayed {} {
349    global freq channel_support
350
351    set m1 .prefs.pane.audio.dd.sampling.ch_in.mb.m
352    $m1 delete 0 last
353    set s [lsearch -glob $channel_support *$freq*]
354   
355    foreach i [lrange [split [lindex $channel_support $s] ","] 1 2] {
356         $m1 add command -label "$i" -command "change_channels $i"
357    }
358}
359
360proc mbus_recv_tool.rat.sampling.supported {arg} {
361    global freq channel_support
362
363    #clear away old state of channel support
364    if [info exists channel_support] {
365        unset channel_support
366    }
367
368    set freqs [list]
369    set channel_support [list]
370
371    .prefs.pane.audio.dd.sampling.freq.mb.m delete 0 last
372
373    set mode [split $arg]
374    foreach m $mode {
375        lappend channel_support $m
376        set support [split $m ","]
377        set f [lindex $support 0]
378        lappend freqs $f
379        .prefs.pane.audio.dd.sampling.freq.mb.m add command -label $f -command "change_freq $f"
380    }
381    set freq [lindex $freqs 0]
382    update_channels_displayed
383}
384
385# CODEC HANDLING ##############################################################
386
387set codecs {}
388set prencs  {}
389set secencs {}
390set layerencs {}
391
392proc codec_get_name {nickname freq channels} {
393    global codecs codec_nick_name codec_rate codec_channels
394
395    foreach {c} $codecs {
396        if {$codec_nick_name($c)    == $nickname && \
397                $codec_rate($c)     == $freq && \
398                $codec_channels($c) == $channels} {
399            return $c
400        }
401    }
402}
403
404proc codecs_loosely_matching {freq channels} {
405    global codecs codec_nick_name codec_channels codec_rate codec_pt codec_state_size codec_data_size codec_block_size codec_desc
406   
407    set x {}
408
409    foreach {c} $codecs {
410        if {$codec_channels($c) == $channels && \
411        $codec_rate($c) == $freq && \
412        $codec_pt($c) != "-" } {
413            lappend x $c
414        }
415    }
416
417    return $x
418}
419
420proc codecs_matching {freq channels blocksize} {
421    global codec_block_size
422    set codecs [codecs_loosely_matching $freq $channels]
423
424    set x {}
425
426    foreach {c} $codecs {
427        if {$codec_block_size($c) == $blocksize} {
428            lappend x $c
429        }
430    }
431    return $x
432}
433
434proc mbus_recv_tool.rat.codec.details {args} {
435    catch {
436        global codecs codec_nick_name codec_channels codec_rate codec_pt codec_state_size codec_data_size codec_block_size codec_desc codec_caps codec_layers
437       
438        set name [lindex $args 1]
439        if {[lsearch $codecs $name] == -1} {
440            lappend codecs $name
441        }
442        set codec_pt($name)         [lindex $args 0]
443        set codec_nick_name($name)  [lindex $args 2]
444        set codec_channels($name)   [lindex $args 3]
445        set codec_rate($name)       [lindex $args 4]
446        set codec_block_size($name) [lindex $args 5]
447        set codec_state_size($name) [lindex $args 6]
448        set codec_data_size($name)  [lindex $args 7]
449        set codec_desc($name)       [lindex $args 8]
450        set codec_caps($name)       [lindex $args 9]
451        set codec_layers($name)         [lindex $args 10]
452        set stackup ""
453    } details_error
454
455    if { $details_error != "" } {
456        puts "Error: $details_error"
457        destroy .
458        exit -1
459    }
460}
461
462proc update_primary_list {arg} {
463    # We now have a list of codecs which this RAT supports...
464    global prenc prencs
465
466    .prefs.pane.transmission.dd.pri.m.menu delete 0 last
467    set prencs {}
468
469    set codecs [split $arg]
470    foreach c $codecs {
471        .prefs.pane.transmission.dd.pri.m.menu    add command -label $c -command "set prenc $c; update_codecs_displayed"
472        lappend prencs $c
473    }
474
475    if {[lsearch $codecs $prenc] == -1} {
476        #primary is not on list
477        set prenc [lindex $codecs 0]
478    }
479}
480
481proc update_redundancy_list {arg} {
482    global secenc secencs
483
484    .prefs.pane.transmission.cc.red.fc.m.menu delete 0 last
485    set secencs {}
486
487    set codecs [split $arg]
488    foreach c $codecs {
489        .prefs.pane.transmission.cc.red.fc.m.menu add command -label $c -command "set secenc \"$c\""
490        lappend secencs $c
491    }
492    if {[lsearch $codecs $secenc] == -1} {
493        #primary is not on list
494        set secenc [lindex $codecs 0]
495    }
496}
497
498proc update_layer_list {arg} {
499    global layerenc layerencs
500
501    .prefs.pane.transmission.cc.layer.fc.m.menu delete 0 last
502    set layerencs {}
503
504    for {set i 1} {$i <= $arg} {incr i} {
505        .prefs.pane.transmission.cc.layer.fc.m.menu add command -label $i -command "set layerenc \"$i\""
506        lappend layerencs $i
507        }
508        if {$layerenc > $arg} {
509        #new codec doesn't support as many layers
510        set layerenc $arg
511        }
512}
513
514proc reset_encodings {} {
515    global prenc prencs secenc secencs layerenc layerencs
516    set prenc  [lindex $prencs 0]
517    set secenc [lindex $secencs 0]
518        set layerenc [lindex $layerencs 0]
519}
520
521proc update_codecs_displayed { } {
522    global freq ichannels codec_nick_name prenc codec_block_size codec_caps codec_layers
523
524    if {[string match $ichannels Mono]} {
525        set sample_channels 1
526    } else {
527        set sample_channels 2
528    }
529
530    set sample_rate [string trimright $freq -kHz]
531    set sample_rate [expr $sample_rate * 1000]
532
533    set long_names [codecs_loosely_matching $sample_rate $sample_channels]
534
535    set friendly_names {}
536    foreach {n} $long_names {
537        # only interested in codecs that can (e)ncode
538        if {[string first $codec_caps($n) ncode]} {
539            lappend friendly_names $codec_nick_name($n)
540        }
541    }
542
543    update_primary_list $friendly_names
544
545    set long_name [codec_get_name $prenc $sample_rate $sample_channels]
546    set long_names [codecs_matching $sample_rate $sample_channels $codec_block_size($long_name)]
547
548    set friendly_names {}
549    set found 0
550    foreach {n} $long_names {
551        # Only display codecs of same or lower order as primary in primary list
552        if {$codec_nick_name($n) == $prenc} {
553            set found 1
554        }
555        if {$found} {
556            if {[string first $codec_caps($n) ncode]} {
557                lappend friendly_names $codec_nick_name($n)
558            }
559        }
560    }
561   
562    update_redundancy_list $friendly_names
563
564        # Assume that all codecs of one type support the same number of layers
565        foreach {n} $long_names {
566        if {$codec_nick_name($n) == $prenc} {
567        break
568        }
569        }
570        update_layer_list $codec_layers($n)
571}
572
573proc change_sampling { } {
574    update_channels_displayed
575    update_codecs_displayed
576}
577
578###############################################################################
579
580proc mbus_recv_tool.rat.converters.flush {} {
581    .prefs.pane.reception.r.ms.menu delete 0 last
582}
583
584proc mbus_recv_tool.rat.converters.add {arg} {
585    global convert_var
586    .prefs.pane.reception.r.ms.menu add command -label "$arg" -command "set convert_var \"$arg\""
587}
588
589proc mbus_recv_tool.rat.converter {arg} {
590    global convert_var
591    set convert_var $arg
592}
593
594proc mbus_recv_tool.rat.repairs.flush {} {
595    .prefs.pane.reception.r.m.menu delete 0 last
596}
597
598
599proc mbus_recv_tool.rat.repairs.add {arg} {
600    global repair_var
601    .prefs.pane.reception.r.m.menu add command -label "$arg" -command "set repair_var \"$arg\""
602}
603
604proc mbus_recv_audio_devices_flush {} {
605    .prefs.pane.audio.dd.device.mdev.menu delete 0 last
606}
607
608proc mbus_recv_audio_devices_add {arg} {
609    global audio_device
610
611    .prefs.pane.audio.dd.device.mdev.menu add command -label "$arg" -command "set audio_device \"$arg\""
612
613    set len [string length "$arg"]
614    set curr [.prefs.pane.audio.dd.device.mdev cget -width]
615
616    if {$len > $curr} {
617        .prefs.pane.audio.dd.device.mdev configure -width $len
618    }
619}
620
621proc mbus_recv_audio_device {arg} {
622        global audio_device
623        set audio_device $arg
624}
625
626proc mbus_recv_tool.rat.powermeter {arg} {
627        global meter_var
628        set meter_var $arg
629}
630
631proc mbus_recv_tool.rat.agc {arg} {
632  global agc_var
633  set agc_var $arg
634}
635
636proc mbus_recv_security.encryption.key {new_key} {
637        global key_var key
638        set key_var 1
639        set key     $new_key
640}
641
642proc mbus_recv_tool.rat.format.in {arg} {
643    global freq ichannels
644#expect arg to be <sample_type>,<sample rate>,<mono/stereo>
645    set e [split $arg ","]
646   
647    set freq      [lindex $e 1]
648    set ichannels [lindex $e 2]
649}
650
651proc mbus_recv_tool.rat.codec {arg} {
652  global prenc
653  set prenc $arg
654}
655
656proc mbus_recv_tool.rat.rate {arg} {
657    global upp
658    set upp $arg
659}
660
661proc mbus_recv_audio.channel.coding {args} {
662    global channel_var secenc red_off int_units int_gap prenc layerenc
663
664    set channel_var [lindex $args 0]
665
666    switch [string tolower $channel_var] {
667        redundancy {
668                set secenc  [lindex $args 1]
669                set red_off [lindex $args 2]
670        }
671        interleaved {
672                set int_units [lindex $args 1]
673                set int_gap   [lindex $args 2]
674        }
675        layering {
676#               should we be playing with primary encoding?
677#               set prenc         [lindex $args 1]
678                set layerenc  [lindex $args 2]
679        }
680    }
681}
682
683proc mbus_recv_audio.channel.repair {arg} {
684  global repair_var
685  set repair_var $arg
686}
687
688proc mbus_recv_audio.input.powermeter {level} {
689        global bargraphTotalHeight
690        bargraphSetHeight .r.c.tx.au.pow.bar [expr ($level * $bargraphTotalHeight) / 100]
691}
692
693proc mbus_recv_audio.output.powermeter {level} {
694        global bargraphTotalHeight
695        bargraphSetHeight .r.c.rx.au.pow.bar  [expr ($level * $bargraphTotalHeight) / 100]
696}
697
698proc mbus_recv_audio.input.gain {new_gain} {
699    global received gain
700    set received(gain) 1
701    set gain $new_gain
702}
703
704proc mbus_recv_audio.input.ports.flush {} {
705    global iports
706    set iports [list]
707}
708
709proc mbus_recv_audio.input.ports.add {port} {
710    global iports
711    lappend iports "$port"
712}
713
714proc mbus_recv_audio.input.port {port} {
715    global iport
716    set    iport $port
717}
718
719proc mbus_recv_audio.input.mute {val} {
720    global in_mute_var
721    set in_mute_var $val
722    bargraphState .r.c.tx.au.pow.bar [expr ! $val]
723}
724
725proc mbus_recv_audio.output.gain {new_gain} {
726    global received volume
727    set received(volume) 1
728    set volume $new_gain
729}
730
731proc mbus_recv_audio.output.port {port} {
732    global oport
733    set oport $port
734}
735
736proc mbus_recv_audio.output.ports.flush {} {
737    global oports
738    set oports [list]
739}
740
741proc mbus_recv_audio.output.ports.add {port} {
742    global oports
743    lappend oports "$port"
744}
745
746proc mbus_recv_audio.output.mute {val} {
747    global out_mute_var
748    set out_mute_var $val
749}
750
751proc mbus_recv_session.title {title} {
752    global session_title
753    set session_title \"$title\"
754    wm title . "RAT: $title"
755}
756
757proc mbus_recv_rtp.addr {addr rx_port tx_port ttl} {
758    global session_address group_addr
759    set group_addr $addr
760    set session_address "Address: $addr Port: $rx_port TTL: $ttl"
761}
762
763proc mbus_recv_tool.rat.lecture.mode {mode} {
764        global lecture_var
765        set lecture_var $mode
766}
767
768proc mbus_recv_audio.suppress.silence {mode} {
769        global silence_var
770        set silence_var $mode
771}
772
773proc mbus_recv_rtp.ssrc {ssrc} {
774        global my_ssrc
775
776        set my_ssrc $ssrc
777        init_source $ssrc
778        ssrc_update $ssrc
779#        puts "Got my_ssrc $ssrc"
780}
781
782proc mbus_recv_rtp.source.exists {ssrc} {
783        init_source $ssrc
784        chart_add $ssrc
785        ssrc_update $ssrc
786}
787
788proc mbus_recv_rtp.source.cname {ssrc cname} {
789        global CNAME NAME SSRC
790        init_source $ssrc
791        set CNAME($ssrc) $cname
792        if {[string compare $NAME($ssrc) $SSRC($ssrc)] == 0} {
793                set NAME($ssrc) $cname
794        }
795        chart_label $ssrc $NAME($ssrc)
796        ssrc_update $ssrc
797}
798
799proc mbus_recv_rtp.source.name {ssrc name} {
800        global NAME
801        init_source $ssrc
802        set NAME($ssrc) $name
803        chart_label $ssrc $name
804        ssrc_update $ssrc
805}
806
807proc mbus_recv_rtp.source.email {ssrc email} {
808        global EMAIL
809        init_source $ssrc
810        set EMAIL($ssrc) $email
811}
812
813proc mbus_recv_rtp.source.phone {ssrc phone} {
814        global PHONE
815        init_source $ssrc
816        set PHONE($ssrc) $phone
817}
818
819proc mbus_recv_rtp.source.loc {ssrc loc} {
820        global LOC
821        init_source $ssrc
822        set LOC($ssrc) $loc
823}
824
825proc mbus_recv_rtp.source.tool {ssrc tool} {
826        global TOOL my_ssrc tool_name
827        init_source $ssrc
828        set TOOL($ssrc) $tool
829        if {[info exists my_ssrc] && [string compare $ssrc $my_ssrc] == 0} {
830            global tool_name
831            # tool name looks like RAT x.x.x platform ....
832            # lose the platform stuff
833            set tool_frag [split $tool]
834            set tool_name "UCL [lindex $tool_frag 0] [lindex $tool_frag 1]"
835        }
836}
837
838proc mbus_recv_rtp.source.note {ssrc note} {
839        global NOTE
840        init_source $ssrc
841        set NOTE($ssrc) $note
842}
843
844
845proc mbus_recv_rtp.source.codec {ssrc codec} {
846        global CODEC
847        init_source $ssrc
848        set CODEC($ssrc) $codec
849}
850
851proc mbus_recv_rtp.source.gain {ssrc gain} {
852        global GAIN
853        init_source $ssrc
854        set GAIN($ssrc) $gain
855}
856
857proc mbus_recv_rtp.source.packet.duration {ssrc packet_duration} {
858        global DURATION
859        init_source $ssrc
860        set DURATION($ssrc) $packet_duration
861}
862
863proc mbus_recv_tool.rat.audio.buffered {ssrc buffered} {
864        global BUFFER_SIZE
865        init_source $ssrc
866        set BUFFER_SIZE($ssrc) $buffered
867}
868
869proc mbus_recv_tool.rat.audio.delay {ssrc len} {
870        global PLAYOUT_DELAY
871        init_source $ssrc
872        set PLAYOUT_DELAY($ssrc) $len
873}
874
875proc mbus_recv_tool.rat.audio.skew {ssrc skew} {
876        global SKEW
877        init_source $ssrc
878        set SKEW($ssrc) [format "%.3f" $skew]
879}
880
881proc mbus_recv_tool.rat.spike.events {ssrc events} {
882    global SPIKE_EVENTS
883    init_source $ssrc
884    set SPIKE_EVENTS($ssrc) $events
885}
886
887proc mbus_recv_tool.rat.spike.toged {ssrc toged} {
888    global SPIKE_TOGED
889    init_source $ssrc
890    set SPIKE_TOGED($ssrc) $toged
891}
892
893proc mbus_recv_tool.rat.rtt {ssrc rtt} {
894    global RTT
895    init_source $ssrc
896    if {$rtt != 0} {
897        set RTT($ssrc) $rtt
898    }
899}
900
901proc mbus_recv_tool.rat.3d.enabled {mode} {
902        global 3d_audio_var
903        set 3d_audio_var $mode
904}
905
906proc mbus_recv_tool.rat.3d.azimuth.min {min} {
907    global 3d_azimuth
908    set 3d_azimuth(min) $min
909}
910
911proc mbus_recv_tool.rat.3d.azimuth.max {max} {
912    global 3d_azimuth
913    set 3d_azimuth(max) $max
914}
915
916proc mbus_recv_tool.rat.3d.filter.types {args} {
917    global 3d_filters
918    set 3d_filters [split $args ","]
919}
920
921proc mbus_recv_tool.rat.3d.filter.lengths {args} {
922    global 3d_filter_lengths
923    set 3d_filter_lengths [split $args ","]
924}
925
926proc mbus_recv_tool.rat.3d.user.settings {args} {
927    global filter_type filter_length azimuth
928    set ssrc                 [lindex $args 0]
929    set filter_type($ssrc)   [lindex $args 1]
930    set filter_length($ssrc) [lindex $args 2]
931    set azimuth($ssrc)       [lindex $args 3]
932}
933
934proc mbus_recv_rtp.source.packet.loss {dest srce loss} {
935        global my_ssrc LOSS_FROM_ME LOSS_TO_ME HEARD_LOSS_FROM_ME HEARD_LOSS_TO_ME
936        init_source $srce
937        init_source $dest
938        chart_set $srce $dest $loss
939        if {[string compare $dest $my_ssrc] == 0} {
940                set LOSS_TO_ME($srce) $loss
941                set HEARD_LOSS_TO_ME($srce) 1
942        }
943        if {[string compare $srce $my_ssrc] == 0} {
944                set LOSS_FROM_ME($dest) $loss
945                set HEARD_LOSS_FROM_ME($dest) 1
946        }
947        ssrc_update $srce
948        ssrc_update $dest
949}
950
951proc mbus_recv_rtp.source.reception {ssrc packets_recv packets_lost packets_miso packets_dup jitter jit_tog} {
952        global PCKTS_RECV PCKTS_LOST PCKTS_MISO PCKTS_DUP JITTER JIT_TOGED
953        init_source $ssrc
954        set PCKTS_RECV($ssrc) $packets_recv
955        set PCKTS_LOST($ssrc) $packets_lost
956        set PCKTS_MISO($ssrc) $packets_miso
957        set PCKTS_DUP($ssrc)  $packets_dup
958        set JITTER($ssrc) $jitter
959        set JIT_TOGED($ssrc) $jit_tog
960}
961
962proc mbus_recv_rtp.source.active {ssrc} {
963        global speaker_highlight
964        init_source $ssrc
965        ssrc_update $ssrc
966        [window_plist $ssrc] configure -background $speaker_highlight
967}
968
969proc mbus_recv_rtp.source.inactive {ssrc} {
970        init_source $ssrc
971        ssrc_update $ssrc
972        [window_plist $ssrc] configure -background [.l.t.list cget -bg]
973}
974
975proc mbus_recv_rtp.source.remove {ssrc} {
976    global CNAME NAME EMAIL LOC PHONE TOOL NOTE CODEC DURATION PCKTS_RECV    \
977           PCKTS_LOST PCKTS_MISO PCKTS_DUP JITTER BUFFER_SIZE PLAYOUT_DELAY  \
978           LOSS_TO_ME LOSS_FROM_ME INDEX JIT_TOGED num_ssrc loss_to_me_timer \
979           loss_from_me_timer GAIN MUTE HEARD_LOSS_TO_ME HEARD_LOSS_FROM_ME  \
980           SKEW SPIKE_EVENTS SPIKE_TOGED RTT
981
982    # Disable updating of loss diamonds. This has to be done before we destroy the
983    # window representing the participant, else the background update may try to
984    # access a window which has been destroyed...
985    catch {after cancel $loss_to_me_timer($ssrc)}
986    catch {after cancel $loss_from_me_timer($ssrc)}
987   
988    chart_remove $ssrc
989
990    catch [destroy [window_plist $ssrc]]
991    if { [info exists CNAME($ssrc)] } {
992        unset CNAME($ssrc) NAME($ssrc) EMAIL($ssrc) PHONE($ssrc) LOC($ssrc) TOOL($ssrc) NOTE($ssrc)
993        unset CODEC($ssrc) DURATION($ssrc) PCKTS_RECV($ssrc) PCKTS_LOST($ssrc) PCKTS_MISO($ssrc) PCKTS_DUP($ssrc)
994        unset JITTER($ssrc) LOSS_TO_ME($ssrc) LOSS_FROM_ME($ssrc) INDEX($ssrc) JIT_TOGED($ssrc) BUFFER_SIZE($ssrc)
995        unset PLAYOUT_DELAY($ssrc) GAIN($ssrc) MUTE($ssrc) SKEW($ssrc) SPIKE_EVENTS($ssrc) SPIKE_TOGED($ssrc) RTT($ssrc)
996        incr num_ssrc -1
997    }
998    if { [info exists HEARD_LOSS_TO_ME($ssrc)] } {
999        unset HEARD_LOSS_TO_ME($ssrc)
1000    }
1001    if { [info exists HEARD_LOSS_FROM_ME($ssrc)] } {
1002        unset HEARD_LOSS_FROM_ME($ssrc)
1003    }
1004    set stats_win [window_stats $ssrc]
1005    if { [winfo exists $stats_win] } {
1006        destroy $stats_win
1007    }
1008}
1009
1010proc mbus_recv_rtp.source.mute {ssrc val} {
1011        global iht MUTE
1012        set MUTE($ssrc) $val
1013        if {$val} {
1014                [window_plist $ssrc] create line [expr $iht + 2] [expr $iht / 2] 500 [expr $iht / 2] -tags a -width 2.0 -fill gray95
1015        } else {
1016                catch [[window_plist $ssrc] delete a]
1017        }
1018}
1019
1020proc mbus_recv_audio.file.play.ready {name} {
1021    global play_file
1022    set    play_file(name) $name
1023
1024    if {$play_file(state) != "play"} {
1025        file_enable_play
1026    }
1027}
1028
1029proc mbus_recv_audio.file.play.alive {alive} {
1030   
1031    global play_file
1032
1033    if {$alive} {
1034        after 200 file_play_live
1035    } else {
1036        set play_file(state) end
1037        file_enable_play
1038    }
1039}
1040
1041proc mbus_recv_audio.file.record.ready {name} {
1042    global rec_file
1043    set    rec_file(name) $name
1044    if {$rec_file(state) != "record"} {
1045        file_enable_record
1046    }
1047}
1048
1049proc mbus_recv_audio.file.record.alive {alive} {
1050        global rec_file
1051        if {$alive} {
1052                after 200 file_rec_live
1053        } else {
1054                set rec_file(state) end
1055                file_enable_record                                         
1056        }
1057}
1058
1059proc mbus_recv_tool.rat.playout.limit {e} {
1060    global limit_var
1061    set limit_var $e
1062}
1063
1064proc mbus_recv_tool.rat.playout.min {l} {
1065    global min_var
1066    set min_var $l
1067}
1068
1069proc mbus_recv_tool.rat.playout.max {u} {
1070    global max_var
1071    set max_var $u
1072}
1073
1074proc mbus_recv_tool.rat.echo.suppress {e} {
1075    global echo_var
1076    set echo_var $e
1077}
1078
1079proc mbus_recv_tool.rat.loopback {l} {
1080    global audio_loop_var
1081    set audio_loop_var $l
1082}
1083
1084proc format_bps {bps} {
1085    if {$bps < 999} {
1086        set s "b/s"
1087    } elseif {$bps < 999999} {
1088        set s "kb/s"
1089        set bps [expr $bps / 1000.0]
1090    } else {
1091        set s "Mb/s"
1092        set bps [expr $bps / 1000000.0]
1093    }
1094    return [format "%.1f %s" $bps $s]
1095}
1096
1097proc mbus_recv_tool.rat.bps.in {bps} {
1098    global bps_in
1099    set    bps_in [format_bps $bps]
1100}
1101
1102proc mbus_recv_tool.rat.bps.out {bps} {
1103    global bps_out
1104    set    bps_out [format_bps $bps]
1105}
1106
1107proc mbus_recv_mbus.quit {} {
1108        destroy .
1109}
1110
1111#############################################################################################################
1112
1113proc set_loss_to_me {ssrc loss} {
1114        global prev_loss_to_me loss_to_me_timer
1115
1116        catch {after cancel $loss_to_me_timer($ssrc)}
1117        set loss_to_me_timer($ssrc) [after 7500 catch \"[window_plist $ssrc] itemconfigure h -fill grey\"]
1118
1119        if {$loss < 5} {
1120                catch [[window_plist $ssrc] itemconfigure m -fill green]
1121        } elseif {$loss < 10} {
1122                catch [[window_plist $ssrc] itemconfigure m -fill orange]
1123        } elseif {$loss <= 100} {
1124                catch [[window_plist $ssrc] itemconfigure m -fill red]
1125        } else {
1126                catch [[window_plist $ssrc] itemconfigure m -fill grey]
1127        }
1128}
1129
1130proc set_loss_from_me {ssrc loss} {
1131        global prev_loss_from_me loss_from_me_timer
1132
1133        catch {after cancel $loss_from_me_timer($ssrc)}
1134        set loss_from_me_timer($ssrc) [after 7500 catch \"[window_plist $ssrc] itemconfigure h -fill grey\"]
1135
1136        if {$loss < 5} {
1137                catch [[window_plist $ssrc] itemconfigure h -fill green]
1138        } elseif {$loss < 10} {
1139                catch [[window_plist $ssrc] itemconfigure h -fill orange]
1140        } elseif {$loss <= 100} {
1141                catch [[window_plist $ssrc] itemconfigure h -fill red]
1142        } else {
1143                catch [[window_plist $ssrc] itemconfigure h -fill grey]
1144        }
1145}
1146
1147proc ssrc_update {ssrc} {
1148        # This procedure updates the on-screen representation of
1149        # a participant.
1150        global NAME LOSS_TO_ME LOSS_FROM_ME HEARD_LOSS_FROM_ME HEARD_LOSS_TO_ME
1151        global fw iht iwd my_ssrc
1152
1153        set cw [window_plist $ssrc]
1154
1155        if {[winfo exists $cw]} {
1156                $cw itemconfigure t -text $NAME($ssrc)
1157        } else {
1158                # Add this participant to the list...
1159                set thick 0
1160                set l $thick
1161                set h [expr $iht / 2 + $thick]
1162                set f [expr $iht + $thick]
1163                canvas $cw -width $iwd -height $f -highlightthickness $thick
1164                $cw create text [expr $f + 2] $h -anchor w -text $NAME($ssrc) -fill black -tag t
1165                $cw create polygon $l $h $h $l $h $f -outline black -fill grey -tag m
1166                $cw create polygon $f $h $h $l $h $f -outline black -fill grey -tag h
1167
1168                bind $cw <Button-1>         "toggle_stats \"$ssrc\""
1169                bind $cw <Button-2>         "toggle_mute $cw \"$ssrc\""
1170                bind $cw <Control-Button-1> "toggle_mute $cw \"$ssrc\""
1171
1172                if {[info exists my_ssrc] && ([string compare $ssrc $my_ssrc] == 0) && ([pack slaves $fw] != "")} {
1173                        pack $cw -before [lindex [pack slaves $fw] 0] -fill x
1174                }
1175                pack $cw -fill x
1176                fix_scrollbar
1177        }
1178
1179        if {[info exists HEARD_LOSS_TO_ME($ssrc)] && $HEARD_LOSS_TO_ME($ssrc) && $ssrc != $my_ssrc} {
1180            set_loss_to_me $ssrc $LOSS_TO_ME($ssrc)
1181        }
1182        if {[info exists HEARD_LOSS_FROM_ME($ssrc)] && $HEARD_LOSS_FROM_ME($ssrc) && $ssrc != $my_ssrc} {
1183            set_loss_from_me $ssrc $LOSS_FROM_ME($ssrc)
1184        }
1185}
1186
1187#power meters
1188
1189# Colors
1190set bargraphLitColors [list #00cc00 #00cc00 #00cc00 #00cc00 #00cc00 #00cc00 #00cc00 #00cc00 #00cc00 #00cc00 #00cc00 #00cc00 #2ccf00 #58d200 #84d500 #b0d800 #dddd00 #ddb000 #dd8300 #dd5600 #dd2900]
1191
1192set bargraphUnlitColors [list #006600 #006600 #006600 #006600 #006600 #006600 #006600 #006600 #006600 #006600 #006600 #006600 #166700 #2c6900 #426a00 #586c00 #6e6e00 #6e5800 #6e4100 #6e2b00 #6e1400]
1193set bargraphTotalHeight [llength $bargraphLitColors]
1194
1195proc bargraphCreate {bgraph} {
1196        global oh$bgraph bargraphTotalHeight bargraphUnlitColors
1197
1198        frame $bgraph -bd 0 -bg black
1199        for {set i 0} {$i < $bargraphTotalHeight} {incr i} {
1200                frame $bgraph.inner$i -bg "[lindex $bargraphUnlitColors $i]" -width 4 -height 6
1201                pack $bgraph.inner$i -side left -fill both -expand true -padx 1 -pady 1
1202        }
1203        set oh$bgraph 0
1204}
1205
1206proc bargraphSetHeight {bgraph height} {
1207        upvar #0 oh$bgraph oh
1208        global bargraphTotalHeight bargraphLitColors bargraphUnlitColors
1209
1210        if {$oh > $height} {
1211                for {set i [expr $height]} {$i <= $oh} {incr i} {
1212                        $bgraph.inner$i config -bg "[lindex $bargraphUnlitColors $i]"
1213                }
1214        } else {
1215            for {set i [expr $oh]} {$i <= $height} {incr i} {
1216                $bgraph.inner$i config -bg  "[lindex $bargraphLitColors $i]"
1217            }
1218        }
1219        set oh $height
1220}
1221
1222proc bargraphState {bgraph state} {
1223    upvar #0 oh$bgraph oh
1224    if {[winfo exists $bgraph]} {
1225        global bargraphTotalHeight bargraphUnlitColors
1226        if {$state} {
1227            for { set i 0 } { $i < $bargraphTotalHeight} {incr i} {
1228                $bgraph.inner$i config -bg "[lindex $bargraphUnlitColors $i]"
1229            }
1230        } else {
1231            for { set i 0 } { $i < $bargraphTotalHeight} {incr i} {
1232                $bgraph.inner$i config -bg black
1233            }
1234        }
1235    }
1236    set oh 0
1237}
1238
1239proc toggle {varname} {
1240    upvar 1 $varname local
1241    set local [expr !$local]
1242}
1243
1244proc toggle_plist {} {
1245        global plist_on
1246        if {$plist_on} {
1247                pack .l.t  -side top -fill both -expand 1 -padx 2
1248        } else {
1249                pack forget .l.t
1250        }
1251        update
1252        wm deiconify .
1253}
1254
1255proc toggle_mute {cw ssrc} {
1256        global iht
1257        if {[$cw gettags a] == ""} {
1258                mbus_send "R" "rtp.source.mute" "[mbus_encode_str $ssrc] 1"
1259        } else {
1260                mbus_send "R" "rtp.source.mute" "[mbus_encode_str $ssrc] 0"
1261        }
1262}
1263
1264proc send_gain_and_mute {ssrc} {
1265        global GAIN MUTE
1266        mbus_send "R" "rtp.source.gain" "[mbus_encode_str $ssrc] $GAIN($ssrc)"
1267        mbus_send "R" "rtp.source.mute" "[mbus_encode_str $ssrc] $MUTE($ssrc)"
1268}
1269
1270proc fix_scrollbar {} {
1271        global iht iwd fw
1272
1273        set ch [expr $iht * ([llength [pack slaves $fw]] + 2)]
1274        set bh [winfo height .l.t.scr]
1275        if {$ch > $bh} {set h $ch} else {set h $bh}
1276        .l.t.list configure -scrollregion "0.0 0.0 $iwd $h"
1277}
1278
1279proc info_timer {} {
1280        global cancel_info_timer
1281        if {$cancel_info_timer == 1} {
1282                set cancel_info_timer 0
1283        } else {
1284                update_rec_info
1285                after 1000 info_timer
1286        }
1287}
1288
1289proc stats_add_field {widget label watchVar} {
1290    global statsfont
1291    frame $widget
1292    label $widget.l -text $label -font $statsfont -anchor w
1293    label $widget.w -textvariable $watchVar -font $statsfont
1294    pack $widget -side top -fill x -anchor n
1295    pack $widget.l -side left  -fill x -expand 1
1296    pack $widget.w -side right
1297}
1298
1299proc ssrc_set_gain {ssrc gain} {
1300    global GAIN
1301    set    GAIN($ssrc) [format "%.2f " [expr pow (2, $gain)]]
1302    send_gain_and_mute $ssrc
1303}
1304
1305set 3d_azimuth(min) 0
1306set 3d_azimuth(max) 0
1307set 3d_filters        [list "Not Available"]
1308set 3d_filter_lengths [list "0"]
1309
1310proc toggle_stats {ssrc} {
1311    global statsfont
1312    set win [window_stats $ssrc]
1313    if {[winfo exists $win]} {
1314        destroy $win
1315    } else {
1316        global stats_pane
1317        # Window does not exist so create it
1318        toplevel $win 
1319        frame $win.mf
1320        pack $win.mf -padx 0 -pady 0
1321        label $win.mf.l -text "Category:"
1322       
1323        menubutton $win.mf.mb -menu $win.mf.mb.menu -indicatoron 1 -textvariable stats_pane($win) -relief raised -width 16
1324        pack $win.mf.l $win.mf.mb -side left
1325        menu $win.mf.mb.menu -tearoff 0
1326        $win.mf.mb.menu add command -label "Personal Details" -command "set_pane stats_pane($win) $win.df \"Personal Details\""
1327        $win.mf.mb.menu add command -label "Playout"          -command "set_pane stats_pane($win) $win.df Playout"
1328        $win.mf.mb.menu add command -label "Decoder"          -command "set_pane stats_pane($win) $win.df Decoder"
1329        $win.mf.mb.menu add command -label "Audio"            -command "set_pane stats_pane($win) $win.df Audio"
1330        $win.mf.mb.menu add command -label "3D Positioning"   -command "set_pane stats_pane($win) $win.df \"3D Positioning\""
1331
1332        set stats_pane($win) "Personal Details"
1333        frame $win.df
1334        frame $win.df.personal -relief groove -bd 2
1335        pack  $win.df -side top -anchor n -expand 1 -fill both
1336        pack $win.df.personal -expand 1 -fill both
1337
1338        global NAME EMAIL PHONE LOC NOTE CNAME TOOL SSRC
1339        stats_add_field $win.df.personal.1 "Name: "     NAME($ssrc)
1340        stats_add_field $win.df.personal.2 "Email: "    EMAIL($ssrc)
1341        stats_add_field $win.df.personal.3 "Phone: "    PHONE($ssrc)
1342        stats_add_field $win.df.personal.4 "Location: " LOC($ssrc)
1343        stats_add_field $win.df.personal.5 "Note: "     NOTE($ssrc)
1344        stats_add_field $win.df.personal.6 "Tool: "     TOOL($ssrc)
1345        stats_add_field $win.df.personal.7 "CNAME: "    CNAME($ssrc)
1346        stats_add_field $win.df.personal.8 "SSRC: "     SSRC($ssrc)
1347
1348        frame $win.df.playout -relief groove -bd 2
1349        global BUFFER_SIZE PLAYOUT_DELAY JITTER JIT_TOGED SKEW
1350        stats_add_field $win.df.playout.1 "Actual Playout (ms): "     BUFFER_SIZE($ssrc)
1351        stats_add_field $win.df.playout.2 "Target Playout (ms): "     PLAYOUT_DELAY($ssrc)
1352        stats_add_field $win.df.playout.3 "Arrival Jitter (ms): "     JITTER($ssrc)
1353        stats_add_field $win.df.playout.4 "Packets Dropped (jitter):" JIT_TOGED($ssrc)
1354        stats_add_field $win.df.playout.5 "Spike Events:"             SPIKE_EVENTS($ssrc)
1355        stats_add_field $win.df.playout.6 "Packets Dropped (spike):"  SPIKE_TOGED($ssrc)
1356        stats_add_field $win.df.playout.7 "Relative Clock Rate:"      SKEW($ssrc)
1357        stats_add_field $win.df.playout.8 "Round Trip Time (ms):"     RTT($ssrc)
1358
1359        frame $win.df.decoder -relief groove -bd 2
1360        global CODEC DURATION PCKTS_RECV PCKTS_LOST PCKTS_MISO \
1361               PCKTS_DUP LOSS_FROM_ME LOSS_TO_ME
1362        stats_add_field $win.df.decoder.1 "Audio encoding: "         CODEC($ssrc)
1363        stats_add_field $win.df.decoder.2 "Packet duration (ms): "   DURATION($ssrc)
1364        stats_add_field $win.df.decoder.3 "Loss from me (%): "       LOSS_FROM_ME($ssrc)
1365        stats_add_field $win.df.decoder.4 "Loss to me (%): "         LOSS_TO_ME($ssrc)
1366        stats_add_field $win.df.decoder.5 "Packets received: "       PCKTS_RECV($ssrc)
1367        stats_add_field $win.df.decoder.6 "Packets lost: "           PCKTS_LOST($ssrc)
1368        stats_add_field $win.df.decoder.7 "Packets misordered: "     PCKTS_MISO($ssrc)
1369        stats_add_field $win.df.decoder.8 "Packets duplicated: "     PCKTS_DUP($ssrc)
1370
1371# Audio settings
1372        global GAIN MUTE
1373        frame $win.df.audio -relief groove -bd 2
1374        label $win.df.audio.advice -text "The signal from the participant can\nbe scaled and muted with the controls below."
1375        pack  $win.df.audio.advice
1376
1377        checkbutton $win.df.audio.mute -text "Mute" -variable MUTE($ssrc) -command "send_gain_and_mute $ssrc"
1378        pack $win.df.audio.mute
1379
1380        frame $win.df.audio.opts
1381        pack  $win.df.audio.opts -side top
1382        label $win.df.audio.opts.title -text "Gain"
1383        scale $win.df.audio.opts.gain_scale -showvalue 0 -orient h -from -3 -to +3 -resolution 0.25 -command "ssrc_set_gain $ssrc"
1384        label $win.df.audio.opts.gain_text -textvariable GAIN($ssrc) -width 4
1385        pack  $win.df.audio.opts.title $win.df.audio.opts.gain_scale $win.df.audio.opts.gain_text -side left
1386
1387        $win.df.audio.opts.gain_scale set [expr log10($GAIN($ssrc)) / log10(2)]
1388
1389        button $win.df.audio.default -text "Default" -command "set MUTE($ssrc) 0; $win.df.audio.opts.gain_scale set 0.0; send_gain_and_mute $ssrc" 
1390        pack   $win.df.audio.default -side bottom  -anchor e -padx 2 -pady 2
1391
1392# 3D settings
1393        # Trigger engine to send details for this participant
1394        mbus_send "R" "tool.rat.3d.user.settings.request" [mbus_encode_str $ssrc]
1395
1396        frame $win.df.3d -relief groove -bd 2
1397        label $win.df.3d.advice -text "These options allow the rendering of the\nparticipant to be altered when 3D\nrendering is enabled."
1398        checkbutton $win.df.3d.ext -text "3D Audio Rendering" -variable 3d_audio_var
1399        pack $win.df.3d.advice
1400        pack $win.df.3d.ext
1401
1402        frame $win.df.3d.opts
1403        pack $win.df.3d.opts -side top
1404
1405        frame $win.df.3d.opts.filters
1406        label $win.df.3d.opts.filters.l -text "Filter Type:"
1407        pack $win.df.3d.opts.filters.l -side left -fill x -expand 1 -anchor n
1408        global 3d_filters 3d_filter_lengths
1409       
1410        global filter_type
1411        set filter_type($ssrc) [lindex $3d_filters 0]
1412
1413        set cnt 0
1414        foreach i $3d_filters {
1415            radiobutton $win.df.3d.opts.filters.$cnt \
1416                    -value "$i" -variable filter_type($ssrc) \
1417                    -text "$i"
1418                pack $win.df.3d.opts.filters.$cnt -side top -anchor w
1419            incr cnt
1420        }
1421
1422        frame $win.df.3d.opts.lengths
1423        label $win.df.3d.opts.lengths.l -text "Length:"
1424        pack $win.df.3d.opts.lengths.l -side left -fill x -expand 1 -anchor n
1425       
1426        global filter_length
1427        set filter_length($ssrc) [lindex $3d_filter_lengths 0]
1428       
1429        set cnt 0
1430        foreach i $3d_filter_lengths {
1431            radiobutton $win.df.3d.opts.lengths.$cnt \
1432                    -value "$i" -variable filter_length($ssrc) \
1433                    -text "$i"
1434            pack $win.df.3d.opts.lengths.$cnt -side top -anchor w
1435            incr cnt
1436        }
1437        pack $win.df.3d.opts.filters -side left -expand 1 -anchor n -fill x
1438        pack $win.df.3d.opts.lengths -side right -expand 1 -anchor n -fill x
1439       
1440        global 3d_azimuth azimuth
1441        frame $win.df.3d.azi
1442        label $win.df.3d.azi.lab -text "Azimuth:"
1443        scale $win.df.3d.azi.sca -from $3d_azimuth(min) -to $3d_azimuth(max) \
1444                -orient horizontal -variable azimuth($ssrc)
1445        pack  $win.df.3d.azi
1446        pack $win.df.3d.azi.lab $win.df.3d.azi.sca -side left
1447
1448        button $win.df.3d.apply -text "Apply" -command "3d_send_parameters $ssrc"
1449        pack   $win.df.3d.apply -side bottom  -anchor e -padx 2 -pady 2
1450
1451# Window Magic
1452        frame  $win.dis
1453        button $win.dis.b -text "Dismiss" -command "destroy $win; 3d_delete_parameters $ssrc"
1454        pack   $win.dis   -side bottom -anchor e
1455        pack   $win.dis.b -side right -anchor e -padx 2 -pady 2
1456        wm title $win "Participant $NAME($ssrc)"
1457#       wm resizable $win 1 1
1458        constrain_window $win $statsfont 36 24
1459    }
1460}
1461
1462proc 3d_send_parameters {ssrc} {
1463    global azimuth filter_type filter_length 3d_audio_var
1464
1465    mbus_send "R" "tool.rat.3d.enabled"   $3d_audio_var
1466    mbus_send "R" "tool.rat.3d.user.settings" "[mbus_encode_str $ssrc] [mbus_encode_str $filter_type($ssrc)] $filter_length($ssrc) $azimuth($ssrc)"
1467}
1468
1469proc 3d_delete_parameters {ssrc} {
1470    global filter_type filter_length azimuth
1471   
1472# None of these should ever fail, but you can't be too defensive...
1473    catch {
1474        unset filter_type($ssrc)
1475        unset filter_length($ssrc)
1476        unset azimuth($ssrc)
1477    }
1478}
1479
1480proc do_quit {} {
1481        catch {
1482                profile off pdat
1483                profrep pdat cpu
1484        }
1485        destroy .
1486}
1487
1488# Initialise RAT MAIN window
1489frame .r
1490frame .l
1491frame .l.t -relief groove -bd 2
1492scrollbar .l.t.scr -relief flat -highlightthickness 0 -command ".l.t.list yview"
1493canvas .l.t.list -highlightthickness 0 -bd 0 -relief flat -width $iwd -height 120 -yscrollcommand ".l.t.scr set" -yscrollincrement $iht
1494frame .l.t.list.f -highlightthickness 0 -bd 0
1495.l.t.list create window 0 0 -anchor nw -window .l.t.list.f
1496
1497frame .l.f -relief groove -bd 2
1498label .l.f.title -bd 0 -textvariable session_title -justify center
1499label .l.f.addr  -bd 0 -textvariable session_address
1500
1501frame  .st -bd 0
1502label  .st.tool -textvariable tool_name -font $infofont -justify center -pady 0
1503button .st.opts  -text "Options"   -command {wm deiconify .prefs; update_user_panel; raise .prefs}
1504button .st.about -text "About"     -command {jiggle_credits; wm deiconify .about}
1505button .st.quit  -text "Quit"      -command do_quit
1506
1507frame .r.c -bd 0
1508frame .r.c.rx -relief groove -bd 2
1509frame .r.c.tx -relief groove -bd 2
1510
1511pack .st -side bottom -fill x -padx 2 -pady 0
1512pack .st.tool -side left -fill both -expand 1
1513
1514pack .st.quit .st.about .st.opts -side right -anchor w -padx 2 -pady 2
1515
1516pack .r -side top -fill x -padx 2
1517pack .r.c -side top -fill x -expand 1
1518pack .r.c.rx -side left -fill x -expand 1
1519pack .r.c.tx -side left -fill x -expand 1
1520
1521pack .l -side top -fill both -expand 1
1522pack .l.f -side bottom -fill x -padx 2 -pady 2
1523pack .l.f.title .l.f.addr -side top -pady 2 -anchor w -fill x
1524pack .l.t  -side top -fill both -expand 1 -padx 2
1525pack .l.t.scr -side left -fill y
1526pack .l.t.list -side left -fill both -expand 1
1527bind .l.t.list <Configure> {fix_scrollbar}
1528
1529# Device output controls
1530set out_mute_var 0
1531frame .r.c.rx.net
1532frame .r.c.rx.au
1533
1534pack .r.c.rx.net -side top -anchor n -fill both
1535pack .r.c.rx.au -side bottom -expand 1 -fill both
1536
1537checkbutton .r.c.rx.net.on -highlightthickness 0 -text "Listen" -onvalue 0 -offvalue 1 -variable out_mute_var -command {output_mute $out_mute_var} -font $compfont -width 5 -anchor w -padx 4
1538label       .r.c.rx.net.bw -textv bps_in -font $compfont -anchor e
1539pack .r.c.rx.net.on -side left
1540pack .r.c.rx.net.bw -side right -fill x -expand 1
1541
1542frame  .r.c.rx.au.port -bd 0
1543button .r.c.rx.au.port.l0 -highlightthickness 0 -command {incr_port oport oports -1} -font $compfont -bitmap left -relief flat
1544label  .r.c.rx.au.port.l1 -highlightthickness 0 -textv oport -font $compfont -width 10
1545button .r.c.rx.au.port.l2 -highlightthickness 0 -command {incr_port oport oports +1} -font $compfont -bitmap right -relief flat
1546pack   .r.c.rx.au.port -side top -fill x -expand 1
1547pack   .r.c.rx.au.port.l0 -side left -fill y
1548pack   .r.c.rx.au.port.l1 -side left -fill x -expand 1
1549pack   .r.c.rx.au.port.l2 -side left -fill y
1550
1551frame  .r.c.rx.au.pow -relief sunk -bd 2
1552bargraphCreate .r.c.rx.au.pow.bar
1553scale .r.c.rx.au.pow.sli -highlightthickness 0 -from 0 -to 99 -command set_vol -orient horizontal -showvalue false -width 8 -variable volume -resolution 4 -bd 0 -troughcolor black -sliderl 16
1554pack .r.c.rx.au.pow .r.c.rx.au.pow.bar .r.c.rx.au.pow.sli -side top -fill both -expand 1
1555
1556# Device input controls
1557set in_mute_var 1
1558
1559frame .r.c.tx.net
1560frame .r.c.tx.au
1561
1562pack .r.c.tx.net -side top -anchor n  -fill both
1563pack .r.c.tx.au -side bottom -expand 1 -fill both
1564
1565checkbutton .r.c.tx.net.on -highlightthickness 0 -text "Talk" -onvalue 0 -offvalue 1 -variable in_mute_var -command {input_mute $in_mute_var} -font $compfont -width 5 -anchor w -padx 4
1566label       .r.c.tx.net.bw -textv bps_out -font $compfont -anchor e
1567pack .r.c.tx.net.on -side left
1568pack .r.c.tx.net.bw -side right -fill x -expand 1
1569
1570frame  .r.c.tx.au.port -bd 0
1571button .r.c.tx.au.port.l0 -highlightthickness 0 -command {incr_port iport iports -1} -font $compfont -bitmap left -relief flat
1572label  .r.c.tx.au.port.l1 -highlightthickness 0 -textv iport -font $compfont -width 10
1573button .r.c.tx.au.port.l2 -highlightthickness 0 -command {incr_port iport iports +1} -font $compfont -bitmap right -relief flat
1574pack   .r.c.tx.au.port -side top -fill x -expand 1
1575pack   .r.c.tx.au.port.l0 -side left -fill y
1576pack   .r.c.tx.au.port.l1 -side left -fill x -expand 1
1577pack   .r.c.tx.au.port.l2 -side left -fill y
1578
1579frame  .r.c.tx.au.pow -relief sunk -bd 2
1580bargraphCreate .r.c.tx.au.pow.bar
1581scale .r.c.tx.au.pow.sli -highlightthickness 0 -from 0 -to 99 -command set_gain -orient horizontal -showvalue false -width 8 -variable gain -resolution 4 -bd 0 -sliderl 16 -troughco black
1582pack .r.c.tx.au.pow .r.c.tx.au.pow.bar .r.c.tx.au.pow.sli -side top -fill both -expand 1
1583
1584bind all <ButtonPress-3>   {toggle in_mute_var; input_mute $in_mute_var}
1585bind all <ButtonRelease-3> {toggle in_mute_var; input_mute $in_mute_var}
1586bind all <q>               {+if {[winfo class %W] != "Entry"} {do_quit}}
1587
1588# Override default tk behaviour
1589wm protocol . WM_DELETE_WINDOW do_quit
1590
1591if {$win32 == 0} {
1592        wm iconbitmap . rat_small
1593}
1594#wm resizable . 0 1
1595if ([info exists geometry]) {
1596        wm geometry . $geometry
1597}
1598
1599proc averageCharacterWidth {font} {
1600    set sample "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
1601    set slen [string length $sample]
1602    set wpc  [expr [font measure $font $sample] / $slen + 1]
1603    return $wpc
1604}
1605
1606# constrain_window - window, font, characters wide, characters high
1607proc constrain_window {w font cW cH} {
1608   
1609    catch {
1610            set wpc [averageCharacterWidth $font]
1611            set hpc [font metrics $font -ascent]
1612   
1613        # Calculate dimensions
1614            set width [expr $cW * $wpc]
1615            set height [expr $cH * $hpc]
1616            wm geometry $w [format "%sx%s" $width $height]
1617            set dummy ""
1618    } err
1619    if {$err != ""} {
1620        puts "Error: $err"
1621    }
1622}
1623
1624proc tk_optionCmdMenu {w varName firstValue args} {
1625    upvar #0 $varName var
1626 
1627    if ![info exists var] {
1628        set var $firstValue
1629    }
1630    menubutton $w -textvariable $varName -indicatoron 1 -menu $w.menu \
1631            -relief raised -bd 2 -highlightthickness 2 -anchor c
1632
1633    menu $w.menu -tearoff 0
1634    $w.menu add command -label $firstValue -command "set $varName \"$firstValue\""
1635    foreach i $args {
1636        $w.menu add command -label $i -command "set $varName \"$i\""
1637    }
1638    return $w.menu
1639}
1640
1641
1642###############################################################################
1643# Preferences Panel
1644#
1645
1646set prefs_pane "Personal"
1647toplevel .prefs
1648wm title .prefs "Preferences"
1649wm resizable .prefs 0 0
1650wm withdraw  .prefs
1651
1652frame .prefs.m
1653pack .prefs.m -side top -fill x -expand 0 -padx 2 -pady 2
1654frame .prefs.m.f
1655pack .prefs.m.f -padx 0 -pady 0
1656label .prefs.m.f.t -text "Category: "
1657pack .prefs.m.f.t -pady 2 -side left
1658menubutton .prefs.m.f.m -menu .prefs.m.f.m.menu -indicatoron 1 -textvariable prefs_pane -relief raised -width 14
1659pack .prefs.m.f.m -side top
1660menu .prefs.m.f.m.menu -tearoff 0
1661.prefs.m.f.m.menu add command -label "Personal"     -command {set_pane prefs_pane .prefs.pane "Personal"}
1662.prefs.m.f.m.menu add command -label "Transmission" -command {set_pane prefs_pane .prefs.pane "Transmission"; update_codecs_displayed}
1663.prefs.m.f.m.menu add command -label "Reception"    -command {set_pane prefs_pane .prefs.pane "Reception"}
1664.prefs.m.f.m.menu add command -label "Audio"        -command {set_pane prefs_pane .prefs.pane "Audio"}
1665.prefs.m.f.m.menu add command -label "Codecs"        -command {set_pane prefs_pane .prefs.pane "Codecs"; codecs_panel_fill}
1666.prefs.m.f.m.menu add command -label "Security"     -command {set_pane prefs_pane .prefs.pane "Security"}
1667.prefs.m.f.m.menu add command -label "Interface"    -command {set_pane prefs_pane .prefs.pane "Interface"}
1668
1669frame  .prefs.buttons
1670pack   .prefs.buttons       -side bottom -fill x
1671button .prefs.buttons.bye   -text "Cancel" -command {sync_ui_to_engine; wm withdraw .prefs}
1672button .prefs.buttons.apply -text "Apply" -command {wm withdraw .prefs; sync_engine_to_ui}
1673pack   .prefs.buttons.bye .prefs.buttons.apply -side right -padx 2 -pady 2
1674
1675wm protocol .prefs WM_DELETE_WINDOW {sync_ui_to_engine; wm withdraw .prefs}
1676
1677frame .prefs.pane -relief groove -bd 2
1678pack  .prefs.pane -side left -fill both -expand 1 -padx 4 -pady 2
1679
1680# setup width of prefs panel
1681constrain_window .prefs $infofont 56 30
1682
1683# Personal Info Pane ##########################################################
1684set i .prefs.pane.personal
1685frame $i
1686pack $i -fill both -expand 1 -pady 2 -padx 2
1687
1688frame $i.a
1689frame $i.a.f -rel fl
1690pack $i.a -side top -fill both -expand 1
1691pack $i.a.f -side left -fill x -expand 1
1692
1693frame $i.a.f.f -rel fl
1694pack $i.a.f.f
1695
1696label $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
1697pack $i.a.f.f.l -side top -anchor w -fill x
1698
1699frame $i.a.f.f.lbls
1700frame $i.a.f.f.ents
1701pack  $i.a.f.f.lbls -side left -fill y
1702pack  $i.a.f.f.ents -side right
1703
1704label $i.a.f.f.lbls.1  -text "Name:"     -anchor w
1705label $i.a.f.f.lbls.2 -text "Email:"    -anchor w
1706label $i.a.f.f.lbls.3 -text "Phone:"    -anchor w
1707label $i.a.f.f.lbls.4   -text "Location:" -anchor w
1708label $i.a.f.f.lbls.5  -text "Note:" -anchor w
1709pack $i.a.f.f.lbls.1 $i.a.f.f.lbls.2 $i.a.f.f.lbls.3 $i.a.f.f.lbls.4 $i.a.f.f.lbls.5 -fill x -anchor w -side top
1710
1711entry $i.a.f.f.ents.name -width 28 -highlightthickness 0 -textvariable rtcp_name
1712entry $i.a.f.f.ents.email -width 28 -highlightthickness 0 -textvariable rtcp_email
1713entry $i.a.f.f.ents.phone -width 28 -highlightthickness 0 -textvariable rtcp_phone
1714entry $i.a.f.f.ents.loc  -width 28 -highlightthickness 0 -textvariable rtcp_loc
1715entry $i.a.f.f.ents.note  -width 28 -highlightthickness 0 -textvariable rtcp_note
1716pack $i.a.f.f.ents.name $i.a.f.f.ents.email $i.a.f.f.ents.phone $i.a.f.f.ents.loc $i.a.f.f.ents.note -anchor n -expand 0
1717
1718proc update_user_panel {} {
1719    global my_ssrc NAME EMAIL PHONE LOC NOTE
1720    global rtcp_name rtcp_email rtcp_phone rtcp_loc rtcp_note
1721    if {[info exists my_ssrc]} {
1722        set rtcp_name  $NAME($my_ssrc)
1723        set rtcp_email $EMAIL($my_ssrc)
1724        set rtcp_phone $PHONE($my_ssrc)
1725        set rtcp_loc   $LOC($my_ssrc)
1726        set rtcp_note  $NOTE($my_ssrc)
1727    }
1728}
1729
1730# Transmission Pane ###########################################################
1731set i .prefs.pane.transmission
1732frame $i
1733frame $i.dd
1734frame $i.cc
1735frame $i.cc.van
1736frame $i.cc.red
1737frame $i.cc.layer
1738frame $i.cc.int
1739label $i.intro -text "This panel allows you to select codecs for transmission.  The choice\nof codecs available depends on the sampling rate and channels\nin the audio panel."
1740frame $i.title1-f -relief raised
1741label $i.title1-f.l -text "Audio Encoding"
1742pack $i.intro $i.title1-f $i.title1-f.l $i.dd -side top -fill x
1743
1744#pack $i.dd -fill x -side top -anchor n
1745
1746frame $i.title2-f -relief raised
1747label $i.title2-f.l -text "Channel Coding Options"
1748pack $i.title2-f $i.title2-f.l -fill x -side top
1749pack $i.cc -fill x -anchor w -pady 1
1750
1751pack $i.cc.van $i.cc.red $i.cc.layer -fill x -anchor w -pady 0
1752# interleaving panel $i.cc.int not packed since interleaving isn't support in this release
1753frame $i.dd.units
1754frame $i.dd.pri
1755
1756pack $i.dd.units $i.dd.pri -side right -fill x
1757
1758label $i.dd.pri.l -text "Encoding:"
1759menubutton $i.dd.pri.m -menu $i.dd.pri.m.menu -indicatoron 1 -textvariable prenc -relief raised -width 13
1760pack $i.dd.pri.l $i.dd.pri.m -side top
1761# fill in codecs
1762menu $i.dd.pri.m.menu -tearoff 0
1763
1764label $i.dd.units.l -text "Units:"
1765tk_optionCmdMenu $i.dd.units.m upp 1 2 4 8
1766$i.dd.units.m configure -width 13 -highlightthickness 0 -bd 1
1767pack $i.dd.units.l $i.dd.units.m -side top -fill x
1768
1769radiobutton $i.cc.van.rb -text "No Loss Protection" -justify right -value none        -variable channel_var
1770radiobutton $i.cc.red.rb -text "Redundancy"         -justify right -value redundancy  -variable channel_var
1771radiobutton $i.cc.layer.rb -text "Layering"                     -justify right -value layering    -variable channel_var
1772radiobutton $i.cc.int.rb -text "Interleaving"       -justify right -value interleaved -variable channel_var -state disabled
1773pack $i.cc.van.rb $i.cc.red.rb $i.cc.layer.rb $i.cc.int.rb -side left -anchor nw -padx 2
1774
1775frame $i.cc.red.fc
1776label $i.cc.red.fc.l -text "Encoding:"
1777menubutton $i.cc.red.fc.m -textvariable secenc -indicatoron 1 -menu $i.cc.red.fc.m.menu -relief raised -width 13
1778menu $i.cc.red.fc.m.menu -tearoff 0
1779
1780frame $i.cc.red.u
1781label $i.cc.red.u.l -text "Offset in Pkts:"
1782tk_optionCmdMenu $i.cc.red.u.m red_off "1" "2" "4" "8" 
1783$i.cc.red.u.m configure -width 13 -highlightthickness 0 -bd 1
1784pack $i.cc.red.u -side right -anchor e -fill y
1785pack $i.cc.red.u.l $i.cc.red.u.m -fill x
1786pack $i.cc.red.fc -side right
1787pack $i.cc.red.fc.l $i.cc.red.fc.m
1788
1789frame $i.cc.layer.fc
1790label $i.cc.layer.fc.l -text "Layers:"
1791menubutton $i.cc.layer.fc.m -textvariable layerenc -indicatoron 1 -menu $i.cc.layer.fc.m.menu -relief raised -width 13
1792menu $i.cc.layer.fc.m.menu -tearoff 0
1793pack $i.cc.layer.fc -side right
1794pack $i.cc.layer.fc.l $i.cc.layer.fc.m
1795
1796frame $i.cc.int.zz
1797label $i.cc.int.zz.l -text "Units:"
1798tk_optionCmdMenu $i.cc.int.zz.m int_units 2 4 6 8
1799$i.cc.int.zz.m configure -width 13 -highlightthickness 0 -bd 1 -state disabled
1800
1801frame $i.cc.int.fc
1802label $i.cc.int.fc.l -text "Separation:" 
1803tk_optionCmdMenu $i.cc.int.fc.m int_gap 2 4 6 8
1804$i.cc.int.fc.m configure -width 13 -highlightthickness 0 -bd 1 -state disabled
1805
1806pack $i.cc.int.fc $i.cc.int.zz -side right
1807pack $i.cc.int.fc.l $i.cc.int.fc.m -fill x -expand 1
1808pack $i.cc.int.zz.l $i.cc.int.zz.m -fill x -expand 1
1809
1810# Reception Pane ##############################################################
1811set i .prefs.pane.reception
1812frame $i 
1813frame $i.r -rel f
1814frame $i.o -rel f
1815frame $i.c -rel f
1816pack $i.r -side top -fill x -pady 0 -ipady 1
1817pack $i.o -side top -fill both  -pady 1
1818pack $i.c -side top -fill both  -pady 1 -expand 1
1819label $i.r.l -text "Repair Scheme:"
1820tk_optionCmdMenu $i.r.m repair_var {}
1821
1822label $i.r.ls -text "Sample Rate Conversion"
1823tk_optionCmdMenu $i.r.ms convert_var {}
1824
1825$i.r.m  configure -width 20 -bd 1
1826$i.r.ms configure -width 20 -bd 1
1827pack $i.r.l $i.r.m $i.r.ls $i.r.ms -side top
1828
1829frame $i.o.f
1830checkbutton $i.o.f.cb -text "Limit Playout Delay" -variable limit_var
1831frame $i.o.f.fl
1832label $i.o.f.fl.l1 -text "Minimum Delay (ms)" 
1833scale $i.o.f.fl.scmin -orient horizontal -from 0 -to 1000    -variable min_var -font $smallfont
1834frame $i.o.f.fr
1835label $i.o.f.fr.l2 -text "Maximum Delay (ms)"           
1836scale $i.o.f.fr.scmax -orient horizontal -from 1000 -to 2000 -variable max_var -font $smallfont
1837pack $i.o.f
1838pack $i.o.f.cb -side top -fill x
1839pack $i.o.f.fl $i.o.f.fr -side left
1840pack $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
1841
1842frame $i.c.f
1843frame $i.c.f.f
1844checkbutton $i.c.f.f.lec -text "Lecture Mode"       -variable lecture_var
1845checkbutton $i.c.f.f.ext -text "3D Audio Rendering" -variable 3d_audio_var
1846
1847pack $i.c.f -fill x -side left -expand 1
1848pack $i.c.f.f
1849pack $i.c.f.f.lec -side top  -anchor w
1850pack $i.c.f.f.ext -side top  -anchor w
1851
1852# Audio #######################################################################
1853set i .prefs.pane.audio
1854frame $i 
1855frame $i.dd -rel fl
1856pack $i.dd -fill both -expand 1 -anchor w -pady 1
1857
1858label $i.dd.title -height 2 -width 40 -text "This panel allows for the selection of alternate audio devices\nand the configuring of device related options." -justify left
1859pack $i.dd.title -fill x
1860
1861frame $i.dd.device
1862pack $i.dd.device -side top
1863
1864label $i.dd.device.l -text "Audio Device:"
1865pack  $i.dd.device.l -side top -fill x
1866menubutton $i.dd.device.mdev -menu $i.dd.device.mdev.menu -indicatoron 1 \
1867                                -textvariable audio_device -relief raised -width 5
1868pack $i.dd.device.mdev -fill x -expand 1
1869menu $i.dd.device.mdev.menu -tearoff 0
1870
1871frame $i.dd.sampling 
1872pack  $i.dd.sampling
1873
1874frame $i.dd.sampling.freq
1875frame $i.dd.sampling.ch_in
1876pack $i.dd.sampling.freq $i.dd.sampling.ch_in -side left -fill x
1877
1878label $i.dd.sampling.freq.l   -text "Sample Rate:   "
1879label $i.dd.sampling.ch_in.l  -text "Channels:"
1880pack $i.dd.sampling.freq.l $i.dd.sampling.ch_in.l -fill x
1881
1882menubutton $i.dd.sampling.freq.mb -menu $i.dd.sampling.freq.mb.m -indicatoron 1 \
1883                                  -textvariable freq -relief raised
1884pack $i.dd.sampling.freq.mb -side left -fill x -expand 1
1885menu $i.dd.sampling.freq.mb.m
1886
1887menubutton $i.dd.sampling.ch_in.mb -menu $i.dd.sampling.ch_in.mb.m -indicatoron 1 \
1888                                  -textvariable ichannels -relief raised
1889pack $i.dd.sampling.ch_in.mb -side left -fill x -expand 1
1890menu $i.dd.sampling.ch_in.mb.m
1891
1892frame $i.dd.cks
1893pack $i.dd.cks -fill both -expand 1
1894frame $i.dd.cks.f
1895frame $i.dd.cks.f.f
1896checkbutton $i.dd.cks.f.f.silence  -text "Silence Suppression"    -variable silence_var
1897checkbutton $i.dd.cks.f.f.agc      -text "Automatic Gain Control" -variable agc_var
1898checkbutton $i.dd.cks.f.f.loop     -text "Audio Loopback"         -variable audio_loop_var
1899checkbutton $i.dd.cks.f.f.suppress -text "Echo Suppression"       -variable echo_var
1900pack $i.dd.cks.f -fill x -side top -expand 1
1901pack $i.dd.cks.f.f
1902pack $i.dd.cks.f.f.silence $i.dd.cks.f.f.agc $i.dd.cks.f.f.loop $i.dd.cks.f.f.suppress -side top -anchor w
1903
1904# Codecs pane #################################################################
1905set i .prefs.pane.codecs
1906frame $i 
1907
1908
1909frame $i.of -rel fl
1910pack  $i.of -fill both -expand 1 -anchor w -pady 1 -side top
1911
1912message $i.of.l -width 30c -justify left -text "This panel shows available codecs and allows RTP payload re-mapping." 
1913pack $i.of.l -side top -fill x
1914
1915frame   $i.of.codecs
1916
1917pack    $i.of.codecs -side left -padx 2 -fill y
1918frame   $i.of.codecs.l -rel raised
1919label   $i.of.codecs.l.l -text "Codec"
1920listbox $i.of.codecs.lb -width 20 -yscrollcommand "$i.of.codecs.scroll set" -relief fl -bg white
1921scrollbar $i.of.codecs.scroll -command "$i.of.codecs.lb yview" -rel fl
1922pack    $i.of.codecs.l $i.of.codecs.l.l -side top -fill x
1923pack    $i.of.codecs.scroll $i.of.codecs.lb -side left -fill both
1924
1925frame   $i.of.details -bd 0
1926pack    $i.of.details -side left -fill both -expand 1 -anchor n
1927
1928frame $i.of.details.upper
1929pack $i.of.details.upper -fill x
1930
1931frame $i.of.details.desc
1932pack $i.of.details.desc -side top -fill x
1933
1934frame $i.of.details.pt
1935pack $i.of.details.pt -side bottom -fill x -anchor s
1936label $i.of.details.pt.l -anchor w -text "RTP payload:"
1937pack  $i.of.details.pt.l -side left -anchor w
1938
1939entry $i.of.details.pt.e -width 4
1940pack  $i.of.details.pt.e -side left -padx 4
1941
1942button $i.of.details.pt.b -text "Map Codec" -command map_codec
1943pack  $i.of.details.pt.b -side right -padx 4
1944
1945frame $i.of.details.upper.l0 -relief raised
1946label $i.of.details.upper.l0.l -text "Details"
1947pack $i.of.details.upper.l0 $i.of.details.upper.l0.l -side top -fill x -expand 1
1948
1949frame $i.of.details.upper.l
1950pack $i.of.details.upper.l -side left
1951label $i.of.details.upper.l.0 -text "Short name:"  -anchor w
1952label $i.of.details.upper.l.1 -text "Sample Rate (Hz):" -anchor w
1953label $i.of.details.upper.l.2 -text "Channels:"    -anchor w
1954label $i.of.details.upper.l.3 -text "Bitrate (kbps):"     -anchor w
1955label $i.of.details.upper.l.4 -text "RTP Payload:" -anchor w
1956label $i.of.details.upper.l.5 -text "Capability:" -anchor w
1957label $i.of.details.upper.l.6 -text "Layers:" -anchor w
1958
1959for {set idx 0} {$idx < 7} {incr idx} {
1960    pack $i.of.details.upper.l.$idx -side top -fill x
1961}
1962
1963frame $i.of.details.upper.r
1964pack $i.of.details.upper.r -side left -fill x -expand 1
1965label $i.of.details.upper.r.0 -anchor w
1966label $i.of.details.upper.r.1 -anchor w
1967label $i.of.details.upper.r.2 -anchor w
1968label $i.of.details.upper.r.3 -anchor w
1969label $i.of.details.upper.r.4 -anchor w
1970label $i.of.details.upper.r.5 -anchor w
1971label $i.of.details.upper.r.6 -anchor w
1972
1973for {set idx 0} {$idx < 7} {incr idx} {
1974    pack $i.of.details.upper.r.$idx -side top -fill x
1975}
1976
1977set descw [expr [averageCharacterWidth $infofont] * 30]
1978label $i.of.details.desc.l -text "Description:" -anchor w -wraplength $descw -justify left
1979pack $i.of.details.desc.l -side left -fill x
1980unset descw
1981
1982bind $i.of.codecs.lb <1> {
1983    codecs_panel_select [%W index @%x,%y]
1984}
1985
1986bind $i.of.codecs.lb <ButtonRelease-1> {
1987    codecs_panel_select [%W index @%x,%y]
1988}
1989proc codecs_panel_fill {} {
1990    global codecs
1991
1992    .prefs.pane.codecs.of.codecs.lb delete 0 end
1993
1994    foreach {c} $codecs {
1995        .prefs.pane.codecs.of.codecs.lb insert end $c
1996    }
1997}
1998
1999set last_selected_codec -1
2000
2001proc codecs_panel_select { idx } {
2002    global codecs codec_nick_name codec_rate codec_channels codec_pt codec_block_size codec_data_size codec_desc codec_caps codec_layers
2003    global last_selected_codec
2004
2005    set last_selected_codec $idx
2006
2007    set codec [lindex $codecs $idx]
2008    set root  .prefs.pane.codecs.of.details.upper.r
2009    $root.0 configure -text $codec_nick_name($codec)
2010    $root.1 configure -text $codec_rate($codec)
2011    $root.2 configure -text $codec_channels($codec)
2012
2013    set fps [expr $codec_rate($codec) * 2 * $codec_channels($codec) / $codec_block_size($codec) ]
2014    set kbps [expr 8 * $fps * $codec_data_size($codec) / 1000.0]
2015    $root.3 configure -text [format "%.1f" $kbps]
2016
2017    $root.4 configure -text $codec_pt($codec)
2018    $root.5 configure -text $codec_caps($codec)
2019    $root.6 configure -text $codec_layers($codec)
2020   
2021    .prefs.pane.codecs.of.details.desc.l configure -text "Description: $codec_desc($codec)"
2022
2023}
2024
2025proc map_codec {} {
2026    global codecs last_selected_codec
2027
2028    set idx $last_selected_codec
2029
2030    if {$last_selected_codec == -1} {
2031        return
2032    }
2033
2034    set pt [.prefs.pane.codecs.of.details.pt.e get]
2035    .prefs.pane.codecs.of.details.pt.e delete 0 end
2036
2037    set ptnot [string trim $pt 1234567890]
2038    if {$ptnot != ""} {
2039        return
2040    }
2041
2042    set codec [lindex $codecs $idx]
2043
2044    mbus_send "R" "tool.rat.payload.set" "[mbus_encode_str $codec] $pt"
2045    after 1000 codecs_panel_select $idx
2046}
2047
2048# Security Pane ###############################################################
2049set i .prefs.pane.security
2050frame $i 
2051frame $i.a -rel fl
2052frame $i.a.f
2053frame $i.a.f.f
2054label $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."
2055pack $i.a.f.f.l
2056pack $i.a -side top -fill both -expand 1
2057label $i.a.f.f.lbl -text "Key:"
2058entry $i.a.f.f.e -width 28 -textvariable key
2059checkbutton $i.a.f.f.cb -text "Enabled" -variable key_var
2060pack $i.a.f -fill x -side left -expand 1
2061pack $i.a.f.f
2062pack $i.a.f.f.lbl $i.a.f.f.e $i.a.f.f.cb -side left -pady 4 -padx 2 -fill x
2063
2064# Interface Pane ##############################################################
2065set i .prefs.pane.interface
2066frame $i 
2067frame $i.a -rel fl
2068frame $i.a.f
2069frame $i.a.f.f
2070label $i.a.f.f.l -anchor w -justify left -text "The following features may be\ndisabled to conserve processing\npower."
2071pack $i.a -side top -fill both -expand 1
2072pack $i.a.f -fill x -side left -expand 1
2073checkbutton $i.a.f.f.power   -text "Powermeters active"       -variable meter_var
2074checkbutton $i.a.f.f.balloon -text "Balloon help"             -variable help_on
2075checkbutton $i.a.f.f.matrix  -text "Reception quality matrix" -variable matrix_on -command chart_show
2076checkbutton $i.a.f.f.plist   -text "Participant list"         -variable plist_on  -command toggle_plist
2077checkbutton $i.a.f.f.fwin    -text "File Control Window"      -variable files_on  -command file_show
2078pack $i.a.f.f $i.a.f.f.l
2079pack $i.a.f.f.power $i.a.f.f.balloon $i.a.f.f.matrix $i.a.f.f.plist $i.a.f.f.fwin -side top -anchor w
2080
2081proc set_pane {p base desc} {
2082    upvar 1 $p pane
2083    set tpane [string tolower [lindex [split $pane] 0]]
2084    pack forget $base.$tpane
2085    set tpane [string tolower [lindex [split $desc] 0]]
2086    pack $base.$tpane -fill both -expand 1 -padx 2 -pady 2
2087    set pane $desc
2088}
2089
2090# Initialise "About..." toplevel window
2091toplevel   .about
2092frame      .about.rim -relief groove -bd 2
2093frame      .about.m
2094frame      .about.rim.d
2095pack .about.m -fill x
2096pack .about.rim -padx 4 -pady 2 -side top -fill both -expand 1
2097pack .about.rim.d -side top -fill both -expand 1
2098
2099frame .about.m.f
2100label .about.m.f.l -text "Category:"
2101menubutton .about.m.f.mb -menu .about.m.f.mb.menu -indicatoron 1 -textvariable about_pane -relief raised -width 10
2102menu .about.m.f.mb.menu -tearoff 0
2103.about.m.f.mb.menu add command -label "Credits"   -command {set_pane about_pane .about.rim.d "Credits"   }
2104.about.m.f.mb.menu add command -label "Feedback"  -command {set_pane about_pane .about.rim.d "Feedback"  }
2105.about.m.f.mb.menu add command -label "Copyright" -command {set_pane about_pane .about.rim.d "Copyright" }
2106
2107pack .about.m.f
2108pack .about.m.f.l .about.m.f.mb -side left
2109
2110frame     .about.rim.d.copyright
2111frame     .about.rim.d.copyright.f -relief flat
2112frame     .about.rim.d.copyright.f.f
2113text      .about.rim.d.copyright.f.f.blurb -height 14 -yscrollcommand ".about.rim.d.copyright.f.f.scroll set" -relief flat -bg white
2114scrollbar .about.rim.d.copyright.f.f.scroll -command ".about.rim.d.copyright.f.f.blurb yview" -relief flat
2115
2116pack      .about.rim.d.copyright.f -expand 1 -fill both
2117pack      .about.rim.d.copyright.f.f -expand 1 -fill both
2118pack      .about.rim.d.copyright.f.f.scroll -side left -fill y -expand 1
2119pack      .about.rim.d.copyright.f.f.blurb -side left -fill y -expand 1
2120
2121frame     .about.rim.d.credits
2122frame     .about.rim.d.credits.f -relief flat
2123frame     .about.rim.d.credits.f.f
2124pack      .about.rim.d.credits.f -fill both -expand 1
2125pack      .about.rim.d.credits.f.f -side left -fill x -expand 1
2126label     .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:"
2127label     .about.rim.d.credits.f.f.2 -foreground blue -text Good
2128label     .about.rim.d.credits.f.f.3                  -text "Development Team:"
2129label     .about.rim.d.credits.f.f.4 -foreground blue -text Bad
2130label     .about.rim.d.credits.f.f.5                  -text "Additional Contributions:"
2131label     .about.rim.d.credits.f.f.6 -foreground blue -text Ugly
2132for {set i 1} {$i<=6} {incr i} {
2133    pack  .about.rim.d.credits.f.f.$i -side top -fill x -anchor n
2134}
2135
2136button    .about.dismiss -text Dismiss -command "wm withdraw .about"
2137pack      .about.dismiss -side bottom -anchor e -padx 2 -pady 2
2138
2139frame     .about.rim.d.feedback
2140frame     .about.rim.d.feedback.f -relief flat
2141frame     .about.rim.d.feedback.f.f
2142pack      .about.rim.d.feedback.f -fill both -expand 1
2143pack      .about.rim.d.feedback.f.f -side left -fill x -expand 1
2144label     .about.rim.d.feedback.f.f.1                  -text "Comments, suggestions, and bug-reports should be sent to:"
2145label     .about.rim.d.feedback.f.f.2 -foreground blue -text "rat-trap@cs.ucl.ac.uk\n"
2146label     .about.rim.d.feedback.f.f.3                  -text "Further information is available on the world-wide web at:"
2147label     .about.rim.d.feedback.f.f.4 -foreground blue -text "http://www-mice.cs.ucl.ac.uk/multimedia/software/rat/\n"
2148for {set i 1} {$i<=4} {incr i} {
2149    pack  .about.rim.d.feedback.f.f.$i -side top -fill x
2150}
2151
2152wm withdraw  .about
2153wm title     .about "About RAT"
2154wm resizable .about 0 0
2155set about_pane Copyright
2156set_pane about_pane .about.rim.d "Credits" 
2157constrain_window .about $infofont 64 25
2158
2159.about.rim.d.copyright.f.f.blurb insert end \
2160{Copyright (C) 1995-2000 University College London
2161All rights reserved.
2162
2163Redistribution and use in source and binary forms, with or without
2164modification, is permitted provided that the following conditions
2165are met:
2166
21671. Redistributions of source code must retain the above copyright
2168   notice, this list of conditions and the following disclaimer.
2169
21702. Redistributions in binary form must reproduce the above copyright
2171   notice, this list of conditions and the following disclaimer in the
2172   documentation and/or other materials provided with the distribution.
2173
21743. All advertising materials mentioning features or use of this software
2175   must display the following acknowledgement:
2176
2177     This product includes software developed by the Computer Science
2178     Department at University College London.
2179
21804. Neither the name of the University nor of the Department may be used
2181   to endorse or promote products derived from this software without
2182   specific prior written permission.
2183
2184THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
2185``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
2186BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
2187AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
2188EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2189INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2190(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2191SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2192HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2193CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2194OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
2195EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2196
2197This software is derived, in part, from publically available
2198and contributed source code with the following copyright:
2199
2200Copyright (C) 1991-1993 Regents of the University of California
2201Copyright (C) 1992 Stichting Mathematisch Centrum, Amsterdam
2202Copyright (C) 1991-1992 RSA Data Security, Inc
2203Copyright (C) 1992 Jutta Degener and Carsten Bormann, TU Berlin
2204Copyright (C) 1994 Paul Stewart
2205Copyright (C) 1996 Regents of the University of California
2206Copyright (C) 2000 Nortel Networks
2207Copyright (C) 2000 Argonne National Laboratory
2208
2209This product includes software developed by the Computer
2210Systems Engineering Group and by the Network Research Group
2211at Lawrence Berkeley Laboratory.
2212
2213The WB-ADPCM algorithm was developed by British Telecommunications
2214plc.  Permission has been granted to use it for non-commercial
2215research and development projects.  BT retain the intellectual
2216property rights to this algorithm.
2217
2218Encryption features of this software use the RSA Data
2219Security, Inc. MD5 Message-Digest Algorithm.
2220
2221}
2222
2223proc shuffle_rats {args} {
2224    # This should really animate the movement and play fruit-machine sounds.... :-)
2225    set r ""
2226    set end [llength $args]
2227    set l 0
2228    while { $l < $end } {
2229        set toget [expr abs([clock clicks]) % [llength $args]]
2230        set r [format "%s%s  " $r [lindex $args $toget]]
2231        set args [lreplace $args $toget $toget]
2232        lappend used $toget
2233        if {$l >0 && [expr ($l + 1) % 3] == 0} {
2234            set r "$r\n"
2235        }
2236        incr l
2237    }
2238    return $r
2239}
2240
2241proc jiggle_credits {} {
2242# Software really developed by the Socialist Department of Computer Science
2243    .about.rim.d.credits.f.f.2 configure -text [shuffle_rats "Angela Sasse" "Vicky Hardman"]
2244    .about.rim.d.credits.f.f.4 configure -text [shuffle_rats "Colin Perkins" "Orion Hodson"]
2245    .about.rim.d.credits.f.f.6 configure -text [shuffle_rats "Isidor Kouvelas" "Darren Harris" "Anna Watson" "Mark Handley" "Jon Crowcroft" "Marcus Iken" "Kris Hasler" "Tristan Henderson" "Dimitrios Miras" "Socrates Varakliotis"]
2246}
2247
2248proc sync_ui_to_engine {} {
2249    # the next time the display is shown, it needs to reflect the
2250    # state of the audio engine.
2251    mbus_send "R" "tool.rat.settings" ""
2252}
2253
2254proc sync_engine_to_ui {} {
2255    # make audio engine concur with ui
2256    global my_ssrc rtcp_name rtcp_email rtcp_phone rtcp_loc rtcp_note
2257    global prenc upp channel_var secenc layerenc red_off int_gap int_units
2258    global silence_var agc_var audio_loop_var echo_var
2259    global repair_var limit_var min_var max_var lecture_var 3d_audio_var convert_var 
2260    global meter_var gain volume iport oport
2261    global in_mute_var out_mute_var ichannels freq key key_var
2262    global audio_device received
2263
2264    #rtcp details
2265    mbus_send "R" "rtp.source.name"  "[mbus_encode_str $my_ssrc] [mbus_encode_str $rtcp_name]"
2266    mbus_send "R" "rtp.source.email" "[mbus_encode_str $my_ssrc] [mbus_encode_str $rtcp_email]"
2267    mbus_send "R" "rtp.source.phone" "[mbus_encode_str $my_ssrc] [mbus_encode_str $rtcp_phone]"
2268    mbus_send "R" "rtp.source.loc"   "[mbus_encode_str $my_ssrc] [mbus_encode_str $rtcp_loc]"
2269    mbus_send "R" "rtp.source.note"   "[mbus_encode_str $my_ssrc] [mbus_encode_str $rtcp_note]"
2270
2271    #cheat to update my details right away (it's disgusting)
2272    mbus_recv_rtp.source.name  $my_ssrc "$rtcp_name"
2273    mbus_recv_rtp.source.email $my_ssrc "$rtcp_email"
2274    mbus_recv_rtp.source.phone $my_ssrc "$rtcp_phone"
2275    mbus_recv_rtp.source.loc   $my_ssrc "$rtcp_loc"
2276    mbus_recv_rtp.source.note  $my_ssrc "$rtcp_note"
2277   
2278    #transmission details
2279    mbus_send "R" "tool.rat.codec"      "[mbus_encode_str $prenc] [mbus_encode_str $ichannels] [mbus_encode_str $freq]"
2280    mbus_send "R" "tool.rat.rate"         $upp
2281
2282    switch $channel_var {
2283        none         {mbus_send "R" "audio.channel.coding" "[mbus_encode_str $channel_var]"}
2284        redundancy   {mbus_send "R" "audio.channel.coding" "[mbus_encode_str $channel_var] [mbus_encode_str $secenc] $red_off"}
2285        interleaved {mbus_send "R" "audio.channel.coding" "[mbus_encode_str $channel_var] $int_gap $int_units"}
2286        layering        {mbus_send "R" "audio.channel.coding" "[mbus_encode_str $channel_var] [mbus_encode_str $prenc] [mbus_encode_str $ichannels] [mbus_encode_str $freq] $layerenc"}
2287        *           {error "unknown channel coding scheme $channel_var"}
2288    }
2289
2290    mbus_send "R" "tool.rat.silence"       $silence_var
2291    mbus_send "R" "tool.rat.agc"           $agc_var
2292    mbus_send "R" "tool.rat.loopback"      $audio_loop_var
2293    mbus_send "R" "tool.rat.echo.suppress" $echo_var
2294
2295    #Reception Options
2296    mbus_send "R" "audio.channel.repair"   [mbus_encode_str $repair_var]
2297    mbus_send "R" "tool.rat.playout.limit" $limit_var
2298    mbus_send "R" "tool.rat.playout.min"   $min_var
2299    mbus_send "R" "tool.rat.playout.max"   $max_var
2300    mbus_send "R" "tool.rat.lecture"       $lecture_var
2301    mbus_send "R" "tool.rat.3d.enabled"    $3d_audio_var
2302    mbus_send "R" "tool.rat.converter"     [mbus_encode_str $convert_var]
2303
2304    #Security
2305    if {$key_var==1 && [string length $key]!=0} {
2306        mbus_send "R" "security.encryption.key" [mbus_encode_str $key]
2307    } else {
2308        mbus_send "R" "security.encryption.key" [mbus_encode_str ""]
2309    }
2310
2311    #Interface
2312    mbus_send "R" "tool.rat.powermeter"   $meter_var
2313
2314    #device
2315    mbus_send "R" "audio.device"        [mbus_encode_str "$audio_device"]
2316    if {$received(gain)} {
2317        mbus_send "R" "audio.input.gain"    $gain
2318    }
2319    if {$received(volume)} {
2320        mbus_send "R" "audio.output.gain"   $volume
2321    }
2322    mbus_send "R" "audio.input.port"    [mbus_encode_str $iport]
2323    mbus_send "R" "audio.output.port"   [mbus_encode_str $oport]
2324    mbus_send "R" "audio.input.mute"    $in_mute_var
2325    mbus_send "R" "audio.output.mute"   $out_mute_var
2326}
2327
2328#
2329# Routines to display the "chart" of RTCP RR statistics...
2330#
2331
2332toplevel  .chart
2333canvas    .chart.c  -xscrollcommand {.chart.sb set} -yscrollcommand {.chart.sr set}
2334frame     .chart.c.f
2335scrollbar .chart.sr -orient vertical   -command {.chart.c yview}
2336scrollbar .chart.sb -orient horizontal -command {.chart.c xview}
2337
2338pack .chart.sb -side bottom -fill x    -expand 0 -anchor s
2339pack .chart.sr -side right  -fill y    -expand 0 -anchor e
2340pack .chart.c  -side left   -fill both -expand 1 -anchor n
2341
2342.chart.c create window 0 0 -anchor nw -window .chart.c.f
2343
2344proc mtrace_callback {fd src dst} {
2345        if [winfo exists .mtrace-$src-$dst] {
2346                .mtrace-$src-$dst.t insert end [read $fd]
2347        } else {
2348                # The user has closed the mtrace window before the trace has completed
2349                close $fd
2350        }
2351        if [eof $fd] {
2352                close $fd
2353        }
2354}
2355
2356proc mtrace {src dst} {
2357        global CNAME group_addr
2358        regsub {.*@([0-9]+.[0-9]+.[0-9]+.[0-9]+)} $CNAME($src) {\1} src_addr
2359        regsub {.*@([0-9]+.[0-9]+.[0-9]+.[0-9]+)} $CNAME($dst) {\1} dst_addr
2360
2361        toplevel  .mtrace-$src-$dst
2362        text      .mtrace-$src-$dst.t -background white -font "Courier 8" -wrap none \
2363                                      -yscrollcommand ".mtrace-$src-$dst.sr set" \
2364                                      -xscrollcommand ".mtrace-$src-$dst.sb set"
2365        scrollbar .mtrace-$src-$dst.sb -command ".mtrace-$src-$dst.t xview" -orient horizontal
2366        scrollbar .mtrace-$src-$dst.sr -command ".mtrace-$src-$dst.t yview" -orient vertical
2367        pack .mtrace-$src-$dst.sb -fill x    -expand 0 -side bottom -anchor s
2368        pack .mtrace-$src-$dst.sr -fill y    -expand 0 -side right  -anchor e
2369        pack .mtrace-$src-$dst.t  -fill both -expand 1 -side left   -anchor w
2370
2371        wm title .mtrace-$src-$dst "mtrace from $src_addr to $dst_addr via group $group_addr"
2372
2373        set fd [open "|mtrace $src_addr $dst_addr $group_addr" "r"]
2374        fconfigure $fd -blocking 0
2375        fileevent  $fd readable "mtrace_callback $fd $src $dst"
2376}
2377
2378toplevel .chart_popup       -bg black
2379label    .chart_popup.text  -bg lavender -justify left
2380pack .chart_popup.text -side top -anchor w -fill x
2381wm transient        .chart_popup .
2382wm withdraw         .chart_popup
2383wm overrideredirect .chart_popup true
2384
2385proc chart_popup_show {window} {
2386        global chart_popup_src chart_popup_dst chart_popup_id NAME
2387        .chart_popup.text  configure -text "From: $NAME($chart_popup_src($window))\nTo: $NAME($chart_popup_dst($window))"
2388        # Beware! Don't put the popup under the cursor! Else we get window enter
2389        # for .help and leave for $window, making us hide_help which removes the
2390        # help window, giving us a window enter for $window making us popup the
2391        # help again.....
2392        if {[winfo width $window] > [winfo height $window]} {
2393            set xpos [expr [winfo pointerx $window] + 10]
2394            set ypos [expr [winfo rooty    $window] + [winfo height $window] + 4]
2395        } else {
2396            set xpos [expr [winfo rootx    $window] + [winfo width $window] + 4]
2397            set ypos [expr [winfo pointery $window] + 10]
2398        }
2399       
2400        wm geometry  .chart_popup +$xpos+$ypos
2401        set chart_popup_id [after 100 wm deiconify .chart_popup]
2402        raise .chart_popup $window
2403}
2404
2405proc chart_popup_hide {window} {
2406        global chart_popup_id
2407        if {[info exists chart_popup_id]} {
2408                after cancel $chart_popup_id
2409        }
2410        wm withdraw .chart_popup
2411}
2412
2413proc chart_popup_add {window src dst} {
2414        global chart_popup_src chart_popup_dst
2415        set chart_popup_src($window) $src
2416        set chart_popup_dst($window) $dst
2417        bind $window <Enter>    "+chart_popup_show $window"
2418        bind $window <Leave>    "+chart_popup_hide $window"
2419}
2420
2421proc chart_add {ssrc} {
2422        global NAME
2423        frame  .chart.c.f.$ssrc
2424        frame  .chart.c.f.$ssrc.f
2425        button .chart.c.f.$ssrc.l -width 25 -text $ssrc -padx 0 -pady 0 -anchor w -relief flat -command "toggle_stats $ssrc"
2426        pack   .chart.c.f.$ssrc.f -expand 0 -anchor e -side right
2427        pack   .chart.c.f.$ssrc.l -expand 1 -anchor w -fill x -side left
2428        pack   .chart.c.f.$ssrc   -expand 1 -anchor n -fill x -side top
2429        foreach s [pack slaves .chart.c.f] {
2430                regsub {.chart.c.f.(.*)} $s {\1} s
2431                button .chart.c.f.$s.f.$ssrc -width 4 -text "" -background white -padx 0 -pady 0 -command "mtrace $s $ssrc"
2432                pack   .chart.c.f.$s.f.$ssrc -expand 0 -side left
2433                chart_popup_add .chart.c.f.$s.f.$ssrc $s $ssrc
2434                if {![winfo exists .chart.c.f.$ssrc.f.$s]} {
2435                        button .chart.c.f.$ssrc.f.$s -width 4 -text "" -background white -padx 0 -pady 0 -command "mtrace $ssrc $s"
2436                        pack   .chart.c.f.$ssrc.f.$s -expand 0 -side left
2437                        chart_popup_add .chart.c.f.$ssrc.f.$s $ssrc $s
2438                }
2439        }
2440        update
2441        .chart.c configure -scrollregion "0.0 0.0 [winfo width .chart.c.f] [winfo height .chart.c.f]"
2442}
2443
2444proc chart_remove {ssrc} {
2445        destroy .chart.c.f.$ssrc
2446        foreach s [pack slaves .chart.c.f] {
2447                regsub {.chart.c.f.(.*)} $s {\1} s
2448                destroy .chart.c.f.$s.f.$ssrc
2449        }
2450        update
2451        .chart.c configure -scrollregion "0.0 0.0 [winfo width .chart.c.f] [winfo height .chart.c.f]"
2452}
2453
2454proc chart_label {ssrc label} {
2455        .chart.c.f.$ssrc.l configure -text $label
2456}
2457
2458proc chart_set {src dst val} {
2459        if {$val < 5} {
2460                set colour green
2461                set txtval "$val%"
2462        } elseif {$val < 10} {
2463                set colour orange
2464                set txtval "$val%"
2465        } elseif {$val <= 100} {
2466                set colour red
2467                set txtval "$val%"
2468        } else {
2469                set colour white
2470                set txtval { }
2471        }
2472        .chart.c.f.$src.f.$dst configure -background $colour -text "$txtval"
2473}
2474
2475proc chart_show {} {
2476        global matrix_on
2477        if {$matrix_on} {
2478                wm deiconify .chart
2479        } else {
2480                wm withdraw .chart
2481        }
2482}
2483
2484wm withdraw .chart
2485wm title    .chart "Reception quality matrix"
2486wm geometry .chart 320x200
2487wm protocol .chart WM_DELETE_WINDOW    {set matrix_on 0; chart_show}
2488
2489chart_show
2490
2491#
2492# End of RTCP RR chart routines
2493#
2494
2495#
2496# File Control Window
2497#
2498
2499set play_file(state) end
2500set rec_file(state) end
2501
2502catch {
2503    toplevel .file
2504    wm protocol .file WM_DELETE_WINDOW {set files_on 0; file_show}
2505    frame .file.play -relief groove -bd 2
2506    frame .file.rec  -relief groove -bd 2
2507    pack  .file.play -side top -pady 2 -padx 2 -fill x -expand 1
2508    pack  .file.rec  -side top -pady 2 -padx 2 -fill x -expand 1
2509   
2510    label .file.play.l -text "Playback"
2511    pack  .file.play.l -side top -fill x
2512    label .file.rec.l -text "Record"   
2513    pack  .file.rec.l -side top -fill x
2514
2515    button .file.dismiss -text Dismiss -command "set files_on 0; file_show"
2516    pack   .file.dismiss -side bottom -anchor e -padx 2 -pady 2
2517   
2518    wm withdraw .file
2519    wm title    .file "RAT File Control"
2520   
2521    foreach action { play rec } {
2522        frame  .file.$action.buttons
2523        pack   .file.$action.buttons
2524        button .file.$action.buttons.disk -bitmap disk -command "fileDialog $action"
2525        pack   .file.$action.buttons.disk -side left -padx 2 -pady 2 -anchor n
2526       
2527        foreach cmd "$action pause stop" {
2528            button .file.$action.buttons.$cmd -bitmap $cmd -state disabled -command file_$action\_$cmd
2529            pack   .file.$action.buttons.$cmd -side left -padx 2 -pady 2 -anchor n -fill x
2530        }
2531
2532        label  .file.$action.buttons.status -text "No file selected." -width 16 -anchor w
2533        pack   .file.$action.buttons.status -side bottom -fill both -expand 1 -padx 2 -pady 2
2534    }
2535} fwinerr
2536
2537if {$fwinerr != {}} {
2538        puts stderr $fwinerr
2539}
2540
2541proc fileDialog {cmdbox} {
2542    global win32 tcl_platform
2543   
2544        set defaultExtension au
2545        set defaultLocation  .
2546
2547    switch -glob $tcl_platform(os) {
2548        SunOS    {
2549                if [file exists /usr/demo/SOUND/sounds] { set defaultLocation /usr/demo/SOUND/sounds }
2550                }
2551        Windows* {
2552                if [file exists C:/Windows/Media]       { set defaultLocation C:/Windows/Media }
2553                set defaultExtension wav
2554                }
2555        }
2556   
2557    set types {
2558                {"NeXT/Sun Audio files" "au"}
2559                {"Microsoft RIFF files" "wav"}
2560                {"All files"            "*"}
2561    }
2562   
2563    if {![string compare $cmdbox "play"]} {
2564                catch { asFileBox .playfilebox  -defaultextension $defaultExtension -command file_open_$cmdbox -directory $defaultLocation -extensions $types } asferror
2565    } else {
2566                catch { asFileBox .recfilebox   -defaultextension $defaultExtension -command file_open_$cmdbox  -extensions $types -force_extension 1 } asferror
2567    }
2568       
2569        if {$asferror != ""} {
2570                puts stderr asferror
2571        }
2572}
2573
2574proc file_show {} {
2575    global files_on
2576   
2577    if {$files_on} {
2578                wm deiconify .file
2579    } else {
2580                wm withdraw .file
2581    }
2582}
2583
2584proc file_play_live {} {
2585# Request heart beat to determine if file is valid
2586        mbus_send "R" audio.file.play.live ""
2587}
2588
2589proc file_rec_live {} {
2590# Request heart beat to determine if file is valid
2591        mbus_send "R" audio.file.record.live ""
2592}
2593
2594proc file_open_play {path} {
2595    global play_file
2596
2597    mbus_send "R" "audio.file.play.open" [mbus_encode_str $path]
2598    mbus_send "R" "audio.file.play.pause" 1
2599    set play_file(state) paused
2600    set play_file(name) $path
2601   
2602    # Test whether file is still playing/valid
2603    after 200 file_play_live
2604}
2605
2606proc file_open_rec {path} {
2607    global rec_file
2608
2609    mbus_send "R" "audio.file.record.open" [mbus_encode_str $path]
2610    mbus_send "R" "audio.file.record.pause" 1
2611
2612    set rec_file(state) paused
2613    set rec_file(name)  $path
2614
2615    # Test whether file is still recording/valid
2616    after 200 file_rec_live
2617}
2618
2619proc file_enable_play { } {
2620    .file.play.buttons.play   configure -state normal
2621    .file.play.buttons.pause  configure -state disabled
2622    .file.play.buttons.stop   configure -state disabled
2623    .file.play.buttons.status configure -text "Ready to play."
2624}       
2625
2626proc file_enable_record { } {
2627    .file.rec.buttons.rec configure -state normal
2628    .file.rec.buttons.pause  configure -state disabled
2629    .file.rec.buttons.stop   configure -state disabled
2630    .file.rec.buttons.status configure -text "Ready to record."
2631}
2632
2633proc file_play_play {} {
2634        global play_file
2635       
2636        catch {
2637                puts stderr $play_file(state)
2638                if {$play_file(state) == "paused"} {
2639                        mbus_send "R" "audio.file.play.pause" 0
2640                        puts stderr "unpaused"
2641                } else {
2642                        mbus_send "R" "audio.file.play.open" [mbus_encode_str $play_file(name)]
2643                        puts stderr "re-opening"
2644                }
2645                set play_file(state) play
2646        } pferr
2647
2648        if { $pferr != "play" } { puts stderr "pferr: $pferr" }
2649
2650        .file.play.buttons.play   configure -state disabled
2651        .file.play.buttons.pause  configure -state normal
2652        .file.play.buttons.stop   configure -state normal
2653        .file.play.buttons.status configure -text "Playing."
2654        after 200 file_play_live
2655}
2656
2657proc file_play_pause {} {
2658    global play_file
2659   
2660    .file.play.buttons.play   configure -state normal
2661    .file.play.buttons.pause  configure -state disabled
2662    .file.play.buttons.stop   configure -state normal
2663    .file.play.buttons.status configure -text "Paused."
2664    set play_file(state) paused
2665    mbus_send "R" "audio.file.play.pause" 1
2666}
2667
2668proc file_play_stop {} {
2669        global play_file
2670       
2671        set play_file(state) end
2672        file_enable_play
2673        mbus_send "R" "audio.file.play.stop" ""
2674}
2675
2676proc file_rec_rec {} {
2677        global rec_file
2678       
2679        catch {
2680                puts stderr $rec_file(state)
2681                if {$rec_file(state) == "paused"} {
2682                        mbus_send "R" "audio.file.record.pause" 0
2683                } else {
2684                        mbus_send "R" "audio.file.record.open" [mbus_encode_str $rec_file(name)]
2685                }
2686                set rec_file(state) record
2687        } prerr
2688
2689        if { $prerr != "record" } { puts stderr "prerr: $prerr" }
2690
2691        .file.rec.buttons.rec    configure -state disabled
2692        .file.rec.buttons.pause  configure -state normal
2693        .file.rec.buttons.stop   configure -state normal
2694        .file.rec.buttons.status configure -text "Recording."
2695        after 200 file_rec_live
2696}
2697
2698proc file_rec_pause {} {
2699    global rec_file
2700   
2701    .file.rec.buttons.rec    configure -state normal
2702    .file.rec.buttons.pause  configure -state disabled
2703    .file.rec.buttons.stop   configure -state normal
2704    .file.rec.buttons.status configure -text "Paused."
2705    set rec_file(state) paused
2706    mbus_send "R" "audio.file.record.pause" 1
2707}
2708
2709proc file_rec_stop {} {
2710        global rec_file
2711       
2712        set rec_file(state) end
2713        file_enable_record
2714        mbus_send "R" "audio.file.record.stop" ""
2715}
2716
2717#
2718# End of File Window routines
2719#
2720
2721proc show_help {window} {
2722        global help_text help_on help_id
2723        if {$help_on} {
2724                .help.text  configure -text $help_text($window)
2725                # Beware! Don't put the popup under the cursor! Else we get window enter
2726                # for .help and leave for $window, making us hide_help which removes the
2727                # help window, giving us a window enter for $window making us popup the
2728                # help again.....
2729                if {[winfo width $window] > [winfo height $window]} {
2730                    set xpos [expr [winfo pointerx $window] + 10]
2731                    set ypos [expr [winfo rooty    $window] + [winfo height $window] + 4]
2732                } else {
2733                    set xpos [expr [winfo rootx    $window] + [winfo width $window] + 4]
2734                    set ypos [expr [winfo pointery $window] + 10]
2735                }
2736               
2737                wm geometry  .help +$xpos+$ypos
2738                set help_id [after 100 wm deiconify .help]
2739                raise .help $window
2740        }
2741}
2742
2743proc hide_help {window} {
2744        global help_id help_on
2745        if {[info exists help_id]} {
2746                after cancel $help_id
2747        }
2748        wm withdraw .help
2749}
2750
2751proc add_help {window text} {
2752        global help_text
2753        set help_text($window)  $text
2754        bind $window <Enter>    "+show_help $window"
2755        bind $window <Leave>    "+hide_help $window"
2756}
2757
2758bind Entry   <KeyPress> "+hide_help %W"
2759toplevel .help       -bg black
2760label    .help.text  -bg lavender -justify left
2761pack .help.text -side top -anchor w -fill x
2762wm transient        .help .
2763wm withdraw         .help
2764wm overrideredirect .help true
2765
2766add_help .r.c.tx.au.pow.sli     "This slider controls the volume\nof the sound you send."
2767add_help .r.c.tx.au.port.l0     "Click to change input device."
2768add_help .r.c.tx.au.port.l2     "Click to change input device."
2769add_help .r.c.tx.net.on         "If this button is pushed in, you are are transmitting, and\nmay be\
2770        heard by other participants. Holding down the\nright mouse button in\
2771        any RAT window will temporarily\ntoggle the state of this button,\
2772        allowing for easy\npush-to-talk operation."
2773add_help .r.c.tx.au.pow.bar     "Indicates the loudness of the\nsound you are sending. If this\nis\
2774                         moving, you may be heard by\nthe other participants."
2775
2776add_help .r.c.rx.au.pow.sli     "This slider controls the volume\nof the sound you hear."
2777add_help .r.c.rx.au.port.l0     "Click to change output device."
2778add_help .r.c.rx.au.port.l2     "Click to change output device."
2779add_help .r.c.rx.au.pow.bar     "Indicates the loudness of the\nsound you are hearing."
2780add_help .r.c.rx.net.on         "If pushed in, reception is muted."
2781
2782add_help .l.f           "Name of the session, and the IP address, port\n&\
2783                         TTL used to transmit the audio data."
2784add_help .l.t           "The participants in this session with you at the top.\nClick on a name\
2785                         with the left mouse button to display\ninformation on that participant,\
2786                         and with the middle\nbutton to mute that participant (the right button\nwill\
2787                         toggle the transmission mute button, as usual)."
2788
2789add_help .st.opts       "Brings up another window allowing\nthe control of various options."
2790add_help .st.about      "Brings up another window displaying\ncopyright & author information."
2791add_help .st.quit       "Press to leave the session."
2792
2793# preferences help
2794add_help .prefs.m.f.m  "Click here to change the preference\ncategory."
2795set i .prefs.buttons
2796add_help $i.bye         "Cancel changes."
2797add_help $i.apply       "Apply changes."
2798#add_help $i.save        "Save and apply changes."
2799
2800# user help
2801set i .prefs.pane.personal.a.f.f.ents
2802add_help $i.name        "Enter your name for transmission\nto other participants."
2803add_help $i.email       "Enter your email address for transmission\nto other participants."
2804add_help $i.phone       "Enter your phone number for transmission\nto other participants."
2805add_help $i.loc         "Enter your location for transmission\nto other participants."
2806
2807#audio help
2808set i .prefs.pane.audio
2809add_help $i.dd.device.mdev "Selects preferred audio device."
2810add_help $i.dd.sampling.freq.mb \
2811                        "Sets the sampling rate of the audio device.\nThis changes the available codecs."
2812add_help $i.dd.sampling.ch_in.mb \
2813                        "Changes between mono and stereo audio input."
2814add_help $i.dd.cks.f.f.silence\
2815                         "Prevents silence from being transmitted when the speaker is silent\n\
2816                          and the input is unmuted."
2817add_help $i.dd.cks.f.f.agc       "Enables automatic control of the volume\nof the sound you send."
2818add_help $i.dd.cks.f.f.loop "Enables hardware for loopback of audio input."
2819add_help $i.dd.cks.f.f.suppress \
2820                         "Mutes microphone when playing audio."
2821
2822# transmission help
2823set i .prefs.pane.transmission
2824
2825add_help $i.dd.units.m  "Sets the duration of each packet sent.\nThere is a fixed per-packet\
2826                         overhead, so\nmaking this larger will reduce the total\noverhead.\
2827                                                 The effects of packet loss are\nmore noticable with large packets."
2828add_help $i.dd.pri.m    "Changes the primary audio compression\nscheme. The list is arranged\
2829                         with high-\nquality, high-bandwidth choices at the\ntop, and\
2830                                                 poor-quality, lower-bandwidth\nchoices at the bottom."
2831add_help $i.cc.van.rb   "Sets no channel coding."
2832add_help $i.cc.red.rb   "Piggybacks earlier units of audio into packets\n\
2833                         to protect against packet loss. Some audio\n\
2834                         tools (eg: vat-4.0) are not able to receive\n\
2835                         audio sent with this option."
2836add_help $i.cc.red.fc.m \
2837                        "Sets the format of the piggybacked data."
2838add_help $i.cc.red.u.m \
2839                        "Sets the offset of the piggybacked data."
2840add_help $i.cc.layer.fc.m  "Sets the number of discrete layers which will\nbe sent. You need\
2841                                                    to start RAT with the options\n-l n <address>/<port> <address>/<port>,\nwhere\
2842                                                    n is the number of layers and there is an\naddress and port for each layer.\
2843                                                        NB: this is only\nsupported by the WBS codec at present."
2844add_help $i.cc.int.fc.m \
2845                        "Sets the separation of adjacent units within\neach packet. Larger values correspond\
2846                         to longer\ndelays."
2847add_help $i.cc.int.zz.m "Number of compound units per packet."
2848add_help $i.cc.int.rb   "Enables interleaving which exchanges latency\n\
2849                         for protection against burst losses.  No other\n\
2850                         audio tools can decode this format (experimental)."
2851
2852# Reception Help
2853set i .prefs.pane.reception
2854add_help $i.r.m         "Sets the type of repair applied when packets are\nlost. The schemes\
2855                         are listed in order of increasing\ncomplexity and quality of repair."
2856add_help $i.r.ms        "Sets the type of sample rate conversion algorithm\n\
2857                         that will be applied to streams that differ in rate\n\
2858                         to the audio device rate."
2859add_help $i.o.f.cb      "Enforce playout delay limits set below.\nThis is not usually desirable."
2860add_help $i.o.f.fl.scmin   "Sets the minimum playout delay that will be\napplied to incoming\
2861                         audio streams."
2862add_help $i.o.f.fr.scmax   "Sets the maximum playout delay that will be\napplied to incoming\
2863                         audio streams."
2864add_help $i.c.f.f.lec   "If enabled, extra delay is added at both sender and receiver.\nThis allows\
2865                         the receiver to better cope with host scheduling\nproblems, and the sender\
2866                         to perform better silence suppression.\nAs the name suggests, this option\
2867                         is intended for scenarios such\nas transmitting a lecture, where interactivity\
2868                         is less important\nthan quality."
2869
2870# security...too obvious for balloon help!
2871add_help .prefs.pane.security.a.f.f.e "Due to government export restrictions\nhelp\
2872                                       for this option is not available."
2873
2874# interface...ditto!
2875set i .prefs.pane.interface
2876add_help $i.a.f.f.power "Disable display of audio powermeters. This\nis only\
2877                         useful if you have a slow machine"
2878add_help $i.a.f.f.balloon "If you can see this, balloon help\nis enabled. If not, it isn't."
2879add_help $i.a.f.f.matrix  "Displays a chart showing the reception\nquality reported by all participants"
2880add_help $i.a.f.f.plist   "Hides the list of participants"
2881
2882add_help .chart         "This chart displays the reception quality reported\n by all session\
2883                         participants. Looking along a row\n gives the quality with which that\
2884                         participant was\n received by all other participants in the session:\n green\
2885                         is good quality, orange medium quality, and\n red poor quality audio."
2886
2887} script_error
2888
2889if { $script_error != "" } {
2890    puts "Error: \"$script_error\""
2891    destroy .
2892    exit -1
2893}
2894
Note: See TracBrowser for help on using the browser.