rserota / wad

Web Audio DAW. Use the Web Audio API for dynamic sound synthesis. It's like jQuery for your ears.
MIT License
1.9k stars 160 forks source link

Pitch detection : no nodes in .play() #27

Closed maximelebastard closed 9 years ago

maximelebastard commented 9 years ago

Hi, I'm testing the Pitch detection example with this script:


var voice = new Wad({source : 'mic' });
var tuner = new Wad.Poly({
    recConfig : { // The Recorder configuration object. The only required property is 'workerPath'.
        workerPath : 'bower_components/wad/src/Recorderjs/recorderWorker.js' // The path to the Recorder.js web worker script.
    }
   });
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.

I have this console error when running the script:

 Uncaught TypeError: Cannot read property 'length' of undefined (wad:304)

After puting breakpoints, the error comes when the line 304 is called from the line 534 (else if ( this.source === 'mic' ) { plugEmIn(this, arg); } ). The first parameter of plugEmIn (this) does not contains the nodes property. So, when line 304 tries to loop in that.nodes, the var is undefined and the 'length' property is undefined.

But line 304 is called successfully a first time with this in that.node: 0: AnalyserNode 1: PannerNode 2: GainNode length: 3 proto: Array[0]

I don't know if i did something wrong (I'm not familiar with this library), but the example does not seems to work.

And I'm on Chrome 40 for Mac OS X.

Thanks for your feedback ! The library seems really useful, and I can't wait to make it work ! :smiley:

rserota commented 9 years ago

I think I know what's happening here.

After you call var voice = new Wad({source : 'mic' });, chrome will ask permission to use your microphone. After you accept, the microphone's nodes array will be populated, and then you can call play(). Calling play() before giving chrome access to your microphone will throw an error.

You'll probably need to bind voice.play() to a button click event, or some other user-action.

I need to update the documentation since, as you noticed, that code snippet does not work if run as-is. I should also find a more helpful way to handle that error.

I really appreciate your enthusiasm for this project. Let me know if you continue to have issues. If you make a complete application that uses Wad.js, I'd love to see it.

maximelebastard commented 9 years ago

And you are right !

This code works well:

var voice = new Wad({source : 'mic' });
var tuner = new Wad.Poly({
    recConfig : { // The Recorder configuration object. The only required property is 'workerPath'.
        workerPath : 'bower_components/wad/src/Recorderjs/recorderWorker.js' // The path to the Recorder.js web worker script.
    }
   });
tuner.add(voice);

$("#playit").click(function(){
    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();
});

Your library makes my project possible and makes some points really easier to realize, so thanks a lot again ! I can't really talk about it at this point, but I will email you when it will be released ! ;)

EDIT: To readers, before copy/paste, note that jQuery is required for the click event listener.

ghost commented 8 years ago

How can I make it faster? It's too slow..