diff --git a/repl/src/tunes.ts b/repl/src/tunes.ts index f5855fcf..0eff5997 100644 --- a/repl/src/tunes.ts +++ b/repl/src/tunes.ts @@ -637,3 +637,34 @@ stack( "mad".slow(2).tone(breaks) ).cpm(78).slow(4).pianoroll() `; + +export const goodTimes = `const scale = slowcat('C3 dorian','Bb2 major').slow(4); +stack( + "2*4".add(12).scale(scale) + .off(1/8,x=>x.scaleTranspose("2")).fast(2) + .scaleTranspose("<0 1 2 1>").hush(), + "<0 1 2 3>(3,8,2)" + .scale(scale) + .off(1/4,x=>x.scaleTranspose("2,4")), + "<0 4>(5,8)".scale(scale).transpose(-12) +) + .velocity(".6 .7".fast(4)) + .legato("2") + .scale(scale) +.scaleTranspose("<0>".slow(4)) +.tone((await piano()).chain(out())) +//.midi() +.velocity(.8) +.transpose(5) +.slow(2) +.pianoroll({maxMidi:100,minMidi:20})`; + +export const echoPiano = `"<0 2 [4 6](3,4,1) 3*2>" +.scale('D minor') +.color('salmon') +.off(1/4, x=>x.scaleTranspose(2).color('green')) +.off(1/2, x=>x.scaleTranspose(6).color('steelblue')) +.legato(.5) +.echo(4, 1/8, .5) +.tone((await piano()).chain(out())) +.pianoroll()`; diff --git a/strudel.mjs b/strudel.mjs index 8cf90e0f..38e3afcf 100644 --- a/strudel.mjs +++ b/strudel.mjs @@ -733,12 +733,12 @@ class Pattern { } // these might change with: https://github.com/tidalcycles/Tidal/issues/902 - echoWith(times, time, func) { + _echoWith(times, time, func) { return stack(...range(0, times - 1).map((i) => func(this.late(i * time), i))); } - echo(times, time, feedback) { - return this.echoWith(times, time, (pat, i) => pat.velocity(Math.pow(feedback, i))); + _echo(times, time, feedback) { + return this._echoWith(times, time, (pat, i) => pat.velocity(Math.pow(feedback, i))); } iter(times) { @@ -1000,6 +1000,19 @@ export function makeComposable(func) { return func; } +const patternify2 = (f) => (pata, patb, pat) => pata.fmap(a => b => f.call(pat, a, b)).appLeft(patb).outerJoin() +const patternify3 = (f) => (pata, patb, patc, pat) => pata.fmap(a => b => c => f.call(pat, a, b, c)).appLeft(patb).appLeft(patc).outerJoin() +const patternify4 = (f) => (pata, patb, patc, patd, pat) => pata.fmap(a => b => c => d => f.call(pat, a, b, c, d)).appLeft(patb).appLeft(patc).appLeft(patd).outerJoin() + +Pattern.prototype.echo = function (...args) { + args = args.map(reify); + return patternify3(Pattern.prototype._echo)(...args, this); +}; +Pattern.prototype.echoWith = function (...args) { + args = args.map(reify); + return patternify3(Pattern.prototype._echoWith)(...args, this); +}; + // call this after all Patter.prototype.define calls have been executed! (right before evaluate) Pattern.prototype.bootstrap = function() { // makeComposable(Pattern.prototype);