{"id":1350,"date":"2026-05-07T09:43:24","date_gmt":"2026-05-07T08:43:24","guid":{"rendered":"https:\/\/mohoyt.com\/blog\/?p=1350"},"modified":"2026-05-07T09:43:26","modified_gmt":"2026-05-07T08:43:26","slug":"siren-a-workshop-system-drone-oscillator","status":"publish","type":"post","link":"https:\/\/mohoyt.com\/blog\/2026\/siren-a-workshop-system-drone-oscillator\/","title":{"rendered":"Siren &#8211; a Workshop System Drone Oscillator"},"content":{"rendered":"\n<p>I&#8217;ve been spending time recently with my <a href=\"https:\/\/www.musicthing.co.uk\/workshopsystem\/\">Music Thing Modular Workshop System<\/a>: a complete modular synth in a small peli-style case. It\u2019s mostly analogue, but it has a digital computer module on the left that\u2019s powered by cards. For each card the hardware stays the same (a few knobs, a switch, two audio in jacks, two CV in jacks, two pulse in jacks (and the same for audio\/cv\/pulse out)) and the card you plug in decides what the thing actually does. Reverb today, Turing machine tomorrow, something I wrote myself the day after.<\/p>\n\n\n\n<p>Siren is one of those something-I-wrote-myself cards. It&#8217;s a multi-algorithm drone oscillator, and the <a href=\"https:\/\/github.com\/mohoyt\/siren\">code is on GitHub<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why?<\/h2>\n\n\n\n<p>A few reasons, really.<\/p>\n\n\n\n<p>The <a href=\"https:\/\/www.forge-tme.com\/product\/vhikk-x\/\">Forge TME Vhikk X<\/a> had been on my radar for ages &#8211; its SEED\/SCAN paradigm (structural randomisation on one knob, timbral morphing on another) is a really nice way to think about a drone, because it separates &#8220;what is this thing fundamentally made of&#8221; from &#8220;what does it sound like right now.&#8221; I think that split is the bit that makes it interesting to play with rather than just set and forget.<\/p>\n\n\n\n<p>But Vhikk X is a popular module, and as a result a hard one to get and also on the expensive side. I also didn&#8217;t really want another module taking up rack space when I wasn&#8217;t sure that I needed it. So the obvious thing was to write the card I wanted and use it as a trial to see if this was a module that I should get.<\/p>\n\n\n\n<p>The other reason is that I&#8217;d been wanting an excuse to get into the Workshop Computer development side of things. There&#8217;s a <a href=\"https:\/\/github.com\/TomWhitwell\/Workshop_Computer\">vibrant little community<\/a> building cards in C++, Rust, Python, Lua \u2014 and the <code>ComputerCard.h<\/code> header gives you a really clean abstraction over the hardware. I dipped my toe earlier by adding some arpeggiator features to the chord blimey card, But now I wanted to do something myself.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What it does<\/h2>\n\n\n\n<p>This is where I took lots and lots of inspiration from Vhikk X and its documentation. Six oscillator banks, each with its own character:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>SINE<\/strong> \u2014 multi-sine cluster with phase feedback. The purest of the lot.<\/li>\n\n\n\n<li><strong>CLST<\/strong> \u2014 tightly detuned oscillators for beating and phaser textures.<\/li>\n\n\n\n<li><strong>DTON<\/strong> \u2014 diatonic intervals using just intonation, with wavefolding. Comes out as actual chords.<\/li>\n\n\n\n<li><strong>ANLG<\/strong> \u2014 two oscillators that crossfade between cross-modulation and ring modulation.<\/li>\n\n\n\n<li><strong>WSHP<\/strong> \u2014 FM-ish timbres via tanh waveshaping. Metallic, bright.<\/li>\n\n\n\n<li><strong>WAVE<\/strong> \u2014 wavetable scanning with bit reduction. The most digital-sounding bank.<\/li>\n<\/ul>\n\n\n\n<p>The six parameters that I took exactly from the ones on Vhikk X (WARP, SPAN, MORPH, SEED, SCAN, BASIS) are spread across two switch positions on the three knobs. Each parameter does something different in each bank, which is the bit I find genuinely fun, though also a little confusing at times: the same MORPH knob is shifting per-oscillator amplitudes in SINE, swapping waveforms in CLST, and scanning carriers in WSHP. Same physical gesture, six different behaviours. It rewards exploration.<\/p>\n\n\n\n<p>Effects, filtering, modulation are things that are in the \u2018original\u2019 or real module, but for this card I left these roles to external modules. I think that&#8217;s the right call. There&#8217;s already enough going on inside the card without trying to be a complete signal chain.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Some things I had to figure out<\/h2>\n\n\n\n<p>A few quick notes on bits that took thought.<\/p>\n\n\n\n<p><strong>Knob pickup.<\/strong> When you switch between Up and Middle on the switch, the knobs are now controlling completely different parameters. If they jumped instantly to whatever the physical knob position said, you&#8217;d get ugly parameter snaps every time you switched. So I borrowed the Arturia MicroFreak&#8217;s behaviour: the parameter holds its old value until the physical knob crosses near it, and only then does it start tracking. It&#8217;s the kind of thing you don&#8217;t notice when it works, which is the point.<\/p>\n\n\n\n<p><strong>Fitting everything onto so few controls.<\/strong> The real Vhikk X module has a lot more knobs and space on it. The Workshop System Computer, not so much. I had to figure out how to map these different controls onto the Computer. It&#8217;s not perfect, but I think my idea on settling on Z-switch positions to determine what each knob does combined with the knob pickup kind of solves it.<\/p>\n\n\n\n<p><strong>Fixed-point everything.<\/strong> The Workshop Computer runs on an RP2040, which is a lovely little chip but doesn&#8217;t have hardware floating point. So all the DSP is fixed-point \u2014 Q15 for audio, Q16.16 for phase accumulators. Lookup tables for the waveforms (1024 points, linearly interpolated) and the nonlinearities (tanh, wavefold). Estimated CPU usage is around 20\u201340% of budget per sample at 48 kHz, which leaves headroom for the crossfade buffer to do its thing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Status<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.youtube.com\/watch?v=DORHEYpUqWU\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"575\" src=\"https:\/\/mohoyt.com\/blog\/wp-content\/uploads\/2026\/05\/Screenshot-2026-05-07-at-10.35.53-1024x575.png\" alt=\"\" class=\"wp-image-1351\" srcset=\"https:\/\/mohoyt.com\/blog\/wp-content\/uploads\/2026\/05\/Screenshot-2026-05-07-at-10.35.53-1024x575.png 1024w, https:\/\/mohoyt.com\/blog\/wp-content\/uploads\/2026\/05\/Screenshot-2026-05-07-at-10.35.53-300x168.png 300w, https:\/\/mohoyt.com\/blog\/wp-content\/uploads\/2026\/05\/Screenshot-2026-05-07-at-10.35.53-768x431.png 768w, https:\/\/mohoyt.com\/blog\/wp-content\/uploads\/2026\/05\/Screenshot-2026-05-07-at-10.35.53-1536x862.png 1536w, https:\/\/mohoyt.com\/blog\/wp-content\/uploads\/2026\/05\/Screenshot-2026-05-07-at-10.35.53-1568x880.png 1568w, https:\/\/mohoyt.com\/blog\/wp-content\/uploads\/2026\/05\/Screenshot-2026-05-07-at-10.35.53.png 1616w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>It works. It&#8217;s running on a card in my workshop system. There are two videos on the GitHub repo if you want to hear it: <a href=\"https:\/\/youtu.be\/DORHEYpUqWU\">an overview of the banks<\/a> and <a href=\"https:\/\/youtu.be\/Lqdvu03-Lqs\">a short jam<\/a>. The code is MIT licensed, the build instructions are in the README, and if you&#8217;ve got a Workshop System or the standalone Workshop Computer with a blank card lying around you can flash it yourself. You can find the latest uf2 to download and flash here (it&#8217;s card number 27): <a href=\"https:\/\/tomwhitwell.github.io\/Workshop_Computer\/index.html\">https:\/\/tomwhitwell.github.io\/Workshop_Computer\/index.html<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Things I&#8217;ve learnt<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>ComputerCard.h<\/code> abstraction is genuinely good: most of the work was DSP, not hardware-wrangling.<\/li>\n\n\n\n<li>There\u2019s some great instructions and background in the wonderfully named <code>WORKSHOP_COMPUTER_AI_DIRECTIVE<\/code> that I gave to Claude to help with everything.<\/li>\n\n\n\n<li>Crossfading bank transitions made a much bigger difference to how the card feels than I&#8217;d expected. Worth the buffer.<\/li>\n\n\n\n<li>The community on Discord for the Workshop System\/Computer is super nice, gives incredible feedback and is a great place to learn things. Thank you to all those kind folks there.<\/li>\n\n\n\n<li>It\u2019s a lot of fun to play with, a little bit confusing with all of the controls at times, but to me it&#8217;s a good way of dipping my toe into the Vhikk X ecosystem.<\/li>\n<\/ul>\n\n\n\n<p>If you&#8217;ve got a Workshop System or Workshop Computer, give it a go. If you don&#8217;t, the Vhikk X is likely far better but also a little more expensive.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been spending time recently with my Music Thing Modular Workshop System: a complete modular synth in a small peli-style case. It\u2019s mostly analogue, but it has a digital computer module on the left that\u2019s powered by cards. For each card the hardware stays the same (a few knobs, a switch, two audio in jacks, &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/mohoyt.com\/blog\/2026\/siren-a-workshop-system-drone-oscillator\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Siren &#8211; a Workshop System Drone Oscillator&#8221;<\/span><\/a><\/p>\n","protected":false},"author":5,"featured_media":1351,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[87],"tags":[],"class_list":["post-1350","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-projects","entry"],"_links":{"self":[{"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/posts\/1350","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/comments?post=1350"}],"version-history":[{"count":2,"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/posts\/1350\/revisions"}],"predecessor-version":[{"id":1353,"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/posts\/1350\/revisions\/1353"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/media\/1351"}],"wp:attachment":[{"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/media?parent=1350"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/categories?post=1350"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohoyt.com\/blog\/wp-json\/wp\/v2\/tags?post=1350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}