Sunday, January 3, 2016

Real Time Visualization of Raw Sound from Microphone Input using HTML5

From www.smartjava.org ...

In order to use the webkitGetUserMedia method, your html code needs to be deployed on a server. That means, you can't just open the html in Google Chrome. This is unfortunate. However, you can deploy onto a server doing these three steps.


1. Install Tomcat 7 - http://mirror.symnds.com/software/Apache/tomcat/tomcat-7/v7.0.54/bin/apache-tomcat-7.0.54.exe
2. Go to the Task Manager, Services Tab, Services and start Tomcat
3. Open http://localhost:8080 in Chrome

You should see the index.jsp page that was installed with Tomcat. This would normally be in the "C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\ROOT" directory.

Create and html file named volume.html with the following contents:

<html>
<head>

<script type="text/javascript">

function canvasDrawLine(oPosX, oPosY, fPosX, fPosY) {
    var ctx = getCanvas().getContext('2d');
    ctx.beginPath();
    ctx.moveTo(oPosX, oPosY);
    ctx.lineTo(fPosX, fPosY);
    ctx.stroke();
}

function canvasDrawSquare(ulPosX, ulPosY, lrPosX, lrPosY) {
    canvasDrawLine(ulPosX, ulPosY, ulPosX, lrPosY);
    canvasDrawLine(ulPosX, lrPosY, lrPosX, lrPosY);
    canvasDrawLine(lrPosX, lrPosY, lrPosX, ulPosY);
    canvasDrawLine(lrPosX, ulPosY, ulPosX, ulPosY);


function canvasInitialize(width, height) {
    // Set canvas parameters
    getCanvas().width = width;
    getCanvas().height = height;

    // Outline
    getCanvas().getContext('2d').clearRect(0,0,width,height);
    canvasDrawSquare(0,0,width,height);
}

function getAverageVolume(array) {
    var values = 0; 
    // get all the frequency amplitudes
    for (var i = 0; i < array.length; i++) {
        values += array[i];
    }
    return values / (array.length);
}

function onSuccess(stream) {
    var context = new webkitAudioContext();
    var mediaStreamSource = context.createMediaStreamSource(stream);
    
    var analyser = context.createAnalyser();
    analyser.smoothingTimeConstant = 0.3;
    analyser.fftSize = 1024;
    
    var javascriptNode = context.createScriptProcessor(2048, 1, 1);
    
    javascriptNode.onaudioprocess = function(e) {
        //var sample = e.inputBuffer.getChannelData(0);

        // get the average, bincount is fftsize / 2
        var array =  new Uint8Array(analyser.frequencyBinCount);
        analyser.getByteFrequencyData(array);
        
        // calculate average
        var average = getAverageVolume(array)
        
        // print value out
        log(average);
        
        // draw green bar
        getCanvas().getContext('2d').strokeStyle='#000000';
        canvasInitialize(200,200);
        getCanvas().getContext('2d').strokeStyle='#00ff00';
        canvasDrawSquare(10, 150, 20, 150-average*5);
    };
    
    // stream -> mediaSource -> analyser -> javascriptNode -> destination
    mediaStreamSource.connect(analyser);
    analyser.connect(javascriptNode);
    javascriptNode.connect(context.destination);
}

function onError() {
    alert('Error');
}

function log(logVal) {
    getLog().innerHTML = logVal + '\n<br>';
}

function getCanvas() {
    return document.getElementById('mycanvas');
}    
 
function getLog() {
    return document.getElementById('mylog');
}
  
function documentReady() {
    if(navigator.getUserMedia) {
        navigator.getUserMedia({video: false, audio: true}, onSuccess, onError);
    } else if(navigator.webkitGetUserMedia) {
        navigator.webkitGetUserMedia({video: false, audio: true}, onSuccess, onError);
    }
}
</script>
</head>

<body onload="documentReady();">
   <canvas id="mycanvas"></canvas>
   <div id="mylog"></div>
</body>
</html>


Without stopping Tomcat, copy this file into the ROOT directory, specified above and open the http://localhost:8080/volume.html in Google Chrome. You should see a message that allows you to access the Microphone. Then you should see a green box along with changing numbers that indicate the volume.

This post was reposted from scottizu.wordpress.com, originally written on June 23rd, 2014.

3 comments:

  1. Replies
    1. Yes, it should. Javascript works in the Chrome/Safari browsers in IOS.

      Delete
  2. Yes, because it is html for Chrome Browser. On IOS, operating system, download Chrome and run the above.

    ReplyDelete