💾 Archived View for heavysquare.com › noise › 2018-09-19-hooktheory-workflow.sc.txt captured on 2023-04-19 at 23:12:07.

View Raw

More Information

⬅️ Previous capture (2021-12-03)

-=-=-=-=-=-=-

/*

This session was an attempt to implement the way of "composing" as
per the famous Hooktheory books/videos/hookpad[1], namely (as far as I
vaguely remember):

1. chord progression
2. impose some rhythm on it
3. derive the bass (a simple way: base note of the chord)
4. put melody on it
   (a) harmoric notes are the ones of the chord (+- octaves)
   (b) use other notes in case you need tension, etc.
       (other notes of the scale or even ones out of the scale)

Lessons learnt from this session.

(i) You can have repeatable randomness with Pseed

(ii) As you can see from 1.-4., you design some superstructure and
then derive things from it. Like you design a "parent" pattern from
which you derive children patterns. The parent is not even necessarily
something of a note or notes, it just has some parameters for the
children.  Well, this is Pspawn(pattern).

You could either wait for a child before starting the next one
(after a certain defined, patternable gap) or just give a pattern
of delays between the starts, not waiting.

[1] https://www.hooktheory.com



s.boot;

~triad={|i,scale|[i-1,i+1,i+3].mod(scale.degrees.size)}

(
  SynthDef(\triBass,
    { arg out=0, amp=1, gate=1, freq=110, shift=40;
      var envelope = EnvGen.ar(Env.perc, doneAction: Done.freeSelf);
      Out.ar(out, amp * envelope * LFTri.ar(freq) ! 2)
    }
  ).add;
)

(Pdef(\workflow0,
  Pfindur(16,
    Pseed(4,
      Pcollect({|ev|ev.postln;ev},
      Pspawn(
        Pbind(
          \scale,Pstutter(4,Pseq([Scale.major,Scale.minor],inf)),
          \method,\seq,
          \delta,0,
          \triad,Pseq([1,6,4,5],inf), // chord progression I vi IV V
          \pattern,Pfunc{|e|
            var bar=(1..3).choose;
            var scale=e[\scale];
            var base=e[\triad];
            var chord=~triad.(base,scale);
            Pfindur(bar,
              Ppar([
                Pbind(\dur,bar,\degree,chord,\octave,4), // chord
                Pbind( // bass note
                  \instrument,\triBass,
                  \degree,Prand([\rest,base],inf),
                  \dur,1/4,
                  \octave,3
                ), 
                Pbind( // melody
                  \octave,5,
                  \dur,1/4,
                  \degree,Pwrand(chord++(chord+1)++[\rest],[4,3,2,1,1,1,4].normalizeSum,inf)
                )
              ]) <> Pbind(\scale,scale))
            })))))))

      Pdef(\workflow0).record("/tmp/2018-09-19.wav",headerFormat:"WAV")
      // ffmpeg -i /tmp/2018-09-19.wav -b:a 24k 2018-09-19.mp3