Version 4.4.4

This commit is contained in:
Gary Scavone
2013-09-29 23:22:28 +02:00
committed by Stephen Sinclair
parent 0aec39260a
commit fc877b87bf
233 changed files with 9035 additions and 5800 deletions

View File

@@ -80,11 +80,11 @@ void processMessage( TickData* data )
return;
case __SK_NoteOn_:
if ( value2 == 0.0 ) // velocity is zero ... really a NoteOff
data->voicer->noteOff( value1, 64.0 );
else // a NoteOn
if ( value2 > 0.0 ) { // velocity > 0
data->voicer->noteOn( value1, value2 );
break;
break;
}
// else a note off, so continue to next case
case __SK_NoteOff_:
data->voicer->noteOff( value1, value2 );

View File

@@ -127,6 +127,10 @@ SOURCE=..\..\src\Clarinet.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\Fir.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\Delay.cpp
# End Source File
# Begin Source File
@@ -251,7 +255,7 @@ SOURCE=..\..\src\Plucked.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\PluckTwo.cpp
SOURCE=..\..\src\Twang.cpp
# End Source File
# Begin Source File
@@ -427,6 +431,10 @@ SOURCE=..\..\include\Clarinet.h
# End Source File
# Begin Source File
SOURCE=..\..\include\Fir.h
# End Source File
# Begin Source File
SOURCE=..\..\include\Delay.h
# End Source File
# Begin Source File
@@ -571,7 +579,7 @@ SOURCE=..\..\include\Plucked.h
# End Source File
# Begin Source File
SOURCE=..\..\include\PluckTwo.h
SOURCE=..\..\include\Twang.h
# End Source File
# Begin Source File

View File

@@ -6,8 +6,6 @@ set cont1 127.0
set cont2 0.0
set cont4 0.0
set cont11 0.0
set outID "stdout"
set commtype "stdout"
set struckbow 0
set preset 0
@@ -16,17 +14,6 @@ wm title . "STK Bowed Bar Controller"
wm iconname . "bowedbar"
. config -bg black
# Configure "communications" menu
menu .menu -tearoff 0
menu .menu.communication -tearoff 0
.menu add cascade -label "Communication" -menu .menu.communication \
-underline 0
.menu.communication add radio -label "Console" -variable commtype \
-value "stdout" -command { setComm }
.menu.communication add radio -label "Socket" -variable commtype \
-value "socket" -command { setComm }
. configure -menu .menu
# Configure preset radio buttons
frame .radio1 -bg black
@@ -116,60 +103,51 @@ pack .right.reson -padx 10 -pady 10
pack .left -side left
pack .right -side right
bind all <KeyPress> {
noteOn $pitch $press
}
bind all <KeyPress> { noteOn $pitch $press }
# Bind an X windows "close" event with the Exit routine
bind . <Destroy> +myExit
proc myExit {} {
global pitch outID
puts $outID [format "NoteOff 0.0 1 %f 127" $pitch ]
flush $outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
global pitch
puts [format "NoteOff 0.0 1 %f 127" $pitch ]
flush stdout
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc noteOn {pitchVal pressVal} {
global outID
puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc noteOff {pitchVal pressVal} {
global outID
puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc patchChange {value} {
global outID patch
global patch
set patch $value
puts $outID [format "ProgramChange 0.0 1 %i" $value]
flush $outID
puts [format "ProgramChange 0.0 1 %i" $value]
flush stdout
}
proc printWhatz {tag value1 value2 } {
global outID
puts $outID [format "%s %i %f" $tag $value1 $value2]
flush $outID
puts [format "%s %i %f" $tag $value1 $value2]
flush stdout
}
proc changePress {value} {
global outID
puts $outID [format "AfterTouch 0.0 1 %f" $value]
flush $outID
puts [format "AfterTouch 0.0 1 %f" $value]
flush stdout
}
proc changePitch {value} {
global outID
puts $outID [format "PitchChange 0.0 1 %.3f" $value]
flush $outID
puts [format "PitchChange 0.0 1 %.3f" $value]
flush stdout
}
proc activateVel {} {
@@ -178,69 +156,32 @@ proc activateVel {} {
printWhatz "ControlChange 0.0 1 " 65 0
}
bind . <Configure> { center_the_toplevel %W }
proc center_the_toplevel { w } {
# Socket connection procedure
set d .socketdialog
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
proc setComm {} {
global outID
global commtype
global d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
switch $i {
0 {set commtype "socket"}
1 {close $outID
set outID "stdout"}
}
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
-command { set commtype "stdout"
set outID "stdout"
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket $sockhost $sockport} outID]
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
if {$err == 0} {
destroy $d
} else {
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
} }
pack $d.buttons.cancel -side left -padx 5 -pady 10
pack $d.buttons.connect -side right -padx 5 -pady 10
pack $d.buttons -side bottom -padx 5 -pady 10
}
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

@@ -1,5 +1,5 @@
# Tcl/Tk Demo GUI for the Synthesis Toolkit (STK)
# by Gary P. Scavone, CCRMA, Stanford University, 1999-2002.
# by Gary P. Scavone, CCRMA, Stanford University, 1999-2012.
# Set initial control values
set pitch 64.0
@@ -11,8 +11,6 @@ set cont4 20.0
set cont7 128.0
set cont11 64.0
set cont44 24.0
set outID "stdout"
set commtype "stdout"
set patchnum 0
set oldpatch 0
set temp 0
@@ -22,19 +20,10 @@ wm title . "STK Demo GUI"
wm iconname . "demo"
. config -bg black
# Configure "communications" menu
menu .menu -tearoff 0
menu .menu.communication -tearoff 0
.menu add cascade -label "Communication" -menu .menu.communication \
-underline 0
.menu.communication add radio -label "Console" -variable commtype \
-value "stdout" -command { setComm }
.menu.communication add radio -label "Socket" -variable commtype \
-value "socket" -command { setComm }
# Configure instrument change menu. Use a unique number for each
# voice. The STK program change value is found by dividing by 100,
# while the remainder corresponds to within-class preset values.
menu .menu -tearoff 0
menu .menu.instrument -tearoff 0
.menu add cascade -label "Instruments" -menu .menu.instrument \
-underline 0
@@ -96,45 +85,45 @@ menu .menu.instrument -tearoff 0
-value 2301 -command { patchChange $patchnum }
.menu.instrument add radio -label "Sekere" -variable patchnum \
-value 2302 -command { patchChange $patchnum }
.menu.instrument add radio -label "Guiro" -variable patchnum \
.menu.instrument add radio -label "Tambourine" -variable patchnum \
-value 2303 -command { patchChange $patchnum }
.menu.instrument add radio -label "Waterdrop" -variable patchnum \
.menu.instrument add radio -label "Sleigh Bells" -variable patchnum \
-value 2304 -command { patchChange $patchnum }
.menu.instrument add radio -label "Bamboo" -variable patchnum \
.menu.instrument add radio -label "Bamboo Chimes" -variable patchnum \
-value 2305 -command { patchChange $patchnum } \
-columnbreak 1
.menu.instrument add radio -label "Tambourine" -variable patchnum \
.menu.instrument add radio -label "Sandpaper" -variable patchnum \
-value 2306 -command { patchChange $patchnum }
.menu.instrument add radio -label "Sleigh Bell" -variable patchnum \
.menu.instrument add radio -label "Coke Can" -variable patchnum \
-value 2307 -command { patchChange $patchnum }
.menu.instrument add radio -label "Sticks" -variable patchnum \
-value 2308 -command { patchChange $patchnum }
.menu.instrument add radio -label "Crunch" -variable patchnum \
-value 2309 -command { patchChange $patchnum }
.menu.instrument add radio -label "Wrench" -variable patchnum \
-value 2310 -command { patchChange $patchnum }
.menu.instrument add radio -label "SandPaper" -variable patchnum \
-value 2311 -command { patchChange $patchnum }
.menu.instrument add radio -label "CokeCan" -variable patchnum \
-value 2312 -command { patchChange $patchnum }
.menu.instrument add radio -label "NeXT Mug" -variable patchnum \
-value 2313 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Penny" -variable patchnum \
-value 2314 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Nickle" -variable patchnum \
-value 2315 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Dime" -variable patchnum \
-value 2316 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Quarter" -variable patchnum \
-value 2317 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Franc" -variable patchnum \
-value 2318 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Peso" -variable patchnum \
-value 2319 -command { patchChange $patchnum }
.menu.instrument add radio -label "Big Rocks" -variable patchnum \
-value 2320 -command { patchChange $patchnum }
-value 2310 -command { patchChange $patchnum }
.menu.instrument add radio -label "Little Rocks" -variable patchnum \
-value 2311 -command { patchChange $patchnum }
.menu.instrument add radio -label "NeXT Mug" -variable patchnum \
-value 2312 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Penny" -variable patchnum \
-value 2313 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Nickle" -variable patchnum \
-value 2314 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Dime" -variable patchnum \
-value 2315 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Quarter" -variable patchnum \
-value 2316 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Franc" -variable patchnum \
-value 2317 -command { patchChange $patchnum }
.menu.instrument add radio -label "Mug & Peso" -variable patchnum \
-value 2318 -command { patchChange $patchnum }
.menu.instrument add radio -label "Guiro" -variable patchnum \
-value 2319 -command { patchChange $patchnum }
.menu.instrument add radio -label "Wrench" -variable patchnum \
-value 2320 -command { patchChange $patchnum }
.menu.instrument add radio -label "Water Drops" -variable patchnum \
-value 2321 -command { patchChange $patchnum }
.menu.instrument add radio -label "Tuned Bamboo" -variable patchnum \
-value 2322 -command { patchChange $patchnum }
@@ -183,7 +172,7 @@ button .pretty -bitmap @$bitmappath/Klar.xbm \
-background white -foreground black
pack .pretty -padx 5 -pady 10
# Configure "note-on" buttons
# Configure "note on" buttons
frame .noteOn -bg black
button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press }
@@ -200,50 +189,50 @@ frame .left -bg black
frame .right -bg black
scale .left.volume -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 7} \
-orient horizontal -label "Volume" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont7
-command {printWhatz "ControlChange 0.0 1 " 7} \
-orient horizontal -label "Volume" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont7
scale .left.bPressure -from 0 -to 128 -length 200 \
-command {changePress } -variable press \
-orient horizontal -label "Breath Pressure" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePress } -variable press \
-orient horizontal -label "Breath Pressure" \
-tickinterval 32 -showvalue true -bg grey66
scale .left.pitch -from 0 -to 128 -length 200 \
-command {changePitch } -variable pitch \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePitch } -variable pitch \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66
scale .left.cont2 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 2} \
-orient horizontal -label "Reed Stiffness" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont2
-command {printWhatz "ControlChange 0.0 1 " 2} \
-orient horizontal -label "Reed Stiffness" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont2
scale .right.reverb -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont44
-command {printWhatz "ControlChange 0.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont44
scale .right.cont4 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 4} \
-orient horizontal -label "Breath Noise" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
-command {printWhatz "ControlChange 0.0 1 " 4} \
-orient horizontal -label "Breath Noise" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
scale .right.cont11 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 11} \
-orient horizontal -label "Vibrato Rate" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11
-command {printWhatz "ControlChange 0.0 1 " 11} \
-orient horizontal -label "Vibrato Rate" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11
scale .right.cont1 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 1} \
-orient horizontal -label "Vibrato Amount" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont1
-command {printWhatz "ControlChange 0.0 1 " 1} \
-orient horizontal -label "Vibrato Amount" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont1
pack .left.volume -padx 10 -pady 10
pack .left.bPressure -padx 10 -pady 10
@@ -261,31 +250,57 @@ pack .right -side right
set p .drumwindow
proc myExit {} {
global pitch outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
global pitch
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc noteOn {pitchVal pressVal} {
global outID
puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOn 0.0 1 %3.2f %3.2f" $pitchVal $pressVal]
flush stdout
}
proc noteOff {pitchVal pressVal} {
global outID
puts $outID [format "NoteOff 0.0 1 %3.2f %3.2f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOff 0.0 1 %3.2f %3.2f" $pitchVal $pressVal]
flush stdout
}
# Set bindings
bind . <KeyPress> { noteOn $pitch $press }
bind . <Destroy> +myExit
proc playDrum {value} {
global velocity
puts [format "NoteOn 0.0 1 %3i %3.2f" $value $velocity]
flush stdout
}
proc printWhatz {tag value1 value2 } {
puts [format "%s %2i %3.2f" $tag $value1 $value2]
flush stdout
}
proc changePress {value} {
global patchnum
if { $patchnum<700 || ($patchnum>900 && $patchnum<2500) || $patchnum>=2600 } {
puts [format "AfterTouch 0.0 1 %3.2f" $value]
flush stdout
}
}
proc changePitch {value} {
puts [format "PitchChange 0.0 1 %3.2f" $value]
flush stdout
}
proc patchChange {value} {
global outID bitmappath cont1 cont2 cont4 cont11 oldpatch press pitch temp
global bitmappath cont1 cont2 cont4 cont11 oldpatch press pitch temp
if {$value!=$oldpatch} {
set program [expr $value / 100]
puts $outID [format "ProgramChange 0.0 1 %2i" $program]
flush $outID
puts [format "ProgramChange 0.0 1 %2i" $program]
flush stdout
# This stuff below sets up the correct bitmaps, slider labels, and control
# parameters.
@@ -374,7 +389,7 @@ proc patchChange {value} {
printWhatz "ControlChange 0.0 1 " 2 $cont2
printWhatz "ControlChange 0.0 1 " 4 $cont4
printWhatz "ControlChange 0.0 1 " 11 $cont11
puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press]
puts [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press]
}
if {$program==5} { # Bottle
.pretty config -bitmap @$bitmappath/prcFunny.xbm
@@ -595,12 +610,12 @@ proc patchChange {value} {
set cont2 0.0
set cont4 0.0
set cont11 0.0
puts $outID [format "ControlChange 0.0 1 16 %3.2f" $preset]
puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press]
puts [format "ControlChange 0.0 1 16 %3.2f" $preset]
puts [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press]
printWhatz "ControlChange 0.0 1 " 1 $cont1
printWhatz "ControlChange 0.0 1 " 2 $cont2
printWhatz "ControlChange 0.0 1 " 11 $cont11
flush $outID
flush stdout
}
if {$program==23} { # Shakers
.pretty config -bitmap @$bitmappath/phism.xbm
@@ -619,23 +634,23 @@ proc patchChange {value} {
.pretty config -bitmap @$bitmappath/cabasa.xbm
}
3 {
.pretty config -bitmap @$bitmappath/guiro.xbm
.pretty config -bitmap @$bitmappath/tambourine.xbm
}
4 {
.pretty config -bitmap @$bitmappath/sleighbell.xbm
}
5 {
.pretty config -bitmap @$bitmappath/bamboo.xbm
}
6 {
.pretty config -bitmap @$bitmappath/tambourine.xbm
}
7 {
.pretty config -bitmap @$bitmappath/sleighbell.xbm
}
10 {
.pretty config -bitmap @$bitmappath/rachet.xbm
}
12 {
.pretty config -bitmap @$bitmappath/cokecan.xbm
}
19 {
.pretty config -bitmap @$bitmappath/guiro.xbm
}
20 {
.pretty config -bitmap @$bitmappath/rachet.xbm
}
22 {
.pretty config -bitmap @$bitmappath/bamboo.xbm
}
@@ -644,12 +659,12 @@ proc patchChange {value} {
set cont2 64.0
set cont4 64.0
set cont11 64.0
puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press]
puts [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press]
printWhatz "ControlChange 0.0 1 " 1 $cont1
printWhatz "ControlChange 0.0 1 " 2 $cont2
printWhatz "ControlChange 0.0 1 " 4 $cont4
printWhatz "ControlChange 0.0 1 " 11 $cont11
flush $outID
flush stdout
}
if {$program==24} { # Modal Instruments
.pretty config -bitmap @$bitmappath/KModal.xbm
@@ -673,7 +688,7 @@ proc patchChange {value} {
printWhatz "ControlChange 0.0 1 " 2 $cont2
printWhatz "ControlChange 0.0 1 " 4 $cont4
printWhatz "ControlChange 0.0 1 " 11 $cont11
flush $outID
flush stdout
}
if { $program==25 } { # Mesh2D
.pretty config -bitmap @$bitmappath/prcFunny.xbm
@@ -691,7 +706,7 @@ proc patchChange {value} {
printWhatz "ControlChange 0.0 1 " 2 $cont2
printWhatz "ControlChange 0.0 1 " 4 $cont4
printWhatz "ControlChange 0.0 1 " 11 $cont11
flush $outID
flush stdout
}
if { $program==26 } { # Resonate
.pretty config -bitmap @$bitmappath/prcFunny.xbm
@@ -709,7 +724,7 @@ proc patchChange {value} {
printWhatz "ControlChange 0.0 1 " 11 $cont11
printWhatz "ControlChange 0.0 1 " 1 $cont1
printWhatz "ControlChange 0.0 1 " 2 $cont2
flush $outID
flush stdout
}
if { $program==27 } { # Whistle
.pretty config -bitmap @$bitmappath/prcFunny.xbm
@@ -727,105 +742,38 @@ proc patchChange {value} {
printWhatz "ControlChange 0.0 1 " 11 $cont11
printWhatz "ControlChange 0.0 1 " 1 $cont1
printWhatz "ControlChange 0.0 1 " 2 $cont2
flush $outID
flush stdout
}
set oldpatch $value
}
}
#bind all <KeyPress> {
bind . <KeyPress> {
noteOn $pitch $press
}
bind . <Configure> {+ center_the_toplevel %W }
proc center_the_toplevel { w } {
# Bind an X windows "close" event with the Exit routine
bind . <Destroy> +myExit
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
proc playDrum {value} {
global velocity outID
puts $outID [format "NoteOn 0.0 1 %3i %3.2f" $value $velocity]
flush $outID
}
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
proc printWhatz {tag value1 value2 } {
global outID
puts $outID [format "%s %2i %3.2f" $tag $value1 $value2]
flush $outID
}
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
proc changePress {value} {
global outID patchnum
if { $patchnum<700 || ($patchnum>900 && $patchnum<2500) || $patchnum>=2600 } {
puts $outID [format "AfterTouch 0.0 1 %3.2f" $value]
flush $outID
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
}
proc changePitch {value} {
global outID
puts $outID [format "PitchChange 0.0 1 %3.2f" $value]
flush $outID
}
# Socket connection procedure
set d .socketdialog
proc setComm {} {
global outID commtype d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
switch $i {
0 {set commtype "socket"}
1 {close $outID
set outID "stdout"}
}
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
-command { set commtype "stdout"
set outID "stdout"
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket $sockhost $sockport} outID]
if {$err == 0} {
destroy $d
} else {
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
} }
pack $d.buttons.cancel -side left -padx 5 -pady 10
pack $d.buttons.connect -side right -padx 5 -pady 10
pack $d.buttons -side bottom -padx 5 -pady 10
}
return
}

View File

@@ -2,28 +2,15 @@
# Set initial control values
set press 127
set outID "stdout"
set commtype "stdout"
# Turn down the reverb
puts $outID "ControlChange 0.0 1 44.0 0.0"
puts "ControlChange 0.0 1 44.0 0.0"
# Configure main window
wm title . "STK Drum Controller"
wm iconname . "drum"
. config -bg black
# Configure "communications" menu
menu .menu -tearoff 0
menu .menu.communication -tearoff 0
.menu add cascade -label "Communication" -menu .menu.communication \
-underline 0
.menu.communication add radio -label "Console" -variable commtype \
-value "stdout" -command { setComm }
.menu.communication add radio -label "Socket" -variable commtype \
-value "socket" -command { setComm }
. configure -menu .menu
# Configure slider
scale .bPressure -from 0 -to 128 -length 100 \
-command {changePress } -variable press\
@@ -87,18 +74,16 @@ pack .exit -side bottom -pady 20
bind . <Destroy> +myExit
proc myExit {} {
global outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc playDrum {value} {
global press
global outID
puts $outID [format "NoteOn 0.0 1 %i %f" $value $press]
flush $outID
puts [format "NoteOn 0.0 1 %i %f" $value $press]
flush stdout
}
proc changePress {value} {
@@ -106,67 +91,32 @@ proc changePress {value} {
set press $value
}
# Socket connection procedure
set d .socketdialog
bind . <Configure> { center_the_toplevel %W }
proc center_the_toplevel { w } {
proc setComm {} {
global outID
global commtype
global d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
switch $i {
0 {set commtype "socket"}
1 {close $outID
set outID "stdout"}
}
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
-command { set commtype "stdout"
set outID "stdout"
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket $sockhost $sockport} outID]
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
if {$err == 0} {
destroy $d
} else {
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
} }
pack $d.buttons.cancel -side left -padx 5 -pady 10
pack $d.buttons.connect -side right -padx 5 -pady 10
pack $d.buttons -side bottom -padx 5 -pady 10
}
}
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

@@ -6,8 +6,6 @@ set cont4 64.0
set cont7 128.0
set cont11 64.0
set cont44 24.0
set outID "stdout"
set commtype "stdout"
set preset 0
# Configure main window
@@ -15,16 +13,6 @@ wm title . "STK Modal Bar Interface"
wm iconname . "modal"
. config -bg black
# Configure "communications" menu
menu .menu -tearoff 0
menu .menu.communication -tearoff 0
.menu add cascade -label "Communication" -menu .menu.communication \
-underline 0
.menu.communication add radio -label "Console" -variable commtype \
-value "stdout" -command { setComm }
.menu.communication add radio -label "Socket" -variable commtype \
-value "socket" -command { setComm }
# Configure preset radio buttons
frame .radio1 -bg black
frame .radio2 -bg black
@@ -88,50 +76,50 @@ frame .left -bg black
frame .right -bg black
scale .left.volume -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 7} \
-orient horizontal -label "Volume" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont7
-command {printWhatz "ControlChange 0.0 1 " 7} \
-orient horizontal -label "Volume" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont7
scale .left.bPressure -from 0 -to 128 -length 200 \
-command {changePress } -variable press \
-orient horizontal -label "Strike Vigor" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePress } -variable press \
-orient horizontal -label "Strike Vigor" \
-tickinterval 32 -showvalue true -bg grey66
scale .left.pitch -from 0 -to 128 -length 200 \
-command {changePitch } -variable pitch \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePitch } -variable pitch \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66
scale .left.cont2 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 2} \
-orient horizontal -label "Stick Hardness" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont2
-command {printWhatz "ControlChange 0.0 1 " 2} \
-orient horizontal -label "Stick Hardness" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont2
scale .right.reverb -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont44
-command {printWhatz "ControlChange 0.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont44
scale .right.cont4 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 4} \
-orient horizontal -label "Stick Position" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
-command {printWhatz "ControlChange 0.0 1 " 4} \
-orient horizontal -label "Stick Position" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
scale .right.cont11 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 11} \
-orient horizontal -label "Disabled" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11 -state disabled
-command {printWhatz "ControlChange 0.0 1 " 11} \
-orient horizontal -label "Disabled" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11 -state disabled
scale .right.cont1 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 1} \
-orient horizontal -label "Direct Stick Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont1
-command {printWhatz "ControlChange 0.0 1 " 1} \
-orient horizontal -label "Direct Stick Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont1
pack .left.volume -padx 10 -pady 10
pack .left.bPressure -padx 10 -pady 10
@@ -146,35 +134,31 @@ pack .left -side left
pack .right -side right
#bind all <KeyPress> {
bind . <KeyPress> {
noteOn $pitch $press
}
bind . <KeyPress> { noteOn $pitch $press }
# Bind an X windows "close" event with the Exit routine
bind . <Destroy> +myExit
proc myExit {} {
global pitch outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
global pitch
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc noteOn {pitchVal pressVal} {
global outID
puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOn 0.0 1 %3.2f %3.2f" $pitchVal $pressVal]
flush stdout
}
proc noteOff {pitchVal pressVal} {
global outID
puts $outID [format "NoteOff 0.0 1 %3.2f %3.2f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOff 0.0 1 %3.2f %3.2f" $pitchVal $pressVal]
flush stdout
}
proc patchChange {value} {
global outID preset
global preset
if {$preset == 1} {
.right.cont11 config -state normal -label "Vibrato Rate"
} else {
@@ -184,84 +168,48 @@ proc patchChange {value} {
}
proc printWhatz {tag value1 value2 } {
global outID
puts $outID [format "%s %2i %3.2f" $tag $value1 $value2]
flush $outID
puts [format "%s %2i %3.2f" $tag $value1 $value2]
flush stdout
}
proc changePress {value} {
global outID
puts $outID [format "AfterTouch 0.0 1 %3.2f" $value]
flush $outID
puts [format "AfterTouch 0.0 1 %3.2f" $value]
flush stdout
}
proc changePitch {value} {
global outID
puts $outID [format "PitchChange 0.0 1 %3.2f" $value]
flush $outID
puts [format "PitchChange 0.0 1 %3.2f" $value]
flush stdout
}
# Socket connection procedure
set d .socketdialog
bind . <Configure> { center_the_toplevel %W }
proc center_the_toplevel { w } {
proc setComm {} {
global outID commtype d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
switch $i {
0 {set commtype "socket"}
1 {close $outID
set outID "stdout"}
}
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
-command { set commtype "stdout"
set outID "stdout"
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket $sockhost $sockport} outID]
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
if {$err == 0} {
destroy $d
} else {
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
} }
pack $d.buttons.cancel -side left -padx 5 -pady 10
pack $d.buttons.connect -side right -padx 5 -pady 10
pack $d.buttons -side bottom -padx 5 -pady 10
}
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

@@ -9,8 +9,6 @@ set cont4 64.0
set cont7 128.0
set cont11 64.0
set cont44 24.0
set outID "stdout"
set commtype "stdout"
set oldpatch 0
set patchnum 0
@@ -19,17 +17,6 @@ wm title . "STK Physical Model Controller"
wm iconname . "physical"
. config -bg black
# Configure "communications" menu
menu .menu -tearoff 0
menu .menu.communication -tearoff 0
.menu add cascade -label "Communication" -menu .menu.communication \
-underline 0
.menu.communication add radio -label "Console" -variable commtype \
-value "stdout" -command { setComm }
.menu.communication add radio -label "Socket" -variable commtype \
-value "socket" -command { setComm }
. configure -menu .menu
# Configure patch change buttons
frame .radios1 -bg black
frame .radios2 -bg black
@@ -68,7 +55,6 @@ pack .radios2.pluk -side left -padx 5 -pady 10
pack .radios2.karp -side left -padx 5 -pady 10
pack .radios2.sitr -side left -padx 5 -pady 10
pack .radios2.mand -side left -padx 5 -pady 10
pack .radios2.blot -side left -padx 5 -pady 10
pack .radios1
pack .radios2
@@ -100,50 +86,50 @@ frame .left -bg black
frame .right -bg black
scale .left.volume -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 7} \
-orient horizontal -label "Volume" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont7
-command {printWhatz "ControlChange 0.0 1 " 7} \
-orient horizontal -label "Volume" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont7
scale .left.bPressure -from 0 -to 128 -length 200 \
-command {changePress } -variable press \
-orient horizontal -label "Breath Pressure" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePress } -variable press \
-orient horizontal -label "Breath Pressure" \
-tickinterval 32 -showvalue true -bg grey66
scale .left.pitch -from 0 -to 128 -length 200 \
-command {changePitch } -variable pitch \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePitch } -variable pitch \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66
scale .left.cont2 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 2} \
-orient horizontal -label "Reed Stiffness" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont2
-command {printWhatz "ControlChange 0.0 1 " 2} \
-orient horizontal -label "Reed Stiffness" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont2
scale .right.reverb -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont44
-command {printWhatz "ControlChange 0.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont44
scale .right.cont4 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 4} \
-orient horizontal -label "Breath Noise" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
-command {printWhatz "ControlChange 0.0 1 " 4} \
-orient horizontal -label "Breath Noise" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
scale .right.cont11 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 11} \
-orient horizontal -label "Vibrato Rate" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11
-command {printWhatz "ControlChange 0.0 1 " 11} \
-orient horizontal -label "Vibrato Rate" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11
scale .right.cont1 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 1} \
-orient horizontal -label "Vibrato Amount" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont1
-command {printWhatz "ControlChange 0.0 1 " 1} \
-orient horizontal -label "Vibrato Amount" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont1
pack .left.volume -padx 10 -pady 10
pack .left.bPressure -padx 10 -pady 10
@@ -157,37 +143,32 @@ pack .right.cont1 -padx 10 -pady 10
pack .left -side left
pack .right -side right
#bind all <KeyPress> {
bind . <KeyPress> {
noteOn $pitch $press
}
bind . <KeyPress> { noteOn $pitch $press }
# Bind an X windows "close" event with the Exit routine
bind . <Destroy> +myExit
proc myExit {} {
global pitch outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
global pitch
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc noteOn {pitchVal pressVal} {
global outID
puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc noteOff {pitchVal pressVal} {
global outID
puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc patchChange {value} {
global outID bitmappath cont1 cont2 cont4 cont11 pitch oldpatch
puts $outID [format "ProgramChange 0.0 1 %i" $value]
global bitmappath cont1 cont2 cont4 cont11 pitch oldpatch
puts [format "ProgramChange 0.0 1 %i" $value]
if {$value==0} { # Clarinet
.pretty config -bitmap @$bitmappath/Klar.xbm
.left.bPressure config -state normal -label "Breath Pressure"
@@ -273,7 +254,7 @@ proc patchChange {value} {
printWhatz "ControlChange 0.0 1 " 2 $cont2
printWhatz "ControlChange 0.0 1 " 4 $cont4
printWhatz "ControlChange 0.0 1 " 11 $cont11
puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press]
puts [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press]
}
if {$value==5} { # Bottle
.pretty config -bitmap @$bitmappath/prcFunny.xbm
@@ -363,87 +344,49 @@ proc patchChange {value} {
}
proc printWhatz {tag value1 value2 } {
global outID
puts $outID [format "%s %i %f" $tag $value1 $value2]
flush $outID
puts [format "%s %i %f" $tag $value1 $value2]
flush stdout
}
proc changePress {value} {
global outID patchnum
global patchnum
if { $patchnum<7 || $patchnum>9 } {
puts $outID [format "AfterTouch 0.0 1 %f" $value]
flush $outID
puts [format "AfterTouch 0.0 1 %f" $value]
flush stdout
}
}
proc changePitch {value} {
global outID
puts $outID [format "PitchChange 0.0 1 %.3f" $value]
flush $outID
puts [format "PitchChange 0.0 1 %.3f" $value]
flush stdout
}
# Socket connection procedure
set d .socketdialog
bind . <Configure> { center_the_toplevel %W }
proc center_the_toplevel { w } {
proc setComm {} {
global outID
global commtype
global d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
switch $i {
0 {set commtype "socket"}
1 {close $outID
set outID "stdout"}
}
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
-command { set commtype "stdout"
set outID "stdout"
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket $sockhost $sockport} outID]
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
if {$err == 0} {
destroy $d
} else {
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
} }
pack $d.buttons.cancel -side left -padx 5 -pady 10
pack $d.buttons.connect -side right -padx 5 -pady 10
pack $d.buttons -side bottom -padx 5 -pady 10
}
}
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

@@ -6,8 +6,6 @@ set cont1 64.0
set cont4 64.0
set cont11 64.0
set cont99 24.0
set outID "stdout"
set commtype "stdout"
set patchnum 0
# Configure main window
@@ -15,48 +13,37 @@ wm title . "STK Shakers Controller"
wm iconname . "shakers"
. config -bg black
# Configure "communications" menu
menu .menu -tearoff 0
menu .menu.communication -tearoff 0
.menu add cascade -label "Communication" -menu .menu.communication \
-underline 0
.menu.communication add radio -label "Console" -variable commtype \
-value "stdout" -command { setComm }
.menu.communication add radio -label "Socket" -variable commtype \
-value "socket" -command { setComm }
. configure -menu .menu
# Configure sliders
frame .right -bg black
scale .right.bPressure -from 0 -to 128 -length 300 \
-command {changePress } -variable press\
-orient horizontal -label "Shake Energy" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePress } -variable press\
-orient horizontal -label "Shake Energy" \
-tickinterval 32 -showvalue true -bg grey66
scale .right.cont2 -from 0 -to 128 -length 300 \
-command {printWhatz "ControlChange -1.0 1 " 11} \
-orient horizontal -label "(<--High) System Damping (Low-->)" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
-command {printWhatz "ControlChange -1.0 1 " 11} \
-orient horizontal -label "(<--High) System Damping (Low-->)" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
scale .right.cont3 -from 0 -to 128 -length 300 \
-command {printWhatz "ControlChange -1.0 1 " 4} \
-orient horizontal -label "Number of Objects" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11
-command {printWhatz "ControlChange -1.0 1 " 4} \
-orient horizontal -label "Number of Objects" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11
scale .right.vibrato -from 0 -to 128 -length 300 \
-command {printWhatz "ControlChange -1.0 1 " 1} \
-orient horizontal -label "Resonance Center Freq." \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont1
-command {printWhatz "ControlChange -1.0 1 " 1} \
-orient horizontal -label "Resonance Center Freq." \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont1
scale .right.reverb -from 0 -to 128 -length 300 \
-command {printWhatz "ControlChange -1.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont99
-command {printWhatz "ControlChange -1.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont99
pack .right.bPressure -padx 10 -pady 10
pack .right.vibrato -padx 10 -pady 10
@@ -73,89 +60,88 @@ frame .buttons.columns.left1 -bg black
frame .buttons.columns.left2 -bg black
radiobutton .buttons.columns.left1.maraca -text Maraca -bg grey66 \
-command { patchChange 0 } -variable patchnum -width 12 \
-command { patchChange 0 } -variable patchnum -width 15 \
-justify left -value 0
radiobutton .buttons.columns.left1.sekere -text Sekere -bg grey66 \
-command { patchChange 2 } -variable patchnum -width 12 \
-justify left -value 2
radiobutton .buttons.columns.left1.cabasa -text Cabasa -bg grey66 \
-command { patchChange 1 } -variable patchnum -width 12 \
-command { patchChange 1 } -variable patchnum -width 15 \
-justify left -value 1
radiobutton .buttons.columns.left1.bamboo -text Bamboo -bg grey66 \
-command { patchChange 5 } -variable patchnum -width 12 \
-justify left -value 5
radiobutton .buttons.columns.left1.waterdrp -text "Water Drops" -bg grey66 \
-command { patchChange 4 } -variable patchnum -width 12 \
-justify left -value 4
radiobutton .buttons.columns.left1.sekere -text Sekere -bg grey66 \
-command { patchChange 2 } -variable patchnum -width 15 \
-justify left -value 2
radiobutton .buttons.columns.left1.tambourn -text Tambourine -bg grey66 \
-command { patchChange 6 } -variable patchnum -width 12 \
-justify left -value 6
radiobutton .buttons.columns.left1.sleighbl -text "Sleigh Bells" -bg grey66 \
-command { patchChange 7 } -variable patchnum -width 12 \
-justify left -value 7
radiobutton .buttons.columns.left1.guiro -text Guiro -bg grey66 \
-command { patchChange 3 } -variable patchnum -width 12 \
-command { patchChange 3 } -variable patchnum -width 15 \
-justify left -value 3
radiobutton .buttons.columns.left1.sleighbl -text "Sleigh Bells" -bg grey66 \
-command { patchChange 4 } -variable patchnum -width 15 \
-justify left -value 4
radiobutton .buttons.columns.left1.bamboo -text Bamboo -bg grey66 \
-command { patchChange 5 } -variable patchnum -width 15 \
-justify left -value 5
radiobutton .buttons.columns.left1.sandpapr -text "Sand Paper" -bg grey66 \
-command { patchChange 6 } -variable patchnum -width 15 \
-justify left -value 6
radiobutton .buttons.columns.left1.cokecan -text "Coke Can" -bg grey66 \
-command { patchChange 7 } -variable patchnum -width 15 \
-justify left -value 7
radiobutton .buttons.columns.left1.stix1 -text Sticks -bg grey66 \
-command { patchChange 8 } -variable patchnum -width 12 \
-command { patchChange 8 } -variable patchnum -width 15 \
-justify left -value 8
radiobutton .buttons.columns.left1.crunch1 -text Crunch -bg grey66 \
-command { patchChange 9 } -variable patchnum -width 12 \
-command { patchChange 9 } -variable patchnum -width 15 \
-justify left -value 9
radiobutton .buttons.columns.left1.wrench -text Wrench -bg grey66 \
-command { patchChange 10 } -variable patchnum -width 12 \
radiobutton .buttons.columns.left1.bigrocks -text "Big Rocks" -bg grey66 \
-command { patchChange 10 } -variable patchnum -width 15 \
-justify left -value 10
radiobutton .buttons.columns.left2.sandpapr -text "Sand Paper" -bg grey66 \
-command { patchChange 11 } -variable patchnum -width 12 \
radiobutton .buttons.columns.left1.littlerocks -text "Little Rocks" -bg grey66 \
-command { patchChange 11 } -variable patchnum -width 15 \
-justify left -value 11
radiobutton .buttons.columns.left2.cokecan -text "Coke Can" -bg grey66 \
-command { patchChange 12 } -variable patchnum -width 12 \
-justify left -value 12
radiobutton .buttons.columns.left2.nextmug -text "NeXT Mug" -bg grey66 \
-command { patchChange 13 } -variable patchnum -width 12 \
-justify left -value 13
-command { patchChange 12 } -variable patchnum -width 15 \
-justify left -value 12
radiobutton .buttons.columns.left2.pennymug -text "Mug & Penny" -bg grey66 \
-command { patchChange 14 } -variable patchnum -width 12 \
-justify left -value 14
-command { patchChange 13 } -variable patchnum -width 15 \
-justify left -value 13
radiobutton .buttons.columns.left2.nicklemug -text "Mug & Nickle" -bg grey66 \
-command { patchChange 15 } -variable patchnum -width 12 \
-justify left -value 15
-command { patchChange 14 } -variable patchnum -width 15 \
-justify left -value 14
radiobutton .buttons.columns.left2.dimemug -text "Mug & Dime" -bg grey66 \
-command { patchChange 16 } -variable patchnum -width 12 \
-justify left -value 16
-command { patchChange 15 } -variable patchnum -width 15 \
-justify left -value 15
radiobutton .buttons.columns.left2.quartermug -text "Mug & Quarter" -bg grey66 \
-command { patchChange 17 } -variable patchnum -width 12 \
-justify left -value 17
-command { patchChange 16 } -variable patchnum -width 15 \
-justify left -value 16
radiobutton .buttons.columns.left2.francmug -text "Mug & Franc" -bg grey66 \
-command { patchChange 18 } -variable patchnum -width 12 \
-justify left -value 18
-command { patchChange 17 } -variable patchnum -width 15 \
-justify left -value 17
radiobutton .buttons.columns.left2.pesomug -text "Mug & Peso" -bg grey66 \
-command { patchChange 19 } -variable patchnum -width 12 \
-command { patchChange 18 } -variable patchnum -width 15 \
-justify left -value 18
radiobutton .buttons.columns.left2.guiro -text Guiro -bg grey66 \
-command { patchChange 19 } -variable patchnum -width 15 \
-justify left -value 19
radiobutton .buttons.columns.left2.bigrocks -text "Big Rocks" -bg grey66 \
-command { patchChange 20 } -variable patchnum -width 12 \
radiobutton .buttons.columns.left2.wrench -text Wrench -bg grey66 \
-command { patchChange 20 } -variable patchnum -width 15 \
-justify left -value 20
radiobutton .buttons.columns.left2.littlerocks -text "Little Rocks" -bg grey66 \
-command { patchChange 21 } -variable patchnum -width 12 \
radiobutton .buttons.columns.left2.waterdrp -text "Water Drops" -bg grey66 \
-command { patchChange 21 } -variable patchnum -width 15 \
-justify left -value 21
radiobutton .buttons.columns.left1.tunedbamboo -text "Tuned Bamboo" -bg grey66 \
-command { patchChange 22 } -variable patchnum -width 12 \
radiobutton .buttons.columns.left2.tunedbamboo -text "Tuned Bamboo" -bg grey66 \
-command { patchChange 22 } -variable patchnum -width 15 \
-justify left -value 22
pack .buttons.columns.left1.maraca -pady 5
pack .buttons.columns.left1.sekere -pady 5
pack .buttons.columns.left1.cabasa -pady 5
pack .buttons.columns.left1.bamboo -pady 5
pack .buttons.columns.left1.tunedbamboo -pady 5
pack .buttons.columns.left1.waterdrp -pady 5
pack .buttons.columns.left1.sekere -pady 5
pack .buttons.columns.left1.tambourn -pady 5
pack .buttons.columns.left1.sleighbl -pady 5
pack .buttons.columns.left1.guiro -pady 5
pack .buttons.columns.left1.bamboo -pady 5
pack .buttons.columns.left1.sandpapr -pady 5
pack .buttons.columns.left1.cokecan -pady 5
pack .buttons.columns.left1.stix1 -pady 5
pack .buttons.columns.left1.crunch1 -pady 5
pack .buttons.columns.left1.wrench -pady 5
pack .buttons.columns.left2.sandpapr -pady 5
pack .buttons.columns.left2.cokecan -pady 5
pack .buttons.columns.left1.bigrocks -pady 5
pack .buttons.columns.left1.littlerocks -pady 5
pack .buttons.columns.left2.nextmug -pady 5
pack .buttons.columns.left2.pennymug -pady 5
pack .buttons.columns.left2.nicklemug -pady 5
@@ -163,8 +149,10 @@ pack .buttons.columns.left2.dimemug -pady 5
pack .buttons.columns.left2.quartermug -pady 5
pack .buttons.columns.left2.francmug -pady 5
pack .buttons.columns.left2.pesomug -pady 5
pack .buttons.columns.left2.bigrocks -pady 5
pack .buttons.columns.left2.littlerocks -pady 5
pack .buttons.columns.left2.guiro -pady 5
pack .buttons.columns.left2.wrench -pady 5
pack .buttons.columns.left2.waterdrp -pady 5
pack .buttons.columns.left2.tunedbamboo -pady 5
pack .buttons.columns.left1 -side left -padx 10
pack .buttons.columns.left2 -side left -padx 10
@@ -184,94 +172,56 @@ bind . <KeyPress> {
bind . <Destroy> +myExit
proc myExit {} {
global outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc patchChange {value} {
global outID press
puts $outID [format "NoteOn -1.0 1 %i $press" $value]
flush $outID
global press
puts [format "NoteOn -1.0 1 %i $press" $value]
flush stdout
}
proc printWhatz {tag value1 value2 } {
global outID
puts $outID [format "%s %i %f" $tag $value1 $value2]
flush $outID
puts [format "%s %i %f" $tag $value1 $value2]
flush stdout
}
proc changePress {value} {
global outID
puts $outID [format "AfterTouch -1.0 1 %f" $value]
flush $outID
puts [format "AfterTouch -1.0 1 %f" $value]
flush stdout
}
eval patchChange $patchnum
# Socket connection procedure
set d .socketdialog
bind . <Configure> { center_the_toplevel %W }
proc center_the_toplevel { w } {
proc setComm {} {
global outID
global commtype
global d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
switch $i {
0 {set commtype "socket"}
1 {close $outID
set outID "stdout"}
}
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
-command { set commtype "stdout"
set outID "stdout"
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket $sockhost $sockport} outID]
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
if {$err == 0} {
destroy $d
} else {
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
} }
pack $d.buttons.cancel -side left -padx 5 -pady 10
pack $d.buttons.connect -side right -padx 5 -pady 10
pack $d.buttons -side bottom -padx 5 -pady 10
}
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

@@ -7,8 +7,6 @@ set cont1 20.0
set cont2 64.0
set cont4 64.0
set cont11 64.0
set outID "stdout"
set commtype "stdout"
set patchnum 17
# Configure main window
@@ -16,17 +14,6 @@ wm title . "STK Voice Model Controller"
wm iconname . "voice"
. config -bg black
# Configure "communications" menu
menu .menu -tearoff 0
menu .menu.communication -tearoff 0
.menu add cascade -label "Communication" -menu .menu.communication \
-underline 0
.menu.communication add radio -label "Console" -variable commtype \
-value "stdout" -command { setComm }
.menu.communication add radio -label "Socket" -variable commtype \
-value "socket" -command { setComm }
. configure -menu .menu
# Configure patch change buttons
frame .instChoice -bg black
@@ -67,38 +54,38 @@ frame .left -bg black
frame .right -bg black
scale .left.bPressure -from 0 -to 128 -length 200 \
-command {changePress } -variable press \
-orient horizontal -label "Loudness (Spectral Tilt)" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePress } -variable press \
-orient horizontal -label "Loudness (Spectral Tilt)" \
-tickinterval 32 -showvalue true -bg grey66
scale .left.pitch -from 0 -to 128 -length 200 \
-command {changePitch } -variable pitch \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66
-command {changePitch } -variable pitch \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66
scale .left.cont1 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange -1.0 1 " 2} \
-orient horizontal -label "Formant Q / Voiced/Un." \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont2
-command {printWhatz "ControlChange -1.0 1 " 2} \
-orient horizontal -label "Formant Q / Voiced/Un." \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont2
scale .right.cont2 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange -1.0 1 " 4} \
-orient horizontal -label "Vowel (Bass, Tenor, Alto, Sop.)" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
-command {printWhatz "ControlChange -1.0 1 " 4} \
-orient horizontal -label "Vowel (Bass, Tenor, Alto, Sop.)" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont4
scale .right.cont3 -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange -1.0 1 " 11} \
-orient horizontal -label "Vibrato Rate" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11
-command {printWhatz "ControlChange -1.0 1 " 11} \
-orient horizontal -label "Vibrato Rate" \
-tickinterval 32 -showvalue true -bg grey66 \
-variable cont11
scale .right.vibrato -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange -1.0 1 " 1} \
-orient horizontal -label "Vibrato Amount" \
-tickinterval 32 -showvalue true -bg grey66\
-variable cont1
-command {printWhatz "ControlChange -1.0 1 " 1} \
-orient horizontal -label "Vibrato Amount" \
-tickinterval 32 -showvalue true -bg grey66\
-variable cont1
pack .left.bPressure -padx 10 -pady 10
pack .left.pitch -padx 10 -pady 10
@@ -114,35 +101,33 @@ pack .right -side right
bind . <Destroy> +myExit
proc myExit {} {
global pitch outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
global pitch
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc noteOn {pitchVal pressVal} {
global outID
puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc noteOff {pitchVal pressVal} {
global outID
puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc patchChange {value} {
global outID bitmappath cont1 cont2 cont4 cont11
puts $outID [format "ProgramChange 0.0 1 %i" $value]
global bitmappath cont1 cont2 cont4 cont11
puts [format "ProgramChange 0.0 1 %i" $value]
if {$value==16} {
.pretty config -bitmap @$bitmappath/KVoiceFM.xbm
}
if {$value==17} {
.pretty config -bitmap @$bitmappath/KVoicForm.xbm
}
flush $outID
flush stdout
set cont1 0.0
set cont2 20.0
set cont4 64.0
@@ -150,84 +135,46 @@ proc patchChange {value} {
}
proc printWhatz {tag value1 value2 } {
global outID
puts $outID [format "%s %i %f" $tag $value1 $value2]
flush $outID
puts [format "%s %i %f" $tag $value1 $value2]
flush stdout
}
proc changePress {value} {
global outID
puts $outID [format "AfterTouch 0.0 1 %f" $value]
flush $outID
puts [format "AfterTouch 0.0 1 %f" $value]
flush stdout
}
proc changePitch {value} {
global outID
puts $outID [format "PitchChange 0.0 1 %.3f" $value]
flush $outID
puts [format "PitchChange 0.0 1 %.3f" $value]
flush stdout
}
# Socket connection procedure
set d .socketdialog
bind . <Configure> { center_the_toplevel %W }
proc center_the_toplevel { w } {
proc setComm {} {
global outID
global commtype
global d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
switch $i {
0 {set commtype "socket"}
1 {close $outID
set outID "stdout"}
}
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
-command { set commtype "stdout"
set outID "stdout"
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket $sockhost $sockport} outID]
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
if {$err == 0} {
destroy $d
} else {
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
} }
pack $d.buttons.cancel -side left -padx 5 -pady 10
pack $d.buttons.connect -side right -padx 5 -pady 10
pack $d.buttons -side bottom -padx 5 -pady 10
}
}
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

@@ -8,9 +8,9 @@ OBJECT_PATH = @object_path@
vpath %.o $(OBJECT_PATH)
OBJECTS = Stk.o Generator.o Envelope.o SineWave.o \
Filter.o Delay.o DelayL.o \
Effect.o Echo.o PitShift.o Chorus.o \
PRCRev.o JCRev.o NRev.o \
Filter.o Delay.o DelayL.o OnePole.o \
Effect.o Echo.o PitShift.o Chorus.o LentPitShift.o \
PRCRev.o JCRev.o NRev.o FreeVerb.o \
FileRead.o WvIn.o FileWvIn.o WaveLoop.o Skini.o Messager.o
INCLUDE = @include@

View File

@@ -1,6 +1,6 @@
The Synthesis ToolKit in C++ (STK)
By Perry R. Cook and Gary P. Scavone, 1995-2011.
By Perry R. Cook and Gary P. Scavone, 1995-2012.
EFFECTS PROJECT:

View File

@@ -6,9 +6,10 @@
#include "PRCRev.h"
#include "JCRev.h"
#include "NRev.h"
#include "FreeVerb.h"
#include "Echo.h"
#include "PitShift.h"
//#include "LentPitShift.h"
#include "LentPitShift.h"
#include "Chorus.h"
#include "Messager.h"
#include "RtAudio.h"
@@ -41,9 +42,10 @@ struct TickData {
PRCRev prcrev;
JCRev jcrev;
NRev nrev;
FreeVerb frev;
Echo echo;
PitShift shifter;
//LentPitShift shifter;
LentPitShift lshifter;
Chorus chorus;
Envelope envelope;
Messager messager;
@@ -101,25 +103,29 @@ void processMessage( TickData* data )
case 22: // effect parameter change 1
data->echo.setDelay( (unsigned long) (temp * Stk::sampleRate() * 0.95) );
// data->shifter.setShift( temp * 3 + 0.25);
data->shifter.setShift( 1.4 * temp + 0.3);
data->lshifter.setShift( 1.4 * temp + 0.3 );
data->shifter.setShift( 1.4 * temp + 0.3 );
data->chorus.setModFrequency( temp );
data->prcrev.setT60( temp * 10.0 );
data->jcrev.setT60( temp * 10.0 );
data->nrev.setT60( temp * 10.0 );
data->frev.setDamping( temp );
break;
case 23: // effect parameter change 2
data->chorus.setModDepth( temp * 0.2 );
data->frev.setRoomSize( temp );
break;
case 44: // effect mix
data->echo.setEffectMix( temp );
data->shifter.setEffectMix( temp );
data->lshifter.setEffectMix( temp );
data->chorus.setEffectMix( temp );
data->prcrev.setEffectMix( temp );
data->jcrev.setEffectMix( temp );
data->nrev.setEffectMix( temp );
data->frev.setEffectMix( temp );
break;
default:
@@ -165,31 +171,37 @@ int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
counter = min( nTicks, data->counter );
data->counter -= counter;
for ( i=0; i<counter; i++ ) {
if ( data->effectId < 2 ) { // Echo and PitShift ... mono output
if ( data->effectId < 3 ) { // Echo, PitShift and LentPitShift ... mono output
if ( data->effectId == 0 )
sample = data->envelope.tick() * data->echo.tick( *iSamples++ );
else
else if ( data->effectId == 1 )
sample = data->envelope.tick() * data->shifter.tick( *iSamples++ );
else
sample = data->envelope.tick() * data->lshifter.tick( *iSamples++ );
*oSamples++ = sample; // two channels interleaved
*oSamples++ = sample;
}
else { // Chorus or a reverb ... stereo output
if ( data->effectId == 2 ) {
if ( data->effectId == 3 ) {
data->chorus.tick( *iSamples++ );
effect = (Effect *) &(data->chorus);
}
else if ( data->effectId == 3 ) {
else if ( data->effectId == 4 ) {
data->prcrev.tick( *iSamples++ );
effect = (Effect *) &(data->prcrev);
}
else if ( data->effectId == 4 ) {
else if ( data->effectId == 5 ) {
data->jcrev.tick( *iSamples++ );
effect = (Effect *) &(data->jcrev);
}
else {
else if ( data->effectId == 6 ) {
data->nrev.tick( *iSamples++ );
effect = (Effect *) &(data->nrev);
}
else {
data->frev.tick( *iSamples++ );
effect = (Effect *) &(data->frev);
}
const StkFrames& samples = effect->lastFrame();
*oSamples++ = data->envelope.tick() * samples[0];
*oSamples++ = data->envelope.lastOut() * samples[1];

View File

@@ -134,6 +134,14 @@ SOURCE=..\..\include\Envelope.h
# End Source File
# Begin Source File
SOURCE=..\..\src\OnePole.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\OnePole.h
# End Source File
# Begin Source File
SOURCE=..\..\src\FileRead.cpp
# End Source File
# Begin Source File
@@ -190,6 +198,14 @@ SOURCE=..\..\include\NRev.h
# End Source File
# Begin Source File
SOURCE=..\..\src\FreeVerb.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\FreeVerb.h
# End Source File
# Begin Source File
SOURCE=..\..\src\PitShift.cpp
# End Source File
# Begin Source File
@@ -198,6 +214,14 @@ SOURCE=..\..\include\PitShift.h
# End Source File
# Begin Source File
SOURCE=..\..\src\LentPitShift.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\LentPitShift.h
# End Source File
# Begin Source File
SOURCE=..\..\src\PRCRev.cpp
# End Source File
# Begin Source File

View File

@@ -80,21 +80,27 @@ radiobutton .effectSelect.echo -text "Echo" -variable effect -relief flat \
-value 0 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
radiobutton .effectSelect.shifter -text "Pitch Shift" -variable effect -relief flat \
-value 1 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
radiobutton .effectSelect.lshifter -text "Lent Pitch Shift" -variable effect -relief flat \
-value 2 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
radiobutton .effectSelect.chorus -text "Chorus" -variable effect -relief flat \
-value 2 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
radiobutton .effectSelect.prcrev -text "PRC Reverb" -variable effect -relief flat \
-value 3 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
radiobutton .effectSelect.jcrev -text "JC Reverb" -variable effect -relief flat \
radiobutton .effectSelect.prcrev -text "PRC Reverb" -variable effect -relief flat \
-value 4 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
radiobutton .effectSelect.nrev -text "NRev Reverb" -variable effect -relief flat \
radiobutton .effectSelect.jcrev -text "JC Reverb" -variable effect -relief flat \
-value 5 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
radiobutton .effectSelect.nrev -text "NRev Reverb" -variable effect -relief flat \
-value 6 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
radiobutton .effectSelect.freerev -text "FreeVerb" -variable effect -relief flat \
-value 7 -command {changeEffect "ControlChange 0.0 1 " 20 $effect}
pack .effectSelect.echo -pady 2 -padx 5 -side top -anchor w -fill x
pack .effectSelect.shifter -pady 2 -padx 5 -side top -anchor w -fill x
pack .effectSelect.lshifter -pady 2 -padx 5 -side top -anchor w -fill x
pack .effectSelect.chorus -pady 2 -padx 5 -side top -anchor w -fill x
pack .effectSelect.prcrev -pady 2 -padx 5 -side top -anchor w -fill x
pack .effectSelect.jcrev -pady 2 -padx 5 -side top -anchor w -fill x
pack .effectSelect.nrev -pady 2 -padx 5 -side top -anchor w -fill x
pack .effectSelect.freerev -pady 2 -padx 5 -side top -anchor w -fill x
proc myExit {} {
@@ -131,18 +137,22 @@ proc changeEffect {tag value1 value2 } {
.left.effect1 config -state normal -label "Echo Delay"
.left.effect2 config -state disabled -label "Disabled"
}
if ($value2==1) {
if {$value2>=1 && $value2<=2} {
.left.effect1 config -state normal -label "Pitch Shift Amount (center = no shift)"
.left.effect2 config -state disabled -label "Disabled"
}
if ($value2==2) {
if ($value2==3) {
.left.effect1 config -state normal -label "Chorus Modulation Frequency"
.left.effect2 config -state normal -label "Chorus Modulation Depth"
}
if {$value2>=3 && $value2<=5} {
if {$value2>=4 && $value2<=6} {
.left.effect1 config -state normal -label "T60 Decay Time ( 0 - 10 seconds)"
.left.effect2 config -state disabled -label "Disabled"
}
if ($value2==7) {
.left.effect1 config -state normal -label "Damping (low to high)"
.left.effect2 config -state normal -label "Room Size (comb feedback gain)"
}
puts $outID [format "%s %i %f" $tag $value1 $value2]
flush $outID
}
@@ -215,5 +225,32 @@ proc setComm {} {
}
}
bind . <Configure> {+ center_the_toplevel %W }
proc center_the_toplevel { w } {
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

View File

@@ -0,0 +1 @@
wish < tcl/EGuitar.tcl | ./eguitar -or -ip

View File

@@ -0,0 +1 @@
wish < tcl/EGuitar.tcl | eguitar -or -ip

View File

@@ -0,0 +1,71 @@
### Do not edit -- Generated by 'configure --with-whatever' from Makefile.in
### STK eguitar Makefile - for various flavors of unix
PROGRAMS =
RM = /bin/rm
SRC_PATH = ../../src
OBJECT_PATH = @object_path@
vpath %.o $(OBJECT_PATH)
OBJECTS = Stk.o Filter.o Fir.o Delay.o DelayL.o DelayA.o OnePole.o \
Effect.o JCRev.o Twang.o \
Guitar.o Noise.o Cubic.o \
FileRead.o WvIn.o FileWvIn.o FileWrite.o FileWvOut.o \
Skini.o Messager.o utilities.o
INCLUDE = @include@
ifeq ($(strip $(INCLUDE)), )
INCLUDE = ../../include
endif
vpath %.h $(INCLUDE)
CC = @CXX@
DEFS = @CPPFLAGS@
DEFS += @byte_order@
CFLAGS = @CXXFLAGS@
CFLAGS += -I$(INCLUDE) -I$(INCLUDE)/../src/include
LIBRARY = @LIBS@
REALTIME = @realtime@
ifeq ($(REALTIME),yes)
PROGRAMS += eguitar
OBJECTS += RtMidi.o RtAudio.o Thread.o Mutex.o Socket.o TcpServer.o @objects@
endif
RAWWAVES = @rawwaves@
ifeq ($(strip $(RAWWAVES)), )
RAWWAVES = ../../rawwaves/
endif
DEFS += -DRAWWAVE_PATH=\"$(RAWWAVES)\"
%.o : $(SRC_PATH)/%.cpp
$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@
%.o : ../../src/include/%.cpp
$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@
all : $(PROGRAMS)
eguitar: eguitar.cpp $(OBJECTS)
$(CC) $(LDFLAGS) $(CFLAGS) $(DEFS) -o eguitar eguitar.cpp $(OBJECT_PATH)/*.o $(LIBRARY)
libeguitar: eguitar.cpp
$(CC) $(LDFLAGS) $(CFLAGS) $(DEFS) -o eguitar utilities.cpp eguitar.cpp -L../../src -lstk $(LIBRARY)
$(OBJECTS) : Stk.h
clean :
$(RM) -f $(OBJECT_PATH)/*.o
$(RM) -f $(PROGRAMS) *.exe
$(RM) -fR *~ *.dSYM
distclean: clean
$(RM) Makefile
strip :
strip $(PROGRAMS)
# Project specific objects:
utilities.o: utilities.cpp
$(CC) $(CFLAGS) $(DEFS) -c utilities.cpp -o $(OBJECT_PATH)/$@

View File

@@ -0,0 +1,44 @@
This is eguitar by Gary Scavone, McGill University, 2012.
This is a program to create a simple electric guitar model using
the STK Guitar class. The is model is derived in part from an
implementation made by Nicholas Donaldson at McGill University in
2009. The distortion model is poor, using a simple soft-clipping
expression provided by Charles R. Sullivan in "Extending the
Karplus-String Algorithm to Synthesize Electric Guitar Timbres with
Distortion and Feedback," Computer Music Journal, Vol.14 No.3, Fall
1990. Other distortion models would be better, such as that found
in Pakarinen and Yeh's "A Review of Digital Techniques for Modeling
Vacuum-Tube Guitar Amplifiers," Computer Music Journal, Vol 33
No. 2, Summer 2009.
This program performs simple voice management if all noteOn and
noteOff events are on channel 0. Otherwise, channel values > 0 are
mapped to specific string numbers. By default, the program creates
a 6-string guitar. If the normalized noteOn() velocity is < 0.2, a
string is undamped but not plucked (this is implemented in the
stk::Guitar class). Thus, you can lightly depress a key on a MIDI
keyboard and then experiment with string coupling.
The Tcl/Tk GUI allows you to experiment with various parameter
settings and that can be used in conjunction with a MIDI keyboard
as: wish < tcl/EGuitar.tcl | ./eguitar -or -ip -im 1
For the moment, this program does not support pitch bends.
In the eguitar directory, type:
> make
to compile and then
> ElectricGuitar.bat
to run the program with the Tcl/Tk GUI.
There are many improvements that could be made to this project. In
particular, you could record real body responses from different
guitars and use those with the Guitar class. As well, you could
improve the distortion model and perhaps add some typical electric
guitar effects, such as an echo. If you find any bugs, please let me
know!

View File

View File

@@ -0,0 +1,381 @@
// Eguitar.cpp
//
// This is a program to create a simple electric guitar model using
// the STK Guitar class. The is model is derived in part from an
// implementation made by Nicholas Donaldson at McGill University in
// 2009. The distortion model is poor, using a simple soft-clipping
// expression provided by Charles R. Sullivan in "Extending the
// Karplus-String Algorithm to Synthesize Electric Guitar Timbres with
// Distortion and Feedback," Computer Music Journal, Vol.14 No.3, Fall
// 1990. Other distortion models would be better, such as that found
// in Pakarinen and Yeh's "A Review of Digital Techniques for Modeling
// Vacuum-Tube Guitar Amplifiers," Computer Music Journal, Vol 33
// No. 2, Summer 2009.
//
// This program performs simple voice management if all noteOn and
// noteOff events are on channel 0. Otherwise, channel values > 0 are
// mapped to specific string numbers. By default, the program creates
// a 6-string guitar. If the normalized noteOn() velocity is < 0.2, a
// string is undamped but not plucked (this is implemented in the
// stk::Guitar class). Thus, you can lightly depress a key on a MIDI
// keyboard and then experiment with string coupling.
//
// The Tcl/Tk GUI allows you to experiment with various parameter
// settings and that can be used in conjunction with a MIDI keyboard
// as: wish < tcl/EGuitar.tcl | ./eguitar -or -ip -im 1
//
// For the moment, this program does not support pitch bends.
//
// Gary P. Scavone, McGill University 2012.
#include "Guitar.h"
#include "SKINI.msg"
#include "WvOut.h"
#include "JCRev.h"
#include "Skini.h"
#include "RtAudio.h"
#include "Delay.h"
#include "Cubic.h"
// Miscellaneous command-line parsing and instrument allocation
// functions are defined in utilites.cpp ... specific to this program.
#include "utilities.h"
#include <signal.h>
#include <iostream>
#include <algorithm>
#include <cmath>
using std::min;
bool done;
static void finish(int ignore){ done = true; }
using namespace stk;
const unsigned int nStrings = 6;
// Data structure for string information.
struct StringInfo{
bool inUse; // is this string being used?
unsigned int iNote; // note number associated with this string
StringInfo() : inUse(false), iNote(0) {};
};
// The TickData structure holds all the class instances and data that
// are shared by the various processing functions.
struct TickData {
WvOut **wvout;
Guitar *guitar;
StringInfo voices[nStrings];
JCRev reverb;
Messager messager;
Skini::Message message;
StkFloat volume;
StkFloat t60;
unsigned int nWvOuts;
int channels;
int counter;
bool realtime;
bool settling;
bool haveMessage;
int keysDown;
StkFloat feedbackGain;
StkFloat oldFeedbackGain;
StkFloat distortionGain;
StkFloat distortionMix;
Delay feedbackDelay;
Cubic distortion;
StkFloat feedbackSample;
// Default constructor.
TickData()
: wvout(0), volume(1.0), t60(0.75),
nWvOuts(0), channels(2), counter(0),
realtime( false ), settling( false ), haveMessage( false ),
keysDown(0), feedbackSample( 0.0 ) {}
};
#define DELTA_CONTROL_TICKS 30 // default sample frames between control input checks
// The processMessage() function encapsulates the handling of control
// messages. It can be easily relocated within a program structure
// depending on the desired scheduling scheme.
void processMessage( TickData* data )
{
register StkFloat value1 = data->message.floatValues[0];
register StkFloat value2 = data->message.floatValues[1];
unsigned int channel = (unsigned int) data->message.channel;
switch( data->message.type ) {
case __SK_Exit_:
if ( data->settling == false ) goto settle;
done = true;
return;
case __SK_NoteOn_:
if ( value2 > 0.0 ) { // velocity > 0
unsigned int iNote = data->message.intValues[0];
if ( channel == 0 ) { // do basic voice management
unsigned int s;
if ( data->keysDown >= (int) nStrings ) break; // ignore extra note on's
// Find first unused string
for ( s=0; s<nStrings; s++ )
if ( !data->voices[s].inUse ) break;
if ( s == nStrings ) break;
data->voices[s].inUse = true;
data->voices[s].iNote = iNote;
data->guitar->noteOn( Midi2Pitch[iNote], value2 * ONE_OVER_128, s );
data->keysDown++;
// If first key down, turn on feedback gain
if ( data->keysDown == 1 )
data->feedbackGain = data->oldFeedbackGain;
}
else if ( channel <= nStrings )
data->guitar->noteOn( Midi2Pitch[iNote], value2 * ONE_OVER_128, channel-1 );
break;
}
// else a note off, so continue to next case
case __SK_NoteOff_:
if ( channel == 0 ) { // do basic voice management
if ( !data->keysDown ) break;
// Search for the released note
unsigned int s, iNote;
iNote = data->message.intValues[0];
for ( s=0; s<nStrings; s++ )
if ( data->voices[s].inUse && iNote == data->voices[s].iNote )
break;
if ( s == nStrings ) break;
data->voices[s].inUse = false;
data->guitar->noteOff( value2 * ONE_OVER_128, s );
data->keysDown--;
if ( data->keysDown == 0 ) { // turn off feedback gain and clear delay
data->feedbackDelay.clear();
data->feedbackGain = 0.0;
}
}
else if ( channel <= nStrings )
data->guitar->noteOff( value2 * ONE_OVER_128, channel-1 );
break;
case __SK_ControlChange_:
if ( value1 == 44.0 )
data->reverb.setEffectMix( value2 * ONE_OVER_128 );
else if ( value1 == 7.0 )
data->volume = value2 * ONE_OVER_128;
else if ( value1 == 27 ) // feedback delay
data->feedbackDelay.setDelay( (value2 * Stk::sampleRate() / 127) + 1 );
else if ( value1 == 28 ) { // feedback gain
//data->oldFeedbackGain = value2 * 0.01 / 127.0;
data->oldFeedbackGain = value2 * 0.02 / 127.0;
data->feedbackGain = data->oldFeedbackGain;
}
else if ( value1 == 71 ) // pre-distortion gain
data->distortionGain = 2.0 * value2 * ONE_OVER_128;
else if ( value1 == 72 ) // distortion mix
data->distortionMix = value2 * ONE_OVER_128;
else
data->guitar->controlChange( (int) value1, value2 );
break;
case __SK_AfterTouch_:
data->guitar->controlChange( 128, value1 );
break;
case __SK_PitchBend_:
// Implement me!
break;
case __SK_Volume_:
data->volume = value1 * ONE_OVER_128;
break;
} // end of switch
data->haveMessage = false;
return;
settle:
// Exit and program change messages are preceeded with a short settling period.
for ( unsigned int s=0; s<nStrings; s++ )
if ( data->voices[s].inUse ) data->guitar->noteOff( 0.6, s );
data->counter = (int) (0.3 * data->t60 * Stk::sampleRate());
data->settling = true;
}
// The tick() function handles sample computation and scheduling of
// control updates. If doing realtime audio output, it will be called
// automatically when the system needs a new buffer of audio samples.
int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
double streamTime, RtAudioStreamStatus status, void *dataPointer )
{
TickData *data = (TickData *) dataPointer;
register StkFloat temp, sample, *samples = (StkFloat *) outputBuffer;
int counter, nTicks = (int) nBufferFrames;
while ( nTicks > 0 && !done ) {
if ( !data->haveMessage ) {
data->messager.popMessage( data->message );
if ( data->message.type > 0 ) {
data->counter = (long) (data->message.time * Stk::sampleRate());
data->haveMessage = true;
}
else
data->counter = DELTA_CONTROL_TICKS;
}
counter = min( nTicks, data->counter );
data->counter -= counter;
for ( int i=0; i<counter; i++ ) {
// Put the previous distorted sample thru feedback
sample = data->feedbackDelay.tick( data->feedbackSample * data->feedbackGain );
sample = data->guitar->tick( sample );
// Apply distortion (x - x^3/3) and mix
temp = data->distortionGain * sample;
if ( temp > 0.6666667 ) temp = 0.6666667;
else if ( temp < -0.6666667 ) temp = -0.6666667;
else temp = data->distortion.tick( temp );
sample = (data->distortionMix * temp) + ((1 - data->distortionMix) * sample );
data->feedbackSample = sample;
// Tick instrument and apply reverb
sample = data->volume * data->reverb.tick( sample );
for ( unsigned int j=0; j<data->nWvOuts; j++ ) data->wvout[j]->tick( sample );
if ( data->realtime )
for ( int k=0; k<data->channels; k++ ) *samples++ = sample;
nTicks--;
}
if ( nTicks == 0 ) break;
// Process control messages.
if ( data->haveMessage ) processMessage( data );
}
return 0;
}
int main( int argc, char *argv[] )
{
TickData data;
int i;
#if defined(__STK_REALTIME__)
RtAudio dac;
#endif
// If you want to change the default sample rate (set in Stk.h), do
// it before instantiating any objects! If the sample rate is
// specified in the command line, it will override this setting.
Stk::setSampleRate( 44100.0 );
// By default, warning messages are not printed. If we want to see
// them, we need to specify that here.
Stk::showWarnings( true );
// Check the command-line arguments for errors and to determine
// the number of WvOut objects to be instantiated (in utilities.cpp).
data.nWvOuts = checkArgs( argc, argv );
data.wvout = (WvOut **) calloc( data.nWvOuts, sizeof(WvOut *) );
// Parse the command-line flags, instantiate WvOut objects, and
// instantiate the input message controller (in utilities.cpp).
try {
data.realtime = parseArgs( argc, argv, data.wvout, data.messager );
}
catch (StkError &) {
goto cleanup;
}
// If realtime output, allocate the dac here.
#if defined(__STK_REALTIME__)
if ( data.realtime ) {
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
RtAudio::StreamParameters parameters;
parameters.deviceId = dac.getDefaultOutputDevice();
parameters.nChannels = data.channels;
unsigned int bufferFrames = RT_BUFFER_SIZE;
try {
dac.openStream( &parameters, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void *)&data );
}
catch ( RtError& error ) {
error.printMessage();
goto cleanup;
}
}
#endif
// Set the reverb parameters.
data.reverb.setT60( data.t60 );
data.reverb.setEffectMix( 0.2 );
// Allocate guitar
data.guitar = new Guitar( nStrings );
// Configure distortion and feedback.
data.distortion.setThreshold( 2.0 / 3.0 );
data.distortion.setA1( 1.0 );
data.distortion.setA2( 0.0 );
data.distortion.setA3( -1.0 / 3.0 );
data.distortionMix = 0.9;
data.distortionGain = 1.0;
data.feedbackDelay.setMaximumDelay( (unsigned long int)( 1.1 * Stk::sampleRate() ) );
data.feedbackDelay.setDelay( 20000 );
data.feedbackGain = 0.001;
data.oldFeedbackGain = 0.001;
// Install an interrupt handler function.
(void) signal(SIGINT, finish);
// If realtime output, set our callback function and start the dac.
#if defined(__STK_REALTIME__)
if ( data.realtime ) {
try {
dac.startStream();
}
catch ( RtError &error ) {
error.printMessage();
goto cleanup;
}
}
#endif
// Setup finished.
while ( !done ) {
#if defined(__STK_REALTIME__)
if ( data.realtime )
// Periodically check "done" status.
Stk::sleep( 200 );
else
#endif
// Call the "tick" function to process data.
tick( NULL, NULL, 256, 0, 0, (void *)&data );
}
// Shut down the output stream.
#if defined(__STK_REALTIME__)
if ( data.realtime ) {
try {
dac.closeStream();
}
catch ( RtError& error ) {
error.printMessage();
}
}
#endif
cleanup:
for ( i=0; i<(int)data.nWvOuts; i++ ) delete data.wvout[i];
free( data.wvout );
delete data.guitar;
std::cout << "\nStk eguitar finished ... goodbye.\n\n";
return 0;
}

View File

@@ -0,0 +1,298 @@
# Microsoft Developer Studio Project File - Name="eguitar" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=eguitar - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ragamat.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ragamat.mak" CFG="eguitar - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "eguitar - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "eguitar - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "eguitar - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ""
# PROP Intermediate_Dir "release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib dsound.lib winmm.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "eguitar - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ""
# PROP Intermediate_Dir "debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib dsound.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "eguitar - Win32 Release"
# Name "eguitar - Win32 Debug"
# Begin Source File
SOURCE=..\..\src\Fir.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Fir.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Delay.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Delay.h
# End Source File
# Begin Source File
SOURCE=..\..\src\DelayA.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\DelayA.h
# End Source File
# Begin Source File
SOURCE=..\..\src\DelayL.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\DelayL.h
# End Source File
# Begin Source File
SOURCE=..\..\include\Effect.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Twang.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Twang.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Guitar.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Guitar.h
# End Source File
# Begin Source File
SOURCE=..\..\src\FileRead.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\FileRead.h
# End Source File
# Begin Source File
SOURCE=..\..\src\FileWrite.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\FileWrite.h
# End Source File
# Begin Source File
SOURCE=..\..\src\FileWvOut.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\FileWvOut.h
# End Source File
# Begin Source File
SOURCE=..\..\src\FileWvIn.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\FileWvIn.h
# End Source File
# Begin Source File
SOURCE=..\..\include\Filter.h
# End Source File
# Begin Source File
SOURCE=..\..\include\Generator.h
# End Source File
# Begin Source File
SOURCE=..\..\src\JCRev.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\JCRev.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Messager.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Messager.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Mutex.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Mutex.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Noise.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Noise.h
# End Source File
# Begin Source File
SOURCE=..\..\include\Cubic.h
# End Source File
# Begin Source File
SOURCE=..\..\src\OnePole.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\OnePole.h
# End Source File
# Begin Source File
SOURCE=.\eguitar.cpp
# End Source File
# Begin Source File
SOURCE=.\utilities.cpp
# End Source File
# Begin Source File
SOURCE=.\utilities.h
# End Source File
# Begin Source File
SOURCE=..\..\src\RtAudio.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\RtAudio.h
# End Source File
# Begin Source File
SOURCE=..\..\src\RtMidi.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\RtMidi.h
# End Source File
# Begin Source File
SOURCE=..\..\src\SKINI.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\SKINI.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Socket.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Socket.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Stk.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Stk.h
# End Source File
# Begin Source File
SOURCE=..\..\src\TcpServer.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\TcpServer.h
# End Source File
# Begin Source File
SOURCE=..\..\src\Thread.cpp
# End Source File
# Begin Source File
SOURCE=..\..\include\Thread.h
# End Source File
# Begin Source File
SOURCE=..\..\include\WvIn.h
# End Source File
# Begin Source File
SOURCE=..\..\include\WvOut.h
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "eguitar"=.\eguitar.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,27 @@
/* Howdy!! SKINI File, Perry Cook */
NoteOn 0.1 0 40 100.000000
NoteOn 0.01 0 44 100.000000
NoteOn 0.01 0 47 100.000000
NoteOn 0.01 0 52 100.000000
NoteOff 1.0 0 40 64.000000
NoteOff 0.0 0 44 64.000000
NoteOff 0.0 0 47 64.000000
NoteOff 0.0 0 52 64.000000
NoteOn 0.3 0 39 100.000000
NoteOn 0.01 0 42 100.000000
NoteOn 0.01 0 47 100.000000
NoteOn 0.01 0 51 100.000000
NoteOff 1.0 0 39 64.000000
NoteOff 0.0 0 42 64.000000
NoteOff 0.0 0 47 64.000000
NoteOff 0.0 0 51 64.000000
NoteOn 0.3 0 40 100.000000
NoteOn 0.01 0 44 100.000000
NoteOn 0.01 0 47 100.000000
NoteOn 0.01 0 52 100.000000
NoteOff 2.0 0 40 64.000000
NoteOff 0.0 0 44 64.000000
NoteOff 0.0 0 47 64.000000
NoteOff 0.0 0 52 64.000000

View File

@@ -0,0 +1,264 @@
# Tcl/Tk Electric Guitar Model GUI for the Synthesis Toolkit (STK)
# by Gary P. Scavone, McGill University, 2012.
# Set lowest string note numbers and range
set stringRange 20
array set stringMin {
1 40
2 45
3 50
4 55
5 59
6 64
}
array set stringNote {
1 40
2 45
3 50
4 55
5 59
6 64
}
#array set stringAmp { 1 64 2 64 3 64 4 64 5 64 6 64 }
array set stringAmp {
1 64
2 64
3 64
4 64
5 64
6 64
}
# Set initial control values
set cont2 20.0
set cont7 100.0
set cont27 64.0
set cont28 0.0
set cont44 24.0
set cont72 64.0
set cont128 64.0
set velocity 64.0
# Configure main window
wm title . "STK Electric Guitar Model Controller"
wm iconname . "guitar"
. config -bg white
# Configure message box
label .message -font {Times 14 normal} -background white \
-foreground darkred -relief raised \
-wraplength 300 -width 60 \
-text "Use the spacebar or button to strum all the strings. Use the pulldown menu next to the velocity slider to control the velocity for individual strings."
pack .message -padx 5 -pady 10
# Configure "note on" buttons
frame .top
button .top.on -text Strum -bg grey66 -command strum
button .top.off -text "All Off" -bg grey66 -command allOff
button .top.exit -text "Quit" -bg grey66 -command quit
pack .top.on -side left -padx 5
pack .top.off -side left -padx 5 -pady 10
pack .top.exit -side left -padx 5 -pady 10
pack .top
frame .left -borderwidth 5 -relief groove -bg grey88
scale .left.volume -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 7} \
-orient horizontal -label "Volume" \
-tickinterval 32 -showvalue true \
-variable cont7
scale .left.reverb -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 44} \
-orient horizontal -label "Reverb Mix" \
-tickinterval 32 -showvalue true \
-variable cont44
scale .left.bridge -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 2} \
-orient horizontal -label "Bridge Coupling Gain" \
-tickinterval 32 -showvalue true -variable cont2
scale .left.fbGain -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 28} \
-orient horizontal -label "Feedback Gain" \
-tickinterval 32 -showvalue true -variable cont28
scale .left.fbDelay -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 27} \
-orient horizontal -label "Feedback Delay" \
-tickinterval 32 -showvalue true -variable cont27
scale .left.dmix -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 72} \
-orient horizontal -label "Distortion Mix" \
-tickinterval 32 -showvalue true -variable cont72
scale .left.pick -from 0 -to 128 -length 200 \
-command {printWhatz "ControlChange 0.0 1 " 128} \
-orient horizontal -label "Pick Hardness" \
-tickinterval 32 -showvalue true -variable cont128
pack .left.volume -padx 10 -pady 5
pack .left.reverb -padx 10 -pady 5
pack .left.bridge -padx 10 -pady 5
pack .left.fbGain -padx 10 -pady 5
pack .left.fbDelay -padx 10 -pady 5
pack .left.dmix -padx 10 -pady 5
pack .left.pick -padx 10 -pady 10
pack .left -side left
proc quit {} {
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc strum {} {
global stringNote stringAmp
for {set n 1} {$n < 7} {incr n} {
puts [format "NoteOn %2.3f %d %3.2f %3.2f" [expr rand()*0.04] $n $stringNote($n) $stringAmp($n)]
}
flush stdout
}
proc allOff {} {
global stringNote stringAmp
for {set n 1} {$n < 7} {incr n} {
puts [format "NoteOff 0.0 %d %3f %3f" $n $stringNote($n) $stringAmp($n)]
}
flush stdout
}
# Set bindings
bind . <KeyPress> { strum }
bind . <Destroy> +quit
proc printWhatz {tag value1 value2 } {
puts [format "%s %2i %3.2f" $tag $value1 $value2]
flush stdout
}
proc pluckOne {value} {
global stringNote stringAmp
puts [format "NoteOn 0.0 %d %3f %3f" $value $stringNote($value) $stringAmp($value)]
flush stdout
}
proc setNote {string value} {
global stringNote
set stringNote($string) $value
}
proc setStringAmp {value} {
global stringAmp cbpath
set n [$cbpath current]
if { $n > 0 } {
set stringAmp($n) $value
} else {
for {set i 1} {$i < 7} {incr i} {
set stringAmp($i) $value
}
}
}
frame .strings -bg grey88 -borderwidth 5 -relief groove
scale .strings.s1 -from $stringMin(1) -to [expr $stringMin(1)+$stringRange] \
-length 350 -orient horizontal -label "String 1: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(1) \
-command {setNote 1}
scale .strings.s2 -from $stringMin(2) -to [expr $stringMin(2)+$stringRange] \
-length 350 -orient horizontal -label "String 2: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(2) \
-command {setNote 2}
scale .strings.s3 -from $stringMin(3) -to [expr $stringMin(3)+$stringRange] \
-length 350 -orient horizontal -label "String 3: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(3) \
-command {setNote 3}
scale .strings.s4 -from $stringMin(4) -to [expr $stringMin(4)+$stringRange] \
-length 350 -orient horizontal -label "String 4: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(4) \
-command {setNote 4}
scale .strings.s5 -from $stringMin(5) -to [expr $stringMin(5)+$stringRange] \
-length 350 -orient horizontal -label "String 5: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(5) \
-command {setNote 5}
scale .strings.s6 -from $stringMin(6) -to [expr $stringMin(6)+$stringRange] \
-length 350 -orient horizontal -label "String 6: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(6) \
-command {setNote 6}
button .strings.b1 -text Pluck -command { pluckOne 1 }
button .strings.b2 -text Pluck -command { pluckOne 2 }
button .strings.b3 -text Pluck -command { pluckOne 3 }
button .strings.b4 -text Pluck -command { pluckOne 4 }
button .strings.b5 -text Pluck -command { pluckOne 5 }
button .strings.b6 -text Pluck -command { pluckOne 6 }
grid .strings -column 0 -row 0
grid .strings.b1 -column 1 -row 0 -padx 5 -pady 5
grid .strings.b2 -column 1 -row 1
grid .strings.b3 -column 1 -row 2
grid .strings.b4 -column 1 -row 3
grid .strings.b5 -column 1 -row 4
grid .strings.b6 -column 1 -row 5
grid .strings.s1 -column 0 -row 0 -padx 5 -pady 5
grid .strings.s2 -column 0 -row 1 -padx 5 -pady 5
grid .strings.s3 -column 0 -row 2 -padx 5 -pady 5
grid .strings.s4 -column 0 -row 3 -padx 5 -pady 5
grid .strings.s5 -column 0 -row 4 -padx 5 -pady 5
grid .strings.s6 -column 0 -row 5 -padx 5 -pady 5
set stringSelect "All"
ttk::combobox .strings.combo \
-values [ list "All" "String 1" "String 2" "String 3" "String 4" "String 5" "String 6" ] \
-width 8 -textvariable stringSelect -justify center
scale .strings.velocity -from 0 -to 128 -length 350 \
-orient horizontal -label "Note Velocity" \
-tickinterval 32 -showvalue true -command setStringAmp -variable velocity
grid .strings.combo -column 1 -row 7
grid .strings.velocity -column 0 -row 7 -padx 5 -pady 10
pack .strings
set cbpath .strings.combo
bind . <Configure> { center_the_toplevel %W }
proc center_the_toplevel { w } {
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

@@ -0,0 +1,207 @@
// Miscellaneous parsing and error functions for use with STK projects.
//
// Gary P. Scavone, 1999.
#include "utilities.h"
#include <cstring>
#include <stdlib.h>
#if defined(__STK_REALTIME__)
#include "RtAudio.h"
#endif
using namespace stk;
void usage(char *function) {
// Error function in case of incorrect command-line argument specifications
printf("\nusage: %s flag(s)\n", function);
printf(" where flag(s) = \n");
printf(" -s RATE to specify a sample rate,\n");
printf(" -ow <file name> for .wav audio output file,\n");
printf(" -os <file name> for .snd audio output file,\n");
printf(" -om <file name> for .mat audio output file,\n");
printf(" -oa <file name> for .aif audio output file,\n");
printf(" -if <file name> to read control input from SKINI file,\n");
#if defined(__STK_REALTIME__)
printf(" -or for realtime audio output,\n");
printf(" -ip for realtime control input by pipe,\n");
printf(" -im <port> for realtime control input by MIDI (virtual port = 0, default = 1).");
#endif
printf("\n");
printf("\n Simultaneous multiple output types are supported.\n");
printf(" Likewise, simultaneous control input types are supported.\n");
printf(" SKINI formatted scorefiles can be piped or redirected\n");
printf(" to %s, though realtime control flags should be omitted\n", function);
printf(" when doing so. If the optional <file names> are not\n");
printf(" specified, default names will be indicated. Each flag\n");
printf(" must include its own '-' sign.\n\n");
exit(0);
}
int checkArgs(int nArgs, char *args[])
{
int w, i = 1, j = 0;
int nWvOuts = 0;
char flags[2][50] = {""};
bool realtime = false;
if (nArgs < 3 || nArgs > 22) usage(args[0]);
while (i < nArgs) {
if (args[i][0] == '-') {
if (args[i][1] == 'o') {
if ( args[i][2] == 'r' ) realtime = true;
if ( (args[i][2] == 's') || (args[i][2] == 'w') ||
(args[i][2] == 'm') || (args[i][2] == 'a') )
nWvOuts++;
flags[0][j] = 'o';
flags[1][j++] = args[i][2];
}
else if (args[i][1] == 'i') {
if ( (args[i][2] != 'p') &&
(args[i][2] != 'm') && (args[i][2] != 'f') ) usage(args[0]);
flags[0][j] = 'i';
flags[1][j++] = args[i][2];
}
else if (args[i][1] == 's' && (i+1 < nArgs) && args[i+1][0] != '-' ) {
Stk::setSampleRate( atoi(args[i+1]) );
flags[0][j++] = 's';
}
else usage(args[0]);
}
i++;
}
// Check for multiple flags of the same type
for ( i=0; i<=j; i++ ) {
w = i+1;
while (w <= j ) {
if ( flags[0][i] == flags[0][w] && flags[1][i] == flags[1][w] ) {
printf("\nError: Multiple command line flags of the same type specified.\n\n");
usage(args[0]);
}
w++;
}
}
// Make sure we have at least one output type
if ( nWvOuts < 1 && !realtime ) usage(args[0]);
return nWvOuts;
}
bool parseArgs(int nArgs, char *args[], WvOut **output, Messager& messager)
{
int i = 1, j = 0, nWvIns = 0;
bool realtime = false;
char fileName[256];
while (i < nArgs) {
if ( (args[i][0] == '-') && (args[i][1] == 'i') ) {
switch(args[i][2]) {
case 'f':
strcpy(fileName,args[++i]);
if ( !messager.setScoreFile( fileName ) ) exit(0);
nWvIns++;
break;
case 'p':
#if defined(__STK_REALTIME__)
if ( !messager.startStdInput() ) exit(0);
nWvIns++;
break;
#else
usage(args[0]);
#endif
case 'm':
#if defined(__STK_REALTIME__)
// Check for an optional MIDI port argument.
if ((i+1 < nArgs) && args[i+1][0] != '-') {
int port = atoi(args[++i]);
if ( !messager.startMidiInput( port-1 ) ) exit(0);
}
else if ( !messager.startMidiInput() ) exit(0);
nWvIns++;
break;
#else
usage(args[0]);
#endif
default:
usage(args[0]);
break;
}
}
else if ( (args[i][0] == '-') && (args[i][1] == 'o') ) {
switch(args[i][2]) {
case 'r':
#if defined(__STK_REALTIME__)
realtime = true;
break;
#else
usage(args[0]);
#endif
case 'w':
if ((i+1 < nArgs) && args[i+1][0] != '-') {
i++;
strcpy(fileName,args[i]);
}
else strcpy(fileName,"testwav");
output[j] = new FileWvOut(fileName, 1, FileWrite::FILE_WAV );
j++;
break;
case 's':
if ((i+1 < nArgs) && args[i+1][0] != '-') {
i++;
strcpy(fileName,args[i]);
}
else strcpy(fileName,"testsnd");
output[j] = new FileWvOut(fileName,1, FileWrite::FILE_SND);
j++;
break;
case 'm':
if ((i+1 < nArgs) && args[i+1][0] != '-') {
i++;
strcpy(fileName,args[i]);
}
else strcpy(fileName,"testmat");
output[j] = new FileWvOut(fileName,1, FileWrite::FILE_MAT);
j++;
break;
case 'a':
if ((i+1 < nArgs) && args[i+1][0] != '-') {
i++;
strcpy(fileName,args[i]);
}
else strcpy(fileName,"testaif");
output[j] = new FileWvOut(fileName,1, FileWrite::FILE_AIF );
j++;
break;
default:
usage(args[0]);
break;
}
}
i++;
}
if ( nWvIns == 0 ) {
#if defined(__STK_REALTIME__)
if ( !messager.startStdInput() ) exit(0);
#else
printf("\nError: The -if file input flag must be specified for non-realtime use.\n\n");
usage(args[0]);
#endif
}
return realtime;
}

View File

@@ -0,0 +1,12 @@
// Miscellaneous parsing and error functions for use with STK projects.
//
// Gary P. Scavone, 1999.
#include "FileWvOut.h"
#include "Messager.h"
void usage(char *function);
int checkArgs(int numArgs, char *args[]);
bool parseArgs(int numArgs, char *args[], stk::WvOut **output, stk::Messager& messager);

View File

@@ -3,7 +3,6 @@
# Set initial control values
set pitch 64.0
set press 64.0
set outID "stdout"
# Configure main window
wm title . "A Simple GUI"
@@ -33,22 +32,50 @@ bind . <Destroy> +myExit
proc myExit {} {
global pitch outID
puts $outID [format "NoteOff 0.0 1 %f 127" $pitch ]
flush $outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
puts [format "NoteOff 0.0 1 %f 127" $pitch ]
flush stdout
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
proc noteOn {pitchVal pressVal} {
global outID
puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc changePitch {value} {
global outID
puts $outID [format "PitchChange 0.0 1 %.3f" $value]
flush $outID
puts [format "PitchChange 0.0 1 %.3f" $value]
flush stdout
}
bind . <Configure> {+ center_the_toplevel %W }
proc center_the_toplevel { w } {
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}

View File

@@ -13,7 +13,7 @@
Stanford, bearing the names of Karplus and/or
Strong.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
by Perry R. Cook and Gary P. Scavone, 1995-2012.
*/
/***************************************************/

View File

@@ -24,7 +24,7 @@ namespace stk {
Stanford, bearing the names of Karplus and/or
Strong.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
by Perry R. Cook and Gary P. Scavone, 1995-2012.
*/
/***************************************************/

View File

@@ -8,7 +8,7 @@
sample rates. You can specify the maximum polyphony (maximum
number of simultaneous voices) in Tabla.h.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
by Perry R. Cook and Gary P. Scavone, 1995-2012.
*/
/***************************************************/

View File

@@ -17,7 +17,7 @@ namespace stk {
sample rates. You can specify the maximum polyphony (maximum
number of simultaneous voices) in Tabla.h.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
by Perry R. Cook and Gary P. Scavone, 1995-2012.
*/
/***************************************************/

View File

@@ -8,7 +8,7 @@
sample rates. You can specify the maximum polyphony (maximum
number of simultaneous voices) in VoicDrum.h.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
by Perry R. Cook and Gary P. Scavone, 1995-2012.
*/
/***************************************************/

View File

@@ -17,7 +17,7 @@ namespace stk {
sample rates. You can specify the maximum polyphony (maximum
number of simultaneous voices) in VoicDrum.h.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
by Perry R. Cook and Gary P. Scavone, 1995-2012.
*/
/***************************************************/

View File

@@ -7,25 +7,12 @@ set cont2 7.0
set cont4 0.0
set cont11 10.0
set cont7 3.0
set outID "stdout"
set commtype "stdout"
# Configure main window
wm title . "STK RagaMatic Controller"
wm iconname . "raga"
. config -bg grey20
# Configure "communications" menu
menu .menu -tearoff 0
menu .menu.communication -tearoff 0
.menu add cascade -label "Communication" -menu .menu.communication \
-underline 0
.menu.communication add radio -label "Console" -variable commtype \
-value "stdout" -command { setComm }
.menu.communication add radio -label "Socket" -variable commtype \
-value "socket" -command { setComm }
. configure -menu .menu
# Configure bitmap display
if {[file isdirectory bitmaps]} {
set bitmappath bitmaps
@@ -50,12 +37,11 @@ label .banner.bottom.ragamat -text " * * RagaMatic * *\n\n \
bind . <Destroy> +myExit
proc myExit {} {
global outID
puts $outID [format "NoteOff 0.0 1 60 127"]
flush $outID
puts $outID [format "ExitProgram"]
flush $outID
close $outID
puts [format "NoteOff 0.0 1 60 127"]
flush stdout
puts [format "ExitProgram"]
flush stdout
close stdout
exit
}
@@ -130,27 +116,23 @@ proc rockOut {} {
}
proc raga {scale} {
global outID
puts $outID [format "ControlChange 0.0 1 64 %f" $scale]
flush $outID
puts [format "ControlChange 0.0 1 64 %f" $scale]
flush stdout
}
proc noteOn {pitchVal pressVal} {
global outID
puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc noteOff {pitchVal pressVal} {
global outID
puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
flush $outID
puts [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
flush stdout
}
proc printWhatz {tag value1 value2 } {
global outID
puts $outID [format "%s %i %f" $tag $value1 $value2]
flush $outID
puts [format "%s %i %f" $tag $value1 $value2]
flush stdout
}
frame .banner.butts -bg black
@@ -237,68 +219,32 @@ pack .controls.cont7 -padx 10 -pady 10
pack .controls -side left -padx 10 -pady 10
# Socket connection procedure
set d .socketdialog
bind . <Configure> {+ center_the_toplevel %W }
proc center_the_toplevel { w } {
proc setComm {} {
global outID
global commtype
global d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
switch $i {
0 {set commtype "socket"}
1 {close $outID
set outID "stdout"}
}
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
-command { set commtype "stdout"
set outID "stdout"
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket $sockhost $sockport} outID]
# Callback on the <Configure> event for a toplevel
# that should be centered on the screen
if {$err == 0} {
destroy $d
} else {
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
} }
pack $d.buttons.cancel -side left -padx 5 -pady 10
pack $d.buttons.connect -side right -padx 5 -pady 10
pack $d.buttons -side bottom -padx 5 -pady 10
}
}
# Make sure that we aren't configuring a child window
if { [string equal $w [winfo toplevel $w]] } {
# Calculate the desired geometry
set width [winfo reqwidth $w]
set height [winfo reqheight $w]
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
#set y 0
# Hand the geometry off to the window manager
wm geometry $w ${width}x${height}+${x}+${y}
# Unbind <Configure> so that this procedure is
# not called again when the window manager finishes
# centering the window. Also, revert geometry management
# to internal default for subsequent size changes.
bind $w <Configure> {}
wm geometry $w ""
}
return
}