root/rat/trunk/ui_audiotool.tcl @ 3090

Revision 3090, 95.9 KB (checked in by ucacoxh, 14 years ago)

- typo correction.

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