Skip to content

Commit

Permalink
Analyser added.
Browse files Browse the repository at this point in the history
  • Loading branch information
cwilso committed Mar 30, 2012
1 parent 9e124d2 commit d333194
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 16 deletions.
43 changes: 43 additions & 0 deletions analyser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
var animationRunning = false;
var analysers = new Array;
var CANVAS_WIDTH = 150;
var CANVAS_HEIGHT = 120;

function updateAnalyser(e) {
var SPACER_WIDTH = 2;
var BAR_WIDTH = 2;
var OFFSET = 100;
var CUTOFF = 23;
var numBars = Math.round(CANVAS_WIDTH / SPACER_WIDTH);
var ctx = e.drawingContext;
var freqByteData = new Uint8Array(e.audioNode.frequencyBinCount);

e.audioNode.getByteFrequencyData(freqByteData);
//analyser.getByteTimeDomainData(freqByteData);

ctx.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
ctx.fillStyle = '#F6D565';
ctx.lineCap = 'round';
var multiplier = e.audioNode.frequencyBinCount / numBars;

// Draw rectangle for each frequency bin.
for (var i = 0; i < numBars; ++i) {
var magnitude = 0;
var offset = Math.floor( i * multiplier );
// gotta sum/average the block, or we miss narrow-bandwidth spikes
for (var j = 0; j< multiplier; j++)
magnitude += freqByteData[offset + j];
magnitude = magnitude / multiplier;
var magnitude2 = freqByteData[i * multiplier];
ctx.fillStyle = "hsl( " + Math.round((i*360)/numBars) + ", 100%, 50%)";
ctx.fillRect(i * SPACER_WIDTH, CANVAS_HEIGHT, BAR_WIDTH, -magnitude);
}
}

function updateAnalysers(time) {
window.webkitRequestAnimationFrame( updateAnalysers );

for (var i = 0; i < analysers.length; i++)
updateAnalyser(analysers[i]);
}

101 changes: 87 additions & 14 deletions dragging.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var dragObj = new Object();
dragObj.zIndex = 0;
dragObj.lastLit = null;

// Node Dragging functions - these are used for dragging the audio nodes,
// like Destination or AudioSourceBuffer.
Expand All @@ -11,7 +12,7 @@ function startDraggingNode(event) {
dragObj.elNode = event.target;

// If this is a text node, use its parent element.
if (dragObj.elNode.nodeType == 3)
if ((dragObj.elNode.nodeType == 3)||(dragObj.elNode.className == "analyserCanvas"))
dragObj.elNode = dragObj.elNode.parentNode;

// Get cursor position with respect to the page.
Expand All @@ -38,21 +39,58 @@ function startDraggingNode(event) {

function whileDraggingNode(event) {
var x, y;
var e = dragObj.elNode;

// Get cursor position with respect to the page.
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;

// Move drag element by the same amount the cursor has moved.
dragObj.elNode.style.left = (dragObj.elStartLeft + x - dragObj.cursorStartX) + "px";
dragObj.elNode.style.top = (dragObj.elStartTop + y - dragObj.cursorStartY) + "px";
e.style.left = (dragObj.elStartLeft + x - dragObj.cursorStartX) + "px";
e.style.top = (dragObj.elStartTop + y - dragObj.cursorStartY) + "px";

if (e.inputConnections) { // update any lines that point in here.
var c;

var off = e.inputs;
x = window.scrollX + 12;
y = window.scrollY + 12;

while (off) {
x+=off.offsetLeft;
y+=off.offsetTop;
off=off.offsetParent;
}

for (c=0; c<e.inputConnections.length; c++) {
e.inputConnections[c].line.setAttributeNS(null, "x1", x);
e.inputConnections[c].line.setAttributeNS(null, "y1", y);
}
}

//TODO: update any connectors.
// if inputnode::
// if outputnode::
if (e.outputConnections) { // update any lines that point out of here.
var c;

var off = e.outputs;
x = window.scrollX + 12;
y = window.scrollY + 12;

while (off) {
x+=off.offsetLeft;
y+=off.offsetTop;
off=off.offsetParent;
}

for (c=0; c<e.outputConnections.length; c++) {
e.outputConnections[c].line.setAttributeNS(null, "x2", x);
e.outputConnections[c].line.setAttributeNS(null, "y2", y);
}
}

event.preventDefault();
}


function stopDraggingNode(event) {
// Stop capturing mousemove and mouseup events.
document.removeEventListener("mousemove", whileDraggingNode, true);
Expand Down Expand Up @@ -88,6 +126,9 @@ function startDraggingConnector(event) {

// remember if this is an input or output node, so we can match
dragObj.input = (dragObj.elNode.className.indexOf("inputconnector") != -1);

dragObj.elNode.unlitClassname = dragObj.elNode.className;
dragObj.elNode.className += " canConnect";

// Create a connector visual line
var svgns = "http://www.w3.org/2000/svg";
Expand All @@ -112,6 +153,8 @@ function startDraggingConnector(event) {

function whileDraggingConnector(event) {
var x, y;
var toElem = event.toElement;

// Get cursor position with respect to the page.
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
Expand All @@ -121,15 +164,26 @@ function whileDraggingConnector(event) {

// Move connector visual node
// light up connector point underneath, if any
var str=""+event.toElement.className;
var str = "" + toElem.className;

if (dragObj.input) {
if (str.indexOf("outputconnector") != -1) {
// TODO: light up - can connect!
}
} else { // first node was an output, so we're looking for an input
if (str.indexOf("inputconnector") != -1) {
// TODO: light up - can connect!
if (dragObj.lastLit && (dragObj.lastLit != toElem ) ) {
dragObj.lastLit.className = dragObj.lastLit.unlitClassname;
dragObj.lastLit = null;
}

if (!dragObj.lastLit || (dragObj.lastLit != toElem )) {
if (dragObj.input) {
if (str.indexOf("outputconnector") != -1) {
toElem.unlitClassname = toElem.className;
toElem.className += " canConnect";
dragObj.lastLit = toElem;
}
} else { // first node was an output, so we're looking for an input
if (str.indexOf("inputconnector") != -1) {
toElem.unlitClassname = toElem.className;
toElem.className += " canConnect";
dragObj.lastLit = toElem;
}
}
}

Expand All @@ -156,6 +210,16 @@ function connectNodes( src, dst ) {
connector.destination = dst;
src.outputConnections.push(connector);

//Make sure the connector line points go from src->dest (x1->x2)
if (!dragObj.input) { // need to flip
var shape = dragObj.connectorShape;
var x = shape.getAttributeNS(null, "x2");
var y = shape.getAttributeNS(null, "y2");
shape.setAttributeNS(null, "x2", shape.getAttributeNS(null, "x1"));
shape.setAttributeNS(null, "y2", shape.getAttributeNS(null, "y1"));
shape.setAttributeNS(null, "x1", x);
shape.setAttributeNS(null, "y1", y);
}
// Put an entry into the destinations's inputs
if (!dst.inputConnections)
dst.inputConnections = new Array();
Expand All @@ -169,6 +233,8 @@ function connectNodes( src, dst ) {
if (src.audioNode )
src.audioNode.connect(dst.audioNode);

if (dst.onConnectInput)
dst.onConnectInput();
dragObj.connectorShape = null;
}

Expand All @@ -177,6 +243,13 @@ function stopDraggingConnector(event) {
document.removeEventListener("mousemove", whileDraggingConnector, true);
document.removeEventListener("mouseup", stopDraggingConnector, true);

if (dragObj.lastLit) {
dragObj.lastLit.className = dragObj.lastLit.unlitClassname;
dragObj.lastLit = null;
}

dragObj.elNode.className = dragObj.elNode.unlitClassname;

var to = event.toElement;

// Get the position of the originating connector with respect to the page.
Expand Down
39 changes: 38 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<!-- Dial Control library -->
<script type="text/javascript" src="DialControl.js"></script>

<!-- Analyser Node library -->
<script type="text/javascript" src="analyser.js"></script>


<script type="text/javascript">
var audioContext = null;
Expand Down Expand Up @@ -42,13 +45,15 @@
i.className="inputconnector";
i.onmousedown=startDraggingConnector;
e.appendChild(i);
e.inputs = i;
}

if (output) {
var i=document.createElement("div");
i.className="outputconnector";
i.onmousedown=startDraggingConnector;
e.appendChild(i);
e.outputs = i;
}

// add the node into the soundfield
Expand Down Expand Up @@ -128,7 +133,6 @@
var filter = audioContext.createBiquadFilter();
e.audioNode = filter;
filter.type=0;
// filter.frequency.value = 440.0;

var ctl = createNewDialControl( 50, initDefaultParam(filter.Q) );
ctl.style.left = "10px";
Expand All @@ -144,6 +148,38 @@

}

function onAnalyserConnectInput() {
// set up
if (!animationRunning) {
animationRunning = true;
updateAnalysers( 0 );
}
}

function createAnalyserNode() {
var e=createNewNode("analyser", true, true );
var analyser = audioContext.createAnalyser();
analyser.smoothingTimeConstant = "0.25"; // not much smoothing
e.audioNode = analyser;
var canvas = document.createElement( "canvas" );
canvas.style.left = "10px";
canvas.style.top = "35px";
canvas.style.position = "absolute";
canvas.height = "120";
canvas.width = "150";
canvas.className = "analyserCanvas"
canvas.style.webkitBoxReflect = "below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.9, transparent), to(white))"

e.appendChild( canvas );

e.onConnectInput = onAnalyserConnectInput;
analysers.push(e); // Add to the list of analysers in the animation loop
e.drawingContext = canvas.getContext('2d');
// e.drawingContext.fillStyle = "blue";
// e.drawingContext.fillRect(0,0,150, 120);
}


function createAudioNodeFromBuffer( buffer ) {
var e=createNewNode("audioBufferSource", false, true );

Expand Down Expand Up @@ -284,6 +320,7 @@
<div>Drop a sound file onto the page in order to create an AudioBufferSource with that file</div>
<button onclick="downloadAudioFromURL('440Hz.ogg'); ">Sine Wave AudioBufferSource</button>
<button onclick="createBiquadFilterNode();">Biquad Filter</button>
<button onclick="createAnalyserNode();">Spectrum Analyser</button>
<button onclick="downloadImpulseFromURL('hall.ogg'); ">Hall Impulse ConvolutionNode</button>

<button onclick="var uri=prompt('Enter a URL to a sound file'); if (uri) downloadAudioFromURL(uri); ">AudioBufferSource from URL</button>
Expand Down
3 changes: 2 additions & 1 deletion nodes.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
background: gray;
}

.inputconnector.connected, .outputconnector.connected { background: blue }
.inputconnector.connected, .outputconnector.connected { background: lightgreen }
.inputconnector.canConnect, .outputconnector.canConnect { background: pink }

.outputconnector {
position: absolute;
Expand Down

0 comments on commit d333194

Please sign in to comment.