/
index.js
51 lines (46 loc) · 1.82 KB
/
index.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
import React from 'react';
import {connect} from 'react-redux';
import {mapRange} from '../../util';
import createVirtualAudioGraph, {
delay,
gain,
bufferSource,
biquadFilter
} from 'virtual-audio-graph';
const normFeedback = value => value / 20;
const normDelay = (reader1Position) => mapRange([0, 20], [0, 1], reader1Position);
const normSpeed = tapeSpeed => tapeSpeed <= 10
? mapRange([0, 10], [0, 1], tapeSpeed)
: mapRange([10, 20], [1, 10], tapeSpeed);
const normDry = mix => mapRange([0, 20], [1, 0], mix);
const normWet = mix => mapRange([0, 20], [0, 1], mix);
const normFrequency = lowpass => mapRange([0, 20], [16, 8000], lowpass);
const paramsToGraph = ({tapeSpeed, feedbackAmount, reader1Position, audioBuffer, mix, lowpass}) => {
//ensure a new node is created each time
const bufferSourceDry = `bufferSourceDry${new Date().getTime()}`;
const bufferSourceWet = `bufferSourceWet${new Date().getTime()}`;
return {
master: gain('output', {gain: 0.7}),
dry: gain('master', {gain: normDry(mix)}),
wet: gain('master', {gain: normWet(mix)}),
feedback: gain(['delay'], {gain: normFeedback(feedbackAmount)}),
lowpass: biquadFilter(['feedback', 'wet'], {type: 'lowpass', frequency: normFrequency(lowpass)}),
delay: delay('lowpass', {delayTime: normDelay(reader1Position)}),
[bufferSourceDry]: bufferSource('dry', {buffer: audioBuffer, loop: true}),
[bufferSourceWet]: bufferSource('delay', {buffer: audioBuffer, loop: true, playbackRate: normSpeed(tapeSpeed)}),
};
};
const audioContext = new AudioContext();
const virtualAudioGraph = createVirtualAudioGraph({
audioContext,
output: audioContext.destination,
});
class Audio extends React.Component {
render() {
virtualAudioGraph.update(paramsToGraph(this.props));
return null;
}
}
export default connect(
state => state,
)(Audio);