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

External effects on mic input? #33

Closed jescalan closed 9 years ago

jescalan commented 9 years ago

Hey sorry, so many issues! You've been so helpful in working them out so far though, really appreciate it. So I'm trying to add an external effect to the mic through Tuna. I followed the instructions for how to make it happen in the readme with the constructExternalFx and setUpExternalFxOnPlay methods, and noticed nothing was happening when I passed the arguments for it through to the play function.

Browsing quickly though the code, I saw that while constructExternalFx is being called, setUpExternalFxOnPlay is not anywhere and never goes off. I tried adding this to the same section of code above, and the function does run in that case, but the external effects are not actually applied.

Here's some sample code to work with:

var Wad = require('wad');
var Tuna = require('tuna');

Wad.prototype.constructExternalFx = function(arg, ctx) {
  console.log('constructExternalFx called');
  this.tuna = new Tuna(ctx);
  this.chorus = arg.chorus;
}

Wad.prototype.setUpExternalFxOnPlay = function(arg, context) {
  console.log('setUpExternalFxOnPlay called');
  if (arg.chorus) {
    var chorus = new this.tuna.Chorus({
      rate: arg.chorus.rate || this.chorus.rate,
      feedback: arg.chorus.feedback || this.chorus.feedback,
      delay: arg.chorus.delay || this.chorus.delay,
      bypass: arg.chorus.bypass || this.chorus.bypass
    });

    chorus.input.connect = chorus.connect.bind(chorus);
    this.nodes.push(chorus.input);
  }
}

var voice = new Wad({ source: 'mic' });

voice.play({
  chorus: {
      rate: 1.5,
      feedback: 0.2,
      delay: 0.0045,
      bypass: 0
    }
});

Edit: Also just tried adding these params to the Wad constructor -- no error but still no effects.

rserota commented 9 years ago

The externalFX feature was added a while back by another contributor. I haven't worked with it much, but it doesn't surprise me that it might have broken during a recent refactor. I'll have time to work on this tomorrow and this weekend, and I'll update the readme with a working example when I'm done.

Thanks for finding all these bugs, and thanks for your patience while I'm fixing them.

jescalan commented 9 years ago

Hey thank you for continuing to work on and improve this codebase! It's not something you find every day in the open source world. I'll have to show you what I'm building with this when it's done, I bet you will enjoy it :grinning:

dimapaloskin commented 9 years ago

Hi, guys! I ran into the same problem. I just add that.setUpExternalFxOnPlay(arg, context); line in end setUpMic functions.

Results


   var setUpMic = function(that, arg){
        that.nodes           = [];
        that.gain            = context.createGain();
        that.gain.gain.value = that.volume;
        that.nodes.push(that.mediaStreamSource);
        that.nodes.push(that.gain);

        if ( that.filter || arg.filter ) { createFilters(that, arg); }

        if ( that.reverb || arg.reverb ) { setUpReverbOnPlay(that, arg) }

        if ( that.panning || arg.panning ) {
            var panning = arg.panning || that.panning;
            that.panning.node = context.createPanner();
            that.panning.node.setPosition(panning.location[0], panning.location[1], panning.location[2]);
            that.nodes.push(that.panning.node);
        }

        if ( that.delay || arg.delay ) {
            setUpDelayOnPlay(that, arg);
        }

        that.setUpExternalFxOnPlay(arg, context);
    }

I did not dig all code, but this solution resolved this problem =)

rserota commented 9 years ago

Hey @dimapaloskin, thanks for contributing. If either of you can confirm that you got Tuna working with Wad, feel free to close this issue. @jenius, I would definitely like to see your project when you're done with it.

jescalan commented 9 years ago

Just pulled the latest version and the code above is still not working correctly :cry:

rserota commented 9 years ago

I just tested it out, and Tuna seems to be working on my end. @jenius, I think there's a syntax error in that snippet you pasted here:

voice.play({
  chorus: {
      rate: 1.5,
      feedback: 0.2,
      delay: 0.0045,
      bypass: 0
    }  
  }
});

There are only 2 opening braces, but there are 3 closing braces.

jescalan commented 9 years ago

Yeah it's actually in coffeescript, I converted manually to js to post here so it was just a typo -- there's not actually a syntax error when the code is run.

rserota commented 9 years ago

Is it possible that the chorus effect is just too subtle? I wasn't able to tell if it was working with the arguments you used above, but when I called play() like this, it was apparent that the chorus was applied:

voice.play({
    chorus: {
        rate: 2.5,
        feedback: 0.8,
        delay: 2.0,
        bypass: 0   
    }
});
jescalan commented 9 years ago

I just tried changing it to those settings and still no effect at all :disappointed:

rserota commented 9 years ago

This is rather mysterious. I just pasted the code in this thread into my own app, and it all seems ok. Maybe I'm missing some context? If you want to show me the code for your app, or link me to a live work-in-progress, I might be able to give you more precise help.

jescalan commented 9 years ago

Huh, ok let me dig in a little further and report back

rserota commented 9 years ago

While you're digging, here are some things to think about. I'm not sure how much of this is directly related to the problem you're having right now, but it should give you some background info that will help you debug your application.

To get all the nodes in voice hooked up, they're all pushed into voice.nodes. After granting your browser access to your mic (or after calling play with new args), this array should have a mediaStreamSource, a gainNode, and a pannerNode, in addition to the other nodes you've added (filters, tuna chorus, etc). You can inspect this array to make sure it has the nodes you expect it to have.

After they've been pushed, the plugEmIn function will try to daisy-chain them together, like so: nodes[0].connect(nodes[1]) nodes[1].connect(nodes[2]) etc etc

However, some types of nodes (e.g. reverb and delay) have a custom interface. If plugEmIn sees that nodes[i].interface === 'custom', then it will try to connect them like so: nodes[0].output.connect(nodes[1].input) nodes[1].output.connect(nodes[2].input) etc etc

Tuna nodes are a little weird because they have an input, but no output, so they don't behave like native nodes or custom nodes. The workaround is binding chorus.connect to chorus.input.connect, so that we can pretend our tuna nodes are native nodes. That does work, but it's probably one of the shakier parts of this process.

dimapaloskin commented 9 years ago

Aloha, guys! @rserota Sorry for the long silence. I didn't have a possibility answer you. I tested my changes for tuna overdrive fx and all worked. But I see now that my answer is not actually now =)

@jenius Make sure that changes really to take effect. I see now that Raphael not rebuild code in "build" folder and I forget make new build. You can make build manually. Also you can use wad.js from "src" folder and I think that it resolve your problem.

dimapaloskin commented 9 years ago

Ouch... I found problem. Sorry, it's all because of my carelessness. Please see my PR. I add accidentally square bracket after function and break code. Now I fixed this bug and rebuild wad.

rserota commented 9 years ago

@dimapaloskin I noticed the extra bracket after I merged your pull request, and pushed a fix up immediately after, so I don't think that's the problem here. However, like you said, I've only been working on src/wad.js, and I hadn't rebuilt the build folder after my recent changes.

dimapaloskin commented 9 years ago

Ping @jenius. Please check new changes in your project =)

jescalan commented 9 years ago

Checking now! Thanks guys, good catch :two_men_holding_hands:

jescalan commented 9 years ago

Working now! :tada:

rserota commented 9 years ago

Awesome. I'm glad you got it working.

jescalan commented 9 years ago

Thanks for your help! Extra effects sound awesome. I'm might PR in something that makes connecting up these effects a bit simpler this week as well. Have to make sure something like this makes sense first haha.