[Fpga-synth] Try out spartan3e projects, questions
Theo Verelst
theover at tiscali.nl
Wed Jul 9 18:19:34 CEST 2008
Some work later, I´ve made a fully working Tcl/Tk sound editor for the
GateManPoly design, pasted to the bottom of this email, and it is
usable on all machines which can run tcl, and is easily adaptable.
I´ve added NoteOff midi receiving, which now appears to work (I had a
small keyboard which would have only stuck notes on the synth) to the
picoblaze assembly code, see my addition to my web page about the project:
http://www.theover.org/Fpgasynth
Kind regards,
Theo Verelst
theover at tiscali.nl
http://www.theover.org
------------------------------------------------------------------------------------------------------------
####################################################################################
# GateManEdit
#
####################################################################################
##
## By Ir. Theo Verelst, http://www.theover.org
##
## All parameters of the Gatemanpoly FPGA synthesizer get a slider on a
Tk window
## This isn´t always the best of course, and there are some cases where
I don´t
## know what the intended paramter range exactly is, and there are cases
like the
## Filter Q factor where the slider sense is wrong.
##
## The whole setup works, in my case over a 9600 USB serial connection, and
## parameter changes are sent to the synth immedeately, which is cool.
## Also a test note is sent with each slider motion.
##
## After typing a parameter value in an edit box, press Return to send
the change
## to the synth board
##
####################################################################################
# this shows the console window to see output and type Tcl/Tk commands
at startup,
# close it in the console with : console hide, or comment it out here
by putting
# a hash in front of it.
console show
# on Unix, this requires an extra procedurefile, the com port is
called different, too
# See http://wiki.tcl.tk/786 and http://wiki.tcl.tk/447 , on Redhat
e.g. : /dev/ttyS0
# the unchanged FPGA program IO rate is: 115200
# open the serial port acting as MIDI
# (fill in MOC5 and 9600 as you need)
set fh [open COM5: RDWR]
fconfigure $fh -blocking 0 -mode 9600,n,8,1 -translation binary
-buffering full
# write a hex code to the serial port
#
proc w h {
global fh
foreach c [split $h] {
puts -nonewline $fh [binary format H* $c]
}
flush $fh
}
# every parameter change plays a nonoverlapping test note when playnote!=0
set playnote 0
# write system exclusive decimal encoded byte with submessage codes n1,n2
# and send a test note on, which stops after 1.6 Sec, or with a new
slider move
#
proc wse {n1 n2 h} {
global fh np playnote
foreach c [split [list F0 7F 02 00 $n1 $n2 [format "%02x" $h] F7]] {
puts -nonewline $fh [binary format H* $c]
}
flush $fh
if { $playnote != 0} {
if {$np != 0} { after cancel $np ; w { 90 3C 00 } ; set np 0 }
w { 90 3C 20 } ; set np [after 1600 { w { 90 3C 00 } ; set np 0}]
}
}
# 14 bits are assumed here
proc wse2b {n1 n2 n3 h} {
global fh np playnote
set hi [expr $h>>7] ; set lo [expr $h&127]
puts [format "%02x" $hi],[format "%02x" $lo]
foreach c [split [list F0 7F 02 00 $n1 $n2 [format "%02x" $hi] F7]] {
puts -nonewline $fh [binary format H* $c]
}
foreach c [split [list F0 7F 02 00 $n1 $n3 [format "%02x" $lo] F7]] {
puts -nonewline $fh [binary format H* $c]
}
flush $fh
if { $playnote != 0} {
if {$np != 0} { after cancel $np ; w { 90 3C 00 } ; set np 0 }
w { 90 3C 20 } ; set np [after 1600 { w { 90 3C 00 } ; set np 0}]
}
}
# create a new frame with a slider which sends a certain message when
moved
# and a label with the slider associated MIDI parameter name, and
# an editable entry with connected numerical value (over a global
variable name)
proc newparfr {name n1 n2 max} {
frame .f1.$name
pack .f1.$name -side left -fill y -expand y
scale .f1.$name.sl -from $max -to 0 -length 256 -var $name -showvalue 0
pack .f1.$name.sl -side top -expand y -fill both -anchor center
.f1.$name.sl conf -command "wse $n1 $n2 "
label .f1.$name.l -text $name -justify center
pack .f1.$name.l -side bottom -expand n -fill x -anchor center
# An entry to see and change slider values
entry .f1.$name.e -text $name -justify center -textvar $name
-justify r -width 3
pack .f1.$name.e -side bottom -expand n -fill x -anchor center
# (this bind get evaluated once to send the actual command when
Return is pressed)
bind .f1.$name.e <Key-Return> "wse $n1 $n2 \$$name"
}
# idem for 14 bit messages
#
proc newparfr2b {name n1 n2 n3 max} {
frame .f2.$name
pack .f2.$name -side left -fill y -expand y
scale .f2.$name.sl -from $max -to 0 -length 256 -var $name -showvalue 0
pack .f2.$name.sl -side top -expand y -fill both -anchor center
.f2.$name.sl conf -command "wse2b $n1 $n2 $n3 "
label .f2.$name.l -text $name -justify center
pack .f2.$name.l -side bottom -expand n -fill x -anchor center
entry .f2.$name.e -text $name -justify center -textvar $name
-justify r -width 5
pack .f2.$name.e -side bottom -expand n -fill x -anchor center
# the dollars are quoted because of repeated evaluation
bind .f2.$name.e <Key-Return> "wse2b $n1 $n2 $n3 \$$name"
}
# Initialize the noteplay after id variable
set np 0
# the first frame, so that we can make some major screen groups
frame .f1
pack .f1 -side top -expand y -fill both
frame .f2
pack .f2 -side top -expand y -fill both
frame .f3
pack .f3 -side top -expand y -fill both
# commands to create various sliders ( name of slider and subwidget,
msb,lsb midi, max value)
newparfr wavf1 00 2C 3
newparfr wavf2 00 2D 3
newparfr wavf3 00 2E 3
newparfr wavf4 00 2F 3
newparfr tune1 00 00 64
newparfr tune2 00 01 64
newparfr tune3 00 02 64
newparfr tune4 00 03 64
newparfr trans 01 10 64
newparfr davol 01 60 16
newparfr nfbw1 00 20 31
newparfr nfbw2 00 21 31
newparfr nfbw3 00 22 31
newparfr nfbw4 00 23 31
newparfr nboo1 00 30 15
newparfr nboo2 00 31 15
newparfr nboo3 00 32 15
newparfr nboo4 00 33 15
newparfr pwms1 00 24 127
newparfr pwms2 00 25 127
newparfr pwms3 00 26 127
newparfr pwms4 00 27 127
newparfr pwso1 00 28 3
newparfr pwso2 00 28 3
newparfr pwso3 00 28 3
newparfr pwso4 00 28 3
# commands to create various sliders ( name of slider and subwidget,
msb,lsb 1, 2 midi,
# max value) , second row in main UI window:
newparfr2b fine1 00 04 08 16383
newparfr2b fine2 00 05 09 16383
newparfr2b fine3 00 06 0A 16383
newparfr2b fine4 00 07 0B 16383
newparfr2b ovol1 00 0C 10 16383
newparfr2b ovol2 00 0D 11 16383
newparfr2b ovol3 00 0E 12 16383
newparfr2b ovol4 00 0F 13 16383
newparfr2b nml1 00 18 1C 16383
newparfr2b nml2 00 19 1D 16383
newparfr2b nml3 00 1A 1E 16383
newparfr2b nml4 00 1B 1F 16383
newparfr2b fatt 01 20 21 16383
newparfr2b fdec 01 22 23 16383
newparfr2b fsus 01 24 25 16383
newparfr2b frel 01 26 27 16383
newparfr2b fq 01 50 51 16383
newparfr2b aatt 01 30 31 16383
newparfr2b adec 01 32 33 16383
newparfr2b asus 01 34 35 16383
newparfr2b arel 01 36 37 16383
# Default settings
# 7 bits
set wavf1 2
set wavf2 2
set wavf3 2
set wavf4 2
set tune1 36
set tune2 0
set tune3 12
set tune4 24
set trans 0
set davol 8
set nfbw1 7
set nfbw2 4
set nfbw3 4
set nfbw4 2
set nboo1 3
set nboo2 4
set nboo3 7
set nboo4 9
set pwms1 48
set pwms2 37
set pwms3 36
set pwms4 37
set pwso1 0
set pwso2 1
set pwso3 2
set pwso4 3
# 14 bits
set fine1 8192
set fine2 6363
set fine3 9801
set fine4 10313
set ovol1 10093
set ovol2 9874
set ovol3 12214
set ovol4 9947
set nml1 4608
set nml2 8411
set nml3 5997
set nml4 8484
set fatt 5193
set fdec 20
set fsus 3364
set frel 73
set fq 6363
set aatt 16164
set adec 73
set asus 10386
set arel 73
button .f3.bpars -text "Show all parameters"
pack .f3.bpars -side left -fill y -expand y
.f3.bpars conf -command {
# print a list of reloadable parameter values in the console
foreach i [winfo children .f1] { set t [$i.sl cget -var] ; puts "set
$t [set $t]" }
foreach i [winfo children .f2] { set t [$i.sl cget -var] ; puts "set
$t [set $t]" }
}
button .f3.bsend -text "Send All Midi"
pack .f3.bsend -side left -fill y -expand y
.f3.bsend conf -command {
global playnote
set playnote 0
# update all synth parameters.
# for all frame 1 subframe names:
foreach i [winfo children .f1] {
# get the slider associated variable name
set t [$i.sl cget -var] ;
# Send slider associated change command
eval "[.f1.$t.sl cget -command] [.f1.$t.sl get]"
}
# idem for UI (invisible) frame 2
foreach i [winfo children .f2] {
set t [$i.sl cget -var] ;
eval "[.f2.$t.sl cget -command] [.f2.$t.sl get]"
}
update
set playnote 1
}
update
set playnote 1
puts "Startup done, no parameter change sent yet."
More information about the Fpga-synth
mailing list