I use Pmono
a lot, but I find that it has a number of shortcomings. There’s a simple API problem, where it expects the instrument name as the first argument - this makes it not match Pbind
, and additionally makes it VERY hard to use Pmono
with any event type where the instrument is determined programmatically (for example, I’ve got lots of buffer-playback SynthDefs that have different versions for different channel counts - I’ll choose these based on an event parameter, but this doesn’t work easily with Pmono).
I also find that Pmono does some very weird and disruptive things from time to time - when using it with chained Pdef
s, it can sometimes just kill and restart your monophonic synths because upstream Pdefs have changed. And in general, it’s hard to figure out these problems because the internals of Pmono are a bit arcane and over-complicated.
To work around a few of these problems the other day, I tried to re-implement it from scratch, as a simple Event stream transformation that:
- Sends the first event without an explicit end event or gate,
- Transforms every event after that into a
\set
event.
It’s simple, works well with Pbind, and doesn’t event require a lot of code or infrastructure. It could easily be adapted to conditionally provide PmonoArtic
behavior as well. I thought I’d post it, in case anyone else wants to test or needs to workaround Pmono problems.
There may be holes or bugs in this approach, but so far it’s solved three or four of the things that were troubling me on this project with no downsides. The code is dirt-simple (and could be simplified more).
Usage:
Pbind.mono(
\instrument, \default,
\dur, 1/12,
\scale, Scale.aeolian,
\degree, Pwhite(0, 12) + [0, 2],
).play
(Pmonophonic() <> Pbind(
\instrument, \default,
\dur, 1/12,
\scale, Scale.aeolian,
\degree, Pwhite(0, 12) + [0, 2],
)).play