diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 7e82ec44..381bef06 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -311,6 +311,10 @@ export class Pattern { return this.mul(max - min).add(min); } + rangex(min, max) { + return this.range(Math.log(min), Math.log(max)).fmap(Math.exp); + } + // Assumes source pattern of numbers in range -1..1 range2(min, max) { return this._fromBipolar().range(min, max); @@ -611,6 +615,10 @@ export class Pattern { return new Pattern(query)._splitQueries(); } + palindrome() { + return this.every(2, rev); + } + juxBy(by, func) { by /= 2; const elem_or = function (dict, key, dflt) { diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index fd924cbc..a2f0e4e4 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -1,6 +1,7 @@ import { Hap } from './hap.mjs'; import { Pattern, fastcat, reify, silence } from './pattern.mjs'; import Fraction from './fraction.mjs'; +import { id } from './util.mjs'; export function steady(value) { // A continuous value @@ -29,6 +30,8 @@ export const square2 = square._toBipolar(); export const tri = fastcat(isaw, saw); export const tri2 = fastcat(isaw2, saw2); +export const time = signal(id); + // random signals const xorwise = (x) => { @@ -75,3 +78,13 @@ export const chooseWith = (pat, xs) => { }; export const choose = (...xs) => chooseWith(rand, xs); + +export const perlinWith = (pat) => { + const pata = pat.fmap(Math.floor); + const patb = pat.fmap((t) => Math.floor(t) + 1); + const smootherStep = (x) => 6.0 * x ** 5 - 15.0 * x ** 4 + 10.0 * x ** 3; + const interp = (x) => (a) => (b) => a + smootherStep(x) * (b - a); + return pat.sub(pata).fmap(interp).appBoth(pata.fmap(timeToRand)).appBoth(patb.fmap(timeToRand)); +}; + +export const perlin = perlinWith(time); diff --git a/packages/core/util.mjs b/packages/core/util.mjs index 2de7a8e6..5ec88125 100644 --- a/packages/core/util.mjs +++ b/packages/core/util.mjs @@ -60,6 +60,7 @@ export const removeUndefineds = (xs) => xs.filter((x) => x != undefined); export const flatten = (arr) => [].concat(...arr); export const id = (a) => a; +export const constant = (a, b) => a; export const listRange = (min, max) => Array.from({ length: max - min + 1 }, (_, i) => i + min);