Deep dive into the ThreeTap Delay, part 1
Last updated
Last updated
Right now it's called "Triple-Tap" in the Delay menu. Another bug to fix! Once you drop it in, it's called ThreeTap. So that will be its name. I use this one all the time, even if I only need one or two taps. You'll see why.
Here are all the inputs and outputs identified.
Here's the control panel:
Here's the block diagram of the input section.
Now let's look at the SpinCAD Builder code in Github.
@name ThreeTap
The displayed name of the block.
@color "0x6060c4"
The 24-bit color value for this block
@audioInput adcl Input
@audioInput feedback Feedback
Define the audio inputs. These are drawn in order along the top edge of the displayed block. The syntax is @audioInput variable_name pin_name.
variable_name represents the name of a variable to hold this value
pin_name will be displayed in the editor when you put the mouse over the pin, to remind you what the function is.
@audioOutput output1 'Tap 1 Out'
@audioOutput output2 'Tap 2 Out'
@audioOutput output3 'Tap 3 Out'
Define the audio outputs. These are drawn in order along the bottom edge of the displayed block. The same syntax applies here as for the audioInputs.
@controlInput cIn1 'Delay Time 1'
@controlInput cIn2 'Delay Time 2'
@controlInput cIn3 'Delay Time 3'
@controlInput fbk 'Feedback Gain'
Define the control inputs. These are drawn in order along the left edge of the displayed block. The same syntax applies here as for the audioInputs.
equ inputGain 1.0
This is an actual Spin ASM line which declares the inputGain variable and sets its initial value.
@sliderLabel inputGain 'Input Gain: ' -24 0 0 1.0 1 DBLEVEL
This statement creates an entry in the control panel allowing adjustment of the inputGain variable.
It has a number of parameters that I need to run off to review what they mean!
Back now.
sliderLabel is first encountered in the SpinCAD Builder xtext parser.
Here's how the syntax is defined there.
'@sliderLabel' ename = ID controlName = (ID | STRING) (minVal = SPINDOUBLE maxVal = SPINDOUBLE initVal = SPINDOUBLE multiplier = SPINDOUBLE precision = INT (option = ID)?)?
ename is the variable name
controlName will be the "Pin Name"
minVal is the minimum displayed value of the slider
maxVal is the maximum displayed value of the slider
initVal is the value of the slider when a new block is dropped in
multiplier is ???
precision indicates how many decimal places to show.
option allows an external function to be called to convert between the slider value and the variable being controlled.
Here's the xtend Java generator code for the "sliderLabel" object.
Let's look for the "DBLEVEL" option:
«IF e.option == "DBLEVEL"» // dB level slider goes in steps of 1 dB «e.ename»Slider = new JSlider(JSlider.HORIZONTAL, (int)(«e.minVal»),(int) («e.maxVal»), (int) (20 * Math.log10(gCB.get«e.ename»()))); «ENDIF»
I'm not going to fully dissect this here (one thing definitely leads to another) but suffice it to say that this creates a Java Swing "JSlider" with a horizontal layout, minimum value is minVal, maximum value is maxVal, and the current value is obtained by doing a dB (20 * log10) conversion of the block variable that we will look up using its "ename".
What's interesting to note here is that "multiplier" and "precision" didn't show up yet. I don't know if that's because they are really not used or if they simply show up in another context. I'll save THAT for part 2!
A side note about xtext and xtend languages.
Xtext allows you to define a parsing syntax for your domain-specific language. So for this project I had to start by recreating the parsing rules for Spin ASM itself. After that, I made up the extra bits I would need to use with SpinCAD Builder, after writing a number of them by hand to see how they came together. I wrote quite a number of blocks by hand before I went on the search for what I ultimately found in the Eclipse Java + DSL environment. I really didn't know the first thing about code generation and it took an entire month to get this working at a basic level.
SpinCAD Builder Xtend code is the part that, driven by the results of the parsing step, generates the Java code for both the SpinCADBlocks (the DSP code and its options) and the SpinCADControlPanels (the Java Swing popups with the various controls). When this Java code is combined with the UI, simulator, etc. it becomes the source code for a given version of SpinCAD. Yes, it probably would have been clever to allow the definition of new blocks without requiring a new build of the application, but that's not where fate led me.
Take a look at the code that is generated for the TripleTapCADBlock.java and the TripleTapControlPanel.java. We'll take a closer look at these in an upcoming episode.