Reactive-balsa is a live MIDI event processor based on the Reactive-banana framework and ALSA. (Thus it is currently bound to Linux.) It is the successor of the package StreamEd, that uses a kind of arrow types.
The MIDI event processor can be used for accompaniment, gags, games and more. It is usually inserted between a MIDI input device such as a USB piano keyboard and a MIDI controlled synthesizer, say an internal software synthesizer or an external hardware synthesizer.
Some of the included examples:
- split keyboard
- map key to filter frequency
- arpeggiator: play a pattern according to pressed keys
- generate a beat with controllable tempo
- instrument cycling: every note is played with a different instrument
- LFO-controlled change of MIDI controllers
- simulate playing chords on a guitar
- interval recognition trainer
- keyboard with mirrored order of keys: perfect support for lefties :-)
The functional reactive programming paradigm has precisely the right abstractions that we need for MIDI event processing:
- Events are discrete MIDI events for key press and release, knob turning and fader move, instrument change,
- Behaviours are things like current position of a knob or fader or the set of currently pressed keys.
This becomes especially useful for the arpeggiator. There are several ways to obtain a set of keys:
- The actual set of pressed keys.
- Latched keys: Every key press toggles between press and release
- Group latched keys: A chord is hold until a new chord is played.
- Serial latch: A queue of fixed length holds pressed keys. Newly pressed keys release old keys.
And there are many ways to generate MIDI events from a set of keys:
- cycle them up or down, or play them in ping-pong mode,
- play them randomly,
- play algorithmic patterns, like de-Bruijn sequences or k-nary cross sums, Gray codes or Johnson-Trotter-permutations,
- play the set of keys with random inversions.
The reactive-banana framework enforces the distinction between processes that react only to input events (like reversed keyboard, split keyboard, transposition) and processes that can generate events by themselves (like beat generator, LFO). The first kind of processes is represented by non-monadic functions, whereas the second kind needs to run in the
NetworkDescription monad. It turns out that this distinction is useful when it comes to MIDI controlled switches between MIDI processors: There is a canonical way to suspend and resume the first kind of processes, they do not need computations while at rest. For the second kind of processes there are multiple ways how to treat them when suspended.