This demonstration shows how to use the Snack module to create web pages with embedded sound recording. The guest book client script is 50 lines and the server script 20 lines.

The client script:

policy home

package require snack

sound s

pack [ label .lt -text "Voice Guest Book Demonstration" -font {Helvetica 24 bold}]
pack [ label .lst1 -text "Uploaded Messages:" -font {Helvetica 14 bold}]
pack [ frame .f1]
pack [ listbox .f1.list -yscroll ".f1.scroll set" -font {Helvetica 14 }] -side left
pack [ scrollbar .f1.scroll -command ".f1.list yview"] -side left -fill y
pack [ button .f1.b -text Listen -command Play] -side right

set time "0.00 sec"
pack [ label .lst2 -text "Record a message:" -font {Helvetica 14 bold}]
pack [ frame .f2]
pack [ button .f2.bRec  -bitmap record -command StartRec -wi 40 -he 20 -fg red] -side left
pack [ button .f2.bStop -bitmap stop -command StopRec -wi 40 -he 20] -side left
pack [ button .f2.bPlay -bitmap play -command {s play -output [audio output]} -wi 40 -he 20] -side left
pack [ label -textvar time -width 10] -side left

set name Anonymous
pack [ label .lst3 -text "Enter your name and upload the message:" -font {Helvetica 14 bold}]
pack [ frame .f3]
pack [ entry .f3.e -textvar name -font {Helvetica 14}] -side left
pack [ button .f3.bSend -text Upload -command Send] -side left

proc UpdateCounter {{flag ""}} {
    global time

    set time [format "%.2f sec" [s length -units seconds]]
    after 100 UpdateCounter

proc Play {} {
    set i [.f1.list cursel]
    if {$i == ""} return
    set d [::browser::getURL$i.wav]
    s data $d
    if {[string match "*not found*" $d] == 1} return
    s play

proc StartRec {} {
    s record -input [audio input]
    after 100 UpdateCounter

proc StopRec {} {
    s stop
    after cancel UpdateCounter

proc Send {} {
    global name

    set sock [socket 23456]
    append name "                    "
    puts -nonewline $sock [string range $name 0 19]
    flush $sock
    puts $sock [s data -fileformat wav]
    close $sock
    .f1.list insert end $name