mirror of
https://github.com/thestk/stk
synced 2026-01-11 20:11:52 +00:00
264 lines
8.1 KiB
Tcl
264 lines
8.1 KiB
Tcl
# 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
|
|
} |