h4yn0nnym0u5e
Well-known member
Well lookee here ... it's yet another Teensy-based synth ... or might be, if I ever finish it. But it says "Blog" in the category heading, so this may serve to stimulate discussion if nothing else, and if I'm moved to do so I can report progress as it occurs.
For nearly 4 years now I've been tinkering with Dynamic Audio Objects, that can be created and destroyed at run-time, unlike the existing Teensyduino which can't destroy them without Bad Things happening. I'm not much of an application maker, though, so I've never really done much that's useful with them, but it occurred to me that I should, as a demo to self as much as anything. Hence the following.
In Real Life
In CAD
The hardware consists of:
A few objects are hard-coded into the system at compile time; these are effectively the hardware definition, so in the screen dumps above you see the I²S input on the left, a control object for the SGTL5000, and an I²S output object at the right. They're movable, but can't be deleted. Everything else is created at run-time.
"All very well", I hear you say, "but what about polyphony? That's just a single voice!". Well, yes and no. Objects can be marked as needing to be instantiated per-note, as you can see in the detail dump here - the coloured dots at the top right mark those objects.
The first note you play uses the objects already available, but subsequent notes have a new set of objects and their associated patchcords created at note-on time. Any patchcord coming from a single-instance object is cloned - this might be for a global LFO, for example. Those going out must be connected to a mixer, and there must be an unused input on that mixer, otherwise voice creation fails - you've reached the limit of the available polyphony. You can see the latter above:
Some time after note-off occurs, the voice will become inactive, at which point its objects will be destroyed, unless of course they're the "already available" ones - those are only destroyed during editing, or when you load a different patch from the filesystem.
MIDI commands are accepted from either the PC or via the Host port. Much remains to be done on the MIDI settings side, but the plan is to have all useful settings configurable to any available Continuous Controller, with various mapping curves available, e.g. exponential for envelope times, linear for envelope sustain level, etc. All messages are broadcast to every object, so a single CC can do multiple things if you want. In the future...
Much remains to be done:
If anyone has made a synth they're particularly proud of (I know you're out there...), and wants to drop me a copy of their design as a single voice (i.e. something I can import into the Design Tool), along with an indication of which objects are global and per-voice, plus maybe some settings that they like, I'd love to drop it into this and see if it works OK. I've looked at a few I know of, but disentangling the 1-voice version from the multi-voice one has so far proven too much to bother with
.
For nearly 4 years now I've been tinkering with Dynamic Audio Objects, that can be created and destroyed at run-time, unlike the existing Teensyduino which can't destroy them without Bad Things happening. I'm not much of an application maker, though, so I've never really done much that's useful with them, but it occurred to me that I should, as a demo to self as much as anything. Hence the following.
In Real Life
In CAD
The hardware consists of:
- Teensy 4.1 with 8MB PSRAM; SD card slot accessible through the back of the case
- Teensy USB host cable
- Audio adaptor
- 3.5" ILI9341 TFT screen with XPT2046 touch screen
- M5stack I²C controls
- 8angle: 8 pots, 8 RGB LEDS, 1 switch
- 8encoder: 8 encoders with momentary switches, 8 RGB LEDS, 1 switch
- miscellaneous connectors, some yet to be wired up...
Object placement | Place patchcords | Edit objects (settings and position) |
Modify objects' MIDI settings | Delete objects or patchcords | Filing: save and load patches |
A few objects are hard-coded into the system at compile time; these are effectively the hardware definition, so in the screen dumps above you see the I²S input on the left, a control object for the SGTL5000, and an I²S output object at the right. They're movable, but can't be deleted. Everything else is created at run-time.
"All very well", I hear you say, "but what about polyphony? That's just a single voice!". Well, yes and no. Objects can be marked as needing to be instantiated per-note, as you can see in the detail dump here - the coloured dots at the top right mark those objects.
The first note you play uses the objects already available, but subsequent notes have a new set of objects and their associated patchcords created at note-on time. Any patchcord coming from a single-instance object is cloned - this might be for a global LFO, for example. Those going out must be connected to a mixer, and there must be an unused input on that mixer, otherwise voice creation fails - you've reached the limit of the available polyphony. You can see the latter above:
chor
connects to the first input of mixS
, which defaults to 8 inputs, so this is an 8-note synth. [I haven't implemented it yet, but mixS is a new stereo mixer in the Dynamic Audio Objects, and can be constructed with more than 8 inputs, so I could provide a facility to increase the polyphony].Some time after note-off occurs, the voice will become inactive, at which point its objects will be destroyed, unless of course they're the "already available" ones - those are only destroyed during editing, or when you load a different patch from the filesystem.
MIDI commands are accepted from either the PC or via the Host port. Much remains to be done on the MIDI settings side, but the plan is to have all useful settings configurable to any available Continuous Controller, with various mapping curves available, e.g. exponential for envelope times, linear for envelope sustain level, etc. All messages are broadcast to every object, so a single CC can do multiple things if you want. In the future...
Much remains to be done:
- full implementation of all [relevant] audio objects, complete with internal and MIDI settings
- corner cases like
- loading arbitrary waveforms into
AudioSynthWaveform
objects - implementing
AudioSynthWavetable
objects using samples loaded from SD
- loading arbitrary waveforms into
- make better use of the M5stack LEDs
- fix the annoying ticking due to display activity (probably hardware, that)
- MIDI patch selection, SysEx etc.
- figuring out and implementing a decent sample playback UI
- lots of niggly bugs
- documentation
- stretch goal ... there's no reason this can't be made multi-timbral
just a Small matter Of Programming
If anyone has made a synth they're particularly proud of (I know you're out there...), and wants to drop me a copy of their design as a single voice (i.e. something I can import into the Design Tool), along with an indication of which objects are global and per-voice, plus maybe some settings that they like, I'd love to drop it into this and see if it works OK. I've looked at a few I know of, but disentangling the 1-voice version from the multi-voice one has so far proven too much to bother with