Web Audio API: Load, Filter, Gain, Play
For more info, see "Let's make some noise: Web Audio API" presentation made for Kharkiv Front-End Practice: http://flash-ripper.com/web-audio-api Track playing is "Poor Old Dirt Farmer" by Levon Helm
by enbette
HTML
<section>
<h1>Load Sound, add LowPass Filter & Gain - Web Audio API</h1>
<span class="info">Loading track...</span> | <a href="#pause" class="bt-mute">Mute</a>
</section>
<section class="controls">
<input type="range" min="0" max="1" step="0.01" value="1" class="volume-slider" />
<label>Volume</label>
<input type="range" min="0" max="1" step="0.01" value="1" class="freq-slider" />
<label>Filter Frequency</label>
<input type="range" min="0" max="1" step="0.01" value="0" class="q-slider" />
<label>Filter Q</label>
<input type="range" min="1" max="1000" step="0.01" value="0" class="filter-interval" />
<label>Filter Animation [<a href="#shuffle" class="bt-shuffle">stop</a>]</label>
</section>
<footer>Info: "<a href="http://flash-ripper.com/web-audio-api">Let's make some noise: Web Audio API</a>" presentation for <a href="http://front-end.globallogic.com.ua/">Kharkiv Front-End Practice</a> made by <small><a href="http://facebook.com/rastislavr">Rastislavr</a>. Track is '<a href="https://www.youtube.com/watch?v=cBuJB218UvU">Poor Old Dirt Farmer</a>' by <a href="https://en.wikipedia.org/wiki/Levon_Helm">Levon Helm</a></small>
</footer>
CSS
/** IMPORTANT NOTICE TO WHOM IT MAY CONCERN
* CSS IS MINOR ONLY BASED ON THE BRILLIANT
* https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/
**/
body {
padding: 0.6em 0.5em 0 0.5em;
font-size: 1.2em;
}
h1 {
font-size: 1.7em;
margin: 0 0 1em 0;
}
section {
padding: 0.5em;
}
.controls {
padding: 0em 0 0 3em;
}
footer {
margin-top: 1em;
font-size: 0.8em;
}
.volume-slider, .freq-slider, .q-slider {
background: #fc0
}
label {
display: inline-block;
width: 50%;
padding-left: 0.4em;
font-size: 1.5em;
font-weight: normal;
}
input[type=range] {
-webkit-appearance: none;
margin: 18px 0;
width: 40%;
display: inline-block;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 16px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #ddd, 0px 0px 1px #0d0d0d;
background: #ccc;
border-radius: 0;
}
.volume-slider[type=range]::-webkit-slider-runnable-track {
background: #d31;
}
.freq-slider[type=range]::-webkit-slider-runnable-track {
background: #fc2;
}
.q-slider[type=range]::-webkit-slider-runnable-track {
background: #3b1;
}
input[type=range]::-webkit-slider-thumb {
background-color: #fco;
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 1px 1px 3px #555, 0px 0px 1px #999;
border: 1px none #000000;
height: 27px;
width: 27px;
border-radius: 6px;
background: #fff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -6px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #367ebd;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3px;
border:...
JavaScript
/* global AudioContext, console */
(function () {
'use strict';
// Let's make some noise:
var audioContext;
// a gain node & filter node
var gainNode;
var filterNode;
var shuffleTimeoutInterval;
var params = {
currentGain: 0.1,
currentFilterFrequency: 1,
currentFilterQ: 0,
filterFrequencyMult: 7000,
filterQualityMult: 30,
shuffleTimeoutIntervalDuration: 5000
};
try {
// Fix up for prefixing
window.AudioContext = window.AudioContext || window.webkitAudioContext;
audioContext = new AudioContext();
} catch (e) {
console.log('Web Audio API is not supported in this browser');
}
gainNode = audioContext.createGain();
filterNode = audioContext.createBiquadFilter();
// Create and specify parameters for the low-pass filterNode.
// Low-pass filter. See BiquadFilterNode docs
filterNode.type = 'lowpass';
setFrequency(params.currentFilterFrequency);
setQuality(params.currentFilterQ);
function shiftParameters() {
var f = Math.random();
var q = Math.random();
setFrequency(f);
setQuality(q);
sliderFreq.value = f;
sliderQ.value = q;
}
function loadSomeNoise(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
// Decode asynchronously
request.onload = function () {
audioContext.decodeAudioData(request.response, function (buffer) {
playSound(buffer);
}, function (error) {
console.log(error);
});
};
request.send();
var info = document.querySelector('.info');
function playSound(buffer) {
// create a sound source
var source = audioContext.createBufferSource();
//...