Why does the createDelay function have a max delay argument? - html5-audio

The createDelay function of the AudioContext for the Web Audio API takes a single float argument that is the max delay possible for the produced delay node:
var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioCtx = new AudioContext();
var synthDelay = audioCtx.createDelay(5.0);
What's the motivation behind specifying a max delay? Why can't the spec just leave that flexible? Does less delay mean less memory / faster results?

Related

Is there a way to detect audio frequency in HTML 5 web audio API?

I would like to know is there a way we can detect audio frequency from microphone in html 5 web audio. I wish to make an online guitar tuner, and I need to have the audio frequency in hertz, from the sound input. I've seen some EQ and filters effects, but I didn't see anything about frequency recognition.
EDIT:
I found this: http://www.smartjava.org/content/exploring-html5-web-audio-visualizing-sound
The 2nd point (analyser node) is really interesting. I seen his source code, but I can't figure how to connect the analyser to the microphone input.
He calls a playSound() function when the mp3 file starts to play, and there he draws his canvas. But I do not have a playSound() like function...
I wrote a web audio library which, among other things, can detect frequency from mic input. Check it out at https://github.com/rserota/wad#pitch-detection
var voice = new Wad({source : 'mic' });
var tuner = new Wad.Poly();
tuner.add(voice);
voice.play();
tuner.updatePitch() // The tuner is now calculating the pitch and note name of its input 60 times per second. These values are stored in tuner.pitch and tuner.noteName.
var logPitch = function(){
console.log(tuner.pitch, tuner.noteName)
requestAnimationFrame(logPitch)
};
logPitch();
// If you sing into your microphone, your pitch will be logged to the console in real time.
tuner.stopUpdatingPitch(); // Stop calculating the pitch if you don't need to know it anymore.
You should be able to use BiquadFilterNode.
Example code from the link:
var audioCtx = new AudioContext();
var biquadFilter = audioCtx.createBiquadFilter();
biquadfilter.getFrequencyResponse(myFrequencyArray,magResponseOutput,phaseResponseOutput);
You can use the following code to get the frequencies from the mic.
navigator.mediaDevices.getUserMedia({audio:true}).then(function(localStream){
var audioContext = new(window.AudioContext || window.webkitAudioContext)();
var input = audioContext.createMediaStreamSource(localStream);
var analyser = audioContext.createAnalyser();
var scriptProcessor = audioContext.createScriptProcessor();
// Some analyser setup
analyser.smoothingTimeConstant = 0;
analyser.fftSize = 64;
input.connect(analyser);
analyser.connect(scriptProcessor);
scriptProcessor.connect(audioContext.destination);
var getAverageVolume = function( array){
var length = array.length;
var values = 0;
var i = 0;
for (; i < length; i++) {
values += array[i];
}
return values / length;
};
var onAudio = function(){
var tempArray = new window.Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(tempArray);
var latestFrequency = (getAverageVolume(tempArray));
//use latestFrequency
};
scriptProcessor.onaudioprocess = onAudio;
})
.catch(function(){
//Handle error
});

Filling in my own Web Audio Buffer is not working

I'm using Web Audio for various purposes and while samples loaded via URL and oscillators are working and playing properly, building a custom source buffer is not. I have tried to load my own AudioBuffer into an AudioBufferSourceNode using the code below and through the Chrome-NetBeans debugger I can see that it's loading the buffer with data and no errors are flagged, but when start is called, no sound is ever produced. Note that I'm just filling the buffer with noise, but I plan to fill it with my own custom wave data. I realize it's likely that I'm filling the buffer with the wrong data type, but I have been unable to find any documentation or examples regarding the proper way of doing it. Any help would be appreciated.
var audioContext = new (window.AudioContext || window.webkitAudioContext)();
var frameCount = 2000;
var sampleRate = 4000;
var myBuffer = audioContext.createBuffer(2, frameCount, sampleRate);
// FILL WITH WHITE NOISE
for (var i = 0; i < frameCount; i++) {
myBuffer[i] = Math.random() * 2 - 1;
}
sourceNode = audioContext.createBufferSource();
sourceNode.buffer = myBuffer;
sourceNode.connect(audioContext.destination);
sourceNode.start(0);
This will synth your noise inside a callback method which is called everytime you have rendered yet another BUFF_SIZE number of samples
var BUFF_SIZE = 2048; // spec allows, yet do not go below 1024
var audio_context = new AudioContext();
var gain_node = audio_context.createGain();
gain_node.connect( audio_context.destination );
var source_node = audio_context.createScriptProcessor(BUFF_SIZE, 1, 1);
source_node.onaudioprocess = (function() {
return function(event) {
var synth_buff = event.outputBuffer.getChannelData(0); // mono for now
// FILL WITH WHITE NOISE
for (var i = 0, buff_size = synth_buff.length; i < buff_size; i++) {
synth_buff[i] = Math.random() * 2 - 1;
}
};
}());
source_node.connect(gain_node);

SampleDataEvent.SAMPLE_DATA - regulating how often this event is tirggered

I is to possible to regulate how often flash triggers SAMPLE_DATA event when sampling data from input device ? I need to sample constantly (even silence).
var mySound:Sound = new Sound();
mySound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
AFAIK currently this function gets called 20 times/s
playing with the sample code from http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/SampleDataEvent.html
var mySound:Sound = new Sound();
function sineWaveGenerator(event:SampleDataEvent):void {
for ( var c:int=0; c<8192; c++ ) {
event.data.writeFloat(Math.sin((Number(c+event.position)/Math.PI/2))*0.25);
event.data.writeFloat(Math.sin((Number(c+event.position)/Math.PI/2))*0.25);
}
}
mySound.addEventListener(SampleDataEvent.SAMPLE_DATA,sineWaveGenerator);
mySound.play();
the less data you write, the more often the method gets called.
if you call it too often the sound may get clicky and gross. try adjusting the frame rate.

HTML5 Canvas - Popping popcorn animation / random images?

Maybe I am asking the wrong question completely. I have read quite a bit and seen quite a bit of HTML 5 capabilities; however, I have not yet had time to sit down and really start utilizing any of it yet :(, but hope to soon.
Anyway, I was curious if I could do the following with HTML5 and how to begin to implement it. Or, if this does not work, then how can I make it work?
I have a popcorn image (1 piece of popped popcorn that is).
I wanted to create a canvas and on a button click, start a chain of this image being randomly "popped" onto the canvas, slowly at first then gaining speed until such time there should be a stopping point.
Anyone who has popped popcorn can understand what I am looking to do here.
Is this possible to do easily?
I've popped popcorn and, yep, you can do this. Load the popcorn image by creating an Image object and setting its src attribute. Use the image's onload property to start the animation. Given the animation's duration k, use a sine curve, sin(x/(k/π)), to calculate the number of kernels to show per frame.
Here's one way of doing it, demo here: http://jsfiddle.net/uyk63/8/
var IMAGE_URL = 'http://i.istockimg.com/file_thumbview_approve/959519/2/stock-photo-959519-isolated-single-popcorn.jpg';
var DURATION = 10 * 1000, FRAMES = 30, KERNELS = 10;
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var frame = 0,
start = new Date().getTime(),
image = new Image;
image.src = IMAGE_URL;
image.onload = function() {
function pop() {
ctx.drawImage(image,
Math.floor(Math.random() * canvas.width),
Math.floor(Math.random() * canvas.height),
100, 50);
}
// A little overcomplicated. You could probably do this in a single loop.
// (It's late and I'm tired, though. Sorry.)
function animate() {
var i, delay,
count = Math.floor(Math.sin(frame / (FRAMES / Math.PI)) * KERNELS);
for (i = 0; i < count; i++) {
delay = (DURATION / FRAMES) / count * i;
setTimeout(pop, delay);
}
if (++frame < FRAMES) {
setTimeout(animate, DURATION / FRAMES);
}
}
animate();
};

Understanding Actionscript Garbage Collection

in an attempt to see and hopefully understand actionscript's garbage collector, i've set up a sample project that loop-tweens the value of a pixel bender parameter on stage.
my first concern was the amount of memory that was being used at launch (~26 MB). while i like to believe i'm cautious about memory by removing event listeners and nulling useless objects for the garbage collection as much as possible, i also believe i don't fully grasp where, why and when it works.
the trace of the total system memory displayed a steady rise starting from around 26 MB until around 28 MB after about a minute later (or so). suddenly it's plummeted down to 25 MB only to continue rising once again. this seems to cycle over and over.
here are some questions that come to mind:
1. is there a general time delay for the garbage collector?
2. does it activate after a certain amount of memory has been allocated?
3. can objects be explicitly removed immediately without relying on the garbage collector?
4. what is an acceptable range for memory usage when running flash?
attached is my code.
import fl.transitions.*;
import fl.transitions.easing.*;
var shader:Shader;
var shaderFilter:ShaderFilter;
var motionTween:Tween;
var filterParameter:Number = 0.0;
var loader:URLLoader = new URLLoader();
var phase:Boolean = false;
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, dataLoaded);
loader.load(new URLRequest("myBoringFilter.pbj"));
function dataLoaded(e:Event):void
{
loader.removeEventListener(Event.COMPLETE, dataLoaded);
shader = new Shader(e.target.data);
shaderFilter = new ShaderFilter(shader);
flower.filters = [shaderFilter];
tweenLoop(null);
}
function tweenLoop(e:TweenEvent):void
{
if (motionTween != null)
{
motionTween.removeEventListener(TweenEvent.MOTION_CHANGE, updateFilter);
motionTween.removeEventListener(TweenEvent.MOTION_FINISH, tweenLoop);
motionTween = null;
}
phase = !phase;
if (phase == true)
{motionTween = new Tween(this, "filterParameter", Regular.easeOut, filterParameter, 100.0, 2.0, true);}
else
{motionTween = new Tween(this, "filterParameter", Regular.easeOut, filterParameter, -100.0, 1.0, true);}
motionTween.addEventListener(TweenEvent.MOTION_CHANGE, updateFilter);
motionTween.addEventListener(TweenEvent.MOTION_FINISH, tweenLoop);
}
function updateFilter(e:TweenEvent):void
{
shader.data.amount.value = [filterParameter];
flower.filters = [shaderFilter];
//Update Memory
trace("System Total Memory: " + System.totalMemory);
}
This is generally the most common resource for this question:
http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html