Permalink
Browse files

Init

  • Loading branch information...
0 parents commit 03f5ff3b3afaf768152fb8f3ea1ae24cfada2578 @borismus committed Mar 5, 2013
Showing with 2,414 additions and 0 deletions.
  1. +5 −0 README.md
  2. +6 −0 content/book.txt
  3. +5 −0 content/main.txt
  4. +42 −0 content/posts/audio-tag/audio-tag-sample.js
  5. BIN content/posts/audio-tag/chrono.mp3
  6. +22 −0 content/posts/audio-tag/index.txt
  7. +75 −0 content/posts/crossfade-playlist/crossfade-playlist-sample.js
  8. BIN content/posts/crossfade-playlist/crowd.wav
  9. +13 −0 content/posts/crossfade-playlist/index.txt
  10. BIN content/posts/crossfade-playlist/jam.wav
  11. +73 −0 content/posts/crossfade/crossfade-sample.js
  12. BIN content/posts/crossfade/drums.wav
  13. +13 −0 content/posts/crossfade/index.txt
  14. BIN content/posts/crossfade/organ.wav
  15. +82 −0 content/posts/filter/filter-sample.js
  16. +21 −0 content/posts/filter/index.txt
  17. BIN content/posts/filter/techno.wav
  18. +106 −0 content/posts/frequency-response/events.js
  19. +283 −0 content/posts/frequency-response/frequency-response-sample.js
  20. +42 −0 content/posts/frequency-response/index.txt
  21. +161 −0 content/posts/index.html
  22. +24 −0 content/posts/metering/index.txt
  23. BIN content/posts/metering/loud.wav
  24. +95 −0 content/posts/metering/metering-sample.js
  25. BIN content/posts/metering/sounds/chrono.mp3
  26. +12 −0 content/posts/microphone/index.txt
  27. +70 −0 content/posts/microphone/microphone-sample.js
  28. +36 −0 content/posts/oscillator/index.txt
  29. +78 −0 content/posts/oscillator/oscillator-sample.js
  30. +12 −0 content/posts/procedural/index.txt
  31. BIN content/posts/procedural/noise.wav
  32. +112 −0 content/posts/procedural/procedural-sample.js
  33. +22 −0 content/posts/rapid-sounds/index.txt
  34. +66 −0 content/posts/rapid-sounds/rapid-sounds-sample.js
  35. BIN content/posts/rapid-sounds/sounds/m1-garand.mp3
  36. BIN content/posts/rapid-sounds/sounds/m4a1.mp3
  37. BIN content/posts/rhythm/hihat.wav
  38. +17 −0 content/posts/rhythm/index.txt
  39. BIN content/posts/rhythm/kick.wav
  40. +48 −0 content/posts/rhythm/rhythm-sample.js
  41. BIN content/posts/rhythm/snare.wav
  42. +18 −0 content/posts/room-effects/index.txt
  43. +73 −0 content/posts/room-effects/room-effects-sample.js
  44. BIN content/posts/room-effects/sounds/impulse-response/echo.wav
  45. BIN content/posts/room-effects/sounds/impulse-response/muffler.wav
  46. BIN content/posts/room-effects/sounds/impulse-response/radio.wav
  47. BIN content/posts/room-effects/sounds/impulse-response/spring.wav
  48. BIN content/posts/room-effects/sounds/impulse-response/telephone.wav
  49. BIN content/posts/room-effects/sounds/speech.mp3
  50. BIN content/posts/script-processor/chrono.mp3
  51. +13 −0 content/posts/script-processor/index.txt
  52. +81 −0 content/posts/script-processor/script-processor-sample.js
  53. +54 −0 content/posts/spatialized/arrow.svg
  54. +15 −0 content/posts/spatialized/index.txt
  55. +11 −0 content/posts/spatialized/res/man.svg
  56. +66 −0 content/posts/spatialized/res/speaker.svg
  57. BIN content/posts/spatialized/sounds/position.wav
  58. +217 −0 content/posts/spatialized/spatialized-sample.js
  59. +18 −0 content/posts/value-curve/index.txt
  60. BIN content/posts/value-curve/sound.wav
  61. +83 −0 content/posts/value-curve/value-curve-sample.js
  62. BIN content/posts/visualizer/chrono.mp3
  63. +18 −0 content/posts/visualizer/index.txt
  64. BIN content/posts/visualizer/sound.wav
  65. +114 −0 content/posts/visualizer/visualizer-sample.js
  66. +15 −0 content/posts/volume/index.txt
  67. BIN content/posts/volume/techno.wav
  68. +54 −0 content/posts/volume/volume-sample.js
  69. +7 −0 content/samples.txt
  70. +10 −0 content/site.yaml
  71. +5 −0 lightning.yaml
  72. +1 −0 template
@@ -0,0 +1,5 @@
+# webaudioapi.com
+
+This is the master repo for <http://webaudioapi.com>. If you want
+something to appear on that website, please submit a pull request to
+this repo and I will push the changes once they have landed.
@@ -0,0 +1,6 @@
+Book
+=======
+type: page
+
+The content of the book will be available here for free. For now, check
+out <http://shop.oreilly.com/product/0636920025948.do>.
@@ -0,0 +1,5 @@
+Welcome
+=======
+type: index
+
+Sup.
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2013 Boris Smus. All Rights Reserved.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function AudioTagSample() {
+ // Create a new <audio> tag.
+ this.audio = new Audio();
+
+ // Note: the audio graph must be connected after the page is loaded.
+ // Otherwise, the Audio tag just plays normally and ignores the audio
+ // context. More info: crbug.com/112368
+ window.addEventListener('load', this.onload.bind(this), false);
+}
+
+AudioTagSample.prototype.onload = function() {
+ // Create the audio nodes.
+ this.source = context.createMediaElementSource(this.audio);
+ this.filter = context.createBiquadFilter();
+ this.filter.type = this.filter.LOWPASS;
+ this.filter.frequency.value = 500;
+
+ // Connect the audio graph.
+ this.source.connect(this.filter);
+ this.filter.connect(context.destination);
+};
+
+AudioTagSample.prototype.play = function(url) {
+ this.audio.src = url;
+ this.audio.play();
+};
Binary file not shown.
@@ -0,0 +1,22 @@
+Audio Tag
+=========
+posted: 2013-03-03
+description: >
+ Illustrates the use of MediaElementAudioSourceNode to wrap the audio
+ tag.
+
+A couple issues: `onload` is required <http://crbug.com/112368>. Also,
+reassigning the `@src` attribute causes audio glitches
+<http://crbug.com/162528>.
+
+<input value="chrono.mp3" placeholder="URL to audio file...">
+<button onclick="sample.play(document.querySelector('input').value)">Load URL</button>
+
+<script src="/static/js/shared.js"></script>
+<script src="audio-tag-sample.js"></script>
+<script>
+var input = document.querySelector('input');
+var sample = new AudioTagSample();
+
+sample.play(input.value);
+</script>
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2013 Boris Smus. All Rights Reserved.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var CrossfadePlaylistSample = function() {
+ this.FADE_TIME = 1; // Seconds
+ this.isPlaying = false;
+ loadSounds(this, {
+ jam: 'jam.wav',
+ crowd: 'crowd.wav'
+ });
+};
+
+CrossfadePlaylistSample.prototype.play = function() {
+ var ctx = this;
+ playHelper([this.jam, this.crowd], 4, 1);
+
+ function createSource(buffer) {
+ var source = context.createBufferSource();
+ var gainNode = context.createGainNode();
+ source.buffer = buffer;
+ // Connect source to gain.
+ source.connect(gainNode);
+ // Connect gain to destination.
+ gainNode.connect(context.destination);
+
+ return {
+ source: source,
+ gainNode: gainNode
+ };
+ }
+
+ /**
+ * Plays back a playlist of buffers, automatically crossfading between them.
+ * Iterations specifies the number of times to play through the playlist.
+ */
+ function playHelper(buffers, iterations, fadeTime) {
+ var currTime = context.currentTime;
+ for (var i = 0; i < iterations; i++) {
+ // For each buffer, schedule its playback in the future.
+ for (var j = 0; j < buffers.length; j++) {
+ var buffer = buffers[j];
+ var duration = buffer.duration;
+ var info = createSource(buffer);
+ var source = info.source;
+ var gainNode = info.gainNode;
+ // Fade it in.
+ gainNode.gain.linearRampToValueAtTime(0, currTime);
+ gainNode.gain.linearRampToValueAtTime(1, currTime + fadeTime);
+ // Then fade it out.
+ gainNode.gain.linearRampToValueAtTime(1, currTime + duration-fadeTime);
+ gainNode.gain.linearRampToValueAtTime(0, currTime + duration);
+
+ // Play the track now.
+ source.start(currTime);
+
+ // Increment time for the next iteration.
+ currTime += duration - fadeTime;
+ }
+ }
+ }
+
+};
Binary file not shown.
@@ -0,0 +1,13 @@
+Crossfading Playlist
+====================
+posted: 2013-03-03
+description: >
+ Automatic crossfading between songs (as in a playlist).
+
+<input type="button" onclick="sample.play();" value="Play">
+
+<script src="/static/js/shared.js"></script>
+<script src="crossfade-playlist-sample.js"></script>
+<script>
+var sample = new CrossfadePlaylistSample();
+</script>
Binary file not shown.
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2013 Boris Smus. All Rights Reserved.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var CrossfadeSample = function() {
+ loadSounds(this, {
+ drums: 'drums.wav',
+ organ: 'organ.wav'
+ });
+ this.isPlaying = false;
+}
+
+CrossfadeSample.prototype.play = function() {
+ // Create two sources.
+ this.ctl1 = createSource(this.drums);
+ this.ctl2 = createSource(this.organ);
+ // Mute the second source.
+ this.ctl1.gainNode.gain.value = 0;
+ // Start playback in a loop
+ this.ctl1.source.start(0);
+ this.ctl2.source.start(0);
+ // Set the initial crossfade to be just source 1.
+ this.crossfade(0);
+
+ function createSource(buffer) {
+ var source = context.createBufferSource();
+ var gainNode = context.createGainNode();
+ source.buffer = buffer;
+ // Turn on looping
+ source.loop = true;
+ // Connect source to gain.
+ source.connect(gainNode);
+ // Connect gain to destination.
+ gainNode.connect(context.destination);
+
+ return {
+ source: source,
+ gainNode: gainNode
+ };
+ }
+};
+
+CrossfadeSample.prototype.stop = function() {
+ this.ctl1.source.noteOff(0);
+ this.ctl2.source.noteOff(0);
+};
+
+// Fades between 0 (all source 1) and 1 (all source 2)
+CrossfadeSample.prototype.crossfade = function(element) {
+ var x = parseInt(element.value) / parseInt(element.max);
+ // Use an equal-power crossfading curve:
+ var gain1 = Math.cos(x * 0.5*Math.PI);
+ var gain2 = Math.cos((1.0 - x) * 0.5*Math.PI);
+ this.ctl1.gainNode.gain.value = gain1;
+ this.ctl2.gainNode.gain.value = gain2;
+};
+
+CrossfadeSample.prototype.toggle = function() {
+ this.isPlaying ? this.stop() : this.play();
+ this.isPlaying = !this.isPlaying;
+};
Binary file not shown.
@@ -0,0 +1,13 @@
+Crossfade
+=========
+posted: 2013-03-03
+description: Equal-power crossfading to mix between two tracks.
+
+<input type="button" onclick="sample.toggle();" value="Play/Pause">
+Drums <input type="range" min="0" max="100" value="100" onchange="sample.crossfade(this);"> Organ
+
+<script src="/static/js/shared.js"></script>
+<script src="crossfade-sample.js"></script>
+<script>
+var sample = new CrossfadeSample();
+</script>
Binary file not shown.
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013 Boris Smus. All Rights Reserved.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var QUAL_MUL = 30;
+
+function FilterSample() {
+ this.isPlaying = false;
+ loadSounds(this, {buffer: 'techno.wav'});
+};
+
+FilterSample.prototype.play = function() {
+ // Create the source.
+ var source = context.createBufferSource();
+ source.buffer = this.buffer;
+ // Create the filter.
+ var filter = context.createBiquadFilter();
+ filter.type = filter.LOWPASS;
+ filter.frequency.value = 5000;
+ // Connect source to filter, filter to destination.
+ source.connect(filter);
+ filter.connect(context.destination);
+ // Play!
+ source.start(0);
+ source.loop = true;
+ // Save source and filterNode for later access.
+ this.source = source;
+ this.filter = filter;
+};
+
+FilterSample.prototype.stop = function() {
+ this.source.stop(0);
+};
+
+FilterSample.prototype.toggle = function() {
+ this.isPlaying ? this.stop() : this.play();
+ this.isPlaying = !this.isPlaying;
+};
+
+FilterSample.prototype.changeFrequency = function(element) {
+ // Clamp the frequency between the minimum value (40 Hz) and half of the
+ // sampling rate.
+ var minValue = 40;
+ var maxValue = context.sampleRate / 2;
+ // Logarithm (base 2) to compute how many octaves fall in the range.
+ var numberOfOctaves = Math.log(maxValue / minValue) / Math.LN2;
+ // Compute a multiplier from 0 to 1 based on an exponential scale.
+ var multiplier = Math.pow(2, numberOfOctaves * (element.value - 1.0));
+ // Get back to the frequency value between min and max.
+ this.filter.frequency.value = maxValue * multiplier;
+};
+
+FilterSample.prototype.changeQuality = function(element) {
+ this.filter.Q.value = element.value * QUAL_MUL;
+};
+
+FilterSample.prototype.toggleFilter = function(element) {
+ this.source.disconnect(0);
+ this.filter.disconnect(0);
+ // Check if we want to enable the filter.
+ if (element.checked) {
+ // Connect through the filter.
+ this.source.connect(this.filter);
+ this.filter.connect(context.destination);
+ } else {
+ // Otherwise, connect directly.
+ this.source.connect(context.destination);
+ }
+};
@@ -0,0 +1,21 @@
+Filter
+======
+posted: 2013-03-03
+description: >
+ Apply a simple low pass filter to a sound. Lets you tweak
+ frequency and Q values.
+
+<input type="button" onclick="sample.toggle();" value="Play/Pause">
+
+<input type="checkbox" id="c1" checked="false" onchange="sample.toggleFilter(this);">
+<label for="c1"><span></span>Enable filter</label>
+
+<input type="range" min="0" max="1" step="0.01" value="1" onchange="sample.changeFrequency(this);"> Frequency
+
+<input type="range" min="0" max="1" step="0.01" value="0" onchange="sample.changeQuality(this);"> Quality
+
+<script src="/static/js/shared.js"></script>
+<script src="filter-sample.js"></script>
+<script>
+var sample = new FilterSample();
+</script>
Binary file not shown.
Oops, something went wrong.

0 comments on commit 03f5ff3

Please sign in to comment.