Changes to snack/README.
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
|
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
|
-
+
-
-
+
+
-
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
|
Snack v2.0 - a sound toolkit for scripting languages
Snack v2.1 - a sound toolkit for scripting languages
Kåre Sjölander <kare@speech.kth.se>
Introduction
-------------------------------------------------------------------
Snack is a sound processing toolkit designed as an extension
to a scripting language. Snack currently works with the scripting
languages Tcl/Tk and Python.
Snack has commands to play, record, process, and visualize sound.
Snack supports in-memory sound objects, file based
audio, and streaming audio. It handles fileformats such as WAV, AU, AIFF,
Snack provides high level sound objects, with flexible storage management,
and streaming support. It handles most common sound file formats.
and MP3.
The visualization canvas item types update in real-time and can output
postscript. The same scripts run on Unix (Linux, Solaris, HP-UX, IRIX,
FreeBSD, NetBSD), Macintosh, and Windows 95/98/NT/2000. It is also possible
FreeBSD, NetBSD), Macintosh, and Windows 95/98/NT/2000/XP. It is also possible
to run scripts embedded in web pages through the use of the Tcl plug-in.
Several example scripts can be found in the demos directory.
For more information on Tcl/Tk and Python see
Tcl/Tk: http://dev.scriptics.com/
Tcl/Tk: http://tcl.activestate.com/
Python: http://www.python.org/
In order to use Snack you must have Tcl and Tk version 8.0 or later. Always
use the latest stable release, currently 8.3.2, which can be downloaded from
ftp://ftp.scriptics.com/pub/tcl/.
use the latest stable release, currently 8.3.4, which can be downloaded from
ftp.activestate.com/ActiveTcl/html/.
Tcl/Tk is often included with Python distributions. Snack has been tested
with Python 1.5.2 - 2.0 on Linux and Windows. See the Python
with Python 1.5.2 - 2.1 on Linux and Windows. See the Python
section below.
The Snack package has been tested on the following platforms:
Windows 95/98/NT/2000
Linux 2.0.35 (OSS 3.5) - 2.2.14 (OSS 3.8.2) (x86 and PowerPC)
Windows 95/98/NT/2000/XP
Linux 2.0.35 (OSS 3.5) - 2.4.3 (OSS 3.8.2) (x86 and PowerPC)
SunOS 5.5.1 (Sparc and x86), Solaris 8 (Sparc)
HP-UX B.10.20
HP-UX B.10.20/11.00
IRIX 6.2, 6.3 & 6.4 (even runs under SoftWindows, although slowly)
NetBSD-current/i386 using the OSS emulation library
BSD/OS-4.1
MacOS 8.6
Make sure you have the latest Snack version available at
http://www.speech.kth.se/snack/ before proceeding with the installation.
Compilation instructions for Snack on Unix
-------------------------------------------------------------------
You must have Tcl/Tk installed on your system. Both Tcl and Tk must have
been configured with the "--enable-shared" flag at build time (this is
default for the 8.3 versions). Build them before Snack.
Unpack Snack and change directory to the snack2.0.7/unix directory.
Unpack Snack and change directory to the snack2.1.6/unix directory.
Type "./configure".
If you get this error message "Can't find Tcl configuration definitions",
you have to specify their locations using the options "--with-tcl" and
"--with-tk" when running configure. For example, use
"--with-tcl=/usr/lib --with-tk=/usr/lib" if Tcl/Tk was
|
︙ | | |
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
|
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
|
-
+
-
+
-
+
-
+
-
+
|
contains the Tcl header file (tcl.h). The same goes for TK_INCPATH (tk.h).
XINCLUDES should be the path to the directory containing the X11 include
files.
Summary in case you download Tcl, Tk, and Snack and build from scratch:
You should place the distributions in the same directory and unpack them.
Build Snack using the following commands:
cd tcl8.3.1/unix
cd tcl8.3.4/unix
./configure --enable-shared
cd ../../tk8.3.1/unix
cd ../../tk8.3.4/unix
./configure --enable-shared
cd ../../snack2.0.7/unix
cd ../../snack2.1.6/unix
./configure
make
If you use Tcl/Tk 8.0 to 8.0.5 you change the last configure to
configure --disable-stubs
Testing
-------------------------------------------------------------------
When you have succesfully compiled Snack it's time to look at the demos.
In order to run these you will have to set the environment variable
TCLLIBPATH to the directory containing the Snack library files (you don't
need this step if you install Snack as described below). If you have
compiled Snack in /u/kare/snack2.0.7/unix, this would be:
compiled Snack in /u/kare/snack2.1.6/unix, this would be:
setenv TCLLIBPATH /u/kare/snack2.0.7/unix
setenv TCLLIBPATH /u/kare/snack2.1.6/unix
Change to the demos/tcl/ directory and type ./widget.tcl:
cd ../demos/tcl/
./widget.tcl
this runs the Snack widget demonstration.
|
︙ | | |
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
|
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
|
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
|
make install
Compilation instructions for Snack on Windows
-------------------------------------------------------------------
The workspace and project files necessary to build Snack on Windows are
in the win directory of the source distribution.
The MSVC++ workspace and project files necessary to build Snack on Windows
are located in the win directory of the source distribution.
In order to use Snack you will have to install Tcl/Tk 8.3 first, don't forget
to tick the box to install include and library files.
In order to use Snack you will have to install Tcl/Tk 8.3 first.
Snack's project files are set up for use with Tcl installed in C:\Tcl\, it
might be easiest to change such paths by editing all *.dsp files in a text
editor.
Don't forget to copy the files snack.tcl and pkgIndex.tcl.dll from the
unix directory to C:\Tcl\lib\snack2.1\ and rename the last file pkgIndex.tcl
Using Snack with Python
-------------------------------------------------------------------
Snack must currently be used in conjunction with Tkinter. You need to have a
matching installation of Snack and Tcl. For example, Python 1.5.2 uses
Tcl8.0.5 and Python 1.6-2.1 uses Tcl8.3 on Windows. For Unix you have to
edit Modules/Setup before building Python to specify which Tcl version to use.
Tcl8.0.5 and Python 1.6-2.0 uses Tcl8.3. You can check this by typing the
following lines at the Python prompt:
The default is Tcl8.0. You can check this by typing the following lines
at the Python prompt:
import Tkinter
Tkinter.Tk().tk.eval('info tclversion')
Snack is accessed using the tkSnack module located in the python directory.
You need to put the file tkSnack.py in your Python path.
|
︙ | | |
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
|
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
-
-
-
-
+
+
+
+
-
-
+
+
+
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
copied to "/usr/local/lib/netscape/tclplug/2.0/".
If you have placed the Netscape plug-in somewhere else (e.g. locally in
$HOME/.netscape/) use:
./configure --enable-plugin --with-mozilla=$SOMEWHERE
You can also simply copy the files yourself to get something similar to this:
/usr/local/lib/netscape/tclplug/2.0/snack2.0/unix/libsnack.sl
/usr/local/lib/netscape/tclplug/2.0/snack2.0/unix/libsound.sl
/usr/local/lib/netscape/tclplug/2.0/snack2.0/unix/pkgIndex.tcl
/usr/local/lib/netscape/tclplug/2.0/snack2.0/unix/snack.tcl
/usr/local/lib/netscape/tclplug/2.0/snack2.1/unix/libsnack.sl
/usr/local/lib/netscape/tclplug/2.0/snack2.1/unix/libsound.sl
/usr/local/lib/netscape/tclplug/2.0/snack2.1/unix/pkgIndex.tcl
/usr/local/lib/netscape/tclplug/2.0/snack2.1/unix/snack.tcl
Currently you need to set this environment variable before starting Netscape:
setenv TCL_PLUGIN_WISH 1
In some cases this may also be necessary:
setenv NPX_PLUGIN_PATH $HOME/.netscape/plugins/
Using Snack with NIST/Sphere file formats
-------------------------------------------------------------------
It is possible to configure Snack to create an additional package for
handling the NIST/Sphere file formats. Use the configure option
--with-nist=DIR to specify the location of the NIST/Sphere distribution,
handling the NIST/Sphere file formats. Use the configure options
--with-nist-include and --with-nist-lib to specify the locations of
the corresponding directories of the NIST/Sphere distribution,
which can be downloaded at
ftp://jaguar.ncsl.nist.gov/pub/sphere_2.6a.tar.Z. In the Sphere
distribution you will have to modify the file src/scripts/install.sh and add
the compilation flag to create position independent code in some cases. Look
at the Snack Makefile for these.
On HP-UX with HP cc use: -Ae +z
Linux users should specify platform: 10 (Custom),
compiler flags: -O -Wall -fPIC, architecture: INTEL,and comment the
line "extern char *sys_errlist[];" in nist/src/lib/sp/exit.c
See SphereFile.txt for more info.
Windows users can get a compiled dll at
http://www.speech.kth.se/~kare/libsnacksphere.dll.
Put it in ..Tcl\lib\Snack2.0 (together with libsnack.dll).
Windows users can get a compiled dll at the address
http://www.speech.kth.se/~kare/libsnacksphere.dll
Put it in ..Tcl\lib\Snack2.1 (together with libsnack.dll).
Linux users get a compiled library at the address
http://www.speech.kth.se/~kare/libsnacksphere.so
Put it in the Snack installation directory (together with libsnack.so).
Using Snack with the OGG/Vorbis file format
-------------------------------------------------------------------
It is possible to configure Snack to create an additional package for
handling the OGG/Vorbis file format. Use the configure options
--with-ogg-include and --with-ogg-lib to specify the locations of an
existing OGG/Vorbis installation.
More information about OGG/Vorbis available at http://www.vorbis.com/
Windows users can get a compiled dll at the address
http://www.speech.kth.se/~kare/ogg.tar.gz
Put libsnackogg.dll in ..Tcl\lib\Snack2.1 (together with libsnack.dll).
Linux users can get a compiled library at the address
http://www.speech.kth.se/~kare/ogg.tar.gz
Put libsnackogg.so in the Snack installation directory (together
with libsnack.so).
When building Ogg/Vorbis from source on Unix note that some modifications
to the Makefiles might be necessary. Specify
"AM_CPPFLAGS=-I$prefix/include" "LDFLAGS=-L$exec_prefix/lib"
to get them to find their own installed headers and libraries.
On Solaris force libvorbis to use the native compiler and add
-Dalloca=__builtin_alloca
to prevent the system from using a non-existing alloca.
Dynamic linking problems
-------------------------------------------------------------------
(Sun, Linux, and SGI)
|
︙ | | |
286
287
288
289
290
291
292
|
327
328
329
330
331
332
333
334
335
336
337
|
+
+
+
+
|
Richard Ross-Langley
Uwe Koloska
Kevin Russell
Nicolas Garbe
Tom Wilkason
Jonas Ekeroot
Peter Kabal
Ted Dunning
Andreas Kupries
Erik Allaert
Christian Wegehaupt
|
Changes to snack/changes.
︙ | | |
696
697
698
699
700
701
702
|
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
3/21/01 (bug fix) Fixed problem for spectrogram canvas items that caused a crash in some cases.
3/22/01 (bug fix) Corrected AU file format handler which incorrectly handled Lin8 files as Lin8Offset.
3/23/01 (enhancement) Added read support for files with double (8-byte) samples to AU and WAV file format handlers.
3/23/01 (bug fix) Fixed problems reading sound files containing float samples.
3/27/01 (bug fix) Removed unnecessary limit on the number of channels for audio I/O on the SGI platform.
3/27/01 (bug fix) Fixed problem with data copying that sometimes occured when reallocating from a small size to a much larger one.
3/28/01 (bug fix) Corrected out of bounds problem in the pitch command.
4/10/01 (bug fix) Corrected bug in the snacksphere package for sound files containing fewer samples than specified in the header.
4/15/01 (new feature) New filter type: iir, which implements IIR/FIR filtering. (Dunning)
4/15/01 (new feature) LPC analysis support added in section canvas item and in dBPowerSpectrum command. (Rank)
4/15/01 (enhancement) Slight beautification of Waveform postscript. (Rank)
----------------- Released 2.1b1, 4/17/01 -----------------------
4/24/01 (new feature) Added support for the Ogg/Vorbis file format (SnackOgg.c) through the optional package "snackogg".
5/1/00 (bug fix) Fixed bug in the map filter that occured when re-configuring it with only one value during playback of multi-channel sounds.
5/3/01 (new feature) Added Ogg/Vorbis format support for writing files and for streaming play/record.
5/8/01 (new feature) Added support for encoding in the Ogg/Vorbis file format.
5/8/01 (new feature) Added streaming support for the Ogg/Vorbis file format.
5/8/01 (new feature) Added configureProc member to Snack_FileFormat struct. This makes it possible to configure/get file format specific options, e.g. -bitrate for MP3 format or -nominalbitrate for Ogg.
5/8/01 (feature change) Added objc/objv parameters to putHeaderProc() which allows for file format specific options. Procedure now returns TCL_OK/TCL_ERROR.
5/8/01 (feature change) Changed parameter of writeSamplesProc() and added implementation to support its use in WriteSound().
----------------- Released 2.1b2, 5/9/01 -----------------------
5/11/01 (enhancement) The wrap.tcl executable generator can now compile scripts that use the packages snackogg and snacksphere.
5/20/01 (enhancement) Updated sources and project file for Macintosh to work with CodeWarrior 6.0 and Tcl/Tk8.3.3.
5/20/01 (new feature) Added demos generator.tcl and scale.tcl.
----------------- Released 2.1, 5/21/01 -----------------------
6/6/01 (bug fix) Fixed bug in header parsing of ESPS files (.sd).
6/7/01 (change) Waveform shape files are now saved with a sample rate of 200 in order to conform to the shape sound command.
6/7/01 (change) Modifications to the shape sound command to make it conform to the shape files generated by the waveform canvas items. (Barras)
6/13/01 (new feature) Added demos generator.py and scale.py.
6/18/01 (enhancement) Snack save dialogs now append .wav etc on the Macintosh.
----------------- Released 2.1.1, 6/21/01 -----------------------
6/29/01 (bug fix) Fixed bug during clean-up which occured for the command sequence "sound record", "exit" (Snack_ExitProc()), followed by after handler with "sound destroy".
7/2/01 (enhancement) Added read support for AU sound files with header specifying dataSize = -1.
7/2/01 (change) Changed the Windows binary installer to default to C:\Tcl which is what ActiveTcl-8.3.3 uses.
7/4/01 (bug fix) Fixed problem reading some CSL sample files (.nsp).
7/20/01 (new feature) New sound command 'power', which is used to compute windowed log power values for a sound.
----------------- Released 2.1.2, 7/20/01 -----------------------
8/1/01 (bug fix) Fixed byte order problem with RAW sound streams.
8/1/01 (bug fix) Fixed problem with RAW sound streams which caused a hang, during play, if no samples were received.
8/3/01 (enhancement) The iir filter now supports multi-channel sound.
8/3/01 (new feature) New demo, pitch.tcl.
8/3/01 (new feature) The Snack script compiler, wrap.tcl, now works out-of-the-box on Windows, with the binary distribution, and for Linux with the source distribution, because freeWrap binaries were included.
8/6/01 (bug fix) Fixed memory leak for sounds linked to disk files that occurred for repeteated configure/play sequences.
8/13/01 (change) Changed the Windows binary installer to use the Tcl installation directory from ActiveState's registry entry.
8/13/01 (bug fix) Added missing library definition for the Ogg/Vorbis encoder in configure.in.
----------------- Released 2.1.3, 8/14/01 -----------------------
8/15/01 (enhancement) Overhaul of the configure script. New options --with-nist-include, --with-nist-lib, --with-ogg-include, and --with-ogg-lib replace --with-nist and --with-ogg, in order to facilitate multi-platform builds. Also, --exec-prefix is now used as intended.
10/25/01 (bug fix) Minor fix in the MP3 decoder for gcc v2.96.
10/25/01 (bug fix) CSL files are now written with a correct block size in FORMDS16. (Kabal)
10/25/01 (enhancement) Support for reading AIFF files containing samples with non multiple of 8 number of bits. (Kabal)
10/25/01 (enhancement) Support for reading WAV files with formats that use WAVE_FORMAT_EXTENSIBLE. (Kabal)
10/26/01 (enhancement) Updated the MSVC++ project files match ActiveTcl's directory structure.
10/26/01 (new feature) New demo, phonetogram.tcl.
----------------- Released 2.1.4, 10/29/01 -----------------------
11/9/01 (bug fix) Fixed problem in the configure script which caused Snack to be built without the TCL_81_API flag, which in turn caused problems for the sound data command.
1/9/02 (enhancement) The generator filter now works correctly on multi-channel sounds through channel duplication.
1/10/02 (new feature) New demo, generator2.tcl.
1/9/02 (enhancement) Support for the stereo-only devices.
1/21/02 (enhancement) Configure script now support HP-UX 11.x.
2/4/02 (new feature) Support for variable bit rate MP3 files with XING headers. (Wilkason)
2/4/02 (bug fix) Fixed crash on HP-UX machines without audio server. (Allaert)
----------------- Released 2.1.5, 2/5/02 -----------------------
2/22/02 (enhancement) Support for 96kHz sample rate on Windows/Linux.
2/25/02 (enhancement) Playback support for normalized float, [1.0, -1.0], sounds.
2/27/02 (bug fix) Fixed problem with the 'filter' command and the -end option.
2/28/02 (new feature) New filter type: fade, which implements linear/logarithmic/exponential fade-in/-out.
----------------- Released 2.1.6, 3/4/02 -----------------------
3/6/02 (change) Removed automatic zero-padding of ESPS files, the start_time field can now be accessed using "sndName configure -start_time" instead.
|
Changes to snack/demos/python/MinSect.py.
1
2
3
4
5
6
7
|
1
2
3
4
5
6
7
8
9
|
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
|
︙ | | |
| |
Changes to snack/demos/python/MinSpeg.py.
1
2
3
4
5
6
7
|
1
2
3
4
5
6
7
8
9
|
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
|
︙ | | |
| |
Changes to snack/demos/python/MinWave.py.
1
2
3
4
5
6
7
|
1
2
3
4
5
6
7
8
9
|
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
|
︙ | | |
| |
Changes to snack/demos/python/echo.py.
1
2
3
4
5
6
7
|
1
2
3
4
5
6
7
8
9
|
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
|
︙ | | |
| |
Added snack/demos/python/generator.py.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
"""AudioControllerSingleton().playLatency(100)"""
s = Sound()
filt = Filter('generator', 440.0)
def play():
s.stop()
s.play(filter=filt)
def stop():
s.stop()
def config(arg):
type = var.get()
if var.get() == "sine" :
shape = 0.0
elif var.get() == "rectangle" :
shape = 0.5
elif var.get() == "triangle" :
shape = 0.5
elif var.get() == "sawtooth" :
type = "triangle"
shape = 0.0
else :
shape = 0.0
filt.configure(s1.get(), s2.get(), shape, type, -1)
f = Frame(root)
f.pack()
s1 = Scale(f, from_=4000, to=50, label="Frequency", length=200, command=config)
s1.pack(side='left')
s2 = Scale(f, from_=32767, to=0, label="Amplitude", length=200, command=config)
s2.pack(side='left')
s1.set(440.0)
s2.set(20000)
var = StringVar()
var.set("sine")
menu = OptionMenu(root, var, "sine", "rectangle", "triangle", "sawtooth", "noise")
menu.pack()
root.bind_all("<Button1-ButtonRelease>", config)
fb = Frame(root)
fb.pack(side='bottom')
Button(fb, bitmap='snackPlay', command=play).pack(side='left')
Button(fb, bitmap='snackStop', command=stop).pack(side='left')
root.mainloop()
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Added snack/demos/python/notescale.py.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
"""AudioControllerSingleton().playLatency(100)"""
def playbeep(freq):
s.stop()
filt.configure(freq)
s.play(filter=filt)
def beepC4():
playbeep(261.6)
def beepD4():
playbeep(293.7)
def beepE4():
playbeep(329.7)
def beepF4():
playbeep(349.3)
def beepG4():
playbeep(392.1)
def beepA4():
playbeep(440.0)
def beepB4():
playbeep(493.9)
def beepC5():
playbeep(523.3)
s = Sound()
filt = Filter('generator', 440.0, 30000, 0.0, 'sine', 8000)
Button(root, text='C4', command=beepC4).pack(side='left')
Button(root, text='D4', command=beepD4).pack(side='left')
Button(root, text='E4', command=beepE4).pack(side='left')
Button(root, text='F4', command=beepF4).pack(side='left')
Button(root, text='G4', command=beepG4).pack(side='left')
Button(root, text='A4', command=beepA4).pack(side='left')
Button(root, text='B4', command=beepB4).pack(side='left')
Button(root, text='C5', command=beepC5).pack(side='left')
root.mainloop()
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Added snack/demos/python/oggplay.py.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#! /usr/bin/env python
#
# Usage: oggplay.py file.ogg
#
# Note: this script will also play audio files in any other format supported
# by tkSnack
import sys
from Tkinter import *
from tkSnack import *
initializeSnack(Tkinter.Tk())
# Load the Ogg/Vorbis format package
Tk().tk.eval('package require snackogg')
if sys.argv[1:]:
snd = Sound(file=sys.argv[1])
snd.play(blocking=1)
else:
print "Usage: oggplay.py file.ogg"
|
| | | | | | | | | | | | | | | | | | | | |
Added snack/demos/python/polarspec.py.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
from math import *
root = Tkinter.Tk()
initializeSnack(root)
snd = Sound()
w = 300
h = 300
s = 100
n = 1024
type = StringVar()
type.set("FFT")
def stop():
snd.stop()
root.after_cancel(id)
def draw():
if (snd.length() > n) :
pos = snd.length() - n
spec = snd.dBPowerSpectrum(start=pos,fftlen=n,winlen=n,analysistype=type.get())
coords=[]
f=0.0001
for val in spec :
v = 6.282985 * log(f)/log(2.0)
a = 1.4*(val+s)
x = w/2+a*cos(v)
y = h/2+a*sin(v)
coords.append(x)
coords.append(y)
f = f + 16000.0 / n
c.delete('polar')
c.create_polygon(coords, tags='polar', fill='green')
if (snd.length(unit='sec') > 20) :
stop()
id = root.after(100,draw)
def start():
pos = 0
snd.record()
c.update_idletasks()
id = root.after(100,draw)
c = SnackCanvas(height=h, width=w, bg='black')
c.pack()
f = Frame()
f.pack()
Button(f, bitmap='snackRecord', fg='red', command=start).pack(side='left')
Button(f, bitmap='snackStop', command=stop).pack(side='left')
Radiobutton(f, text='FFT', variable=type, value='FFT').pack(side='left')
Radiobutton(f, text='LPC', variable=type, value='LPC').pack(side='left')
Button(f, text='Exit', command=root.quit).pack(side='left')
root.mainloop()
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Changes to snack/demos/python/python-demos.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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
|
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
Included Python demos
--------------------------------------------------------------------------
widget.py
The basic Snack demonstrator.
MinWave.py
Minimal waveform example
Minimal waveform example.
MinSect.py
Minimal section example
Minimal section example.
MinSpeg.py
Minimal spectrogram example
Minimal spectrogram example.
echo.py
Demo of echo filter with interactive parameter modification.
sphere.py
Demo that shows how to read NIST/Sphere format files.
polarspec.py
Polar spectrum plot of microphone input signal.
spectrogram.py
Spectrogram plot of microphone input signal.
generator.py
Simple real-time tone generator.
notescale.py
Example of on-the-fly beep generation.
|
Added snack/demos/python/spectrogram.py.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
snd = Sound()
def stop():
snd.stop()
def start():
snd.record()
c = SnackCanvas(height=200, width=400, bg='black')
c.pack()
c.create_spectrogram(1,1,sound=snd,width=400,height=200,pixelspersec=200)
f = Frame()
f.pack()
Button(f, bitmap='snackRecord', fg='red', command=start).pack(side='left')
Button(f, bitmap='snackStop', command=stop).pack(side='left')
Button(f, text='Exit', command=root.quit).pack(side='left')
root.mainloop()
|
| | | | | | | | | | | | | | | | | | | | | | | | | |
Added snack/demos/python/sphere.py.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
# Load the sphere format package
Tk().tk.eval('package require snacksphere')
snd = Sound()
file = 'test.sph'
print 'reading sphere file \'%s\'' % file
snd.read(file)
print 'playing file \'%s\'' % file
snd.play(blocking=1)
print 'writing wav file \'%s\'' % file
snd.write('new.wav')
|
| | | | | | | | | | | | | | | | | | | | | | | |
Changes to snack/demos/python/widget.py.
1
2
3
4
5
6
7
|
1
2
3
4
5
6
7
8
9
|
+
+
|
#! /usr/bin/env python
from Tkinter import *
from tkSnack import *
root = Tkinter.Tk()
initializeSnack(root)
|
︙ | | |
| |
Added snack/demos/tcl/CSLwithAB.tcl.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
# This file shows how to handle CSL/NSP files with both A and B data chunks
package require -exact snack 2.1
set filename CSL_file_with_A_and_B_chunks.nsp
# Read in file using Snack's CSL/NSP decoder, which only gets channel A
# This is done in order to determine the number of samples in each channel
snack::sound s -load $filename
set end [expr [s length] - 1]
# Now read channel A by treating the file as raw data skipping initial
# headers and write it out in a file of its own
s read $filename -fileformat raw -skip 60 -end $end
s write channel_A.wav
# Read channel B by skipping channel A and initial headers and write it
s read $filename -fileformat raw -skip [expr 60 + $end * 2 + 8] -end $end
s write channel_B.wav
exit
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Changes to snack/demos/tcl/MinSect.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
pack [canvas .c -width 300 -height 300]
snack::sound s -load ex1.wav
.c create section 0 0 -sound s -start 6000 -end 6100 -height 300 -width 300
|
︙ | | |
Changes to snack/demos/tcl/MinSpeg.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
pack [canvas .c -height 200 -width 400]
snack::sound s -load ex1.wav
.c create spectrogram 0 0 -sound s -height 200 -width 400
|
︙ | | |
Changes to snack/demos/tcl/MinWave.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
pack [canvas .c -width 400 -height 100]
snack::sound s -load ex1.wav
.c create waveform 0 0 -sound s -width 400
|
︙ | | |
Changes to snack/demos/tcl/Section.tcl.
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
|
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
|
-
+
+
+
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
set width 300
set height 200
set start 0
set end 48000
set stipple ""
set winlen 256
set fftlen 512
set filename section.ps
set topfr 8000
set maxval 0.0
set minval -80.0
set skip 500
set atype FFT
set order 20
set type Hamming
set wtype Hamming
option add *font {Helvetica 10 bold}
pack [ canvas .c -width 400 -height 250]
pack [ canvas .c2 -height 50 -width 400 -closeenough 5]
pack [ label .l -text "Drag markers with left mouse button"]
pack [ frame .f1] -pady 2
pack [ scale .f1.s1 -variable width -label Width -from 10 -to 400 \
|
︙ | | |
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
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
|
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
-orient horizontal -length 100 -command [list .c itemconf sect -minvalue ]]\
-side left
pack [ scale .f1.s6 -variable skip -label "Skip" -from 50 -to 500 \
-orient horizontal -length 100 -command [list .c itemconf sect -skip ]] \
-side left
pack [ frame .f2i] -pady 2
pack [ label .f2i.lt -text "Type:"] -side left
tk_optionMenu .f2i.cm type Hamming Hanning Bartlett Blackman Rectangle
.f2i.cm.menu entryconfigure 0 -command {.c itemconf sect -windowtype $type}
.f2i.cm.menu entryconfigure 1 -command {.c itemconf sect -windowtype $type}
.f2i.cm.menu entryconfigure 2 -command {.c itemconf sect -windowtype $type}
.f2i.cm.menu entryconfigure 3 -command {.c itemconf sect -windowtype $type}
.f2i.cm.menu entryconfigure 4 -command {.c itemconf sect -windowtype $type}
tk_optionMenu .f2i.at atype FFT LPC
.f2i.at.menu entryconfigure 0 -command {.c itemconf sect -analysistype $atype;.f2i.e configure -state disabled;.f2i.s configure -state disabled}
.f2i.at.menu entryconfigure 1 -command {.c itemconf sect -analysistype $atype;.f2i.e configure -state normal;.f2i.s configure -state normal}
pack .f2i.at -side left
pack [ label .f2i.lo -text "order:"] -side left
entry .f2i.e -textvariable order -width 3
scale .f2i.s -variable order -from 1 -to 40 -orient horiz -length 60 -show no
pack .f2i.e .f2i.s -side left
.f2i.e configure -state disabled
.f2i.s configure -state disabled
bind .f2i.e <Key-Return> {.c itemconf sect -lpcorder $order}
bind .f2i.s <Button1-Motion> {.c itemconf sect -lpcorder $order}
tk_optionMenu .f2i.cm wtype Hamming Hanning Bartlett Blackman Rectangle
for {set i 0} {$i < 5} {incr i} {
.f2i.cm.menu entryconfigure $i -command {.c itemconf sect -windowtype $wtype}
}
pack .f2i.cm -side left
pack [ label .f2i.lw -text "window:"] -side left
foreach n {32 64 128 256 512} {
pack [ radiobutton .f2i.w$n -text $n -variable winlen -value $n \
-command {.c itemconf sect -winlength $winlen}] -side left
}
|
︙ | | |
Changes to snack/demos/tcl/Spectrogram.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
set width 300
set height 200
set pps 300
set bright 0.0
set contrast 0.0
set winlen 128
|
︙ | | |
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
-
-
+
+
-
-
-
+
|
pack [ scale .f1.s5 -variable contrast -label Contrast -from -100 -to 100 -res 0.1 -orient hori -length 100 -command {.c itemconf speg -contrast }] -side left
set topfr 8000
pack [ scale .f1.s7 -variable topfr -label Top -from 1000 -to 8000 -orient hori -length 100 -command {.c itemconf speg -topfr }] -side left
pack [ frame .f2] -pady 2
tk_optionMenu .f2.cm type Hamming Hanning Bartlett Blackman Rectangle
.f2.cm.menu entryconfigure 0 -command {.c itemconf speg -windowtype $type}
.f2.cm.menu entryconfigure 1 -command {.c itemconf speg -windowtype $type}
for {set i 0} {$i < 5} {incr i} {
.f2.cm.menu entryconfigure $i -command {.c itemconf speg -windowtype $type}
.f2.cm.menu entryconfigure 2 -command {.c itemconf speg -windowtype $type}
.f2.cm.menu entryconfigure 3 -command {.c itemconf speg -windowtype $type}
.f2.cm.menu entryconfigure 4 -command {.c itemconf speg -windowtype $type}
}
pack .f2.cm -side left
pack [ label .f2.lw -text "window:"] -side left
foreach n {32 64 128 256 512 1024 2048} {
pack [ radiobutton .f2.w$n -text $n -variable winlen -value $n\
-command {.c itemconf speg -winlength $winlen}] -side left
}
|
︙ | | |
Changes to snack/demos/tcl/SphereTest.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
-
+
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec tclsh8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
package require snacksphere
snack::debug 0
snack::sound s -debug 0
set path "nistlibs"
set path "nist/lib"
set fileList [glob $path/data/ex*.wav]
foreach file $fileList {
puts "Playing: $file"
s config -file $file
s play -block 1
}
|
Changes to snack/demos/tcl/Waveform.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
set width 400
set height 100
set pps 300
set color black
set stipple ""
set filename waveform.ps
|
︙ | | |
Changes to snack/demos/tcl/aserver.tcl.
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
|
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
|
-
+
+
+
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
# Try to load optional file format handler
catch { package require snackogg }
snack::debug 0
set port 23654
proc Cmd { sock addr port } {
global servsock msg
set cmd [read $sock 4]
switch $cmd {
play {
set s [snack::sound -debug 0]
puts $sock $s ;# return token for this job
flush $sock
$s config -channel $sock -guessproperties yes
$s configure -channel $sock -guessproperties yes
$s play -command "[list close $sock]; set msg idle;$s destroy"
set msg playing
}
stop {
set handle [gets $sock] ;# get token (sound name) and stop playback
catch { $handle stop }
catch { $handle destroy }
|
︙ | | |
Changes to snack/demos/tcl/compose.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
snack::sound s
set f0 [snack::filter map 0.5]
set f1 [snack::filter echo 0.6 0.6 30 0.4]
set f2 [snack::filter echo 0.6 0.6 50 0.3]
set f3 [snack::filter compose $f0 $f1 $f2]
|
︙ | | |
Changes to snack/demos/tcl/cool.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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
|
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
# An example of how to build a sound application using Snack.
# Can also be used as a base for specialized applications.
package require -exact snack 2.0
package require -exact snack 2.1
# 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
set v(debug) 0
snack::sound snd -debug $v(debug)
set v(rate) 16000
set v(width) 600
set v(height) 150
set v(pps) 10
|
︙ | | |
Changes to snack/demos/tcl/dbrec.scr.
1
2
3
4
|
1
2
3
4
|
-
+
|
This is sentence one
This is sentence two
This is sentence two, which is very much longer than the rest in order to illustrate how the font size adapts to fit the window.
This is sentence three
This is sentence four
|
Changes to snack/demos/tcl/dbrec.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
# Prompted sentence recording application
package require -exact snack 2.0
package require -exact snack 2.1
set rate 16000
snack::sound t -rate $rate
snack::sound s -rate $rate
# dbrec.tcl menus
|
︙ | | |
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
-
-
-
-
-
+
+
+
+
+
+
+
|
snack::levelMeter .f1.lm -width 20 -length 200
label .f1.level -textvariable level
# Arrow key descriptions
frame .f1.f
grid [frame .f1.f.g]
grid [label .f1.f.g.lc -text <Space>=Play -relief raised -bd 3] -row 2 -col 1 -padx 20
grid [label .f1.f.g.lu -text <Up>=Record -relief raised -bd 3] -row 1 -col 3
grid [label .f1.f.g.ll -text <Left>=Prev -relief raised -bd 3] -row 2 -col 2
grid [label .f1.f.g.ld -text <Down>=Stop -relief raised -bd 3] -row 2 -col 3
grid [label .f1.f.g.lr -text <Right>=Next -relief raised -bd 3] -row 2 -col 4
grid [label .f1.f.g.lc -text <Space>=Play -relief raised -bd 3] -row 2 \
-column 1 -padx 20
grid [label .f1.f.g.lu -text <Up>=Record -relief raised -bd 3] -row 1 -column 3
grid [label .f1.f.g.ll -text <Left>=Prev -relief raised -bd 3] -row 2 -column 2
grid [label .f1.f.g.ld -text <Down>=Stop -relief raised -bd 3] -row 2 -column 3
grid [label .f1.f.g.lr -text <Right>=Next -relief raised -bd 3] -row 2 \
-column 4
pack .f1.bp .f1.br .f1.pr .f1.ne .f1.be .f1.time .f1.lm .f1.level \
.f1.f -side left
bind .f1.br <ButtonPress-1> Record
bind .f1.br <ButtonRelease-1> Stop
|
︙ | | |
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
|
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
|
-
+
|
#.f1.br configure -state normal
#bind . <KeyRelease-Up> Record
#bind . <KeyPress-Down> Stop
# Use session number specified on command line, otherwise use next slot
if {$argv != ""} {
if {[info exists argv] && $argv != ""} {
if {[string match "-b" [lindex $argv 0]]} {
OpenBrowser
set argv [lreplace $argv 0 0]
}
set session [lindex $argv end]
if {$session != ""} {
set ::dir [format "sn%04d" $session]
|
︙ | | |
Changes to snack/demos/tcl/echo.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
set f [snack::filter echo 0.6 0.6 30 0.4 50 0.3]
snack::sound s
pack [frame .f]
|
︙ | | |
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
-
-
+
|
proc Config {args} {
global f v
$f configure $v(iGain) $v(oGain) $v(delay1) $v(decay1) $v(delay2) $v(decay2)
}
proc Play {} {
global f
s stop
s play -filter $f
s play -filter $::f
}
proc Load {} {
set file [snack::getOpenFile -initialdir [file dirname [s cget -file]]]
if {$file == ""} return
s config -file $file
}
|
Changes to snack/demos/tcl/formant.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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
|
-
+
+
+
+
+
+
+
+
+
+
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
# there is no way (?) to find out from Tk if we can display UNICODE IPA
# but it seems to be standard on windows installations
if {[string match windows $tcl_platform(platform)]} {set UNICODE_IPA 1}
switch $tcl_platform(platform) {
windows {
proc milliseconds { } {clock clicks}
}
unix {
proc milliseconds { } {expr {[clock clicks]/1000}}
}
}
set vowels(sw) {
O: u 300 600 2350 3250
O \u028a 350 700 2600 3200
Å: o 400 700 2450 3250
Å \u0254 500 850 2550 3250
A: \u0251 600 950 2550 3300
|
︙ | | |
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
-
+
-
+
|
> \u0254 590 880 2540 {}
U \u028a 450 1030 2380 {}
u u 310 870 2250 {}
}
set vowels(lang) us
proc vok4Create {w} {
proc vok4Create {w {wid 200} {hei 200}} {
upvar #0 $w a
frame $w -width 200 -height 200
frame $w -width $wid -height $hei
pack [canvas $w.c -bg black] -fill both -expand 1
pack propagate $w 0
set a(xm) 20
set a(ym) 20
set a(F10) 800
set a(F11) 200
set a(F20) 2300
|
︙ | | |
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
-
+
|
$w.m add radiobutton -variable vowels(lang) -value us \
-command [list vok4Config $w] -label "American vowels (after Ladefoged)"
$w.m add radiobutton -variable vowels(lang) -value NIL \
-command [list vok4Config $w] -label "Don't display vowels"
# trailInit $w 10
bind $w.c <ButtonPress-1> "Play;vok4Move $w %x %y"
bind $w.c <ButtonPress-1> "vok4Move $w %x %y;Play"
bind $w.c <B1-Motion> [list vok4Move $w %x %y]
bind $w.c <ButtonRelease-1> "Stop"
bind $w.c <Configure> [list vok4Config $w %w %h]
bind $w.c <ButtonPress-3> [list tk_popup $w.m %X %Y]
return $w
}
|
︙ | | |
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
|
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
|
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
|
set y [expr {$a(y0)+($a(y1)-$a(y0))*($f1-$a(F10))*1.0/($a(F11)-$a(F10))}]
$w.c create text $x $y -font "times 16" -anchor c -text $sym -fill gray -tags sym
}
}
}
proc vok4Move {w x y} {
# puts [info level 0]
upvar #0 $w a
if $::v(on) {
set f1 [expr {int($a(F10)+($a(F11)-$a(F10))*($y-$a(y0))*1.0/($a(y1)-$a(y0)))}]
set f2 [expr {int($a(F20)+($a(F21)-$a(F20))*($x-$a(x0))*1.0/($a(x1)-$a(x0)))}]
set ::v(f1) $f1
set ::v(f2) $f2
Config
set a(curx) $x
set a(cury) $y
# trailUpdate $w
set f1 [expr {int($a(F10)+($a(F11)-$a(F10))*($y-$a(y0))*1.0/($a(y1)-$a(y0)))}]
set f2 [expr {int($a(F20)+($a(F21)-$a(F20))*($x-$a(x0))*1.0/($a(x1)-$a(x0)))}]
set ::v(f1) $f1
set ::v(f2) $f2
Config
set a(curx) $x
set a(cury) $y
# trailUpdate $w
}
return ""
}
proc updatePreview {} {
$::v(pGen) configure \
$::v(g,freq) $::v(g,ampl) [expr 0.01*$::v(g,shape)] $::v(g,type) 1024
$::v(pF1) configure $::v(f1) $::v(b1)
|
︙ | | |
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
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
}
proc Play {} {
set ::v(on) 1
s stop
s play -filter $::v(All)
updatePreview
set ::v(tstart) [milliseconds]
# updateTracks
.f1.b config -relief sunken
}
proc Stop {} {
s stop
set ::v(on) 0
.f1.b config -relief raised
}
proc Load {} {
set file [snack::getOpenFile]
if {$file != ""} {s read $file}
}
proc updateTracks {} {
set tt 50
set now [milliseconds]
set then $::v(tstart)
set dt [expr 1.0*([milliseconds]-$::v(tstart))]
#set ::v(g,freq) [expr 100+100*(1.0*$dt/$tt)*exp(-$dt/$tt)]
set ::v(g,freq) [expr {100+2*cos(2*3.1415*$dt/$tt)}]
Config
if $::v(on) {
after 50 updateTracks
}
}
proc labeledScale {w args} {
array set a {-valwidth 4 -labwidth 8}
array set a $args
catch {set a(-text) $a(-label)}
frame $w
|
︙ | | |
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
|
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
-
-
+
+
-
-
+
+
|
catch {destroy $w}
toplevel $w
wm title $w "About: Formant Synthesis Demo"
set text " This application demonstrates formant-based synthesis
of vowels in real time, in the spirit of Gunnar Fant's
Orator Verbis Electris (OVE-1) synthesizer of 1953.
Set source and filter parameters to the left. Click and
drag in the \"vowel space\" to the right to hear the vowels.
Set source and filter parameters at the top. Click and
drag in the \"vowel space\" to hear the vowels.
Right-click to select target language for vowel symbols.
Waveform and power spectrum of source (red) and
output signal (green) are displayed at the bottom.
Power spectrum of source (red) and output signal (green) are
to the right, waveforms are displayed at the bottom.
The source type \"sampled\" will use a sound file
containing a single period of a waveform as voice source.
Copyright © 2000 Jonas Beskow
Centre for Speech Technology
KTH, Stockholm"
|
︙ | | |
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
-
+
-
+
-
+
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
+
-
-
+
-
-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
|
.m.file add command -label Exit -command exit
.m.help add command -label About... -command About
. configure -menu .m
# Generator GUI
frame .f1 -relief groove -bd 2
grid .f1 -sticky news -padx 5 -pady 5
grid .f1 -row 0 -column 0 -sticky news -padx 5 -pady 5
label .f1.l -text Source -bg red -anchor w
tk_optionMenu .f1.gt v(g,type) rectangle triangle sine sampled noise
button .f1.b -bitmap snackPlay -command Play
button .f1.c -bitmap snackStop -command Stop
labeledScale .f1.gf -label "Freq." -variable v(g,freq) -from 0.0 -to 1000 -resolution 1.0 -orient horiz -command Config
labeledScale .f1.ga -label "Ampl." -variable v(g,ampl) -from 0.0 -to 6000 -resolution 1.0 -length 160 -orient horiz -command Config
labeledScale .f1.gs -label "Shape" -variable v(g,shape) -from 0.0 -to 100 -resolution 1.0 -length 160 -orient horiz -command Config
grid .f1.l .f1.gt .f1.b .f1.c -sticky we -padx 5
grid .f1.gf -columnspan 4 -sticky we
grid .f1.ga -columnspan 4 -sticky we
grid .f1.gs -columnspan 4 -sticky we
grid columnconfigure .f1 0 -weight 1
grid rowconfigure .f1 4 -weight 1
# Formant filter GUI
frame .f2 -relief groove -bd 2
grid .f2 -sticky news -padx 5 -pady 5
grid .f2 -row 0 -column 1 -sticky news -padx 5 -pady 5
label .f2.l -text "Formants" -bg green -anchor w
grid .f2.l -columnspan 5 -sticky we -padx 5 -pady 5
label .f2.lf -text "Frequency" -anchor w
label .f2.lfu -text "Hz "
label .f2.lb -text "Bandwidth" -anchor w
label .f2.lbu -text "Hz "
grid .f2.lf -row 1 -col 1 -sticky w
grid .f2.lfu -row 1 -col 2 -sticky w
grid .f2.lb -row 1 -col 3 -sticky w
grid .f2.lbu -row 1 -col 4 -sticky w
grid .f2.lf -row 1 -column 1 -sticky w
grid .f2.lfu -row 1 -column 2 -sticky w
grid .f2.lb -row 1 -column 3 -sticky w
grid .f2.lbu -row 1 -column 4 -sticky w
for {set i 1} {$i<=4} {incr i} {
label .f2.l0$i -text F$i -width 2
scale .f2.f$i -variable v(f$i) -from 0 -to 5000 -resolution 1.0 -orient horiz -command Config -showvalue 0 -bd 1 -width 10
label .f2.l1$i -textvariable v(f$i) -anchor w -width 4
scale .f2.b$i -variable v(b${i}) -from 1.0 -to 500 -resolution 1.0 -orient horiz -command Config -showvalue 0 -bd 1 -width 10 -length 80
label .f2.l2$i -textvariable v(b$i) -anchor w -width 3
grid .f2.l0$i .f2.f$i .f2.l1$i .f2.b$i .f2.l2$i -sticky news
}
grid columnconfigure .f2 1 -weight 1
set vokh 250
set vokw 275
# Vowel space
vok4Create .voc
grid .voc -row 0 -col 1 -rowspan 2 -sticky news
vok4Create .voc $vokw $vokh
grid .voc -row 1 -column 0 -sticky news
# Waveforms preview
# Spectrum section preview
set prew 550
snack::sound preview1
snack::sound preview2
set secw $vokw
canvas .c1 -bg black -height 100 -width $prew
grid .c1 -columnspan 2 -sticky news
.c1 create waveform 0 50 -anchor w -sound preview1 -fill red -height 90 -pixelspersecond 16000
.c1 create waveform 0 50 -anchor w -sound preview2 -fill green -height 90 -pixelspersecond 16000
set sech $vokh
# Spectrum section preview
canvas .c2 -bg black -height 100 -width $prew
grid .c2 -columnspan 2 -sticky news
.c2 create section 0 50 -anchor w -sound preview1 -fill red -height 90 -topfrequency 8000 -width $prew -preemphasis 10 -maxval 40 -tags sect
.c2 create section 0 50 -anchor w -sound preview2 -fill green -height 90 -topfrequency 8000 -width $prew -preemphasis 10 -maxval 40 -tags sect
canvas .c2 -bg black -height 100 -width $secw
grid .c2 -row 1 -column 1 -sticky news
.c2 create section 0 0 -sound preview1 -fill red -height $sech -topfrequency 4000 -width $secw -analysistype lpc -tags sect -maxvalue 30
.c2 create section 0 0 -sound preview2 -fill green -height $sech -topfrequency 4000 -width $secw -analysistype lpc -tags sect -maxvalue 30
foreach freq {1 2 3 4 5 6 7 8} {
set x [expr {$freq*$prew/8.0}]
.c2 create line $x 0 $x 100 -fill #666666
.c2 create text $x 0 -anchor ne -text $freq -fill #666666
foreach freq {1 2 3 4} {
set x [expr {$freq*$secw/4.0}]
.c2 create line $x 0 $x $sech -fill #999999
.c2 create text $x 0 -anchor ne -text $freq -fill #999999
}
.c2 create text 0 0 -anchor nw -text kHz -fill #666666
.c2 create text 0 0 -anchor nw -text kHz -fill #999999
.c2 raise sect
# Waveforms preview
set wavw 550
set wavh 90
canvas .c1 -bg black -height 100 -width $wavw
grid .c1 -row 2 -columnspan 2 -sticky news
.c1 create waveform 0 50 -anchor w -sound preview1 -fill red -height $wavh -pixelspersecond 16000
.c1 create waveform 0 50 -anchor w -sound preview2 -fill green -height $wavh -pixelspersecond 16000
# Default values
set v(f1) 500
set v(b1) 50
set v(f2) 1500
set v(b2) 75
|
︙ | | |
Changes to snack/demos/tcl/fourChan.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
# Create a four channel sound with some computed waveform data
sound s -channels 4 -rate 8000
s length 16000
set p 16
set n 0
|
︙ | | |
Added snack/demos/tcl/freewrap.
cannot compute difference between binary files
Added snack/demos/tcl/generator.tcl.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.1
set f [snack::filter generator 440.0]
snack::sound s
#snack::audio playLatency 200
tk_optionMenu .m v(type) sine rectangle triangle sawtooth noise
foreach i [list 0 1 2 3 4] {
.m.menu entryconfigure $i -command Config
}
pack .m -side bottom
pack [frame .fb] -side bottom
pack [button .fb.a -bitmap snackPlay -command Play] -side left
pack [button .fb.b -bitmap snackStop -command "s stop"] -side left
set v(freq) 440.0
set v(ampl) 20000
pack [frame .f] -expand yes -fill both -side top
pack [scale .f.s1 -label Frequency -from 4000 -to 50 -length 200\
-variable v(freq) -command Config] -side left -expand yes -fill both
pack [scale .f.s2 -label Amplitude -from 32767 -to 0 -length 200\
-variable v(ampl) -command Config] -side left -expand yes -fill both
proc Config {args} {
global f v
set shape 0.0
set type $v(type)
switch $type {
sine {
set shape 0.0
}
rectangle {
set shape 0.5
}
triangle {
set shape 0.5
}
sawtooth {
set shape 0.0
set type triangle
}
}
$f configure $v(freq) $v(ampl) $shape $type -1
}
proc Play {} {
global f
s stop
s play -filter $f
}
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Added snack/demos/tcl/generator2.tcl.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.1
snack::sound s1 -channels 2
set leftMap [snack::filter map 1 0 0 0]
set left(generator) [snack::filter generator 440 20000 0.0 sine -1]
set leftFilter [snack::filter compose $left(generator) $leftMap]
snack::sound s2 -channels 2
set rightMap [snack::filter map 0 0 0 1]
set right(generator) [snack::filter generator 440 20000 0.0 sine -1]
set rightFilter [snack::filter compose $right(generator) $rightMap]
pack [frame .fb] -side bottom
pack [button .fb.a -bitmap snackPlay -command Play] -side left
pack [button .fb.b -bitmap snackStop -command "snack::audio stop"] -side left
set left(freq) 440.0
set left(ampl) 20000
set right(freq) 440.0
set right(ampl) 20000
pack [frame .left] -expand yes -fill both -side top
pack [label .left.l -text "Left channel "] -side left
pack [scale .left.s1 -label Frequency -from 4000 -to 50 -length 200\
-variable left(freq) -command [list Config left]] -side left -expand yes -fill both
pack [scale .left.s2 -label Amplitude -from 32767 -to 0 -length 200\
-variable left(ampl) -command [list Config left]] -side left -expand yes -fill both
tk_optionMenu .left.m1 left(type) sine rectangle triangle sawtooth noise
foreach i [list 0 1 2 3 4] {
.left.m1.menu entryconfigure $i -command [list Config left]
}
pack .left.m1 -side left
pack [frame .right] -expand yes -fill both -side top
pack [label .right.l -text "Right channel"] -side left
pack [scale .right.s1 -label Frequency -from 4000 -to 50 -length 200\
-variable right(freq) -command [list Config right]] -side left -expand yes -fill both
pack [scale .right.s2 -label Amplitude -from 32767 -to 0 -length 200\
-variable right(ampl) -command [list Config right]] -side left -expand yes -fill both
tk_optionMenu .right.m2 right(type) sine rectangle triangle sawtooth noise
foreach i [list 0 1 2 3 4] {
.right.m2.menu entryconfigure $i -command [list Config right]
}
pack .right.m2 -side left
proc Config {f args} {
set shape 0.0
upvar $f lf
set type $lf(type)
switch $type {
sine {
set shape 0.0
}
rectangle {
set shape 0.5
}
triangle {
set shape 0.5
}
sawtooth {
set shape 0.0
set type triangle
}
}
$lf(generator) configure $lf(freq) $lf(ampl) $shape $type -1
}
proc Play {} {
snack::audio stop
s1 play -filter $::leftFilter
s2 play -filter $::rightFilter
}
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Changes to snack/demos/tcl/levelmeter.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
snack::sound s -channels 2
pack [frame .a]
pack [frame .b]
pack [snack::levelMeter .a.left -width 20 -length 200 \
-orient horizontal]
|
︙ | | |
Changes to snack/demos/tcl/mapChan.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.0
package require -exact snack 2.1
snack::sound s
set v(0) 1
set v(1) 0
set v(2) 0
set v(3) 1
|
︙ | | |
Changes to snack/demos/tcl/mixer.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
-
+
-
-
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
# A cross-platform mixer application that adapts to the capabilities
# of Snack on the machine it is run on.
# Lots of functionality on Linux - play volume only on Windows, currently.
package require -exact snack 2.0
package require -exact snack 2.1
proc Update {} {
global doMonitor
snack::mixer update
if $doMonitor { after 100 Update }
if $::doMonitor { after 100 Update }
}
bind . <Configure> Update
wm protocol . WM_DELETE_WINDOW exit
pack [frame .f] -expand yes -fill both
pack [checkbutton .r -text Monitor -command Update -variable doMonitor]
|
︙ | | |
Added snack/demos/tcl/notescale.tcl.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.1
set f [snack::filter generator 440.0 30000 0.0 sine 8000]
snack::sound s
#snack::audio playLatency 100
wm resizable . 0 0
proc Beep {freq} {
$::f configure $freq
s stop
s play -filter $::f
}
pack [button .b1 -text C4 -command [list Beep 261.6]] -side left
pack [button .b2 -text D4 -command [list Beep 293.7]] -side left
pack [button .b3 -text E4 -command [list Beep 329.7]] -side left
pack [button .b4 -text F4 -command [list Beep 349.3]] -side left
pack [button .b5 -text G4 -command [list Beep 392.1]] -side left
pack [button .b6 -text A4 -command [list Beep 440.0]] -side left
pack [button .b7 -text B4 -command [list Beep 493.9]] -side left
pack [button .b8 -text C5 -command [list Beep 523.3]] -side left
|
| | | | | | | | | | | | | | | | | | | | | | | | |
Added snack/demos/tcl/oggstream.tcl.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#!/bin/sh
# the next line restarts using tclsh \
exec wish8.3 "$0" "$@"
# Demonstration that sends a live recorded Ogg/Vorbis stream
# to the Snack sound server, aserver.tcl
# You will have to edit this script to set host and port
# to reflect were the server is run.
package require snack
package require snackogg
# Edit host and port here
set host ior.speech.kth.se
set port 23654
if [catch {set sock [socket $host $port]} res] {
puts "Error: no aserver.tcl at $host:$port"
exit
}
# Create sound object and attach it to the opened socket stream
sound s -channel $sock -channels 2 -rate 44100 -fileformat ogg
# Notify the server that a play operation is due
puts -nonewline $sock play
# Set desired bitrate
s config -nominalbitrate 32000
# Start recording
s record
# Keep the event loop alive, necessary for background recording
vwait forever
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Added snack/demos/tcl/phonetogram.tcl.
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#!/bin/sh
# the next line restarts using wish \
exec wish8.3 "$0" "$@"
package require -exact snack 2.1
sound s
sound t
pack [frame .b] -side bottom
pack [button .b.r -bitmap snackRecord -command Start -fg red -width 40] \
-side left
pack [button .b.s -bitmap snackStop -command Stop -width 40] -side left
pack [button .b.p -bitmap snackPlay -command {Stop;s play} -width 40] \
-side left
pack [checkbutton .b.l -text "Erase dots" -variable erase] -side left
pack [frame .f] -side top -expand true -fill both
pack [canvas .f.c -bg white] -side left -expand true -fill both
.f.c create text 130 100 -text "Phonetogram plot (pitch and intensity)"
set samplePos 0
set erase 0
proc Stop {} {
s stop
after cancel Draw
}
proc Start {} {
Stop
s record
set ::samplePos 0
.f.c delete all
after 200 Draw
}
proc Draw {} {
if {$::erase} { .f.c delete all }
set length [s length]
while {$::samplePos < $length - 666} {
t copy s -start $::samplePos -end [expr {$::samplePos+665}]
t changed new
set pitch [lindex [t pitch] 2]
set amplitude [t max]
if {$amplitude < 1} { set amplitude 1 }
set y [expr {[winfo height .f.c]*(2.0-log10($amplitude)/2.26)}]
set x [expr {[winfo width .f.c]*($pitch/300.0)}]
if {$pitch > 0.0} {
.f.c create oval [expr {$x-1}] [expr {$y-1}] [expr {$x+1}] [expr {$y+1}]
}
incr ::samplePos 160
}
after 50 Draw
if {[s length] > 320000} Stop
}
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Added snack/demos/tcl/pitch.tcl.