Merge branch 'main' into glossing/fmsss
This commit is contained in:
commit
ac3f477f30
6 changed files with 464 additions and 25 deletions
|
|
@ -2414,7 +2414,6 @@ export const { tsdelay } = registerControl('tsdelay');
|
|||
export const { real } = registerControl('real');
|
||||
export const { imag } = registerControl('imag');
|
||||
export const { enhance } = registerControl('enhance');
|
||||
export const { partials } = registerControl('partials');
|
||||
export const { comb } = registerControl('comb');
|
||||
export const { smear } = registerControl('smear');
|
||||
export const { scram } = registerControl('scram');
|
||||
|
|
|
|||
|
|
@ -3624,3 +3624,66 @@ for (const name of distAlgoNames) {
|
|||
return this.distort(argsPat);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a list of patterns into a single pattern which outputs list-values
|
||||
*
|
||||
* @name parray
|
||||
* @returns Pattern
|
||||
*/
|
||||
export const parray = (pats) => {
|
||||
const pack = (...xs) => xs;
|
||||
let acc = pure(curry(pack, null, pats.length));
|
||||
for (const p of pats) acc = acc.appBoth(reify(p));
|
||||
return acc;
|
||||
};
|
||||
|
||||
const _ensureListPattern = (list) => {
|
||||
if (Array.isArray(list)) {
|
||||
return parray(list);
|
||||
}
|
||||
return reify(list);
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale the magnitude of the harmonics of one of the core synths ('sine', 'tri', 'saw', ..)
|
||||
*
|
||||
* Can also be used to create a new synth via `s('user').partials(...)`
|
||||
*
|
||||
* @name partials
|
||||
* @param {number[] | Pattern} magnitudes List of [0, 1] magnitudes for partials. 0th entry is the fundamental harmonic (i.e. DC offset is skipped)
|
||||
* @example
|
||||
* s("user").seg(16).n(irand(8)).scale("A:major")
|
||||
* .partials([1, 0, 1, 0, 0, 1])
|
||||
* @example
|
||||
* s("saw").seg(8).n(irand(12)).scale("G#:minor")
|
||||
* .partials(binaryL(irand(256).add("1")))
|
||||
*/
|
||||
Pattern.prototype.partials = function (list) {
|
||||
return this.withValue((v) => (l) => ({ ...v, partials: l })).appLeft(_ensureListPattern(list));
|
||||
};
|
||||
|
||||
// Also create a top-level function
|
||||
export const partials = (list) => {
|
||||
return _ensureListPattern(list).as('partials');
|
||||
};
|
||||
|
||||
/**
|
||||
* Rotates the harmonics of one of the core synths ('sine', 'tri', 'saw', 'user', ..) by a list of phases
|
||||
*
|
||||
* @name phases
|
||||
* @param {number[] | Pattern} phases List of [0, 1) phases for partials. 0th entry is the fundamental phase (i.e. DC offset is skipped)
|
||||
* @example
|
||||
* // Phase cancellation
|
||||
* s("saw").seg(8).n(irand(12)).scale("G#1:minor")
|
||||
* .partials(partials([1, 1, 1]))
|
||||
* .superimpose(x => x.phases([0.5, 0.5, 0.5]))
|
||||
*/
|
||||
Pattern.prototype.phases = function (list) {
|
||||
return this.withValue((v) => (l) => ({ ...v, phases: l })).appLeft(_ensureListPattern(list));
|
||||
};
|
||||
|
||||
// Also create a top-level function
|
||||
export const phases = (list) => {
|
||||
return _ensureListPattern(list).as('phases');
|
||||
};
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
|
|||
export const run = (n) => saw.range(0, n).round().segment(n);
|
||||
|
||||
/**
|
||||
* Creates a pattern from a binary number.
|
||||
* Creates a binary pattern from a number.
|
||||
*
|
||||
* @name binary
|
||||
* @param {number} n - input number to convert to binary
|
||||
|
|
@ -242,7 +242,7 @@ export const binary = (n) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates a pattern from a binary number, padded to n bits long.
|
||||
* Creates a binary pattern from a number, padded to n bits long.
|
||||
*
|
||||
* @name binaryN
|
||||
* @param {number} n - input number to convert to binary
|
||||
|
|
@ -258,6 +258,51 @@ export const binaryN = (n, nBits = 16) => {
|
|||
return reify(n).segment(nBits).brshift(bitPos).band(pure(1));
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a binary list pattern from a number.
|
||||
*
|
||||
* @name binaryL
|
||||
* @param {number} n - input number to convert to binary
|
||||
* s("saw").seg(8)
|
||||
* .partials(binaryL(irand(4096).add(1)))
|
||||
*/
|
||||
export const binaryL = (n) => {
|
||||
const nBits = reify(n).log2(0).floor().add(1);
|
||||
return binaryNL(n, nBits);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a binary list pattern from a number, padded to n bits long.
|
||||
*
|
||||
* @name binaryNL
|
||||
* @param {number} n - input number to convert to binary
|
||||
* @param {number} nBits - pattern length, defaults to 16
|
||||
*/
|
||||
export const binaryNL = (n, nBits = 16) => {
|
||||
return reify(n)
|
||||
.withValue((v) => (bits) => {
|
||||
const bList = [];
|
||||
for (let i = bits - 1; i >= 0; i--) {
|
||||
bList.push((v >> i) & 1);
|
||||
}
|
||||
return bList;
|
||||
})
|
||||
.appLeft(reify(nBits));
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a list of random numbers of the given length
|
||||
*
|
||||
* @name randL
|
||||
* @param {number} n Number of random numbers to sample
|
||||
* @example
|
||||
* s("saw").seg(16).n(irand(12)).scale("F1:minor")
|
||||
* .partials(randL(8))
|
||||
*/
|
||||
export const randL = (n) => {
|
||||
return signal((t) => (nVal) => timeToRands(t, nVal).map(Math.abs)).appLeft(reify(n));
|
||||
};
|
||||
|
||||
export const randrun = (n) => {
|
||||
return signal((t) => {
|
||||
// Without adding 0.5, the first cycle is always 0,1,2,3,...
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue