gogins / cloud-5

Complete browser-based computer music studio for algorithmic composition and live coding
Other
9 stars 1 forks source link

Add a Pattern to output simultaneous notes from CsoundAC Chord objects #51

Closed gogins closed 1 year ago

gogins commented 1 year ago

Useful with Chords, Scales, and PITV. Should take a Chord as a stateful parameter, and as a Pattern, emit a stack of the notes comprising the chord.

gogins commented 1 year ago

This is how Strudel does this sort of thing:

export const voicing = register('voicing', function (pat) {
  return pat
    .fmap((value) => {
      // destructure voicing controls out
      value = typeof value === 'string' ? { chord: value } : value;
      let { dictionary = 'default', chord, anchor, offset, mode, n, octaves, ...rest } = value;
      dictionary =
        typeof dictionary === 'string' ? voicingRegistry[dictionary] : { dictionary, mode: 'below', anchor: 'c5' };
      let notes = renderVoicing({ ...dictionary, chord, anchor, offset, mode, n, octaves });
      return stack(...notes)
        .note()
        .set(rest); // rest does not include voicing controls anymore!
    })
    .outerJoin();
});

I'll debug this to see what's actually going on.

gogins commented 1 year ago

OK, in Strudel a JavaScript array of note names with octaves (here notes) is passed to the stack function, and the resulting Pattern is chained to note and then to set(rest). The set of Patterns is chained to outerJoin in order to return a single Pattern.

I'll see if I can get this to work with MIDI key numbers instead of note names with octaves; if not, I'll convert them.

I will try adding a new Pattern ChordPatterns.acCN that will do this.

gogins commented 1 year ago

I will try to use ref for this:

let _mouseX=0.5,_mouseY=0.5;
document.onmousemove = (e) => {
  _mouseX = e.clientX/document.body.clientWidth;
  _mouseY = e.clientY/document.body.clientHeight;
}
let mouseX = ref(() => _mouseX)
let mouseY = ref(() => _mouseY)
stack(
  s("hh*8")
  .speed(mouseX.range(.5,1))
  .gain(mouseY), 
)

Here a Chord instance will take the place of the mouse location state, and ref will get that state into a Pattern.

gogins commented 1 year ago

Rather than doing this, I added PitvPatterns.acPVV which takes a pattern of voice indexes, which can be a mini-notation stack, e.g. "0, 1, 2, 3" for the four voices of a seventh chord.

This may or may not suffice, but it is enough to move forward.