- clip now works like legato in tidal

- supports floats
- hap.duration now respects clip value
- hap.endClipped is now end*clip
- visualizations show clipped length
- clip(0) will now be silence
This commit is contained in:
Felix Roos 2023-06-12 22:39:32 +02:00
parent e4a35fdd72
commit 8c9e06c329
5 changed files with 11 additions and 7 deletions

View file

@ -133,7 +133,7 @@ export class StrudelMirror {
this.code = initialCode; this.code = initialCode;
this.drawer = new Drawer((haps, time) => { this.drawer = new Drawer((haps, time) => {
const currentFrame = haps.filter((hap) => time >= hap.whole.begin && time <= hap.whole.end); const currentFrame = haps.filter((hap) => time >= hap.whole.begin && time <= hap.endClipped);
this.highlight(currentFrame); this.highlight(currentFrame);
onDraw?.(haps, time, currentFrame); onDraw?.(haps, time, currentFrame);
}, drawTime); }, drawTime);

View file

@ -32,7 +32,11 @@ export class Hap {
} }
get duration() { get duration() {
return this.whole.end.sub(this.whole.begin); return this.whole.end.sub(this.whole.begin).mul(typeof this.value?.clip === 'number' ? this.value?.clip : 1);
}
get endClipped() {
return this.whole.begin.add(this.duration);
} }
wholeOrPart() { wholeOrPart() {

View file

@ -83,9 +83,9 @@ Pattern.prototype.pianoroll = function ({
ctx.fillRect(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.endClipped >= t + from;
events.filter(inFrame).forEach((event) => { events.filter(inFrame).forEach((event) => {
const isActive = event.whole.begin <= t && event.whole.end > t; const isActive = event.whole.begin <= t && event.endClipped > t;
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 ?? event.value?.gain ?? 1; ctx.globalAlpha = event.context.velocity ?? event.value?.gain ?? 1;

View file

@ -17,7 +17,7 @@ function useHighlighting({ view, pattern, active, getTime }) {
const begin = Math.max(lastEnd.current ?? audioTime, audioTime - 1 / 10, -0.01); // negative time seems buggy const begin = Math.max(lastEnd.current ?? audioTime, audioTime - 1 / 10, -0.01); // negative time seems buggy
const span = [round(begin), round(audioTime + 1 / 60)]; const span = [round(begin), round(audioTime + 1 / 60)];
lastEnd.current = span[1]; lastEnd.current = span[1];
highlights.current = highlights.current.filter((hap) => hap.whole.end > audioTime); // keep only highlights that are still active highlights.current = highlights.current.filter((hap) => hap.endClipped > audioTime); // keep only highlights that are still active
const haps = pattern.queryArc(...span).filter((hap) => hap.hasOnset()); const haps = pattern.queryArc(...span).filter((hap) => hap.hasOnset());
highlights.current = highlights.current.concat(haps); // add potential new onsets highlights.current = highlights.current.concat(haps); // add potential new onsets
view.dispatch({ effects: setHighlights.of({ haps: highlights.current }) }); // highlight all still active + new active haps view.dispatch({ effects: setHighlights.of({ haps: highlights.current }) }); // highlight all still active + new active haps

View file

@ -170,7 +170,7 @@ export async function onTriggerSample(t, value, onended, bank) {
nudge = 0, // TODO: is this in seconds? nudge = 0, // TODO: is this in seconds?
cut, cut,
loop, loop,
clip = 0, // if 1, samples will be cut off when the hap ends clip = undefined, // if 1, samples will be cut off when the hap ends
n = 0, n = 0,
note, note,
speed = 1, // sample playback speed speed = 1, // sample playback speed
@ -232,7 +232,7 @@ export async function onTriggerSample(t, value, onended, bank) {
out.disconnect(); out.disconnect();
onended(); onended();
}; };
const stop = (endTime, playWholeBuffer = !clip) => { const stop = (endTime, playWholeBuffer = [undefined, false, null].includes(clip)) => {
let releaseTime = endTime; let releaseTime = endTime;
if (playWholeBuffer) { if (playWholeBuffer) {
releaseTime = t + (end - begin) * bufferDuration; releaseTime = t + (end - begin) * bufferDuration;