forked from Palakis/circles-sines-signals
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sound2.html
260 lines (225 loc) · 10.7 KB
/
sound2.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
<html>
<head>
<title>Circles Sines and Signals - Timbre</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="third_party/d3/d3.min.js"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
jax: ["input/TeX","input/MathML","output/SVG"],
extensions: ["tex2jax.js","mml2jax.js","MathMenu.js","MathZoom.js"],
TeX: {
extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]
}
});
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({ TeX: { extensions: ["color.js"] }});
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config(
{
SVG: {linebreaks: { automatic:true }},
displayAlign: "center"
}
);
</script>
<script type="text/javascript"
src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG">
</script>
<link href='//fonts.googleapis.com/css?family=Lato:400,700' rel='stylesheet' type='text/css'>
<link href='//fonts.googleapis.com/css?family=Vollkorn:400italic,400' rel='stylesheet' type='text/css'>
<style>
@import url("fontello-b1d57784/css/fontello.css");
@import url("style.css");
</style>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-59785365-1', 'auto');
ga('send', 'pageview');
</script>
<link rel="icon" type="" href="favicon.ico"></head>
<body>
<div class="title">
<table width="900">
<tr>
<td width="90%">
<div class="bigheader" id="titleinfo">
</div>
</td>
</tr>
<tr>
<td width="70%">
<br/>
<div id="menu" class="menu" style="margin-left: 45; ">
<table> <tr id="menurow"> </tr> </table>
</div>
</td>
</tr>
</table>
</div>
<div class="littleheader"> TIMBRE
<div class="subheader" style="font-size: 14px"> HARMONICS, OVERTONES, AND WAVE SHAPES </div>
</div>
<table class="figureTable">
<tr>
<td style="vertical-align: top;">
<div class="text" style="margin-left: 0px">
<p>
All sound is generated by vibrating objects. When objects vibrate <i>repetitively and predictably</i> our ears interpret the resulting pressure waves as tones or pitches - the sort of thing you could play a tune with. Objects which vibrate in non periodic and random ways generate waves which we interpret as being <i> noisy </i> or <i> atonal</i>.
</p>
<p>
Different patterns of vibration produce sounds with different <i>timbres</i>. Timbre is the quality of a sound that is distinct from pitch and intensity. In other words, a flute and a violin may play the same note, but the quality of the sound produced by each instrument is markedly different. The timbre of a sound is largely determined by the presence or absence of <i>overtones</i> or <i> harmonics</i>. Most musical sounds are composed of a <i>fundamental frequency</i> and additional harmonics which lie at multiples of the fundamental frequency.<sup>1</sup> For example, the note A4 has a fundamental frequency of 440 Hz. Its harmonics are at 880 Hz, 1,320 Hz, 1,760 Hz, and so on. Most instruments generate sound not only at the fundamental, but also at harmonics of the fundamental when struck, bowed, or blown.
</p>
<p>
In digital terms, we often talk about 3 basic types of sound wave. The <i>sine</i> wave is a pure tone with <i>no</i> overtones. A <i>square</i> wave is composed of a fundamental and <i>odd</i> harmonics of the fundamental. A <i>saw</i> wave is composed of a fundamental and <i>all</i> harmonics of the fundamental. The fundamental is usually the loudest component of the signal, and the harmonics decrease in loudness as they increase in frequency.
</p>
<p>
In the visualization below you can hear a two second audio example of each wave shape and see the associated frequency spectrum. The <i>spectrum</i> is a visualization of the <i>frequency</i> content within a given signal. The spectrum tells you where the energy lies within a signal in terms of frequency. Click the Play button associated with each wave shape to see and hear it.
</p>
<svg id="spectrum" class="svgWithText" width="700" height="200" style="padding: 5px"></svg>
<script type="text/javascript" src="js/spectrum.js"></script>
<table>
<tr class="figureCaption">
<td width="25%">
Sine Wave<br/><br/>
</td>
<td width="25%">
Square Wave<br/><br/>
</td>
<td width="25%">
Saw Wave<br/><br/>
</td>
<td width="25%">
Noise Wave<br/><br/>
</td>
</tr>
<tr>
<td width="25%">
<div id="animatedWrapper" class="animation" style="position: relative;">
<svg id="sineicon" class="svgWithText" width="170" height="100" style="padding: 5px"></svg>
<script type="text/javascript" src="js/icon_sine.js"></script>
</div>
</td>
<td width="25%">
<div id="animatedWrapper" class="animation" style="position: relative;">
<svg id="squareicon" class="svgWithText" width="170" height="100" style="padding: 5px"></svg>
<script type="text/javascript" src="js/icon_square.js"></script>
</div>
</td>
<td width="25%">
<div id="animatedWrapper" class="animation" style="position: relative;">
<svg id="sawicon" class="svgWithText" width="170" height="100" style="padding: 5px"></svg>
<script type="text/javascript" src="js/icon_saw.js"></script>
</div>
</td>
<td width="25%">
<div id="animatedWrapper" class="animation" style="position: relative;">
<svg id="noiseicon" class="svgWithText" width="170" height="100" style="padding: 5px"></svg>
<script type="text/javascript" src="js/icon_noise.js"></script>
</div>
</td>
</tr>
<tr class="figureCaption">
<td width="25%" class="animation">
<br/>
<button onClick="playWave('sine');">♫ Play</button>
</td>
<td width="25%" class="animation">
<br/>
<button onClick="playWave('square');">♫ Play</button>
</td>
<td width="25%" class="animation">
<br/>
<button onClick="playWave('sawtooth');">♫ Play</button>
</td>
<td width="25%" class="animation">
<br/>
<button onClick="playWave('custom');">♫ Play</button>
</td>
</tr>
</table>
<br/>
<p>
Notice that the spectrum of the saw and square waves look as if they could be constructed by copying, pasting, and scaling the spectrum of the sine wave. When viewing their frequency components, it looks like the square and saw wave are simply comprised of many individual sine waves. We’ll investigate this idea in later sections, and even more amazingly show that arbitrarily complex waves can be explained as combinations of simple sine waves.<sup>2</sup>
</p>
</td>
<td class="figureExplanation" style="">
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<b>1.</b>
The overtones don't necessarily lie at precise multiples of the fundamental. Many instruments derive their particular character from the drift or offset of the actual harmonic positions from the "ideal" harmonic positions. For example, the upper overtones of a piano tend to drift from the ideal harmonic positions.<br/><br/>
Our treatment of music and mathematics is very cursory. If you want to learn more, I recommend Gareth Loy's <a href="http://www.musimathics.com/">Musimathics</a>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<br/><br/><br/><br/><br/>
<b>2.</b>
We won't spend a great deal of time talking about music in this primer, but if you find the topic interesting, I suggest listening to <a href="https://soundcloud.com/marcusdusautoy/in-our-time-mathematics-and-music">this episode</a> of <i>In Our Time</i> on Music and Mathematics.
</td>
</tr>
</table><br/><br/><br/>
<script>
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var gainNode = audioCtx.createGain ? audioCtx.createGain() : audioCtx.createGainNode();
gainNode.gain.value = 0.01;
var analyser;
var javascriptNode;
FFT_SIZE = 1024;
COLOR = "#333";
var noiseBufferSize = 2 * audioCtx.sampleRate,
noiseBuffer = audioCtx.createBuffer(1, noiseBufferSize, audioCtx.sampleRate),
output = noiseBuffer.getChannelData(0);
for (var i = 0; i < noiseBufferSize; i++) {
output[i] = (Math.random() - 0.5) * 2.5;
}
javascriptNode = audioCtx.createScriptProcessor(FFT_SIZE, 1, 1);
javascriptNode.connect(audioCtx.destination);
analyser = audioCtx.createAnalyser();
analyser.smoothingTimeConstant = 0.7;
analyser.minDecibels = -90;
analyser.maxDecibels = 0;
analyser.fftSize = FFT_SIZE;
analyser.connect(javascriptNode);
analyser.connect(audioCtx.destination);
gainNode.connect(analyser);
ANALYSER_DATA = [];
NEW_DATA_AVAILABLE = false;
function playWave(type) {
console.log(type);
currentTime = audioCtx.currentTime;
if (type == "custom")
{
var whiteNoise = audioCtx.createBufferSource();
whiteNoise.buffer = noiseBuffer;
whiteNoise.loop = true;
whiteNoise.connect(gainNode);
whiteNoise.start(currentTime);
whiteNoise.stop(currentTime + 2);
}
else
{
var oscillator = audioCtx.createOscillator();
oscillator.connect(gainNode);
oscillator.frequency.value = 440;
oscillator.type = type;
oscillator.start(currentTime);
oscillator.stop(currentTime + 2);
}
if (type == 'sine') { COLOR = "steelblue"; }
if (type == 'square') { COLOR = "red"; }
if (type == 'sawtooth') { COLOR = "green"; }
if (type == 'custom') { COLOR = "grey"; }
}
javascriptNode.onaudioprocess = function() {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
ANALYSER_DATA = array;
NEW_DATA_AVAILABLE = true;
//console.log(array.length);
//console.log(max);
}
</script>
<div class="title" id="footer"></div><script type="text/javascript" src="menu.js"></script></body>
</html>