-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathenvelope.html
127 lines (105 loc) · 3.65 KB
/
envelope.html
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Envelope</title>
<link href="css/audio.css" rel="stylesheet" />
<style>
.label {
width: 80px;
}
.slider {
width: 400px;
}
</style>
</head>
<body>
<div>
<span class="title">Envelope</span>
</div>
<div>
<span class="label">Wave</span>
<select id="wave-select">
<option>sine</option>
<option>square</option>
<option>triangle</option>
<option>sawtooth</option>
</select>
</div>
<div>
<span class="label">Frequency</span>
<input type="range" id="freq-slider" class="slider" min="0" max="400" step="1" value="160" />
<span id="freq-display" class="label"></span>
</div>
<div>
<input type="button" id="play" value="play" />
</div>
<div>
<canvas id="visualizer" width="1024" height="300"></canvas>
</div>
<div class="nav">
<a href="keyboard.html">> Keyboard</a><br/>
<a href="index.html">> Index</a>
</div>
</body>
<script type="text/javascript" src="js/frequency-visualizer.js"></script>
<script type="text/javascript">
(function () {
var context = new AudioContext();
var visualizer = new App.FrequencyVisualizer(context, document.getElementById('visualizer'));
var oscNode, gainNode, frequency, loFilterNode;
var freqDisplay = document.getElementById('freq-display');
var freqSlider = document.getElementById('freq-slider');
freqSlider.addEventListener('input', updateFrequency);
var waveSelect = document.getElementById('wave-select');
var playButton = document.getElementById('play');
playButton.addEventListener('mousedown', start);
playButton.addEventListener('mouseup', stop);
function getFrequency(slider) {
return Math.min(Math.round((Math.pow(2, slider.value / 40)) * 20), 20000);
}
function start() {
if (!oscNode) {
oscNode = context.createOscillator();
oscNode.frequency.value = frequency;
oscNode.type = waveSelect.value;
loFilterNode = context.createBiquadFilter();
loFilterNode.frequency.value = 20000;
loFilterNode.type = 'lowpass';
gainNode = context.createGain();
gainNode.gain.value = 0;
oscNode.connect(loFilterNode);
loFilterNode.connect(gainNode);
gainNode.connect(context.destination);
visualizer.acceptConnection(gainNode);
oscNode.start();
var t = context.currentTime;
gainNode.gain.setValueAtTime(0, t + 0.01);
gainNode.gain.linearRampToValueAtTime(1, t + 0.02);
gainNode.gain.setTargetAtTime(0.33, t + 0.02, 0.1);
loFilterNode.frequency.setValueAtTime(20000, t + 0.02);
loFilterNode.frequency.setTargetAtTime(frequency * 2, t + 0.02, 0.1);
}
}
function stop() {
if (oscNode) {
gainNode.gain.setValueAtTime(gainNode.gain.value, context.currentTime + 0.01);
gainNode.gain.linearRampToValueAtTime(0, context.currentTime + 0.02);
setTimeout(function () {
oscNode.stop();
gainNode.disconnect(context.destination);
visualizer.releaseConnection(gainNode);
oscNode = undefined;
loFilterNode = undefined;
gainNode = undefined;
}, 40);
}
}
function updateFrequency() {
frequency = getFrequency(freqSlider);
freqDisplay.textContent = frequency + ' hz';
}
updateFrequency();
})();
</script>
</html>