mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-25 20:48:27 +00:00
Merge remote-tracking branch 'origin/HEAD' into talk-fixes
This commit is contained in:
commit
655a9ff1a4
@ -47,7 +47,6 @@ export const sine2 = signal((t) => Math.sin(Math.PI * 2 * t));
|
|||||||
*/
|
*/
|
||||||
export const sine = sine2._fromBipolar();
|
export const sine = sine2._fromBipolar();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cosine signal between 0 and 1.
|
* A cosine signal between 0 and 1.
|
||||||
*
|
*
|
||||||
@ -59,7 +58,6 @@ export const sine = sine2._fromBipolar();
|
|||||||
export const cosine = sine._early(Fraction(1).div(4));
|
export const cosine = sine._early(Fraction(1).div(4));
|
||||||
export const cosine2 = sine2._early(Fraction(1).div(4));
|
export const cosine2 = sine2._early(Fraction(1).div(4));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A square signal between 0 and 1.
|
* A square signal between 0 and 1.
|
||||||
*
|
*
|
||||||
@ -112,7 +110,14 @@ const timeToRandsPrime = (seed, n) => {
|
|||||||
|
|
||||||
const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
|
const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A continuous pattern of random numbers, between 0 and 1
|
||||||
|
*/
|
||||||
export const rand = signal(timeToRand);
|
export const rand = signal(timeToRand);
|
||||||
|
/**
|
||||||
|
* A continuous pattern of random numbers, between -1 and 1
|
||||||
|
*/
|
||||||
|
export const rand2 = rand._toBipolar();
|
||||||
|
|
||||||
export const _brandBy = (p) => rand.fmap((x) => x < p);
|
export const _brandBy = (p) => rand.fmap((x) => x < p);
|
||||||
export const brandBy = (pPat) => reify(pPat).fmap(_brandBy).innerJoin();
|
export const brandBy = (pPat) => reify(pPat).fmap(_brandBy).innerJoin();
|
||||||
@ -121,19 +126,67 @@ export const brand = _brandBy(0.5);
|
|||||||
export const _irand = (i) => rand.fmap((x) => Math.trunc(x * i));
|
export const _irand = (i) => rand.fmap((x) => Math.trunc(x * i));
|
||||||
export const irand = (ipat) => reify(ipat).fmap(_irand).innerJoin();
|
export const irand = (ipat) => reify(ipat).fmap(_irand).innerJoin();
|
||||||
|
|
||||||
export const chooseWith = (pat, xs) => {
|
export const __chooseWith = (pat, xs) => {
|
||||||
xs = xs.map(reify);
|
xs = xs.map(reify);
|
||||||
if (xs.length == 0) {
|
if (xs.length == 0) {
|
||||||
return silence;
|
return silence;
|
||||||
}
|
}
|
||||||
return pat
|
return pat.range(0, xs.length).fmap((i) => xs[Math.floor(i)]);
|
||||||
.range(0, xs.length)
|
};
|
||||||
.fmap((i) => xs[Math.floor(i)])
|
/**
|
||||||
.outerJoin();
|
* Choose from the list of values (or patterns of values) using the given
|
||||||
|
* pattern of numbers, which should be in the range of 0..1
|
||||||
|
* @param {Pattern} pat
|
||||||
|
* @param {*} xs
|
||||||
|
* @returns {Pattern}
|
||||||
|
*/
|
||||||
|
export const chooseWith = (pat, xs) => {
|
||||||
|
return __chooseWith(pat, xs).outerJoin();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As with {chooseWith}, but the structure comes from the chosen values, rather
|
||||||
|
* than the pattern you're using to choose with.
|
||||||
|
* @param {Pattern} pat
|
||||||
|
* @param {*} xs
|
||||||
|
* @returns {Pattern}
|
||||||
|
*/
|
||||||
|
export const chooseInWith = (pat, xs) => {
|
||||||
|
return __chooseWith(pat, xs).innerJoin();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chooses randomly from the given list of values.
|
||||||
|
* @param {...any} xs
|
||||||
|
* @returns {Pattern} - a continuous pattern.
|
||||||
|
*/
|
||||||
export const choose = (...xs) => chooseWith(rand, xs);
|
export const choose = (...xs) => chooseWith(rand, xs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chooses from the given list of values (or patterns of values), according
|
||||||
|
* to the pattern that the method is called on. The pattern should be in
|
||||||
|
* the range 0 .. 1.
|
||||||
|
* @param {...any} xs
|
||||||
|
* @returns {Pattern}
|
||||||
|
*/
|
||||||
|
Pattern.prototype.choose = function (...xs) {
|
||||||
|
return chooseWith(this, xs);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As with choose, but the pattern that this method is called on should be
|
||||||
|
* in the range -1 .. 1
|
||||||
|
* @param {...any} xs
|
||||||
|
* @returns {Pattern}
|
||||||
|
*/
|
||||||
|
Pattern.prototype.choose2 = function (...xs) {
|
||||||
|
return chooseWith(this._fromBipolar(), xs);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const chooseCycles = (...xs) => chooseInWith(rand.segment(1), xs);
|
||||||
|
|
||||||
|
export const randcat = chooseCycles;
|
||||||
|
|
||||||
const _wchooseWith = function (pat, ...pairs) {
|
const _wchooseWith = function (pat, ...pairs) {
|
||||||
const values = pairs.map((pair) => reify(pair[0]));
|
const values = pairs.map((pair) => reify(pair[0]));
|
||||||
const weights = [];
|
const weights = [];
|
||||||
|
|||||||
@ -22,10 +22,14 @@ Pattern.prototype.pianoroll = function ({
|
|||||||
flipTime = 0,
|
flipTime = 0,
|
||||||
flipValues = 0,
|
flipValues = 0,
|
||||||
hideNegative = false,
|
hideNegative = false,
|
||||||
inactive = '#C9E597',
|
// inactive = '#C9E597',
|
||||||
|
// inactive = '#FFCA28',
|
||||||
|
inactive = '#7491D2',
|
||||||
active = '#FFCA28',
|
active = '#FFCA28',
|
||||||
// background = '#2A3236',
|
// background = '#2A3236',
|
||||||
background = 'transparent',
|
background = 'transparent',
|
||||||
|
smear = 0,
|
||||||
|
playheadColor = 'white',
|
||||||
minMidi = 10,
|
minMidi = 10,
|
||||||
maxMidi = 90,
|
maxMidi = 90,
|
||||||
autorange = 0,
|
autorange = 0,
|
||||||
@ -58,12 +62,14 @@ Pattern.prototype.pianoroll = function ({
|
|||||||
flipTime && timeRange.reverse();
|
flipTime && timeRange.reverse();
|
||||||
flipValues && valueRange.reverse();
|
flipValues && valueRange.reverse();
|
||||||
|
|
||||||
const playheadPosition = scale(-from / timeExtent, ...timeRange);
|
|
||||||
this.draw(
|
this.draw(
|
||||||
(ctx, events, t) => {
|
(ctx, events, t) => {
|
||||||
ctx.fillStyle = background;
|
ctx.fillStyle = background;
|
||||||
ctx.clearRect(0, 0, w, h);
|
ctx.globalAlpha = 1; // reset!
|
||||||
ctx.fillRect(0, 0, w, h);
|
if (!smear) {
|
||||||
|
ctx.clearRect(0, 0, w, h);
|
||||||
|
ctx.fillRect(0, 0, w, h);
|
||||||
|
}
|
||||||
const inFrame = (event) =>
|
const inFrame = (event) =>
|
||||||
(!hideNegative || event.whole.begin >= 0) && event.whole.begin <= t + to && event.whole.end >= t + from;
|
(!hideNegative || event.whole.begin >= 0) && event.whole.begin <= t + to && event.whole.end >= t + from;
|
||||||
events.filter(inFrame).forEach((event) => {
|
events.filter(inFrame).forEach((event) => {
|
||||||
@ -71,15 +77,6 @@ Pattern.prototype.pianoroll = function ({
|
|||||||
ctx.fillStyle = event.context?.color || inactive;
|
ctx.fillStyle = event.context?.color || inactive;
|
||||||
ctx.strokeStyle = event.context?.color || active;
|
ctx.strokeStyle = event.context?.color || active;
|
||||||
ctx.globalAlpha = event.context.velocity ?? 1;
|
ctx.globalAlpha = event.context.velocity ?? 1;
|
||||||
ctx.beginPath();
|
|
||||||
if (vertical) {
|
|
||||||
ctx.moveTo(0, playheadPosition);
|
|
||||||
ctx.lineTo(valueAxis, playheadPosition);
|
|
||||||
} else {
|
|
||||||
ctx.moveTo(playheadPosition, 0);
|
|
||||||
ctx.lineTo(playheadPosition, valueAxis);
|
|
||||||
}
|
|
||||||
ctx.stroke();
|
|
||||||
const timePx = scale((event.whole.begin - (flipTime ? to : from)) / timeExtent, ...timeRange);
|
const timePx = scale((event.whole.begin - (flipTime ? to : from)) / timeExtent, ...timeRange);
|
||||||
let durationPx = scale(event.duration / timeExtent, 0, timeAxis);
|
let durationPx = scale(event.duration / timeExtent, 0, timeAxis);
|
||||||
const value = getValue(event);
|
const value = getValue(event);
|
||||||
@ -107,6 +104,19 @@ Pattern.prototype.pianoroll = function ({
|
|||||||
}
|
}
|
||||||
isActive ? ctx.strokeRect(...coords) : ctx.fillRect(...coords);
|
isActive ? ctx.strokeRect(...coords) : ctx.fillRect(...coords);
|
||||||
});
|
});
|
||||||
|
ctx.globalAlpha = 1; // reset!
|
||||||
|
const playheadPosition = scale(-from / timeExtent, ...timeRange);
|
||||||
|
// draw playhead
|
||||||
|
ctx.strokeStyle = playheadColor;
|
||||||
|
ctx.beginPath();
|
||||||
|
if (vertical) {
|
||||||
|
ctx.moveTo(0, playheadPosition);
|
||||||
|
ctx.lineTo(valueAxis, playheadPosition);
|
||||||
|
} else {
|
||||||
|
ctx.moveTo(playheadPosition, 0);
|
||||||
|
ctx.lineTo(playheadPosition, valueAxis);
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: from - overscan,
|
from: from - overscan,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user