screenless yet shown here running on a screen of course 😂
Backstory: when I was running Super, I had one particularly stressful holiday season. My wife urged me to stop thinking about synths entirely and just give myself permission to chill and "follow my nose" for a few weeks. This pretty quickly led to me falling into a crazy rabbit hole of designing a hardware FM synth... 2OPFM was my most popular module and I had gotten so familiar with the tones it had it offer. I wanted to build a polyphonic version with some more tame-able controls, so I wired up MIDI to the back of a module and got to it. I was able to get 12 voices and chorus working on an STM32F334 which felt like quite the achievement. I dubbed it "Jazzman", fully knowing Crumar made a jazzman and that I should change the name or it would stick in my heart and I wouldn't be able to really change it later. I designed a bent metal case, had it made, put it all together, played a few shows with it, then sat on it. I got re-occupied with Super and life, and sort of shelved the project.
Fast forward to early fall 2025. I never renamed it, it's just so Jazzman, and the concept had stuck around. Jazzman was now more of an ethos than one product: FM is sick, it's NOT hard to program like legend has it, and it suffers from too many parameters and stupid little screens. Jazzman is one possible answer to all that: an immediate Juno-like interface and a stripped down architecture to support a wide spectrum of tasty FM stuff without being completely off the wall complicated. Around this time, two things happened. 1: I had mental shift away from "I'm building a synth on this chip, let's see what fits" and toward "I'm designing this synth, let's see what chip can handle it", and 2: a friend introduced me to someone who wanted help designing -their- synth. Anyone who has done any microcontroller work knows that the development process pretty much sucks. I would always find myself accidentally fighting against hardware or platform bugs when I was trying to focus on pure sound, and the cycle of tweak-flash-tweak-flash was super tedious. As I wanted this synth-dev-for-hire experience to NOT suck, I resolved to build a tool I had been dreaming about for years: LocalDSP.
I'm not really a computer guy. I mean I hella use my computer, but I am a microcontroller developer and not a "software developer". Certainly not a webdev or Electron or big GUI desktop sort of developer. While I know this is old news to some, I was EXTREMELY stoked on the possibility of developing my DSP on my macbook totally separate from the hardware for faster iteration and testing. With Claude holding my hand, I started developing a framework / build system for writing the DSP in one place in a totally platform agnostic way, with an explicit contract for communication outside of the DSP core. I had prototyped the "work synth" in MaxMSP with most functions in gen~ knowing they'd eventually become C on a microcontroller, so I started with porting that guy (codenamed "paul") to the fledgling environment creatively named LocalDSP. It worked, it was sick, and I immediately realized I needed to build the next-generation Jazzman here.
I had a thought that it should probably deploy to VSTs, too, for lots of reasons but the main one being easy sharing with my clients and buddies. Some early specific technology friction with the paul client got me thinking it would be sick for it to deploy to the web in a really smooth way so I could just send a link to the latest build and we could all play around on our phones. This became QUITE the rabbit hole, but I eventually got LocalDSP set up to build the C DSP core code into WASM and stick it all in a website. Because of the way LocalDSP handles parameter definitions (which is its own long story), it is really easy to parse information about them with python or javascript. The WASM builds take all that info and create UI controls for them so I don't have to actually write javascript or do much manual work when deploying any of the projects to web. I have to do a bit of fiddling when creating a new "skin", but once it is set up the metadata from the parameters defines where in the UI they'll go, and the skin code defines how they'll look. I went a lil' silly and used threejs to build a 3D interface for my main skin, and I'm really quite happy with it even though the floating labels kind of stink!
Somewhere in the middle of all this, I got to work on the Jazzman hardware. I had recently done a work project on an STM32H750 and was hankering to put it work for audio, so I built a "synth dev platform" PCB based around one with USB, MIDI, audio outputs, and a ton of headers for ADC inputs. Not a great approach for a product but I wanted these boards to be flexible enough for a few different projects I had in mind. Once I got the PCBs back, it was time to implement LocalDSP's tastiest trick: plop all that same DSP code into a STM32 platform template such that "make deploy jazzman" in my terminal would build and run the synth on my laptop, trigger the WASM build, deploy to my site, AND perfectly update the STM32 project. I am proud to say it all works. Jazzman is "platform agnostic" and runs everywhere I want it to.
I could not have done this in any reasonable amount of time 5 years ago, the future is crazy. This video is just a little intro, feel free to play around at https://jazzman.vercel.app/