/
notesToGraph.js
63 lines (57 loc) · 2.17 KB
/
notesToGraph.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import {
biquadFilter,
createNode,
gain as gainNode,
oscillator,
stereoPanner,
} from 'virtual-audio-graph'
import frequencyToPitch from '../../../audioHelpers/frequencyToPitch'
import pitchToFrequency from '../../../audioHelpers/pitchToFrequency'
const lfoNode = createNode(({frequency, gain, type}) => ({
0: gainNode('output', {gain}),
1: oscillator(0, {frequency, type}),
}))
const osc = createNode(({detune, frequency, gain, pan, pitch, startTime, stopTime, type}) => ({
0: gainNode('output', {gain}),
1: stereoPanner(0, {pan}),
2: oscillator(1, {
detune,
frequency: pitchToFrequency(frequencyToPitch(frequency) + pitch),
startTime,
stopTime,
type,
}),
}))
export default ({filter, lfo, master, oscillatorSingles, oscillatorSupers}, notes) =>
notes.reduce((acc, {frequency, gain, id, startTime, stopTime}) => {
const noteGainId = `noteGain-${id}`
acc[noteGainId] = gainNode('filter', {gain})
for (let i = 0; i < oscillatorSingles.length; i++) {
const oscillatorSingle = oscillatorSingles[i]
acc[`oscSingle-${oscillatorSingle.id}-${id}`] = osc(noteGainId, Object.assign({}, oscillatorSingle, {frequency, startTime, stopTime}))
}
for (let i = 0; i < oscillatorSupers.length; i++) {
const oscillatorSuper = oscillatorSupers[i]
const {numberOfOscillators, type} = oscillatorSuper
for (let j = 0; j < numberOfOscillators; j++) {
acc[`oscSuper-${oscillatorSuper.id}-${j}-${id}`] = osc(noteGainId, {
detune: oscillatorSuper.detune + (j - Math.floor(numberOfOscillators / 2)) * oscillatorSuper.spread,
frequency,
gain: oscillatorSuper.gain,
pan: oscillatorSuper.pan,
pitch: oscillatorSuper.pitch,
startTime,
stopTime,
type: type === 'random'
? ['sawtooth', 'sine', 'square', 'triangle'][Math.floor(Math.random() * 4)]
: type,
})
}
}
return acc
}, {
filter: biquadFilter('masterPan', filter),
lfo: lfoNode({destination: 'frequency', key: 'filter'}, lfo),
masterGain: gainNode('output', {gain: master.gain}),
masterPan: stereoPanner('masterGain', {pan: master.pan}),
})