From b4b303a2d919237446b60f7128fe9796e4f11902 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 20 Feb 2022 22:47:00 +0000 Subject: [PATCH 1/2] Add continuous signals (sine, cosine, saw, etc) --- strudel.mjs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/strudel.mjs b/strudel.mjs index f07faa39..e1bf28c2 100644 --- a/strudel.mjs +++ b/strudel.mjs @@ -148,7 +148,7 @@ class TimeSpan { return result } - get midpoint() { + midpoint() { return(this.begin.add((this.end.sub(this.begin)).div(Fraction(2)))) } @@ -671,6 +671,29 @@ function steady(value) { return new Pattern(span => Hap(undefined, span, value)) } +export const signal = func => { + const query = span => [new Hap(undefined, span, func(span.midpoint()))] + return new Pattern(query) +} + +export const sine2 = signal(t => Math.sin(Math.PI * 2 * t)) +export const sine = signal(t => (Math.sin(Math.PI * 2 * t) + 1) / 2) + +export const cosine2 = sine2._early(0.25) +export const cosine = sine._early(0.25) + +export const saw2 = signal(t => (t % 1) * 2) +export const saw = signal(t => t % 1) + +export const isaw2 = signal(t => (1 - (t % 1)) * 2) +export const isaw = signal(t => 1 - (t % 1)) + +export const tri2 = fastcat(isaw2, saw2) +export const tri = fastcat(isaw, saw) + +export const square2 = signal(t => (Math.floor((t*2) % 2) * 2) - 1) +export const square = signal(t => Math.floor((t*2) % 2)) + function reify(thing) { // Tunrs something into a pattern, unless it's already a pattern if (thing?.constructor?.name == "Pattern") { From fd8f70d914df30852a104b9be3b77a0c6c59b7ae Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 20 Feb 2022 23:59:16 +0000 Subject: [PATCH 2/2] Tweaks and a couple of tests for signals --- strudel.mjs | 11 +++++++---- test/pattern.test.mjs | 24 +++++++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/strudel.mjs b/strudel.mjs index e1bf28c2..9b7a6022 100644 --- a/strudel.mjs +++ b/strudel.mjs @@ -676,23 +676,26 @@ export const signal = func => { return new Pattern(query) } +const _toBipolar = pat => pat.fmap(x => (x * 2) - 1) +const _fromBipolar = pat => pat.fmap(x => (x + 1) / 2) + export const sine2 = signal(t => Math.sin(Math.PI * 2 * t)) -export const sine = signal(t => (Math.sin(Math.PI * 2 * t) + 1) / 2) +export const sine = _fromBipolar(sine2) export const cosine2 = sine2._early(0.25) export const cosine = sine._early(0.25) -export const saw2 = signal(t => (t % 1) * 2) export const saw = signal(t => t % 1) +export const saw2 = _toBipolar(saw) -export const isaw2 = signal(t => (1 - (t % 1)) * 2) export const isaw = signal(t => 1 - (t % 1)) +export const isaw2 = _toBipolar(isaw) export const tri2 = fastcat(isaw2, saw2) export const tri = fastcat(isaw, saw) -export const square2 = signal(t => (Math.floor((t*2) % 2) * 2) - 1) export const square = signal(t => Math.floor((t*2) % 2)) +export const square2 = _toBipolar(square) function reify(thing) { // Tunrs something into a pattern, unless it's already a pattern diff --git a/test/pattern.test.mjs b/test/pattern.test.mjs index c6986538..f6180a80 100644 --- a/test/pattern.test.mjs +++ b/test/pattern.test.mjs @@ -2,7 +2,7 @@ import Fraction from 'fraction.js' import { strict as assert } from 'assert'; -import {TimeSpan, Hap, Pattern, pure, stack, fastcat, slowcat, cat, sequence, polyrhythm, silence, fast, timeCat,add,sub,mul,div} from "../strudel.mjs"; +import {TimeSpan, Hap, Pattern, pure, stack, fastcat, slowcat, cat, sequence, polyrhythm, silence, fast, timeCat,add,sub,mul,div,saw,saw2,isaw,isaw2,sine,sine2,square,square2,tri,tri2} from "../strudel.mjs"; //import { Time } from 'tone'; import pkg from 'tone'; const { Time } = pkg; @@ -307,4 +307,26 @@ describe('Pattern', function() { ) }) }) + describe('signal()', function() { + it('Can make saw/saw2', function() { + assert.deepStrictEqual( + saw.struct(true,true,true,true).firstCycle, + sequence(1/8,3/8,5/8,7/8).firstCycle + ) + assert.deepStrictEqual( + saw2.struct(true,true,true,true).firstCycle, + sequence(-3/4,-1/4,1/4,3/4).firstCycle + ) + }) + it('Can make isaw/isaw2', function() { + assert.deepStrictEqual( + isaw.struct(true,true,true,true).firstCycle, + sequence(7/8,5/8,3/8,1/8).firstCycle + ) + assert.deepStrictEqual( + isaw2.struct(true,true,true,true).firstCycle, + sequence(3/4,1/4,-1/4,-3/4).firstCycle + ) + }) + }) })