File: snamp.tcl

package info (click to toggle)
snack 2.2.10.20090623-dfsg-8
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,764 kB
  • sloc: ansic: 32,662; sh: 8,558; tcl: 1,086; python: 761; makefile: 582
file content (238 lines) | stat: -rwxr-xr-x 6,098 bytes parent folder | download | duplicates (7)
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
}