-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
|
||
const assign = Object.assign; | ||
|
||
/** | ||
quantize() | ||
Quantize events into triplets and duplets. | ||
**/ | ||
|
||
function collect(split, events, i) { | ||
let n = i - 1; | ||
while(events[++n] && events[n][0] < split); | ||
return n > i ? | ||
events.slice(i, n) : | ||
undefined ; | ||
} | ||
|
||
function toBeat0(output, event) { | ||
const e = Array.from(event); | ||
e[0] = 0; | ||
output.push(e); | ||
return output; | ||
} | ||
|
||
function quantizeScale(events, scale = 1, output) { | ||
let i = 0; | ||
|
||
const events00 = collect(scale * 0.0972222222, events, i); | ||
if (events00) { | ||
i += events00.length; | ||
events00.reduce(toBeat0, output); | ||
} | ||
|
||
const events25 = collect(scale * 0.2916666667, events, i); | ||
if (events25) i += events25.length; | ||
const events33 = collect(scale * 0.4305555556, events, i); | ||
if (events33) i += events33.length; | ||
const events50 = collect(scale * 0.5694444444, events, i); | ||
if (events50) i += events50.length; | ||
const events67 = collect(scale * 0.7083333333, events, i); | ||
if (events67) i += events67.length; | ||
const events75 = collect(scale * 0.9027777778, events, i); | ||
|
||
// Quadruplets | ||
if (events25 && events50 | ||
|| events25 && events75 | ||
|| events50 && events75 | ||
|| events25 && events33 | ||
|| events33 && events50 | ||
|| events50 && events67 | ||
|| events67 && events75 | ||
) { | ||
console.log('Quadruplets'); | ||
return; | ||
} | ||
|
||
if (events33) { | ||
console.log('Triplets'); | ||
return events33.map((event) => assign([], event, { 0: 0.333333333 })); | ||
} | ||
|
||
// We already checked (events50 && events67) so this is exclusive OR. In | ||
// english, that means there is only one event beat at 50% or 67% in this | ||
// beat, and we want to fall through to looking at these events at 2x zoom | ||
if (events50 || events67) { | ||
console.log('Recurse at 2x'); | ||
return; | ||
} | ||
|
||
// Quadruplets | ||
if (events25) { | ||
return events25.map((event) => assign([], event, { 0: 0.25 })); | ||
} | ||
|
||
if (events75) { | ||
return events75.map((event) => assign([], event, { 0: 0.75 })); | ||
} | ||
|
||
return output; | ||
} | ||
|
||
export default function quantize(events) { | ||
const output = []; | ||
return quantizeScale(events, 1, output); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title><scribe-music></title> | ||
|
||
<meta charset="utf-8" /> | ||
<meta name="author" content="@stephband" /> | ||
<meta name="description" content="" /> | ||
<meta name="viewport" content="width=device-width" /> | ||
|
||
<script title="debug">window.DEBUG = true;</script> | ||
</head> | ||
<body> | ||
<script type="module"> | ||
import quantize from '../modules/quantize.js'; | ||
import test from '../lib/fn/modules/test.js'; | ||
|
||
const assign = Object.assign; | ||
|
||
test('Quantize', [ | ||
[], | ||
[[0, 'note', 'C4', 1, 1]], | ||
[[0.25, 'note', 'C4', 1, 1]], | ||
[[0.25, 'note', 'C4', 1, 1]], | ||
[[0.333333333, 'note', 'C4', 1, 1]], | ||
[[0.333333333, 'note', 'C4', 1, 1]], | ||
|
||
[[0.75, 'note', 'C4', 1, 1]], | ||
[[0.75, 'note', 'C4', 1, 1]] | ||
], (expect, done) => { | ||
expect(quantize([])); | ||
expect(quantize([[0.0, 'note', 'C4', 1, 1]])); | ||
expect(quantize([[0.1, 'note', 'C4', 1, 1]])); | ||
expect(quantize([[0.2, 'note', 'C4', 1, 1]])); | ||
expect(quantize([[0.3, 'note', 'C4', 1, 1]])); | ||
expect(quantize([[0.4, 'note', 'C4', 1, 1]])); | ||
quantize([[0.5, 'note', 'C4', 1, 1]]); | ||
quantize([[0.6, 'note', 'C4', 1, 1]]); | ||
quantize([[0.7, 'note', 'C4', 1, 1]]); | ||
expect(quantize([[0.8, 'note', 'C4', 1, 1]])); | ||
expect(quantize([[0.9, 'note', 'C4', 1, 1]])); | ||
done(); | ||
}); | ||
</script> | ||
</body> | ||
</html> |