How SpinCAD Builder works

If I do something over and over and over the same way, generally speaking I try to find a way to make that thing easier. This is what led to SpinCAD Designer in the first place. As I kept reading more and more example code, I'd see the same patterns popping up, and I figured, "hey, I want a 1-pole low pass at 3.6 kHz, why should I have to do anything else (like calculate coefficients again)"?

You don't really get extra points for doing repetitive stuff by hand. If you watched that Bob Gallien interview I linked to, he comments (as he did when I worked for him) about his notebook with "60 pages of loop equations for the equalizer done by hand". To be able to do that well, and accurately, is certainly impressive. But should one have to do that every single time? I don't think so. Obviously!

I got the idea for SpinCAD Builder after I found Andrew Kilpatrick's "ElmGen" video on YouTube. I guess he also wanted something to make developing FV-1 code easier, or had some sort of obsession with understanding the FV-1 at a very deep level. I say that partially because he only came out with a few pedals that used the FV-1 and seems not to have used it beyond that. He is mostly a modular synth guy at heart I guess.

ElmGen represents the FV-1 assembly language 1-to-1 with Java functions. I didn't get it at first, but this lets you leverage Java's object-orientation to build up functional blocks. ElmGen also implements the FV-1 simulator, which is really a great feature. I'm not sure I would have come up with that on my own.

I mean, wouldn't it be great if Spin ASM let you say something like:

1pLPF 3500

to make a 1 pole low pass at 3500 Hz? But, it doesn't. You have to keep track of registers and calculate the coefficient. It's not HARD, but don't we have better things to do with our time?

So, initially, I started writing small blocks of Java code, with inputs and outputs, that I could connect up with other blocks of Java code, such that the design task boiled down to selecting the desired blocks and then putting them together. Forget about calculating filter coefficients ever again! (Which is why I forgot how to do that!)

After doing that for awhile, I thought, "Well that's nice but it's still quite the pain to do, and nobody is going to want to learn Java just to be able to write Spin ASM". So then the GUI got thought up, along with per-block control panels that let you specify attributes of the block. So for example, you can say you want the corner frequency at 3.5 kHz and the Java code does the calculation for you to create the coefficient that goes into the actual code. The GUI was written using Java "Swing", which has a Windows 98 feel to it, but can't have everything. Making the GUI "nicer" would be something to have an intern take care of. Where's my intern???

That was ok for awhile. Then I looked at some of these big reverb algorithms and thought, "I REALLY don't want to have to convert 120+ instructions of Spin ASM into the Java equivalent over and over". I didn't really know what I wanted or how to go about getting it.

Somehow (I can't even remember it at this point) I stumbled across the "Eclipse environment for Java and Domain Specific Languages (DSL)." So that's what SpinCAD Builder is - a domain specific language. It is written in Xtext, which provides the parsing, and Xtend, which handles the code generation.

So, what SpinCAD Builder does, is to parse specially written Spin ASM files, and generate Java source code for the DSP part (CADBlocks) and control panels (ControlPanels). The "specially written" bits are commands beginning with "@" (that is not used anywhere in native Spin ASM) for various things like:

  • @inputPin

  • @isPinConnected

  • @spinSlider

that are relevant to SpinCAD's environment but don't translate to anything in Spin ASM directly.

To handle this, we start with one instance of the Eclipse Java/DSL enviroment with the projects for the spincad and spincadmenu languages loaded. spincad syntax lets you create blocks from something that looks similar to Spin ASM, whereas spincadmenu lets you add, remove, or restructure most of the menus where you select the block you want to add to the design.

Once those language infrastructures are properly generated, you launch another instance of Eclipse Java/DSL which now incorporates that extra functionality. There is also a way to create "plugins" that would add these functions to Eclipse Java, and I could also create a special version of Eclipse that had all that built in. But I never did any of that, as it wasn't a big time saver for me, and so few people are going to want to deal with SpinCAD at that level.

So, in the second instance of Eclipse, when you save a file with the .spincad or .spincadmenu extension, the code generation leaps into action. The source file is parsed and then the code generation rules are executed. Once you do this a few times, you wonder why you wrote any Java directly by hand ever. Though clearly, this only lends itself to automating repetitive tasks.

So, not sure if you're still following all this, but in summary:

  • Write an "annotated" Spin ASM file (SpinCAD Builder)

  • Save this in the SpinCAD Builder-enabled version of Eclipse. This generates Java code.

  • Create the SpinCAD Designer jar program (or run it directly) from Eclipse instance #2. This now contains the functionality of the new blocks which you can drop into your designs.

  • The blocks and connections which you see in the GUI are turned into an ordered "model" of blocks and connections which can then be used to generate the final code for your patch.

  • When you export Spin ASM (or hex) for SpinCAD Designer, you are walking through the model from front to end, calling the "generate" method. The structure has all been dictated by the model.

An even shorter summary would be:

  • Spin ASM -> SpinCAD Builder->Java (SpinCAD Designer Source)

  • Create SpinCAD Designer program

  • SpinCAD Designer -> GUI -> model

  • Model -> Spin ASM

It's pretty weird, but it works. Is there a better or different way? Probably, but I'm unlikely to look for that in this lifetime. I'm not a professional software developer, although I've worked with quite a few. My path to getting to this point was a lot of stumbling around in the dark with occasional help from people on various forums, etc. Dogged persistence helped a bit too.

Last updated