From 33fef379ada6fd96001510f5dc2f64eb01756738 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Thu, 10 Oct 2024 14:35:09 -0400
Subject: [PATCH 01/13] Get a basic version of binary working
---
packages/core/signal.mjs | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index 215eac2f..c5eff43d 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -159,6 +159,17 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
*/
export const run = (n) => saw.range(0, n).floor().segment(n);
+/**
+ * A discrete binary pattern using a decimal/hex number as input
+ * @example
+ * "c a f e".struct(binary(0xA5B5)).note().piano()
+ * // "c a f e".struct("0 1 0 1 0 1 0 1 1 0 1 0 1").note().piano()
+ */
+export const binary = (n) => {
+ const binLen = 16;
+ return reify(n).segment(binLen).brshift(run(binLen)).band(pure(1));
+};
+
export const randrun = (n) => {
return signal((t) => {
// Without adding 0.5, the first cycle is always 0,1,2,3,...
From 0d660277f6c1c4f83e8163e98b616d35a0af77fc Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Thu, 10 Oct 2024 14:36:29 -0400
Subject: [PATCH 02/13] Put msb on the right
---
packages/core/signal.mjs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index c5eff43d..8d033499 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th
*/
import { Hap } from './hap.mjs';
-import { Pattern, fastcat, reify, silence, stack, register } from './pattern.mjs';
+import { Pattern, fastcat, pure, register, reify, silence, stack } from './pattern.mjs';
import Fraction from './fraction.mjs';
import { id, _mod } from './util.mjs';
@@ -167,7 +167,9 @@ export const run = (n) => saw.range(0, n).floor().segment(n);
*/
export const binary = (n) => {
const binLen = 16;
- return reify(n).segment(binLen).brshift(run(binLen)).band(pure(1));
+ // Shift right and mask, with msb at the end/right-side
+ const i = run(binLen).mul(-1).add(binLen - 1)
+ return reify(n).segment(binLen).brshift(i).band(pure(1));
};
export const randrun = (n) => {
From 0a408e464a7c9b32f0ba2c56081d5d0d919787a3 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Thu, 10 Oct 2024 14:39:45 -0400
Subject: [PATCH 03/13] Make example more concise
---
packages/core/signal.mjs | 4 +--
test/__snapshots__/examples.test.mjs.snap | 41 +++++++++++++++++++++++
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index 8d033499..8340bc9f 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -162,8 +162,8 @@ export const run = (n) => saw.range(0, n).floor().segment(n);
/**
* A discrete binary pattern using a decimal/hex number as input
* @example
- * "c a f e".struct(binary(0xA5B5)).note().piano()
- * // "c a f e".struct("0 1 0 1 0 1 0 1 1 0 1 0 1").note().piano()
+ * "hh".s().struct(binary(55532))
+ * // "hh".s().struct("1 1 0 1 1 0 0 0 1 1 1 0 1 1 0 0")
*/
export const binary = (n) => {
const binLen = 16;
diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap
index 3ad6ea01..fd7169c5 100644
--- a/test/__snapshots__/examples.test.mjs.snap
+++ b/test/__snapshots__/examples.test.mjs.snap
@@ -967,6 +967,47 @@ exports[`runs examples > example "begin" example index 0 1`] = `
]
`;
+exports[`runs examples > example "binary" example index 0 1`] = `
+[
+ "[ 0/1 → 1/16 | s:hh ]",
+ "[ 1/16 → 1/8 | s:hh ]",
+ "[ 3/16 → 1/4 | s:hh ]",
+ "[ 1/4 → 5/16 | s:hh ]",
+ "[ 1/2 → 9/16 | s:hh ]",
+ "[ 9/16 → 5/8 | s:hh ]",
+ "[ 5/8 → 11/16 | s:hh ]",
+ "[ 3/4 → 13/16 | s:hh ]",
+ "[ 13/16 → 7/8 | s:hh ]",
+ "[ 1/1 → 17/16 | s:hh ]",
+ "[ 17/16 → 9/8 | s:hh ]",
+ "[ 19/16 → 5/4 | s:hh ]",
+ "[ 5/4 → 21/16 | s:hh ]",
+ "[ 3/2 → 25/16 | s:hh ]",
+ "[ 25/16 → 13/8 | s:hh ]",
+ "[ 13/8 → 27/16 | s:hh ]",
+ "[ 7/4 → 29/16 | s:hh ]",
+ "[ 29/16 → 15/8 | s:hh ]",
+ "[ 2/1 → 33/16 | s:hh ]",
+ "[ 33/16 → 17/8 | s:hh ]",
+ "[ 35/16 → 9/4 | s:hh ]",
+ "[ 9/4 → 37/16 | s:hh ]",
+ "[ 5/2 → 41/16 | s:hh ]",
+ "[ 41/16 → 21/8 | s:hh ]",
+ "[ 21/8 → 43/16 | s:hh ]",
+ "[ 11/4 → 45/16 | s:hh ]",
+ "[ 45/16 → 23/8 | s:hh ]",
+ "[ 3/1 → 49/16 | s:hh ]",
+ "[ 49/16 → 25/8 | s:hh ]",
+ "[ 51/16 → 13/4 | s:hh ]",
+ "[ 13/4 → 53/16 | s:hh ]",
+ "[ 7/2 → 57/16 | s:hh ]",
+ "[ 57/16 → 29/8 | s:hh ]",
+ "[ 29/8 → 59/16 | s:hh ]",
+ "[ 15/4 → 61/16 | s:hh ]",
+ "[ 61/16 → 31/8 | s:hh ]",
+]
+`;
+
exports[`runs examples > example "bite" example index 0 1`] = `
[
"[ 0/1 → 1/8 | note:Bb3 ]",
From 947b263b9ccccf10279cfe31746c7f69b5a48e42 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Thu, 10 Oct 2024 14:40:29 -0400
Subject: [PATCH 04/13] Add tests
---
packages/core/test/pattern.test.mjs | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs
index 31ec4868..03f2c60f 100644
--- a/packages/core/test/pattern.test.mjs
+++ b/packages/core/test/pattern.test.mjs
@@ -46,6 +46,7 @@ import {
rev,
time,
run,
+ binary,
pick,
stackLeft,
stackRight,
@@ -958,6 +959,18 @@ describe('Pattern', () => {
expect(run(4).firstCycle()).toStrictEqual(sequence(0, 1, 2, 3).firstCycle());
});
});
+ describe('binary', () => {
+ it('Can make a binary pattern from a decimal', () => {
+ expect(binary(55532).firstCycle()).toStrictEqual(
+ sequence(1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0).firstCycle(),
+ );
+ });
+ it('Can make a binary pattern from a numerical pattern', () => {
+ expect(binary(pure(0x1337)).firstCycle()).toStrictEqual(
+ sequence(0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1).firstCycle(),
+ );
+ });
+ });
describe('ribbon', () => {
it('Can ribbon', () => {
expect(cat(0, 1, 2, 3, 4, 5, 6, 7).ribbon(2, 4).fast(4).firstCycle()).toStrictEqual(
From 34f4afad0158fe8de7c251f588ccd76357160855 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Thu, 10 Oct 2024 14:41:37 -0400
Subject: [PATCH 05/13] Rework binary to binaryN
---
packages/core/signal.mjs | 17 ++++++++++-------
packages/core/test/pattern.test.mjs | 12 ++++++------
test/__snapshots__/examples.test.mjs.snap | 3 ++-
3 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index 8340bc9f..6c905b55 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -160,16 +160,19 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
export const run = (n) => saw.range(0, n).floor().segment(n);
/**
- * A discrete binary pattern using a decimal/hex number as input
+ * @name binaryN
+ * Creates a discrete pattern using binary representation.
+ * @param {number} n - input number to convert to binary
+ * @param {number} nBits - pattern length, defaults to 16
* @example
- * "hh".s().struct(binary(55532))
+ * "hh".s().struct(binaryN(55532, 16))
* // "hh".s().struct("1 1 0 1 1 0 0 0 1 1 1 0 1 1 0 0")
*/
-export const binary = (n) => {
- const binLen = 16;
- // Shift right and mask, with msb at the end/right-side
- const i = run(binLen).mul(-1).add(binLen - 1)
- return reify(n).segment(binLen).brshift(i).band(pure(1));
+export const binaryN = (n, nBits = 16) => {
+ nBits = reify(nBits);
+ // Shift and mask, putting msb on the right-side
+ const i = run(nBits).mul(-1).add(nBits.sub(1));
+ return reify(n).segment(nBits).brshift(i).band(pure(1));
};
export const randrun = (n) => {
diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs
index 03f2c60f..7e6d8fd8 100644
--- a/packages/core/test/pattern.test.mjs
+++ b/packages/core/test/pattern.test.mjs
@@ -46,7 +46,7 @@ import {
rev,
time,
run,
- binary,
+ binaryN,
pick,
stackLeft,
stackRight,
@@ -959,15 +959,15 @@ describe('Pattern', () => {
expect(run(4).firstCycle()).toStrictEqual(sequence(0, 1, 2, 3).firstCycle());
});
});
- describe('binary', () => {
+ describe('binaryN', () => {
it('Can make a binary pattern from a decimal', () => {
- expect(binary(55532).firstCycle()).toStrictEqual(
+ expect(binaryN(55532).firstCycle()).toStrictEqual(
sequence(1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0).firstCycle(),
);
});
- it('Can make a binary pattern from a numerical pattern', () => {
- expect(binary(pure(0x1337)).firstCycle()).toStrictEqual(
- sequence(0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1).firstCycle(),
+ it('Can make a binary pattern from patterned inputs', () => {
+ expect(binaryN(pure(0x1337), pure(14)).firstCycle()).toStrictEqual(
+ sequence(0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1).firstCycle(),
);
});
});
diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap
index fd7169c5..6dce5739 100644
--- a/test/__snapshots__/examples.test.mjs.snap
+++ b/test/__snapshots__/examples.test.mjs.snap
@@ -967,7 +967,8 @@ exports[`runs examples > example "begin" example index 0 1`] = `
]
`;
-exports[`runs examples > example "binary" example index 0 1`] = `
+exports[`runs examples > example "binaryN
+Creates a discrete pattern using binary representation." example index 0 1`] = `
[
"[ 0/1 → 1/16 | s:hh ]",
"[ 1/16 → 1/8 | s:hh ]",
From 4cc019f038cec10ca01bac08f5c8e4303f528404 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Thu, 10 Oct 2024 14:48:47 -0400
Subject: [PATCH 06/13] Rename variable
---
packages/core/signal.mjs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index 6c905b55..c29c0399 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -171,8 +171,8 @@ export const run = (n) => saw.range(0, n).floor().segment(n);
export const binaryN = (n, nBits = 16) => {
nBits = reify(nBits);
// Shift and mask, putting msb on the right-side
- const i = run(nBits).mul(-1).add(nBits.sub(1));
- return reify(n).segment(nBits).brshift(i).band(pure(1));
+ const bitPos = run(nBits).mul(-1).add(nBits.sub(1));
+ return reify(n).segment(nBits).brshift(bitPos).band(pure(1));
};
export const randrun = (n) => {
From f87f2791984057dcd8aa9da3e4931c0a204f47a0 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Thu, 10 Oct 2024 15:43:13 -0400
Subject: [PATCH 07/13] Support those who prefer no left padding
---
packages/core/pattern.mjs | 1 +
packages/core/signal.mjs | 13 +++++++++++++
2 files changed, 14 insertions(+)
diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs
index f3f19f87..35f9cb6a 100644
--- a/packages/core/pattern.mjs
+++ b/packages/core/pattern.mjs
@@ -1023,6 +1023,7 @@ function _composeOp(a, b, func) {
div: [numeralArgs((a, b) => a / b)],
mod: [numeralArgs(_mod)],
pow: [numeralArgs(Math.pow)],
+ log2: [numeralArgs(Math.log2)],
band: [numeralArgs((a, b) => a & b)],
bor: [numeralArgs((a, b) => a | b)],
bxor: [numeralArgs((a, b) => a ^ b)],
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index c29c0399..5f61fe7a 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -159,6 +159,19 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
*/
export const run = (n) => saw.range(0, n).floor().segment(n);
+/**
+ * @name binary
+ * Creates a discrete pattern using binary representation.
+ * @param {number} n - input number to convert to binary
+ * @example
+ * "hh".s().struct(binary(5))
+ * // "hh".s().struct("1 0 1")
+ */
+export const binary = (n) => {
+ const nBits = reify(n).log2(0).floor().add(1);
+ return binaryN(n, nBits)
+};
+
/**
* @name binaryN
* Creates a discrete pattern using binary representation.
From 111cea23819ded11232d3687d0e81f70427771ea Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Mon, 16 Dec 2024 21:31:21 -0500
Subject: [PATCH 08/13] Fix lint
---
packages/core/signal.mjs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index 5f61fe7a..746b207d 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -169,7 +169,7 @@ export const run = (n) => saw.range(0, n).floor().segment(n);
*/
export const binary = (n) => {
const nBits = reify(n).log2(0).floor().add(1);
- return binaryN(n, nBits)
+ return binaryN(n, nBits);
};
/**
From 7cf7575e6d5b61fcab87ab1f84499844227ca502 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Tue, 17 Dec 2024 08:49:49 -0500
Subject: [PATCH 09/13] Make the docs friendlier
---
packages/core/signal.mjs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index 746b207d..31fdbb6a 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -161,7 +161,7 @@ export const run = (n) => saw.range(0, n).floor().segment(n);
/**
* @name binary
- * Creates a discrete pattern using binary representation.
+ * Creates a pattern from a binary number.
* @param {number} n - input number to convert to binary
* @example
* "hh".s().struct(binary(5))
@@ -174,7 +174,7 @@ export const binary = (n) => {
/**
* @name binaryN
- * Creates a discrete pattern using binary representation.
+ * Creates a pattern from a binary number, padded to n bits long.
* @param {number} n - input number to convert to binary
* @param {number} nBits - pattern length, defaults to 16
* @example
From 426c5edf2530e781fa8ebfaf5d24b0f4885f21ca Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Fri, 27 Dec 2024 07:43:41 -0500
Subject: [PATCH 10/13] Update tests snapshot
---
test/__snapshots__/examples.test.mjs.snap | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap
index 6dce5739..88a72883 100644
--- a/test/__snapshots__/examples.test.mjs.snap
+++ b/test/__snapshots__/examples.test.mjs.snap
@@ -967,8 +967,22 @@ exports[`runs examples > example "begin" example index 0 1`] = `
]
`;
+exports[`runs examples > example "binary
+Creates a pattern from a binary number." example index 0 1`] = `
+[
+ "[ 0/1 → 1/3 | s:hh ]",
+ "[ 2/3 → 1/1 | s:hh ]",
+ "[ 1/1 → 4/3 | s:hh ]",
+ "[ 5/3 → 2/1 | s:hh ]",
+ "[ 2/1 → 7/3 | s:hh ]",
+ "[ 8/3 → 3/1 | s:hh ]",
+ "[ 3/1 → 10/3 | s:hh ]",
+ "[ 11/3 → 4/1 | s:hh ]",
+]
+`;
+
exports[`runs examples > example "binaryN
-Creates a discrete pattern using binary representation." example index 0 1`] = `
+Creates a pattern from a binary number, padded to n bits long." example index 0 1`] = `
[
"[ 0/1 → 1/16 | s:hh ]",
"[ 1/16 → 1/8 | s:hh ]",
From 8644b3d163fbf3006faf545dec68158a5f2c1d26 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Fri, 27 Dec 2024 15:14:31 -0500
Subject: [PATCH 11/13] Fix accidental multi-line jsdoc name
---
packages/core/signal.mjs | 6 ++++--
test/__snapshots__/examples.test.mjs.snap | 6 ++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index 31fdbb6a..22f3df72 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -160,8 +160,9 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
export const run = (n) => saw.range(0, n).floor().segment(n);
/**
- * @name binary
* Creates a pattern from a binary number.
+ *
+ * @name binary
* @param {number} n - input number to convert to binary
* @example
* "hh".s().struct(binary(5))
@@ -173,8 +174,9 @@ export const binary = (n) => {
};
/**
- * @name binaryN
* Creates a pattern from a binary number, padded to n bits long.
+ *
+ * @name binaryN
* @param {number} n - input number to convert to binary
* @param {number} nBits - pattern length, defaults to 16
* @example
diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap
index 88a72883..bff15fcc 100644
--- a/test/__snapshots__/examples.test.mjs.snap
+++ b/test/__snapshots__/examples.test.mjs.snap
@@ -967,8 +967,7 @@ exports[`runs examples > example "begin" example index 0 1`] = `
]
`;
-exports[`runs examples > example "binary
-Creates a pattern from a binary number." example index 0 1`] = `
+exports[`runs examples > example "binary" example index 0 1`] = `
[
"[ 0/1 → 1/3 | s:hh ]",
"[ 2/3 → 1/1 | s:hh ]",
@@ -981,8 +980,7 @@ Creates a pattern from a binary number." example index 0 1`] = `
]
`;
-exports[`runs examples > example "binaryN
-Creates a pattern from a binary number, padded to n bits long." example index 0 1`] = `
+exports[`runs examples > example "binaryN" example index 0 1`] = `
[
"[ 0/1 → 1/16 | s:hh ]",
"[ 1/16 → 1/8 | s:hh ]",
From 9d029ac9145b475e7076b904dd577ee5837a31b3 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Fri, 27 Dec 2024 15:14:58 -0500
Subject: [PATCH 12/13] Add binary and binaryN to learn pages
---
website/src/pages/learn/factories.mdx | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/website/src/pages/learn/factories.mdx b/website/src/pages/learn/factories.mdx
index 6a2e165b..b43d3abf 100644
--- a/website/src/pages/learn/factories.mdx
+++ b/website/src/pages/learn/factories.mdx
@@ -55,6 +55,14 @@ These are the equivalents used by the Mini Notation:
## run
-
+
+
+## binary
+
+
+
+## binaryN
+
+
After Pattern Constructors, let's see what [Time Modifiers](/learn/time-modifiers) are available.
From c6418789c445c50f64b198ad347bf09d10d49e33 Mon Sep 17 00:00:00 2001
From: Luke Heerman <43624284+heerman@users.noreply.github.com>
Date: Fri, 27 Dec 2024 21:49:56 -0500
Subject: [PATCH 13/13] Fix lint
---
packages/core/signal.mjs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs
index 22f3df72..eaf2af8d 100644
--- a/packages/core/signal.mjs
+++ b/packages/core/signal.mjs
@@ -161,7 +161,7 @@ export const run = (n) => saw.range(0, n).floor().segment(n);
/**
* Creates a pattern from a binary number.
- *
+ *
* @name binary
* @param {number} n - input number to convert to binary
* @example
@@ -175,7 +175,7 @@ export const binary = (n) => {
/**
* Creates a pattern from a binary number, padded to n bits long.
- *
+ *
* @name binaryN
* @param {number} n - input number to convert to binary
* @param {number} nBits - pattern length, defaults to 16