root/rat/trunk/ui_audiotool.tcl @ 3192

Revision 3192, 96.4 KB (checked in by ucaccsp, 14 years ago)

Fix window width shuffle on startup

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