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

View File

@ -1346,4 +1346,4 @@ span.CodeMirror-selectedtext { background: none; }
color: white !important; 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> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link rel="icon" href="/tutorial/favicon.e3ab9dd9.ico"> <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="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Strudel REPL"> <meta name="description" content="Strudel REPL">
<title>Strudel Tutorial</title> <title>Strudel Tutorial</title>
@ -11,6 +11,6 @@
<body> <body>
<div id="root"></div> <div id="root"></div>
<noscript>You need to enable JavaScript to run this app.</noscript> <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> </body>
</html> </html>

View File

@ -73,7 +73,7 @@ Fraction.prototype.min = function(other) {
} }
Fraction.prototype.show = function () { Fraction.prototype.show = function () {
return this.n + "/" + this.d return (this.s * this.n) + "/" + this.d
} }
Fraction.prototype.or = function(other) { Fraction.prototype.or = function(other) {
@ -404,6 +404,14 @@ class Pattern {
return this._opleft(other, a => b => a - b) 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) { union(other) {
return this._opleft(other, a => b => Object.assign({}, a, b)) return this._opleft(other, a => b => Object.assign({}, a, b))
} }
@ -460,6 +468,14 @@ class Pattern {
return this.outerBind(id) return this.outerBind(id)
} }
_apply(func) {
return func(this)
}
layer(...funcs) {
return stack(...funcs.map(func => func(this)))
}
_patternify(func) { _patternify(func) {
const pat = this const pat = this
const patterned = function (...args) { const patterned = function (...args) {
@ -558,7 +574,7 @@ class Pattern {
} }
off(time_pat, func) { off(time_pat, func) {
return stack([this, func(this._early(time_pat))]) return stack(this, func(this.late(time_pat)))
} }
every(n, func) { every(n, func) {
@ -651,7 +667,7 @@ class Pattern {
} }
// methods of Pattern that get callable factories // 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 // 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}; 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) // 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
)
})
})
}) })