As I tinker with the new PCB and tweak the code to get everything working with it, I've been thinking a lot about what the SquishBox actually is.
For a while now, it's been obvious that there's nothing particularly special about the SquishBox hardware that makes it a FluidPatcher or FluidSynth machine. It's a Raspberry Pi with audio output, MIDI, a little display, an encoder, and some buttons. There's no reason it couldn't run a completely different synthesizer.
I could write Python wrappers for things like AMSynth or setBfree. I could run something like Dexed directly, or use the Hexter DSSI plugin with jack-dssi-host. Pure Data opens up another whole world of possibilities. And those are just the things I've thought of so far.
The more I think about those possibilities, the more obvious it becomes that SquishBox and FluidPatcher need to be separate projects. They basically are already. The SquishBox code has an API for talking to the LCD, reading the encoder and buttons, and doing the other hardware-specific things. My FluidPatcher-based synth imports that code and uses it to turn the SquishBox into an instrument. The idea has always been that someone else could write a different synth or audio application the same way: import the SquishBox code, use its UI, and do whatever interesting audio stuff they want.
The decision to treat the squishbox software as a collection of scripts was made to keep things lightweight and make adoption easier for users that don't touch a lot of code, but it makes it unclear how it's supposed to be used. If somebody wants to experiment with writing their own SquishBox application, where does squishbox.py live so their program can import it? Where do configuration files go? How do you install dependencies? How do you update it when I release a new version?
I had to give in and accept that all that missing machinery is Python packaging. Instead of treating squishbox.py as something that happens to be sitting next to my synth program, SquishBox should be an installable Python library that provides the common interface to the hardware. FluidPatcher should be a separate installable package that provides the audio and synthesis functionality.
That separation also makes sense for FluidPatcher itself. It already has the beginnings of a cross-platform Python synth toolkit, with the Tkinter GUI I've used on desktop Linux and the headless Raspberry Pi version that runs on the SquishBox. It doesn't really need to know that the hardware it's running on happens to have a particular LCD and a couple of buttons attached to it.
So the plan is for SquishBox to become a small Python application framework specifically for the Raspberry Pi. It will provide the pieces needed to build applications around the hardware: the LCD, encoder, buttons, LEDs, and whatever other controls I eventually add. It can also provide some simple helpers for things that are specific to using a Raspberry Pi as an instrument, like managing Wi-Fi, rebooting or shutting down, and running system commands.
Then FluidPatcher can simply be one application that uses that framework.
And once I started thinking about it this way, another question came up: what exactly should that framework do?
It would be possible to turn SquishBox into a general-purpose music workstation. It could start up with a launcher, manage multiple synths, provide global MIDI routing, load plugins, and tie everything together into some kind of unified environment.
There are already projects that take roughly this approach—Zynthian is an obvious example—and they're doing some very cool things.
But I'm not sure that's what I want SquishBox to be.
Part of what I like about the SquishBox is that it doesn't try to make all the decisions for you. I don't want to build a tiny DAW with a complicated architecture that users have to learn before they can write an instrument for it. I want it to be a computer that you can use like an instrument, while still being a computer underneath.
If you want to write a synth for it, you should be able to write a Python program.
If you want to make a sequencer, you should be able to write a Python program.
If you want to make something completely weird that I never anticipated, you should be able to write a Python program.
The SquishBox framework should make that easier, not dictate what you do with it.
That's the direction I'm heading now: SquishBox will provide a relatively thin layer between an application and the hardware, along with a few useful system-level tools. It shouldn't care whether the application is FluidPatcher, AMSynth, a sequencer, a sampler, or something nobody has thought of yet.
This is going to mean some work. There's still a fair amount of unraveling to do to separate FluidPatcher and SquishBox cleanly, and I'll need to turn the existing SquishBox code into something that's actually useful as an API rather than just the guts of my current application.
But I think that separation will also give both projects room to grow.
On the FluidPatcher side, I've been wanting to add more sophisticated router logic—things like logarithmic tapers, counters, and rules that can interact with one another. On the SquishBox side, there are a bunch of hardware/UI features I've wanted for a while: better ways to map MIDI messages to UI events, centralized management of MIDI connections, perhaps text input from a USB keyboard, and more ways for applications to interact with the system.
And the nice thing is that those features no longer all have to live in the same pile of code.
The new PCB has turned out really well. It's more capable, sounds great, and feels much more like the hardware platform I've been imagining all along. I think it deserves software that's similarly clean and flexible.