This commit is contained in:
Felix Roos 2022-02-24 20:16:46 +01:00
commit 62bb91ab14
8 changed files with 458 additions and 369 deletions

View File

@ -53,7 +53,7 @@ Fraction.prototype.min = function(other) {
return this.lt(other) ? this : other;
};
Fraction.prototype.show = function() {
return this.n + "/" + this.d;
return this.s * this.n + "/" + this.d;
};
Fraction.prototype.or = function(other) {
return this.eq(0) ? other : this;
@ -276,6 +276,12 @@ class Pattern {
sub(other) {
return this._opleft(other, (a) => (b) => a - b);
}
mul(other) {
return this._opleft(other, (a) => (b) => a * b);
}
div(other) {
return this._opleft(other, (a) => (b) => a / b);
}
union(other) {
return this._opleft(other, (a) => (b) => Object.assign({}, a, b));
}
@ -316,6 +322,12 @@ class Pattern {
outerJoin() {
return this.outerBind(id);
}
_apply(func) {
return func(this);
}
layer(...funcs) {
return stack(...funcs.map((func) => func(this)));
}
_patternify(func) {
const pat = this;
const patterned = function(...args) {
@ -384,7 +396,7 @@ class Pattern {
return stack(with_pat, without_pat);
}
off(time_pat, func) {
return stack([this, func(this._early(time_pat))]);
return stack(this, func(this.late(time_pat)));
}
every(n, func) {
const pat = this;
@ -447,7 +459,7 @@ class Pattern {
return silence;
}
}
Pattern.prototype.patternified = ["fast", "slow", "early", "late"];
Pattern.prototype.patternified = ["apply", "fast", "slow", "early", "late"];
Pattern.prototype.factories = {pure, stack, slowcat, fastcat, cat, timeCat, sequence, polymeter, pm, polyrhythm, pr};
const silence = new Pattern((_) => []);
function pure(value) {

View File

@ -1346,4 +1346,4 @@ span.CodeMirror-selectedtext { background: none; }
color: white !important;
}
/*# sourceMappingURL=index.fd7d9b66.css.map */
/*# sourceMappingURL=index.a25424f4.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<link rel="icon" href="/tutorial/favicon.e3ab9dd9.ico">
<link rel="stylesheet" type="text/css" href="/tutorial/index.fd7d9b66.css">
<link rel="stylesheet" type="text/css" href="/tutorial/index.a25424f4.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Strudel REPL">
<title>Strudel Tutorial</title>
@ -11,6 +11,6 @@
<body>
<div id="root"></div>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/tutorial/index.acaced6c.js" defer=""></script>
<script src="/tutorial/index.c743025b.js" defer=""></script>
</body>
</html>

View File

@ -73,7 +73,7 @@ Fraction.prototype.min = function(other) {
}
Fraction.prototype.show = function () {
return this.n + "/" + this.d
return (this.s * this.n) + "/" + this.d
}
Fraction.prototype.or = function(other) {
@ -404,6 +404,14 @@ class Pattern {
return this._opleft(other, a => b => a - b)
}
mul(other) {
return this._opleft(other, a => b => a * b)
}
div(other) {
return this._opleft(other, a => b => a / b)
}
union(other) {
return this._opleft(other, a => b => Object.assign({}, a, b))
}
@ -460,6 +468,14 @@ class Pattern {
return this.outerBind(id)
}
_apply(func) {
return func(this)
}
layer(...funcs) {
return stack(...funcs.map(func => func(this)))
}
_patternify(func) {
const pat = this
const patterned = function (...args) {
@ -558,7 +574,7 @@ class Pattern {
}
off(time_pat, func) {
return stack([this, func(this._early(time_pat))])
return stack(this, func(this.late(time_pat)))
}
every(n, func) {
@ -651,7 +667,7 @@ class Pattern {
}
// methods of Pattern that get callable factories
Pattern.prototype.patternified = ['fast', 'slow', 'early', 'late'];
Pattern.prototype.patternified = ['apply', 'fast', 'slow', 'early', 'late'];
// methods that create patterns, which are added to patternified Pattern methods
Pattern.prototype.factories = { pure, stack, slowcat, fastcat, cat, timeCat, sequence, polymeter, pm, polyrhythm, pr};
// the magic happens in Pattern constructor. Keeping this in prototype enables adding methods from the outside (e.g. see tonal.ts)

View File

@ -329,4 +329,52 @@ describe('Pattern', function() {
)
})
})
describe("apply", () => {
it('Can apply a function', () => {
assert.deepStrictEqual(
sequence("a", "b")._apply(fast(2)).firstCycle,
sequence("a", "b").fast(2).firstCycle
)
}),
it('Can apply a pattern of functions', () => {
assert.deepStrictEqual(
sequence("a", "b").apply(fast(2)).firstCycle,
sequence("a", "b").fast(2).firstCycle
)
assert.deepStrictEqual(
sequence("a", "b").apply(fast(2),fast(3)).firstCycle,
sequence("a", "b").fast(2,3).firstCycle
)
})
})
describe("layer", () => {
it('Can layer up multiple functions', () => {
assert.deepStrictEqual(
sequence(1,2,3).layer(fast(2), pat => pat.add(3,4)).firstCycle,
stack(sequence(1,2,3).fast(2), sequence(1,2,3).add(3,4)).firstCycle
)
})
})
describe("early", () => {
it("Can shift an event earlier", () => {
assert.deepStrictEqual(
pure(30)._late(0.25).query(ts(1,2)),
[hap(ts(1/4,5/4), ts(1,5/4), 30), hap(ts(5/4,9/4), ts(5/4,2), 30)]
)
})
it("Can shift an event earlier, into negative time", () => {
assert.deepStrictEqual(
pure(30)._late(0.25).query(ts(0,1)),
[hap(ts(-3/4,1/4), ts(0,1/4), 30), hap(ts(1/4,5/4), ts(1/4,1), 30)]
)
})
})
describe("off", () => {
it("Can offset a transformed pattern from the original", () => {
assert.deepStrictEqual(
pure(30).off(0.25, add(2)).firstCycle,
stack(pure(30), pure(30).early(0.25).add(2)).firstCycle
)
})
})
})