New, improved version of the PolyMod modular digital synthesizer, which was a Hackaday Prize semi-finalist in 2018.
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
I've got a simplified version of the proposed final setup working on a breadboard, which is allowing me to do a lot of the necessary coding. The current plan is for the synth to use something like a Teensy LC to handle all the multiplexing etc, while a Teensy 4.0 handles the synthesis. My breadboard version instead uses an Arduino for multiplexing (with two test modules and a single potentiometer for testing), and a Teensy 3.2 for synthesis - this alternative setup is just because I'm abroad right now and am going to wait til I'm home before ordering more Teensy boards.
The coding is proving difficult, but I feel like I'm slowly getting a handle on it. I'm trying to keep everything modular, flexible, readable, and future-proof, so I'm abstracting every possible part of the design into its own class in the code. While the previous version (PolyMod V1) simply had "modules" and "patch cables", the new code has classes for "physical modules", "virtual modules", "physical patch cables", "virtual patch cables" and so on. This should hopefully keep the classes a bit smaller and cleaner, and allow more interesting uses of the polyphonic patching system.
The previous synth's polyphonic mode simply duplicated each module and patch cable four times, which was cool when you were actually doing polyphonic stuff (like playing chords with a keyboard and four oscillators), but it also enforced polyphony into situations where it wasn't needed or wanted. This new approach should be more flexible, and even allow interaction between mono modules, creating the possibility of things like arpeggiator modules, which would have been tricky with the previous codebase.
I'm currently fighting against my limited understanding of pointers and references in C++ (aka Arduino code) - my approach so far has been almost to guess whether I need a pointer or a reference, then let the compiler tell me where I went wrong, but I think I'm at the stage where I should probably go and check out a few tutorials before carrying on...
UPDATE: My problem turned out not to be directly related to pointers/references etc, but, like most bugs, was just down to me doing something simple and stupid (numbering my ports 0,2,3,4 and skipping number 1 for some reason). Everything working again for now!
Just a quick update to say that this project is now almost certain to use the Teensy 4.0 as its main microcontroller. The Teensy 4.0 was released this month and is somehow both incredibly cheap and amazingly powerful. I haven't managed to get hold of one in the UK yet, and the audio board hasn't yet been updated to be compatible, but all indications are that the Teensy 4.0 will be the perfect board for this project. Check out the new Teensy's specs here: https://www.pjrc.com/teensy-4-0/
I've been on a break from this project for a while, focusing on my DrumKid drum machine for the 2019 Hackaday Prize, but the deadline for that is in a few days so I'll definitely have some time to work on PolyMod 2 over the coming weeks and months. I've now got a lot more experience (albeit self-taught and probably flawed!) with PCB design and, to an extent, product design, so I'm feeling a lot more confident about making PolyMod 2 a reality.
After a couple of busy months, I finally carved out some time to have a proper think about PolyMod 2. I had been somewhat paralysed by indecision, given the sheer number of possibilities in terms of features, form factor, microcontroller, price point, construction method, etc. However, a late-night exploratory session on KiCad focused my mind, and I think I now have a reasonably firm idea of everything. Here is my current thinking:
And what does all this mean for the specifications? Here are the current likely connectivity specs:
And the other features:
If anyone has any thoughts, please comment below - the project is still at a fairly malleable stage right now, but will crystallise over the coming weeks!
Just thought I'd do a quick update to affirm that PolyMod 2 is still alive and (reasonably) well. I've been working on a few less ambitious projects recently, but they've all helped build up the skills I will need to develop PolyMod 2.
I've also done lots of thinking about how to move forward with PolyMod 2. I have come up with a few answers, but also a lot of questions. My main question is: to what extent should I piggy-back on the existing Eurorack standard?
Should I design my master module to be powered by a Eurorack ribbon cable? Should I make it easy to house PolyMod modules alongside Eurorack modules, meaning I don't really have to worry about case design (I can use an existing Eurorack case)? Should I abandon the push fit system in favour of ribbon connectors?
Frankly, these are the questions of someone who has just bought the first parts of a Eurorack system and is now trying to make sure PolyMod 2 doesn't reinvent the wheel for the sake of it. I'm increasingly convinced that I should make PolyMod 2 complement a Eurorack setup rather than be a separate beast. My friend played with the synth and his first response was: "Cool! Can it connect to Eurorack?". To which my answer, having now thought about it for a while, is... yes, it could, and that would be great.
Ramble over.
The other day I stumbled across this project for a modular keyboard design (modular in the general sense, not as in modular synthesis): https://hackaday.io/project/6737-modular-synthesizer-controller-keyboard-case
It inspired me to keep thinking about a physical keyboard for PolyMod 2. I've recently gotten the hang of 3D printing a bit better, so I decided to prototype a keyboard design in PLA. It's based on the plastic toy keyboard keys that I used in PolyMod 1, but scaled up to be the size of MicroKorg keys (about 8cm long). The springiness comes from a thin strip of plastic between the key and the anchor point.
Each key pushes down on two silicone buttons, the idea being that you'll hit one button first, then the other a few microseconds later, and the time taken will yield a "velocity" value. So far I haven't managed to get this to work reliably, but already this design works fine as a non-velocity-sensitive keyboard, so I'm hopeful! Here are some pictures - I'll release some STL files once I've developed the design a bit more.
A little summary of progress over the past week or so:
I've briefly diverted my attention to developing a stripped-down version of PolyMod, because I'm writing a magazine tutorial on how to build a digital synth. This version fits on two breadboards, has 16 patchable sockets, a few knobs, a couple of LEDs, a miniature keyboard and a MIDI input. This has been a useful experience, because I've gone right back to basics with the design and code.
The stripped-down version uses a Teensy 3.2, which has forced me to think about memory usage. With the Teensy 3.6, I was able to be quite cavalier with the amount of memory I used. I tried more and more complex patches, and the 3.6 never struggled. However, with the 3.2 I soon started running into problems. After a bit of experimentation, I realised that there was a memory leak in the Teensy audio library when disconnecting a virtual patch cable. This is now in the process of being fixed in the core code - more details on this forum thread: https://forum.pjrc.com/threads/54760-Audio-stops-working-when-repeatedly-creating-disconnecting-AudioConnections
A helpful user on the forum also pointed out that dynamically creating unlimited audio connections is a recipe for disaster on the Teensy. As an alternative, he suggested a series of mixers to connect the different modules. I don't know whether I've understood his suggestion correctly, but I tried implementing a version of this approach with the stripped-down breadboard PolyMod, and it worked really nicely. Basically, everything is permanently connected to everything else - a mixer is placed before every module input, and every possible module output is routed into each mixer, with the patching being controlled by adjusting the volume of each mixer channel. This creates a huge number of audio connections but, crucially, the connections are known at compile time, meaning that the issue of dynamically creating too many patch cables is solved.
This approach is probably not feasible for a full PolyMod design, partly because the module types are not known at compile time, and partly because it doesn't scale very well as the number of sockets increases (my maths-lecturer friend seemed to think it scaled quadratically, although we were in the pub at the time). However, it's an interesting alternative approach.
Anyway, I'll post the magazine article here when it's published, probably in February - might be an interesting (and less daunting) way into the PolyMod project than building a big eight-module synth.
Oh, and the MIDI input works really well - I borrowed the code and circuit from the official Teensy site: https://www.pjrc.com/teensy/td_libs_MIDI.html
I'm sitting by the fire with my very old cat, writing some preliminary code for PolyMod 2. It's going pretty well thus far - starting from scratch but being able to refer to the old code is very freeing. Here's a summary of what I've been up to:
Case design: I'm trying to emphasise a no-fuss approach to the case design, keeping everything as simple, sturdy, and uncontroversial as possible. With this in mind, I think I'm going to base the main body around a pre-made aluminium box. This one (Hammond 1444-32) looks like a good candidate, and is only about £25. This box would be used upside down. Most of the top surface will be filled with modules (see below), and the rest will be either 3D printed (for the prototype) or possibly cut from aluminium for the final thing. A plywood box would work fine, too. To clarify, this design will be roughly the size and shape of a MicroKorg, rather than the retro angled Minimoog shape of the first PolyMod.
Module physical design: the first PolyMod used modules with circuit boards mounted (precariously) at right-angles to the face-plate. Since I'm going to be using PCBs rather than stripboard this time, I can make better use of the space and mount the circuit boards flat behind the face-plates. The current plan is to base the module size on a 12HP Eurorack module. Obviously the digital PolyMod system is incompatible with the analog Eurorack system, but I can't think of a good reason to diverge from the Eurorack sizing standard right now. The face-plates will probably be 3D printed for the prototype and maybe cut from aluminium for the real thing. I'm toying with the idea of a push-fit (friction) module system, rather than the thumb screws I used before. I'm also considering the idea of removable card labels for the module face-plates, since the modules will no longer have a fixed "identity" (a module with three knobs, six sockets and an LED will happily be able to function as either an LFO or a VCO, for instance). Whether I can make this idea aesthetically pleasing is an open question.
Module features: the previous PolyMod's modules could handle eight sockets and eight knobs. The new ones should be able to handle eight sockets, eight knobs, loads of LEDs (via a shift register), and either loads of switches/buttons (via a shift register) or an extra eight knobs. Pretty pleased with this upgrade, although it's currently totally untested.
Menu system: I've started coding a menu system to allow you to save and load patches, with the option of restoring the patch cables. This could get pretty complicated when combined with the modules-can-change-their-identity feature. The display will almost certainly be a standard 16-character, 2-line LCD, because they're cheap and easy to code for. Might have to upgrade to a 4-line display depending on how the UI works out - they're only a couple of quid more.
Module library: one of the more exciting new elements of PolyMod 2 is the public module library, which I've begun coding. The UI is nothing fancy, but so far it's coming along fairly well. It will be optional, though - I'll make sure the default Arduino/Teensy code contains a good basic selection of modules.
Physical keyboard: I'm 99% certain there will be a MIDI input on the synth, but I'm also toying with the idea of a basic physical keyboard. I had given up on doing this again, after the unimpressive clicky keyboard of the first PolyMod, but I've recently discovered a component that I wasn't aware of before (basically a silent version of a tactile button) which may make it relatively easy (famous last words) to implement a simplified keyboard. And if I could somehow make it microtonal with a menu setting... no, keep it simple. Too many possibilities!
More module slots: this feature is on hold for the moment. I may be able to have eight proper slots rather than seven (i.e. the master module won't count), but I don't want to bite off more than I can chew with the next prototype. I'm hoping that I'll find...
Read more »
Create an account to leave a comment. Already have an account? Log In.
Oh that's really cool about the C++ API, does VCV Rack run fast enough on a Pi?
There is a fork for RPi: https://github.com/miRackModular/Rack
I will order a RPi-4 to test it and see how it is running.
If it is ok, I am thinking about adding a REST API to vcvrack for easy access to patch cables and knobs. Then, we can imagine a small program using this interface and implementing the link with HW control panel.
For I/O, my idea is to use low cost MCU with enough I/O to avoid adding multiplexers. One MCU per Eurorack module. PIC MCU is an option. We can also consider Arduino Nano with a price of 3€ per board (pack of 10 boards). Teensy LC, is also ok, but more expensive if we have one per Eurorack module.
Another idea: if the control panel is using MIDI protocol, then it can also be used by other MIDI software, like any MIDI controller.
That's a cool idea, using Arduino Nanos rather than multiplexers. I've got a big bag of them from another project, so I might try something similar. And yes, using MIDI (or OSC?) has occurred to me, too - would be nice to use some sort of open standard.
I am fighting with miRack to run it on my RPi4. As I have no HDMI monitor here, that is not so easy. VNC is not working properly with knobs. And vcxsrv X11 server is quite slow, probably because of OpenGL. But sound is ok for a basic patch.
Also miRack is based on a quite old vcvrack release, so old plugins installation is to be done manually.
I have also tried Pure Data, but looks like the effort to configure a set of standard modules is quite high (for example, ladder filters).
I am now trying sonaremin (https://github.com/hexdump0815/sonaremin). It is based on up-to-date vcvcrack code.
For Arduino Nano, we will need a synch between boards to detect inter-modules connection with scanning. Another option will be to send serial asynchronous encoded ID on the jack output sockets, with one different ID for each socket. On input sockets, by decoding data with a soft UART, we can know the ID of the sending socket, and so identify the connection wire.
Just had some success using three Arduinos connected via I2C (using the Wire library). One Arduino is the main controller, and the other two are acting as modules. Currently each module has four inputs and four outputs, but this could be increased. Works really nicely, hardly any latency :) Thanks for the suggestion! Definitely a better approach than multiplexing.
I need to tidy up the code and add comments, but if you're interested you can check out "fakeserial" and "fakeserialmain" here https://github.com/mattybrad/polymod2/tree/master/experiments/polymodnano
Great progress with I2C. I am wondering if basic scanning will be ok with a large number of modules. For 64 modules, 8 output sockets per module, you will need: 64x8 sequences of 1xI2C write, and 63xI2C read operations to scan all possible connections. So 32,768 I2C operations. With 400 kbit/s I2C and assuming 32 bits per I2C operation, the full scan will take at least 400ms. We can probably design a smart algorithm to decrease the scanning time. Also, the softuart option could be used for faster connection detection.
On my side, I have received a pack of 10 Arduino nano boards.
I have now a vcvrack running in my RPI-4, in 32bit mode. I have used building scripts coming from https://github.com/hexdump0815/vcvrack-dockerbuild-v1
For display, I am using xrdp + RDP session in mRemoteNG. The GUI is not very responsive, but that should not be an issue because the target is headless mode.
I can see a CPU load of about 260% for basic patch. Pretty high for doing almost nothing, but it works. According to some posts, using 64bit mode should reduce the load by 25%.
I have also investigated a little bit mode Pure Data option: by designing subpatch for "standard modules" VCO, LFO, VCF, etc, we could build this modular synth. There is some information about PD dynamic patching here: https://github.com/hexdump0815/vcvrack-dockerbuild-v1
Looks easy for adding new connections dynamically. However, disconnection seems painful. May be the way to go should be to modify PD code to add an API for that.
Need for more experiment to decide between vcvrack or PD.
There is an enhanced version of Pure Data here: https://github.com/agraef/purr-data
And a library of analog-like synth modules here: https://www.automatonism.com/the-software
I am playing with this stuff and the CPU load is only 6% for a basic patch with VCO, LFO and ladder filter.
For integrating the hardware patch panel, instead of trying to dynamically add/delete PD connections, I guess we can find another solution: developing a PD module exposing I/O of a switch matrix driven by the Arduino boards. And then, hard wiring all sound modules I/O to it.
To simplify the wiring of each sound module, we can have one matrix per sound module. The virtual connection between different matrix, and so sound modules, will then be done as a hidden processing based of some sort of shared memory between them. The Arduino will be used to configure dynamically the connection points.
The advantage with this solution is that we do not need to alter PD code. We only have to develop an external module by using an already existing API. The module could be coded in C, and probably any other officially supported language.
In Autonomatonism modules list, I can see some Organelle related ones. May be a starting point to understand how to do that.
Good progress with Pure Data: I have now an implementation of dynamic patching which works well. It includes smooth switching to avoid spurious signal during transitions. Re-written from scratch with a simplified approach, after the analysis of rePatcher and 3dPd code.
OMG, super awesome. I am a beginner and also just found out about the Teensy 4.9, I am looking into a diy project and found yours. Thank you for the updates. I have a question about microcontrollers like teensy and arduino, can you load multiple programs into them??
Become a member to follow this project and never miss any updates
By using our website and services, you expressly agree to the placement of our performance, functionality, and advertising cookies. Learn More
Awesome. I just discovered this nice project!
I am thinking about something very similar.
For the modules, I am considering I2C chips for digital I/O and analog inputs :
MPS23017: 16 x GPIO
ADS7828: 8 x 12bit ADC
So, we can imagine an I2C bus on the Eurorack backplane along with the power supply rails.
On software side, may be vcvrack running in a RPi. There is a C++ API to create/delete wires dynamically:
https://community.vcvrack.com/t/programmatically-add-wires-between-moduels/6567
Update: just discovered some DIP40 MCU with low price
For example PIC18F47Q43 with 36 GPIO, 12bit ADC, and up to 35 analog inputs.
Very flexible and cost effective solution comparing to I2C chips or Teensy LC