1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.5 "$0" "$@"
package require -exact snack 2.2
# Try to load optional file format handlers
catch { package require snacksphere }
catch { package require snackogg }
# If they are present add new filetypes to file dialogs
set extTypes {}
set loadTypes {}
set loadKeys {}
set saveTypes {}
set saveKeys {}
if {[info exists snack::snacksphere]} {
lappend extTypes {SPHERE .sph} {SPHERE .wav}
lappend loadTypes {{SPHERE Files} {.sph}} {{SPHERE Files} {.wav}}
lappend loadKeys SPHERE SPHERE
}
if {[info exists snack::snackogg]} {
lappend extTypes {OGG .ogg}
lappend loadTypes {{Ogg Vorbis Files} {.ogg}}
lappend loadKeys OGG
lappend saveTypes {{Ogg Vorbis Files} {.ogg}}
lappend saveKeys OGG
}
snack::addExtTypes $extTypes
snack::addLoadTypes $loadTypes $loadKeys
snack::addSaveTypes $saveTypes $saveKeys
snack::debug 0
snack::sound s -debug 0
snack::sound s2
snack::sound sa
set timestr ""
option add *font {Helvetica 10 bold}
wm title . "Snack Audio MPEG Player"
if 0 {
set draw 1
pack [frame .f]
pack [canvas .f.c -width 140 -height 40] -side left
pack [checkbutton .f.a -text Analyzer -variable draw] -side left
for {set i 0} {$i<16} {incr i} {
.f.c create rect [expr 10*$i] 20 [expr 10*$i+10] 40 -fill green -outline ""
.f.c create rect [expr 10*$i] 10 [expr 10*$i+10] 20 -fill yellow -outline ""
.f.c create rect [expr 10*$i] 0 [expr 10*$i+10] 10 -fill red -outline ""
.f.c create rect [expr 10*$i] 0 [expr 10*$i+10] 40 -fill black -tag c$i
}
for {set i 0} {$i<17} {incr i} {
.f.c create line [expr 10*$i] 0 [expr 10*$i] 40 -width 5
}
for {set i 0} {$i<7} {incr i} {
.f.c create line 0 [expr 6*$i] 140 [expr 6*$i] -width 3
}
}
pack [frame .frame] -side top -expand yes -fill both
scrollbar .frame.scroll -command ".frame.list yview"
listbox .frame.list -yscroll ".frame.scroll set" -setgrid 1 -selectmode single -exportselection false -height 16
pack .frame.scroll -side right -fill y
pack .frame.list -side left -expand 1 -fill both
bind .frame.list <Double-ButtonPress-1> Play
bind .frame.list <B1-Motion> {Drag %y}
bind .frame.list <ButtonPress-1> {Select %y}
bind . <BackSpace> Cut
snack::createIcons
pack [frame .panel] -side bottom -before .frame
pack [button .panel.bp -bitmap snackPlay -command Play] -side left
pack [button .panel.bs -bitmap snackStop -command Stop] -side left
pack [button .panel.bo -image snackOpen -command Open] -side left
set p 0
pack [scale .panel.ss -show no -orient horiz -len 130 -var p] -side left
set gain [snack::audio play_gain]
pack [scale .panel.sv -show no -orient horiz -command {snack::audio play_gain}\
-len 70 -var gain] -side left
set setdrag 1
bind .panel.ss <ButtonPress-1> {set setdrag 0}
bind .panel.ss <ButtonRelease-1> {set setdrag 1 ; Play2}
pack [label .panel.l -textvar timestr]
proc Open {} {
global files
set file [snack::getOpenFile -format MP3]
if {$file != ""} {
set name [file tail $file]
set files($name) $file
.frame.list insert end $name
}
}
proc Play args {
global files t0 filelen
if {[.frame.list curselection] == ""} {
set i 0
} else {
set i [lindex [.frame.list curselection] 0]
}
.frame.list selection set $i
Stop
s config -file $files([.frame.list get $i])
sa config -file $files([.frame.list get $i])
if {$args == ""} {
s play -command Next
set t0 [clock scan now]
} else {
s play -start $args -command Next
set t0 [expr [clock scan now] - $args / [s cget -rate]]
}
set filelen [s length]
Timer
}
proc Play2 {} {
global filelen p
Play [expr int($p/100.0*[s length])]
}
proc Stop {} {
s stop
after cancel Timer
}
proc Timer {} {
global t0 timestr setdrag
set time [expr [clock scan now] - $t0]
set timestr [clock format $time -format "%M:%S"]
if $setdrag {
.panel.ss set [expr int(100 * $time / [s length -unit sec])]
}
# Draw
after 100 Timer
}
proc Next {} {
set i [lindex [.frame.list curselection] 0]
if {$i == ""} return
.frame.list selection clear $i
incr i
.frame.list selection set $i
.frame.list see $i
after 10 Play
}
set cut ""
proc Cut {} {
global cut
if {[.frame.list curselection] != ""} {
set cut [.frame.list get [.frame.list curselection]]
.frame.list delete [.frame.list curselection]
}
}
proc Select y {
global old timestr files
set old [.frame.list nearest $y]
s2 config -file $files([.frame.list get $old])
set timestr [clock format [expr int([s2 length -unit sec])] -format "%M:%S"]
}
proc Drag y {
global old
set new [.frame.list nearest $y]
if {$new == -1} return
set tmp [.frame.list get $old]
.frame.list delete $old
.frame.list insert $new $tmp
.frame.list selection set $new
set old $new
}
array set map {
0 2
1 3
2 4
3 5
4 7
5 9
6 12
7 15
8 19
9 23
10 28
11 34
12 41
13 49
14 56
15 63
}
proc Draw {} {
global draw
if ![snack::audio active] return
if {$draw == 1} {
puts [time {
set pos [expr int([s cget -rate] * [snack::audio elapsed])]
if {$pos > 1000} {
set junk [sa sample [expr $pos - 1000]]
set junk [sa sample [expr $pos - 100]]
set junk [sa sample [expr $pos]]
puts $junk
}
set spec [sa dBPower -start $pos -fftlen 128 -windowlength 128]
for {set i 0} {$i < 16} {incr i} {
set val [lindex $spec $::map($i)]
.f.c coords c$i [expr 10*($i-2)] 0 [expr 10*($i-2)+9] \
[expr 100-1.4*($val+100)]
}
}]
}
}
if [info exists argv] {
if [file isdirectory $argv] {
catch {cd $argv}
}
}
wm protocol . WM_DELETE_WINDOW exit
if {$::tcl_platform(platform) == "windows"} {
set filelist [glob -nocomplain *.mp3 *.wav]
} else {
set filelist [glob -nocomplain *.mp3 *.wav *.MP3 *.WAV]
}
if {[info exists snack::snackogg]} {
set filelist [concat $filelist [glob -nocomplain *.ogg *.OGG]]
}
foreach file [lsort -dictionary $filelist] {
set name [file tail $file]
set files($name) $file
.frame.list insert end $file
}
|