A Tutorial for Real Time Pitch Detection with HTML5

This post has been moved to .

Advertisements

Three Ways to Access the JIRA API

Here is a list of various urls and commands that are helpful for accessing JIRA.

The -k is for insecure connections, and -u is to add the username:password to each command. You might need the $projectKey or $issueID as well.

HttpClient


	public static void main(String[] args) throws Exception {
		System.out.println("Step 1: Setup Authentication Information");
		String HOST = jlc.getHost(); // jira.corp.com
		String URL = jlc.getUrl(); // https://jira.corp.com
		String USERNAME = jlc.getUsername(); // ...
		String PASSWORD = jlc.getPassword(); // ...

		System.out.println("Step 2: Install SSL Certificate");		
		SSLHandler.setupSSLContextByInstallingCertification(HOST);

		System.out.println("Step 3: Query Server");	
		HttpGet httpGet = new HttpGet(URL+"/rest/api/2/project");
		String basic_auth = new String(Base64.encodeBase64((USERNAME+":"+PASSWORD).getBytes()));
		httpGet.addHeader("Authorization", "Basic " + basic_auth);
		
		CloseableHttpResponse response = new DefaultHttpClient().execute(httpGet);
		String jsonResponse = EntityUtils.toString(response.getEntity());
		response.close();

		System.out.println("Step 4: List Projects");
		JSONArray projectArray = new JSONArray(jsonResponse);
		for (int i = 0; i < projectArray.length(); i++) {
			JSONObject proj = projectArray.getJSONObject(i);
			System.out.println("JSONObject Project Name:"+proj.getString("name"));
		}
	}

JiraRestClient


	public static void main(String[] args) throws Exception {
		System.out.println("Step 1: Setup Authentication Information");
		String HOST = jlc.getHost(); // jira.corp.com
		String URL = jlc.getUrl(); // https://jira.corp.com
		String USERNAME = jlc.getUsername(); // ...
		String PASSWORD = jlc.getPassword(); // ...

		System.out.println("Step 2: Install SSL Certificate");		
		SSLHandler.setupSSLContextByInstallingCertification(HOST);

		System.out.println("Step 3: Query Server");		
		final JiraRestClientFactory jiraRestClientFactory = new AsynchronousJiraRestClientFactory();
		JiraRestClient jiraRestClient = jiraRestClientFactory
						.createWithBasicHttpAuthentication(URI.create(URL), USERNAME, PASSWORD);
		
		Iterable basicProjects = jiraRestClient.getProjectClient().getAllProjects().get();
		jiraRestClient.close();

		System.out.println("Step 4: List Projects");
		for(BasicProject project: basicProjects) {
			System.out.println("BasicProject Project Name:"+project.getName());
		}	
	}

WebResource


	public static void main(String[] args) throws Exception {
		System.out.println("Step 1: Setup Authentication Information");
		String HOST = jlc.getHost(); // jira.corp.com
		String URL = jlc.getUrl(); // https://jira.corp.com
		String USERNAME = jlc.getUsername(); // ...
		String PASSWORD = jlc.getPassword(); // ...

		System.out.println("Step 2: Install SSL Certificate");		
		SSLHandler.setupSSLContextByInstallingCertification(HOST);

		System.out.println("Step 3: Query Server");	
		Client client = Client.create();
		client.addFilter(new HTTPBasicAuthFilter(USERNAME, PASSWORD));
		WebResource webResource = client.resource(URL+"/rest/api/2/project");
		ClientResponse response = webResource.type("application/json").accept("application/json").get(ClientResponse.class);
		String jsonResponse = response.getEntity(String.class);
		response.close();
		client.destroy();

		System.out.println("Step 4: List Projects:"+jsonResponse);
		JSONArray projectArray = new JSONArray(jsonResponse);
		for (int i = 0; i < projectArray.length(); i++) {
			JSONObject proj = projectArray.getJSONObject(i);
			System.out.println("JSONObject Project Name:"+proj.getString("name"));
		}
	}

You may need this class for SSL:


public class SSLHandler {
	/**
	 * Installs C:\Program Files\Java\jdk1.7.0_51\jre\lib\security\jssecacerts file
	 * @param host
	 * @throws Exception
	 */
	public static void setupSSLContextByInstallingCertification(String host) {
		System.out.println("Installing SSLContext Certification into Java Home...");
		try {
	        int port = 443;
	        char[] passphrase = "changeit".toCharArray();
			
	        char SEP = File.separatorChar;
	        File file = new File("jssecacerts");
	        if (file.isFile() == false) {
	            File dir = new File(System.getProperty("java.home") + SEP
	                    + "lib" + SEP + "security");
	            file = new File(dir, "jssecacerts");
	            if (file.isFile() == false) {
	                file = new File(dir, "cacerts");
	            }
	        }
	        
	        System.out.println("Loading KeyStore " + file + "...");
	        InputStream in = new FileInputStream(file);
	        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
	        ks.load(in, passphrase);
	        in.close();
	 
	        TrustManagerFactory tmf =
	                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
	        tmf.init(ks);
	        final X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
	        final List chainList = new ArrayList();
	        
			TrustManager tm = new X509TrustManager() {
				public void checkClientTrusted(X509Certificate[] arg0, String arg1)
								throws CertificateException { }
				public void checkServerTrusted(X509Certificate[] arg0, String arg1)
						throws CertificateException {
						chainList.clear();
						if(arg0 != null) {
							for (int i = 0; i < arg0.length; i++) {
								chainList.add(arg0[i]);
							}
						}
						defaultTrustManager.checkServerTrusted(arg0, arg1); }
				public X509Certificate[] getAcceptedIssuers() { return null; }
			};
			
	        SSLContext context = SSLContext.getInstance("TLS");
	        context.init(null, new TrustManager[]{tm}, null);
	        SSLSocketFactory factory = context.getSocketFactory();
	 
	        System.out.println("Opening connection to " + host + ":" + port + "...");
	        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
	        socket.setSoTimeout(10000);
	        try {
	            socket.startHandshake();
	            System.out.println("No errors, certificate is already trusted");
	        } catch (SSLException e) { }
	        socket.close();
	 
	        if (chainList.isEmpty()) {
	            System.out.println("Could not obtain server certificate chain");
	            return;
	        }
	 
	        System.out.println("Server sent " + chainList.size() + " certificate(s):");

	        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
	        MessageDigest md5 = MessageDigest.getInstance("MD5");
	        for (int i = 0; i > 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }
}

Other Resources for Creating Tickets

Integrating Google Docs Spreadsheet with Google Maps

Suppose you want to keep a Google Docs Spreadsheet to track your mileage and travel for business expenses.

VIEW DIRECTIONS XML
You can use the Google Maps API as follows. Open Google Chrome and enter the following address:
maps.googleapis.com

If you look at the target anchor, you will see origin=%22…%22&destination=%22…%22. Currently, the first … is a Starbucks location at Berryessa and Lundy in San Jose, CA and the second … is a Starbucks location at Alum Rock and White in San Jose, CA. %20 is a space. You can change this as you would like, but this will show an xml formatted “DirectionsResponse”.

If you look at the xpath “//DirectionsResponse/route/leg/duration/value” and “//DirectionsResponse/route/leg/duration/text” you will see 499 and 8 mins which reflect the time. If you look at the xpath “//DirectionsResponse/route/leg/distance/value” and “//DirectionsResponse/route/leg/distance/text” you will see 6846 and “4.3 mi” which reflect the distance.

ADD MILES CALCULATION DIRECTLY IN GOOGLE DOCS SPREADSHEET
In a Google Docs Spreadsheet, you can place in A1: 3103 Alum Rock Ave, San Jose, CA 95127
You can place in A2: 1712 Berryessa Rd, San Jose, CA 95133
Then, in A3: =importxml(“http://maps.googleapis.com/maps/api/directions/xml?origin=&#8221; & A1 & “&destination=” & A2 & “&sensor=false&alternatives=false”,”//DirectionsResponse/route/leg/distance/text”)

Or alternatively in A3: =importxml(“http://maps.googleapis.com/maps/api/directions/xml?origin=&#8221; & G213 & “&destination=” & H213 & “&sensor=false&alternatives=false”,”//DirectionsResponse/route/leg/distance/value”)/1000*.621371

The value is meters, so divide by 1000 to get kilo meters and then multiply by .621371 since 1 kilo meter is .621371 miles.

This was from productforums.google.com.

Adding links is easy as well (see gearside.com and productforums.google.com).

VIEW PLACE PAGE (Can be used on your phone to navigate to the location by hitting directions)
Open www.google.com in Google Chrome.

ADD HYPERLINK TO LOCATION IN GOOGLE DOCS
=Hyperlink(“www.google.com/maps/place/” & A1, “GO”)

EXAMPLE SPREADSHEET


In A1: Date
In B1: Start
In C1: Nav
In D1: Destination
In E1: Nav
In F1: Distance
In G1: Time
In H1: Purpose
In A2: 07/31/2014
In B2: 1712 Berryessa Rd, San Jose, CA 95133
In C2: =Hyperlink("www.google.com/maps/place/" & B2, "GO S")
In D2: 3103 Alum Rock Ave, San Jose, CA 95127
In E2: =Hyperlink("www.google.com/maps/place/" & D2, "GO D")
In F2: =importxml("http://maps.googleapis.com/maps/api/directions/xml?origin=" & B2 & "&destination=" & D2 & "&sensor=false&alternatives=false","//DirectionsResponse/route/leg/distance/value")/1000*.621371
In G2: =importxml("http://maps.googleapis.com/maps/api/directions/xml?origin=" & B2 & "&destination=" & D2 & "&sensor=false&alternatives=false","//DirectionsResponse/route/leg/duration/text")
In H2: Appointment

This will calculate trip mileage and allow you to pull up recent locations to directly navigate when to recent locations.

Capture

A Simple Image Overlay Example

From jquerytools.org

This example uses jquery 1.2.7. Create a file “test.html” and edit with a text editor. Add the following code. You will need to add an image “myimage.png” to the same directory.


<html>
    <head>
        <meta charset="UTF-8" />
        <title>Image Overlay Example</title>
		<script src="http://cdn.jquerytools.org/1.2.7/full/jquery.tools.min.js"></script>

	</head>
    <body>
<p>
	<button class="modalInput" rel="#myID">Show Image</button>
	<!-- yes/no dialog -->
	<div class="modal" id="myID" style="display:none;padding:15px;border:2px solid #333;-webkit-border-radius:6px;">
		<image src="myImage.png" />
		<br>
		<button class="close">Close</button>
	</div>
</p>

<script>
$(document).ready(function() {
	$(".modalInput").overlay({
		// some mask tweaks suitable for modal dialogs
		mask: {
			color: '#ebecff',
			loadSpeed: 200,
			opacity: 0.9
			},
		closeOnClick: false,
		fixed: false
	});
  });
</script>
    </body>
</html>

Working with JQuery, JSFiddle and Highcharts

At www.highcharts.com, there are several possible javascript charts that can be used to visualize data. Click demo, highcharts demos. Click on edit in JSFiddle to go to jsfiddle.net. In order to get this example working, you will need to include three things: 1) JQuery, 2) Javascript and 3) HTML.

Create a new file named “highcharts.html” and edit it with a text editor like Notepad or Notepad++. Copy the following template:


<html>
<!--INCLUDE_JQUERY-->
<script type="text/javascript">
<!--INCLUDE_JAVASCRIPT-->
</script>
<body>
<!--INCLUDE_HTML-->
</body>
</html>

Insert code to include JQuery on the line after the INCLUDE_JQUERY marker. In this JSFiddle example, they reference JQuery 1.9.1 so you would add the following:


<!--INCLUDE_JQUERY-->
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>

You might have to google “Include JQuery 1.9.1” or such for other versions since JQuery 1.4 is included with the following:


<!--INCLUDE_JQUERY-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>

Next, insert the Javascript code on the line after INCLUDE_JAVASCRIPT and the html code on the line after INCLUDE_HTML. This will give you the following html file:


<html>

<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(function () {
        $('#container').highcharts({
            title: {
                text: 'Monthly Average Temperature',
                x: -20 //center
            },
            subtitle: {
                text: 'Source: WorldClimate.com',
                x: -20
            },
            xAxis: {
                categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
            },
            yAxis: {
                title: {
                    text: 'Temperature (°C)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '°C'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: [{
                name: 'Tokyo',
                data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
            }, {
                name: 'New York',
                data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
            }, {
                name: 'Berlin',
                data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
            }, {
                name: 'London',
                data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
            }]
        });
    });
</script>
<body>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
</html>

You can then open this html file in firefox to see the basic chart demonstrated by the demo.

Pulling out the actual variables from the highcharts code, we create variables for chartTitle, chartSubTitle, yAxisTitle, monthsArray and seriesJSONArray. This might yield the following code:


<html>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
var chartTitle = 'Financial Tracking';
var chartSubTitle = '2014';
var yAxisTitle = 'Totals';
var monthsArray =  ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
var seriesJSONArray = [];
seriesJSONArray[0] = new Object();
seriesJSONArray[0].name = 'Debt'
seriesJSONArray[0].data = [-61958, -57724, -54632, -53689, -34209, -36329];
seriesJSONArray[1] = new Object();
seriesJSONArray[1].name = 'Net Worth'
seriesJSONArray[1].data = [-41794, -38026, -33297, -31256, -25154, -26260];

$(function () {
        $('#container').highcharts({
            title: {
                text: chartTitle,
                x: -20 //center
            },
            subtitle: {
                text: chartSubTitle,
                x: -20
            },
            xAxis: {
                categories: monthsArray
            },
            yAxis: {
                title: {
                    text: yAxisTitle
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
			series: seriesJSONArray
        });
    });
</script>
<body>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
</html>

This displays the following.

Financials

A Skeleton for Real Time Pitch Detection

See Real Time Visualization of a Spectrogram for reference on how to get this html page to respond to mic input (ie needs to be served by Tomcat).

This uses a modification of the pitch detection code found at updates.html5rocks.com to identify frequencies between E (329.6 Hz) and E (659.3 Hz).


<html>
<head>
<script type="text/javascript">

function interpolate(x, x0, xf, y0, yf) {
	// (x - x0)/(xf - x0) = (y - y0)/(yf - y0)
	// y = ( (x-x0)/(xf-x0) ) * (yf-y0) + y0
	return Math.floor( ( (x-x0)/(xf-x0) ) * (yf-y0) + y0 );
}

// colors:['#000000', '#ff0000', '#ffff00', '#ffffff']
// positions:[0, 64-1, 192-1, 255]
// 0 = parseInt('00', 16), 256-1 = parseInt('ff', 16)
function findColor(val) {
	var r, rDec, g, gDec, b, bDec;
	if(val < 64) {
		rDec = interpolate(val, 0, 64-1, 0, 256-1);
		r = rDec.toString(16);
		g = '00';
		b = '00';
	} else if (val < 192) {
		r = 'ff';
		gDec = interpolate(val, 64, 192-1, 0, 256-1); 
		g = gDec.toString(16);
		b = '00';
	} else {
		r = 'ff';
		g = 'ff';
		bDec = interpolate(val, 192, 256-1, 0, 256-1); 
		b = bDec.toString(16);
	}
	return '#'+r+g+b;
}

function canvasFillCoordinate(leftX, topY, color) {
	getCanvas().getContext('2d').fillStyle = color;
    getCanvas().getContext('2d').fillRect(leftX, topY, 2, 4);
}

function canvasShift(shiftAmount) {
	// Copy old image data to the left 1
	var imgData=getCanvas().getContext('2d').getImageData(0,0,getCanvas().width,getCanvas().height);
	getCanvas().getContext('2d').putImageData(imgData,shiftAmount,0);
}

function canvasInitialize(width, height) {
	getCanvas().getContext('2d').strokeStyle='#000000';
	
	// Set canvas parameters
	getCanvas().width = width;
	getCanvas().height = height;

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

function noteFromPitch( frequency ) {
	var noteNum = 12 * (Math.log( frequency / 440 )/Math.log(2) );
	return Math.round( noteNum ) + 69;
}

function frequencyFromNoteNumber( note ) {
	return 440 * Math.pow(2,(note-69)/12);
}

function centsOffFromPitch( frequency, note ) {
	return ( 1200 * Math.log( frequency / frequencyFromNoteNumber( note ))/Math.log(2) );
}

function autoCorrelate( buf, sampleRate) {
	//var MIN_SAMPLES = 4;	// corresponds to an 11kHz signal
	//var MAX_SAMPLES = 1000; // corresponds to a 44Hz signal
	
	var MIN_SAMPLES = 60;	// corresponds to an 11kHz signal, 800
	var MAX_SAMPLES = 160; // corresponds to a 44Hz signal, 300
	var SIZE = 1000;
	var best_offset = -1;
	var best_correlation = 0;
	var rms = 0;

	var retVal = new Object();
	retVal.confidence = 0;
	retVal.currentPitch = 0;

	if (buf.length < (SIZE + MAX_SAMPLES - MIN_SAMPLES))
		return retVal;  // Not enough data

	for (var i=0;i<SIZE;i++) {
		var val = (buf[i] - 128)/128;
		rms += val*val;
	}
	rms = Math.sqrt(rms/SIZE);

	for (var offset = MIN_SAMPLES; offset <= MAX_SAMPLES; offset++) {
		var correlation = 0;

		for (var i=0; i<SIZE; i++) {
			correlation += Math.abs(((buf[i] - 128)/128)-((buf[i+offset] - 128)/128));
		}
		correlation = 1 - (correlation/SIZE);
		if (correlation > best_correlation) {
			best_correlation = correlation;
			best_offset = offset;
		}
	}
	if ((rms>0.01)&&(best_correlation > 0.01)) {
		retVal.confidence = best_correlation * rms * 10000;
		retVal.currentPitch = sampleRate/best_offset;
	}
	return retVal;
}

function createPitchUpdater(analyser, sampleRate) {
	var noteStrings = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
	var buflen = 2048;
	var timeLength = 500;
	var maxFreq = 500;
	canvasInitialize(timeLength,maxFreq);
	
	return function updatePitch(e) {
		canvasShift(-1);
		
		var buf = new Uint8Array( buflen );
		analyser.getByteTimeDomainData( buf );
		
		var retVal = autoCorrelate( buf, sampleRate );
		var floorCurrentPitch = Math.floor( retVal.currentPitch ) ;
		
		if (retVal.confidence > 10) {
			var note =  noteFromPitch( retVal.currentPitch );
			var noteString = noteStrings[note%12];
			var detune = centsOffFromPitch( retVal.currentPitch, note );
			
			var color;
			if (Math.abs(detune)<10) {
				color = "green";
			} else {
				color = "red";
			}
//			if (detune == 0 ) {
//			} else {
//				var color;
//				
//				var desc;
//				if (detune < 0) {
//					desc = "flat";
//				} else {
//					desc = "sharp";
//				}
//				
//				var detuneVal = Math.abs( Math.floor( detune ) );
//			}
			
			//var color = findColor(sample);
			canvasFillCoordinate(timeLength-4, floorCurrentPitch - 250, color);
			
			getLog().innerHTML = ' Note:' + noteString + ' Pitch:'+retVal.currentPitch + ' FloorCurrentPitch:' + floorCurrentPitch + ' confidence:' + retVal.confidence + ' sampleRate:' + sampleRate + '\n<br>';
		}
	}
}

function onSuccess(stream) {
	// stream -> mediaSource -> javascriptNode -> destination
    var context = new webkitAudioContext();
    var mediaStreamSource = context.createMediaStreamSource(stream);
	var analyser = context.createAnalyser();
    analyser.smoothingTimeConstant = 0.3;
    analyser.fftSize = 2048;
	var javascriptNode = context.createScriptProcessor(2048, 1, 1);
	mediaStreamSource.connect(analyser);
	analyser.connect(javascriptNode);
	javascriptNode.connect(context.destination);
	
	javascriptNode.onaudioprocess = createPitchUpdater(analyser, context.sampleRate);
}

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

function getLog() {
	return document.getElementById('mylog');
}

function getCanvas() {
	return document.getElementById('mycanvas');
}	
  
function documentReady() {
	var dataObject = {video: false, audio: true}; // dataObject.video, dataObject.audio
	if(navigator.getUserMedia) {
        navigator.getUserMedia(dataObject, onSuccess, onError);
	} else if(navigator.webkitGetUserMedia) {
        navigator.webkitGetUserMedia(dataObject, onSuccess, onError);
	}
}
</script>
</head>
<body onload="documentReady();">
   <canvas id="mycanvas"></canvas>
   <div id="mylog"></div>
</body>
</html>

Real Time Visualization of an FFT

From www.smartjava.org

This code needs to be added to a Tomcat server to work. This allows the microphone in Chrome to be connected. See Real Time Visualization of Raw Sound from Microphone Input using HTML5.


<html>
<head>
<script type="text/javascript">

function canvasFillRect(leftX, topY, width, height) {
	var gradient = getCanvas().getContext('2d').createLinearGradient(0,0,0,300);
	gradient.addColorStop(1,'#000000');
	gradient.addColorStop(0.75,'#ff0000');
	gradient.addColorStop(0.25,'#ffff00');
	gradient.addColorStop(0,'#ffffff');
	getCanvas().getContext('2d').fillStyle=gradient;
	getCanvas().getContext('2d').fillRect(leftX, topY, width, height);
}

function canvasInitialize(width, height) {
	getCanvas().getContext('2d').strokeStyle='#000000';
	
	// Set canvas parameters
	getCanvas().width = width;
	getCanvas().height = height;

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

function onSuccess(stream) {
	// stream -> mediaSource -> javascriptNode -> destination
    var context = new webkitAudioContext();
    var mediaStreamSource = context.createMediaStreamSource(stream);
	var analyser = context.createAnalyser();
    analyser.smoothingTimeConstant = 0.3;
    analyser.fftSize = 2048;
	var javascriptNode = context.createScriptProcessor(2048, 1, 1);
	mediaStreamSource.connect(analyser);
	analyser.connect(javascriptNode);
	javascriptNode.connect(context.destination);
	
	javascriptNode.onaudioprocess = createProcessBuffer(analyser);
}

function createProcessBuffer(analyser) {
	return function processBuffer() {
		var fftData =  new Uint8Array(analyser.frequencyBinCount);
        analyser.getByteFrequencyData(fftData);
		
		// clear canvas and draw border
		canvasInitialize(1024,500);
	
		var average = 0;
		for(var i=0; i<fftData.length; i++) {
			var sample = fftData[i];
			canvasFillRect(i*5, 250-sample, 3, sample);
			average = average + sample;
		}
		average = average/fftData.length;
		getLog().innerHTML = 'FFT Length:'+fftData.length + ' Average:' + average + '\n<br>';
	};
}

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

function getLog() {
	return document.getElementById('mylog');
}

function getCanvas() {
	return document.getElementById('mycanvas');
}	
  
function documentReady() {
	var dataObject = {video: false, audio: true}; // dataObject.video, dataObject.audio
	if(navigator.getUserMedia) {
        navigator.getUserMedia(dataObject, onSuccess, onError);
	} else if(navigator.webkitGetUserMedia) {
        navigator.webkitGetUserMedia(dataObject, onSuccess, onError);
	}
}
</script>
</head>
<body onload="documentReady();">
   <canvas id="mycanvas"></canvas>
   <div id="mylog"></div>
</body>
</html>