Skip to content

Commit 9239d7f

Browse files
committed
Split out genSynth to clean up the main app file
1 parent 8e004c4 commit 9239d7f

File tree

2 files changed

+75
-60
lines changed

2 files changed

+75
-60
lines changed

planets/app.js

Lines changed: 7 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import {ElementaryWebAudioRenderer as core, el} from '@elemaudio/core';
22
import srvb from '@elemaudio/srvb';
3-
import teoria from 'teoria';
43

5-
import Synth from './Synth';
4+
import genSynth from './genSynth';
65
import {clear, draw} from './drawing';
76

87

@@ -31,65 +30,13 @@ const state = {
3130
],
3231
};
3332

34-
// Random seed stuff
35-
let baseNote = teoria.note.fromKey(25 + Math.round(Math.random() * 24));
36-
let accentNote = teoria.note.fromKey(baseNote.key() + 12);
37-
let scaleType = ['major', 'minor', 'lydian', 'mixolydian'][Math.round(Math.random() * 3)];
38-
let scale = accentNote.scale(scaleType).notes().concat(baseNote.scale(scaleType).notes());
39-
let density = 0.02 + Math.random() * 0.2;
40-
let similarity = Math.random();
41-
42-
console.log(`${baseNote.toString()} ${scaleType} ${density.toFixed(3)}/${similarity.toFixed(3)} alpha:${globalAlpha.toFixed(3)}`);
43-
44-
// Record a bunch of operations against our synth
45-
let syn1 = new Synth('ll', 4);
46-
let syn2 = new Synth('rr', 4);
47-
let adsrDecay = 3.5;
48-
let nextNote1 = 0;
49-
let nextNote2 = 0;
50-
let bpm = 76;
51-
let n64Rate = 1 / ((60 / bpm) / 8);
52-
53-
// Eight bars of 16th notes
54-
let atLeastOneNote = false;
55-
56-
while (!atLeastOneNote) {
57-
syn1.reset();
58-
syn2.reset();
59-
60-
for (let i = 0; i < 128; ++i) {
61-
let playLeft = Math.random() < density;
62-
let playSimilar = Math.random() < similarity;
63-
64-
if (playLeft) {
65-
syn1.noteOff(nextNote1);
66-
nextNote1 = scale[Math.floor(Math.random() * (scale.length - 1))].fq();
67-
syn1.noteOn(nextNote1, 0.125 + Math.random());
68-
atLeastOneNote = true;
69-
}
70-
71-
// If we have high similarity, we duplicate the note event into the right
72-
// channel synth. If we fail our similarity check, we optionally play whatever
73-
// note we want in the right channel synth
74-
if (playLeft && playSimilar) {
75-
syn2.noteOff(nextNote2);
76-
nextNote2 = nextNote1;
77-
syn2.noteOn(nextNote2, Math.random());
78-
} else {
79-
if (Math.random() < density) {
80-
syn2.noteOff(nextNote2);
81-
nextNote2 = scale[Math.floor(Math.random() * (scale.length - 1))].fq();
82-
syn2.noteOn(nextNote2, 0.125 + Math.random() * 0.5);
83-
atLeastOneNote = true;
84-
}
85-
}
86-
87-
syn1.step();
88-
syn2.step();
89-
}
90-
}
91-
33+
// Our main audio rendering step
9234
core.on('load', function(e) {
35+
const bpm = 76;
36+
const n64Rate = 1 / ((60 / bpm) / 8);
37+
const adsrDecay = 3.5;
38+
const [syn1, syn2] = genSynth();
39+
9340
let ll = el.add(...syn1.render(function(key, gs, fs, vs, i) {
9441
let t = el.train(n64Rate);
9542
let env = el.adsr(0.01, adsrDecay, 0, adsrDecay, el.seq({key: `${key}:gs`, seq: gs, hold: true}, t));

planets/genSynth.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import teoria from 'teoria';
2+
3+
import Synth from './Synth';
4+
5+
6+
// Random seed stuff
7+
let baseNote = teoria.note.fromKey(25 + Math.round(Math.random() * 24));
8+
let accentNote = teoria.note.fromKey(baseNote.key() + 12);
9+
let scaleType = ['major', 'minor', 'lydian', 'mixolydian'][Math.round(Math.random() * 3)];
10+
let scale = accentNote.scale(scaleType).notes().concat(baseNote.scale(scaleType).notes());
11+
12+
// Creates two synth instances, records a bunch of operations against each,
13+
// and then returns the two as a pair.
14+
//
15+
// We use two synth instances, one for the left channel and one for the right,
16+
// to create a wide stereo field with harmonic ratios, which yields nice
17+
// figures in the Lissajous plot
18+
export default function genSynth() {
19+
const syn1 = new Synth('ll', 4);
20+
const syn2 = new Synth('rr', 4);
21+
const density = 0.02 + Math.random() * 0.2;
22+
const similarity = Math.random();
23+
24+
console.log(`${baseNote.toString()} ${scaleType} ${density.toFixed(3)}/${similarity.toFixed(3)}`);
25+
26+
let nextNote1 = 0;
27+
let nextNote2 = 0;
28+
let atLeastOneNote = false;
29+
30+
while (!atLeastOneNote) {
31+
syn1.reset();
32+
syn2.reset();
33+
34+
// Eight bars of 16th notes
35+
for (let i = 0; i < 128; ++i) {
36+
let playLeft = Math.random() < density;
37+
let playSimilar = Math.random() < similarity;
38+
39+
if (playLeft) {
40+
syn1.noteOff(nextNote1);
41+
nextNote1 = scale[Math.floor(Math.random() * (scale.length - 1))].fq();
42+
syn1.noteOn(nextNote1, 0.125 + Math.random());
43+
atLeastOneNote = true;
44+
}
45+
46+
// If we have high similarity, we duplicate the note event into the right
47+
// channel synth. If we fail our similarity check, we optionally play whatever
48+
// note we want in the right channel synth
49+
if (playLeft && playSimilar) {
50+
syn2.noteOff(nextNote2);
51+
nextNote2 = nextNote1;
52+
syn2.noteOn(nextNote2, Math.random());
53+
} else {
54+
if (Math.random() < density) {
55+
syn2.noteOff(nextNote2);
56+
nextNote2 = scale[Math.floor(Math.random() * (scale.length - 1))].fq();
57+
syn2.noteOn(nextNote2, 0.125 + Math.random() * 0.5);
58+
atLeastOneNote = true;
59+
}
60+
}
61+
62+
syn1.step();
63+
syn2.step();
64+
}
65+
}
66+
67+
return [syn1, syn2];
68+
}

0 commit comments

Comments
 (0)