Quite on a whim the other week I decided to have another crack at some sort of RPi based digital accessory for a modular synth.
It is quite clear if you read through my previous posts that my original plans are probably feasible, but the tools I chose were hindering more than helping me. Maybe the project goal was also a bit too ambitious and unnecessary.
Building an entire software platform just for a small C++ application is obviously overkill.
Trying to design a system to accept real time external input is complex. Both of the approaches I tried (WiFi and USB device) proved unreliable or required too many moving parts to get something even basically running.
So, instead, what if the device generates it's own data? That removes the need for reliable real time input. What if I instead use the components I already have to construct a basic programmable sequencer? Can I do this using a simpler software stack?
I started drafting a simple sequencer service in python. I made a decision that I would from now on consciously avoid over-engineering any part of this new stack. Just write the minimum core logic. Hard code the configuration for now. Even hard code the sequence pattern. Grab the minimum required code to push some values over i2c to the MCP4728 DAC. It doesn't have to be pretty, it just needs to work.
I ended up with one python source file no longer then a couple of hundred lines, copied it to a downloaded Arch Linux RPi image and ran it. The DAC output danced up and down on the oscilloscope. Blimey, it works. This took a fraction of the time it took me to write the C++ based platform last year.
OK, so this suggests that a simpler system is viable. Granted, it needs a little bit more than I've described above to be a useful device, but this is a start.
I've since refractored the code a little, and made a decision to keep modules as small as possible, and use 0MQ to connect these modules together.
I could write an entire post about how awesome 0MQ is, but I'll restrain myself. Visit the site - http://zeromq.org. There's a variety of socket patterns available which are useful to a project like this.
The result is that my sequencer core is still just as small as the prototype, can run in its own process and can be configured from an external process via a 0MQ socket.
The simplest solution for me to implement the configuration interface is as a web app. This I can write as a small Flask app, which communicates with the core service via 0MQ.
With a little help from systemd unit files and a python fabric fabfile, I can easily deploy these services to my RPi on a basic Arch Linux image.
My code modules are small. The testing and deployment iterations are quick. This makes for a productive development process.
I've still got a fair amount to do (including actually building my own modular synth), but this reboot is far easier to work with. I think I'm much more likely this way to end up with a system which works and will get finished.
The simpleseq code can be found on my bitbucket: http://bitbucket.org/doughammond/simpleseq