mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-25 04:28:30 +00:00
Merge remote-tracking branch 'origin/main' into some-tunes
This commit is contained in:
commit
50f88798d8
@ -63,6 +63,17 @@ export class Pattern {
|
|||||||
return new Pattern((state) => this.query(state.withSpan(func)));
|
return new Pattern((state) => this.query(state.withSpan(func)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withQuerySpanMaybe(func) {
|
||||||
|
const pat = this;
|
||||||
|
return new Pattern((state) => {
|
||||||
|
const newState = state.withSpan(func);
|
||||||
|
if (!newState.span) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return pat.query(newState);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* As with {@link Pattern#withQuerySpan}, but the function is applied to both the
|
* As with {@link Pattern#withQuerySpan}, but the function is applied to both the
|
||||||
* begin and end time of the query timespan.
|
* begin and end time of the query timespan.
|
||||||
@ -744,12 +755,17 @@ export class Pattern {
|
|||||||
// // there is no gap.. so maybe revert to _fast?
|
// // there is no gap.. so maybe revert to _fast?
|
||||||
// return this._fast(factor)
|
// return this._fast(factor)
|
||||||
// }
|
// }
|
||||||
|
// A bit fiddly, to drop zero-width queries at the start of the next cycle
|
||||||
const qf = function (span) {
|
const qf = function (span) {
|
||||||
const cycle = span.begin.sam();
|
const cycle = span.begin.sam();
|
||||||
const begin = cycle.add(span.begin.sub(cycle).mul(factor).min(1));
|
const bpos = span.begin.sub(cycle).mul(factor).min(1);
|
||||||
const end = cycle.add(span.end.sub(cycle).mul(factor).min(1));
|
const epos = span.end.sub(cycle).mul(factor).min(1);
|
||||||
return new TimeSpan(begin, end);
|
if (bpos >= 1) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return new TimeSpan(cycle.add(bpos), cycle.add(epos));
|
||||||
};
|
};
|
||||||
|
// Also fiddly, to maintain the right 'whole' relative to the part
|
||||||
const ef = function (hap) {
|
const ef = function (hap) {
|
||||||
const begin = hap.part.begin;
|
const begin = hap.part.begin;
|
||||||
const end = hap.part.end;
|
const end = hap.part.end;
|
||||||
@ -765,7 +781,7 @@ export class Pattern {
|
|||||||
);
|
);
|
||||||
return new Hap(newWhole, newPart, hap.value, hap.context);
|
return new Hap(newWhole, newPart, hap.value, hap.context);
|
||||||
};
|
};
|
||||||
return this.withQuerySpan(qf)._withHap(ef)._splitQueries();
|
return this.withQuerySpanMaybe(qf)._withHap(ef)._splitQueries();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compress each cycle into the given timespan, leaving a gap
|
// Compress each cycle into the given timespan, leaving a gap
|
||||||
|
|||||||
@ -137,6 +137,9 @@ describe('Pattern', () => {
|
|||||||
it('Can make a pattern', () => {
|
it('Can make a pattern', () => {
|
||||||
expect(pure('hello').query(st(0.5, 2.5)).length).toBe(3);
|
expect(pure('hello').query(st(0.5, 2.5)).length).toBe(3);
|
||||||
});
|
});
|
||||||
|
it('Supports zero-width queries', () => {
|
||||||
|
expect(pure('hello').queryArc(0,0).length).toBe(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('fmap()', () => {
|
describe('fmap()', () => {
|
||||||
it('Can add things', () => {
|
it('Can add things', () => {
|
||||||
@ -430,6 +433,16 @@ describe('Pattern', () => {
|
|||||||
// mini('[c3 g3]/2 eb3') always plays [c3 eb3]
|
// mini('[c3 g3]/2 eb3') always plays [c3 eb3]
|
||||||
// mini('eb3 [c3 g3]/2 ') always plays [c3 g3]
|
// mini('eb3 [c3 g3]/2 ') always plays [c3 g3]
|
||||||
});
|
});
|
||||||
|
it('Supports zero-length queries', () => {
|
||||||
|
expect(steady('a')._slow(1).queryArc(0,0)
|
||||||
|
).toStrictEqual(steady('a').queryArc(0,0))
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('slow()', () => {
|
||||||
|
it('Supports zero-length queries', () => {
|
||||||
|
expect(steady('a').slow(1)._setContext({}).queryArc(0,0)
|
||||||
|
).toStrictEqual(steady('a')._setContext({}).queryArc(0,0))
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('inside', () => {
|
describe('inside', () => {
|
||||||
it('can rev inside a cycle', () => {
|
it('can rev inside a cycle', () => {
|
||||||
|
|||||||
@ -18,6 +18,11 @@ export class TimeSpan {
|
|||||||
const end = this.end;
|
const end = this.end;
|
||||||
const end_sam = end.sam();
|
const end_sam = end.sam();
|
||||||
|
|
||||||
|
// Support zero-width timespans
|
||||||
|
if (begin.equals(end)) {
|
||||||
|
return([new TimeSpan(begin, end)]);
|
||||||
|
}
|
||||||
|
|
||||||
while (end.gt(begin)) {
|
while (end.gt(begin)) {
|
||||||
// If begin and end are in the same cycle, we're done.
|
// If begin and end are in the same cycle, we're done.
|
||||||
if (begin.sam().equals(end_sam)) {
|
if (begin.sam().equals(end_sam)) {
|
||||||
|
|||||||
@ -100,12 +100,8 @@ const getSoundfontKey = (s) => {
|
|||||||
|
|
||||||
const getSampleBufferSource = async (s, n, note, speed) => {
|
const getSampleBufferSource = async (s, n, note, speed) => {
|
||||||
let transpose = 0;
|
let transpose = 0;
|
||||||
let midi;
|
let midi = typeof note === 'string' ? toMidi(note) : note || 36;
|
||||||
|
transpose = midi - 36; // C3 is middle C
|
||||||
if (note !== undefined) {
|
|
||||||
midi = typeof note === 'string' ? toMidi(note) : note;
|
|
||||||
transpose = midi - 36; // C3 is middle C
|
|
||||||
}
|
|
||||||
|
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
// is sample from loaded samples(..)
|
// is sample from loaded samples(..)
|
||||||
@ -128,9 +124,6 @@ const getSampleBufferSource = async (s, n, note, speed) => {
|
|||||||
if (Array.isArray(bank)) {
|
if (Array.isArray(bank)) {
|
||||||
sampleUrl = bank[n % bank.length];
|
sampleUrl = bank[n % bank.length];
|
||||||
} else {
|
} else {
|
||||||
if (!note) {
|
|
||||||
throw new Error('no note(...) set for sound', s);
|
|
||||||
}
|
|
||||||
const midiDiff = (noteA) => toMidi(noteA) - midi;
|
const midiDiff = (noteA) => toMidi(noteA) - midi;
|
||||||
// object format will expect keys as notes
|
// object format will expect keys as notes
|
||||||
const closest = Object.keys(bank)
|
const closest = Object.keys(bank)
|
||||||
|
|||||||
2256
repl/src/prebake.mjs
2256
repl/src/prebake.mjs
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user