mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-19 09:38:38 +00:00
commit
40d4e138b7
44
strudel.mjs
44
strudel.mjs
@ -426,6 +426,36 @@ class Pattern {
|
|||||||
return patterned
|
return patterned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_fastGap (factor) {
|
||||||
|
// Maybe it's better without this fallback..
|
||||||
|
// if (factor < 1) {
|
||||||
|
// // there is no gap.. so maybe revert to _fast?
|
||||||
|
// return this._fast(factor)
|
||||||
|
// }
|
||||||
|
const qf = function(span) {
|
||||||
|
const cycle = span.begin.sam()
|
||||||
|
const begin = cycle.add(span.begin.sub(cycle).mul(factor).min(1))
|
||||||
|
const end = cycle.add(span.end.sub(cycle).mul(factor).min(1))
|
||||||
|
return new TimeSpan(begin, end)
|
||||||
|
}
|
||||||
|
const ef = function(span) {
|
||||||
|
const cycle = span.begin.sam()
|
||||||
|
const begin = cycle.add(span.begin.sub(cycle).div(factor).min(1))
|
||||||
|
const end = cycle.add(span.end.sub(cycle).div(factor).min(1))
|
||||||
|
return new TimeSpan(begin, end)
|
||||||
|
}
|
||||||
|
return this.withQuerySpan(qf).withEventSpan(ef)._splitQueries()
|
||||||
|
}
|
||||||
|
|
||||||
|
_compressSpan(span) {
|
||||||
|
const b = span.begin
|
||||||
|
const e = span.end
|
||||||
|
if (b > e || b > 1 || e > 1 || b < 0 || e < 0) {
|
||||||
|
return silence
|
||||||
|
}
|
||||||
|
return this._fastGap(Fraction(1).div(e.sub(b)))._late(b)
|
||||||
|
}
|
||||||
|
|
||||||
_fast(factor) {
|
_fast(factor) {
|
||||||
const fastQuery = this.withQueryTime(t => t.mul(factor))
|
const fastQuery = this.withQueryTime(t => t.mul(factor))
|
||||||
return fastQuery.withEventTime(t => t.div(factor))
|
return fastQuery.withEventTime(t => t.div(factor))
|
||||||
@ -573,6 +603,18 @@ function cat(...pats) {
|
|||||||
return fastcat(...pats)
|
return fastcat(...pats)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function timeCat(...timepats) {
|
||||||
|
const total = timepats.map(a => a[0]).reduce((a,b) => a.add(b), Fraction(0))
|
||||||
|
let begin = Fraction(0)
|
||||||
|
const pats = []
|
||||||
|
for (const [time, pat] of timepats) {
|
||||||
|
const end = begin.add(time)
|
||||||
|
pats.push(reify(pat)._compressSpan(new TimeSpan(begin.div(total), end.div(total))))
|
||||||
|
begin = end
|
||||||
|
}
|
||||||
|
return stack(...pats)
|
||||||
|
}
|
||||||
|
|
||||||
function _sequenceCount(x) {
|
function _sequenceCount(x) {
|
||||||
if(Array.isArray(x)) {
|
if(Array.isArray(x)) {
|
||||||
if (x.length == 0) {
|
if (x.length == 0) {
|
||||||
@ -639,7 +681,7 @@ const late = curry((a, pat) => pat.late(a))
|
|||||||
const rev = pat => pat.rev()
|
const rev = pat => pat.rev()
|
||||||
|
|
||||||
export {Fraction, TimeSpan, Hap, Pattern,
|
export {Fraction, TimeSpan, Hap, Pattern,
|
||||||
pure, stack, slowcat, fastcat, cat, sequence, polymeter, pm, polyrhythm, pr, reify, silence,
|
pure, stack, slowcat, fastcat, cat, timeCat, sequence, polymeter, pm, polyrhythm, pr, reify, silence,
|
||||||
fast, slow, early, late, rev
|
fast, slow, early, late, rev
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,10 @@ import Fraction from 'fraction.js'
|
|||||||
|
|
||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
|
|
||||||
import {TimeSpan, Hap, Pattern, pure, stack, fastcat, slowcat, cat, sequence, polyrhythm, silence, fast} from "../strudel.mjs";
|
import {TimeSpan, Hap, Pattern, pure, stack, fastcat, slowcat, cat, sequence, polyrhythm, silence, fast, timeCat} from "../strudel.mjs";
|
||||||
|
//import { Time } from 'tone';
|
||||||
|
import pkg from 'tone';
|
||||||
|
const { Time } = pkg;
|
||||||
|
|
||||||
const ts = (begin, end) => new TimeSpan(Fraction(begin), Fraction(end));
|
const ts = (begin, end) => new TimeSpan(Fraction(begin), Fraction(end));
|
||||||
const hap = (whole, part, value) => new Hap(whole, part, value)
|
const hap = (whole, part, value) => new Hap(whole, part, value)
|
||||||
@ -89,6 +92,32 @@ describe('Pattern', function() {
|
|||||||
assert.equal(pure("a")._fast(2).firstCycle.length, 2)
|
assert.equal(pure("a")._fast(2).firstCycle.length, 2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
describe('_fastGap()', function () {
|
||||||
|
it('Makes things faster, with a gap', function () {
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
sequence("a", "b", "c")._fastGap(2).firstCycle,
|
||||||
|
sequence(["a","b","c"], silence).firstCycle
|
||||||
|
)
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
sequence("a", "b", "c")._fastGap(3).firstCycle,
|
||||||
|
sequence(["a","b","c"], silence, silence).firstCycle
|
||||||
|
)
|
||||||
|
})
|
||||||
|
it('Makes things faster, with a gap, when speeded up further', function () {
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
sequence("a", "b", "c")._fastGap(2).fast(2).firstCycle,
|
||||||
|
sequence(["a","b","c"], silence, ["a","b","c"], silence).firstCycle
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('_compressSpan()', function () {
|
||||||
|
it('Can squash cycles of a pattern into a given timespan', function () {
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
pure("a")._compressSpan(new TimeSpan(0.25, 0.5)).firstCycle,
|
||||||
|
sequence(silence, "a", silence, silence).firstCycle
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
describe('fast()', function () {
|
describe('fast()', function () {
|
||||||
it('Makes things faster', function () {
|
it('Makes things faster', function () {
|
||||||
assert.equal(pure("a").fast(2).firstCycle.length, 2)
|
assert.equal(pure("a").fast(2).firstCycle.length, 2)
|
||||||
@ -195,4 +224,12 @@ describe('Pattern', function() {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
describe('timeCat()', function() {
|
||||||
|
it('Can concatenate patterns with different relative durations', function() {
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
sequence("a", ["a", "a"]).firstCycle,
|
||||||
|
timeCat([1,"a"], [0.5, "a"], [0.5, "a"]).firstCycle
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user