Hey forum - I’ve been writing a writing a number of pieces using Pspawner. I have a pretty ignorant approach to using this class, and despite really liking the results of what I’m writing, I’m finding that managing the amount of code when actually writing out a full composition is surprisingly difficult. Currently, I treat it as a big, linear ‘mono’ routine with a lot of .par() + findur() methods, and giving each section a length (see below)
I’ve also tried splitting out sections and patterns into sub-patterns but IMO it has worse downsides: It is significantly more difficult to manage overlapping sections and transitions, and scrolling to where the pattern definitions are located is annoying.
I’ve actually switched to the vscode extension specifically to manage dealing with this amount of code by collapsing arbitary sections, but still finding it tedious to manage. Is there a better way?
Example piece (this uses a bunch of my own functions, as well as a couple of methods and synthdefs I’ve found off the forums):
(
t = TempoClock.new(180/60).permanent_(true).schedAbs(0, {t.beatsPerBar_(4)});
Pdef(\player,
Pspawner({| sp |
var sectionLength = 72;
//fx const
sp.par(
Pbindf(
Pdef(\miVerb),
\time, 0.8,
\damp, 0.6,
\hp, 0.0,
\freeze, 0,
\diff, 0.9,
\gain, -18,
\out, ~mainout
)
);
//pattern const
Pdef(\mod,
Pmono(\west,
\dec, Pkey(\dur) * 1,
\freq, 30,
\gate, 1,
\glide, 0.01,
\fm1Ratio, 4,
\fm2Ratio, 3,
\fm1Amount, 0.1,
\fm2Amount, 0.1,
\vel, 0.5,
\pressure, ~pmodenv.(Pkey(\groupdelta) * 5, Pkey(\dec)),
\timbre, ~pmodenv.(Pwhite(0, 1), Pkey(\dec)),
\waveShape, 0.25,
\waveFolds, ~pmodenv.(1 - Pkey(\groupdelta), Pkey(\dec)),
\envType, ~pmodenv.(Pseq([0, 1], inf), 4),
\peak, ~pmodenv.(Pwhite(250.0, 15000.0), Pkey(\dec)),
\decay, Pwhite(1, 2),
\pan, Pbrown(-0.5,0.5,0.001),
\amp, 0.5,
\lfoShape, 0,
\lfoFreq, Pkey(\dur),
\lfoToWaveShapeAmount, ~pmodenv.((1 - Pkey(\groupdelta)) * 0.25, Pkey(\dec)),
\lfoToWaveFoldsAmount, ~pmodenv.(Pkey(\groupdelta) * 1, Pkey(\dec)),
\lfoToReverbMixAmount, Pwhite(),
\drift, ~pmodenv.(Pwhite(0, 0.1), Pkey(\dec))
)
);
Pdef(\fb1mod,
Pbind(
\amp, 0.7,
\dec, Pkey(\dur) * 2,
\feedback, ~pmodenv.(Pseq([0.2, 0.4, 0.8] * 0.5,inf), Pkey(\dec)),
\time, ~pmodenv.(Pseq(([0.005, 0.001, 0.010] * 100),inf), Pkey(\dec)),
\damp, ~pmodenv.(Pseq([0.1, 1],inf), Pkey(\dec)),
\exciter, ~pmodenv.(Pwhite(1, 0, inf).lincurve(0, 1, 0, 1, -8), Pkey(\dec), 1, Pseq([\sine],inf)),
\impulse, ~pmodenv.(Pwhite(20000, 200,inf), Pkey(\dec)),
\spont, ~pmodenv.(Pseq([60,1000],inf), Pkey(\dec)),
\boost, ~pmodenv.(Pseq([20000,200],inf), Pkey(\dec)),
\restore, 5,
\dist, ~pmodenv.(Pseq([16, 32],inf), Pkey(\dec)),
\rev, ~pmodenv.(Pexprand(0.1, 4, inf), Pkey(\dec)),
\pan, ~pmodenv.(Pwhite(-0.3, 0.3, inf), Pkey(\dec)),
)
);
Pdef(\kickMod,
Pbind(
// \dur, 1,
\freq, 40.0,
\atk, 0.01,
\dec, Pkey(\groupcount).wrap(1, 2).linlin(1, 2, 0.2, 0.5),
\fb, Pkey(\eventcount) * 0.5,
\index, 1.0,
\ratio, 1.5,
\drive, 5.0,
\sweep, 32.0,
\spread, 2,
\lofreq, 500.0,
\lodb, 10.0,
\midfreq, 1200.0,
\middb, -20.0,
\hifreq, 7000.0,
\hidb, 30.0,
\gain, -15.0,
\pan, 0.0,
\noise, 0.5,
\amp, Pkey(\groupcount).wrap(1, 2).linlin(1,2, 1, 0.7, 1),
)
);
////////////////////////////////////////
\a.postln;
Pdef(\p1,
~makeSubdivision.(
PlaceAll([2.5, 1.5, 1.5, Rest(1)], inf),
PlaceAll([[8, 3], 4, 2, 1, 4], inf)
)
);
sp.par(
Pdef(\west,
Pdef(\mod) <>
~pSkew.(Pdef(\p1), key: Pkey(\eventcount), group: [1, 2, 5], skew: [2, -1], curve: \exp) <>
Pdef(\p1)
<> Pbind(
\instrument, \west,
\out, [~convolve_B]
)
).finDur(sectionLength)
);
sp.par(
Pbindf(
Pdef(\seq3,
Pdef(\fb1mod)
<> ~pSkew.(Pdef(\p1), key: Pkey(\eventcount), group: [1, 2, 5], skew: [2, -1], curve: \exp)
<> Pdef(\p1)
<> Pbind(\instrument, \fb1)
),
\out, [~convolve_A, ~miVerb]
).finDur(sectionLength)
);
sp.par(
Pmono(\fftStretch_magAbove_mono,
\amp, 1,
\gain, 0,
\buf, ~specBuff2.at(\file),
\analysis, [~specBuff2.at(\analysis)],
\fftSize, ~specBuff2.at(\fftSize),
\rate, 0.1,
\pos, 0.3,
// \pos, 0.8,
\len, 0.1,
\filter, ~pmodenv.(Pseq([1, 4],inf), Pseq([4, 8, 4], inf), curve: \sine),
\out, [~convolve_B]
).finDur(sectionLength)
);
sp.par(
Pbindf(
Pmono(\pulsar_mono),
\triggerRate, 16,
\fluxMF, 1.5,
\fluxMD, 0,
\grainFreq, 15,
\overlap, 0.5,
\pmRatio, 100,
\pmIndex, 0.5,
\density, 0.1,
\polarityMod, 0,
\out, [~convolve_B],
\lag, 8
).finDur(sectionLength)
);
sp.par(
Pbind(\amp, 1, \freq, 30)
<>~filterBeat.(key: Pkey(\eventcount), beat:[1], mod:4)
<> ~filterBeat.(key: Pkey(\groupcount), beat:[4], mod: 2)
<>Pdef(\p1)
<>Pbind(\instrument, \simpleSub)
);
sp.par(
Pbindf(
Pdef(\morph),
\gain, -6,
\atk, 0,
\rel, 100,
// \swap, ~pmodenv.(Pseq([0, 1],inf), Pseq([1/2], inf), 1, \sin),
// \swap, ~pmodenv.(Pseq([0, 1],inf), Pseq([1/3], inf), 1, \sin),
\swap, ~pmodenv.(Pseq([0, 1],inf), Pseq([4], inf), 1, \sin),
// \swap, 0,
// \swap, 1,
\out, [~mainout, ~miverb]
).finDur(sectionLength)
);
sp.wait(sectionLength);
//////////////////////////////////////////
\b.postln;
sectionLength = 100;
Pdef(\p1,
~makeSubdivision.(
PlaceAll([2.5, 1.5, 1.5, Rest(1)], inf),
PlaceAll([[8, 3], 4, 2, 1, 4], inf)
)
);
sp.par(
Pdef(\west,
Pbindf(Pdef(\mod), \pitchBendRatio, Pwhite(0.5, 2)) <>
~filterBeat.(key: Pkey(\eventcount), beat:[1, 2, 4]) <>
~pSkew.(Pdef(\p1), key: Pkey(\eventcount), group: [1, 2, 5], skew: [2, -1], curve: \exp) <>
Pdef(\p1)
<> Pbind(
\instrument, \west,
\out, [~convolve_B]
)
).finDur(sectionLength)
);
sp.par(
Pbindf(
Pdef(\seq3,
Pdef(\fb1mod)
<> ~pSkew.(Pdef(\p1), key: Pkey(\eventcount), group: [1, 2, 5], skew: [2, -1], curve: \exp)
<> Pdef(\p1)
<> Pbind(\instrument, \fb1)
),
\out, [~convolve_A, ~miVerb]
).finDur(sectionLength)
);
//fade out last section pad
sp.par(
PfadeOut(
Pmono(\fftStretch_magAbove_mono,
\amp, 1,
\gain, 0,
\buf, ~specBuff2.at(\file),
\analysis, [~specBuff2.at(\analysis)],
\fftSize, ~specBuff2.at(\fftSize),
\rate, 0.1,
\pos, 0.3,
// \pos, 0.8,
\len, 0.1,
\filter, ~pmodenv.(Pseq([1, 4],inf), Pseq([4, 8, 4], inf), curve: \sine),
\out, [~convolve_B]
).finDur(sectionLength)
, 16)
);
sp.par(
PfadeIn(
Pmono(\fftStretch_magAbove_mono,
\amp, 1,
\gain, 0,
\buf, ~specBuff.at(\file),
\analysis, [~specBuff.at(\analysis)],
\fftSize, ~specBuff.at(\fftSize),
\rate, 1,
\pos, 0.3,
// \pos, 0.8,
\len, 0.1,
\filter, ~pmodenv.(Pseq([1, 4],inf), Pseq([4, 8, 4], inf), curve: \sine),
\out, [~convolve_B, ~miverb]
).finDur(sectionLength)
, 12)
);
sp.par(
Pbindf(
Pmono(\pulsar_mono),
\triggerRate, 16,
\fluxMF, 1.5,
\fluxMD, 0,
\grainFreq, 15,
\overlap, 0.5,
\pmRatio, 100,
\pmIndex, 0.5,
\density, 0.9,
\polarityMod, 0,
\out, [~convolve_B],
\lag, 4
).finDur(sectionLength)
);
Pdef(\kickP,
~makeSubdivision.(
PlaceAll([0.75, 1.5, 0.25, 2, 1.5, 2], inf),
PlaceAll([4, 1, 1, 2], inf)
)
);
sp.par(
Pdef(\kickMod)
<> ~pSkew.(Pdef(\kickP), key: Pkey(\eventcount), group: [1,3,4], skew: [1], curve: \exp)
<> Pdef(\kickP)
<>Pbind(
\instrument, \fmKick2,
\out, [~convolve_B, ~grain]
).finDur(sectionLength)
);
sp.par(
Pbindf(
Pdef(\morph),
\gain, -6,
\atk, 0,
\rel, 100,
\swap, ~pmodenv.(Pseq([0, 1],inf), Pseq([4], inf), 1, \sin),
\out, [~mainout, ~miverb]
).finDur(sectionLength)
);
sp.wait(sectionLength);
//////////////////////////////////////////
\c.postln;
\etc......
})
).play(t);
)