Skip to content

Instantly share code, notes, and snippets.

@fluffy
Created December 27, 2013 16:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fluffy/8149170 to your computer and use it in GitHub Desktop.
Save fluffy/8149170 to your computer and use it in GitHub Desktop.
Does an audio sweep to speakers then graphs microphone response
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>Sweep 2</title>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
<script>
var startFreq = 500;
var endFreq = 25000;
var freqStep = 250;
var timeStep = 0.100;
function hasGetUserMedia() {
return !!(navigator.getUserMedia
|| navigator.mozGetUserMedia
|| navigator.webkitGetUserMedia
|| navigator.msGetUserMedia);
}
if (hasGetUserMedia()) {
navigator.getUserMedia = navigator.getUserMedia
|| navigator.mozGetUserMedia
|| navigator.webkitGetUserMedia
|| navigator.msGetUserMedia;
} else {
alert('Browser does not support getUserMedia. Try FireFox or Chrome');
}
var contextClass = (window.AudioContext
|| window.webkitAudioContext
|| window.mozAudioContext
|| window.oAudioContext
|| window.msAudioContext);
if (contextClass) {
var context = new contextClass();
} else {
alert('Browser does not support webAudio. Try Firefox or Chrome');
}
var microphone;
var processor;
var osc = context.createOscillator();
osc.frequency.value = 100;
osc.type = 'sine';
var gain = context.createGain();
gain.gain.value = 0.0;
osc.connect( gain )
gain.connect( context.destination );
osc.start( 0 );
var startTime = 0;
var freqVal = new Array( 1000 );
var sigVal = new Array( 1000 );
var numVals = 0;
var numSamples = 2048; // must be power of 2
navigator.getUserMedia( {audio: true} , gumStream, gumError );
function gumStream(stream) {
console.log("Got GUM stream");
microphone = context.createMediaStreamSource(stream);
processor = context.createScriptProcessor(numSamples,2,2);
processor.onaudioprocess = processAudio;
microphone.connect(processor);
processor.connect(context.destination);
}
function gumError(err) {
console.log("The following GUM error occured: " + err);
}
function processAudio(e) {
//console.log( "In processAudio");
var lIn = e.inputBuffer.getChannelData(0);
var rIn = e.inputBuffer.getChannelData(1);
var lOut = e.outputBuffer.getChannelData(0);
var rOut = e.outputBuffer.getChannelData(1);
var time = context.currentTime;
if ( lIn.length > numSamples ){
alert("something bad happended");
}
//if ( osc.frequency.value >= endFreq ) // broken in FF, works in Chrome, Dec 2013
//{
// return;
//}
if ( time >= startTime + timeStep * (endFreq-startFreq)/freqStep ){
draw();
return;
}
var sum = Math.abs( lIn[0] );
var cross = 0;
for (var i = 1; i < lIn.length; i++){
//sum += Math.abs( lIn[i] );
sum += lIn[i] * lIn[i];
if ( lIn[i-1] <= 0.0 ){
if ( lIn[i] > 0.0 ){
cross++;
}
}
}
var freq = startFreq + ( (time-startTime) / timeStep - 1 ) * freqStep ;
freq = Math.floor( freq/freqStep ) * freqStep;
var sig = 10.0 * Math.log( Math.sqrt( sum/lIn.length ) ) / Math.log( 10.0 );
if ( startTime != 0 ){
//console.log( " O Freq=" + osc.frequency.value + " Sig=" + sig + " Time=" + time + " T Freq=" + freq);
freqVal[ numVals ] = freq;
sigVal[ numVals ] = sig;
numVals++;
if ( numVals >= 1000 )
{
alert( "something bad happened - too many values" );
}
}
for (var i = 0; i < lOut.length; i++) {
lOut[i] = 0.0;
rOut[i] = 0.0;
}
}
function line( context, c1,r1, c2,r2, color ) {
context.beginPath();
context.strokeStyle = color;
context.moveTo( c1, r1 );
context.lineTo( c2, r2 );
context.stroke();
}
function draw() {
if ( numVals == 0 ) {
return;
}
var canvas = document.getElementById('canvas1');
var context = canvas.getContext('2d');
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.strokeStyle = '#0000FF'; // blue
context.moveTo( 0, context.canvas.height );
for( var i=0; i < numVals ; i++ ){
var freq = freqVal[i];
var sig = sigVal[i];
console.log( "Freq="+ freq + " Sig=" + sig );
var row = - sig * 4;
var col = context.canvas.width * (freq-startFreq) / (endFreq-startFreq) ;
context.lineTo( col, row );
}
context.stroke();
numVals = 0;
var col = 0;
col = context.canvas.width * ( 5000-startFreq) / (endFreq-startFreq) ;
line( context, col,0, col,context.canvas.height, '#777' );
col = context.canvas.width * (10000-startFreq) / (endFreq-startFreq) ;
line( context, col,0, col,context.canvas.height, '#000' );
col = context.canvas.width * (15000-startFreq) / (endFreq-startFreq) ;
line( context, col,0, col,context.canvas.height, '#777' );
col = context.canvas.width * (20000-startFreq) / (endFreq-startFreq) ;
line( context, col,0, col,context.canvas.height, '#000' );
var row;
row = 0 * 4; line( context, 0,row, context.canvas.width,row, '#777' );
row = 10 * 4; line( context, 0,row, context.canvas.width,row, '#777' );
row = 20 * 4; line( context, 0,row, context.canvas.width,row, '#777' );
row = 30 * 4; line( context, 0,row, context.canvas.width,row, '#777' );
}
function playTones() {
var time = context.currentTime;
startTime = time;
numVals = 0;
gain.gain.setValueAtTime( 0.0, time );
time += timeStep;
//gain.gain.linearRampToValueAtTime( 22000, time+5.0 ); // broken in FF and Chrome Dec, 2013
for ( var f=startFreq; f <= endFreq; f += freqStep ) {
osc.frequency.setValueAtTime( f, time );
gain.gain.linearRampToValueAtTime( 0.5, time+0.010 );
time += timeStep;
gain.gain.setValueAtTime( 0.5, time-0.010 );
gain.gain.linearRampToValueAtTime( 0.0, time );
}
time += timeStep;
gain.gain.setValueAtTime( 0, time );
}
</script>
</head>
<body>
<h1>Sweep 2</h1>
<canvas id="canvas1" width="1000" height="200"></canvas>
</br>
Gen: <input type="button" id="genButton" onclick="playTones()" value="Go" />
</br>
</body> </html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment