rserota / wad

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

Alllow changing volume during playback #60

Closed torch2424 closed 8 years ago

torch2424 commented 8 years ago

The readme states you can change properties of a wad during playback by using it's setter functions, however, setVolume did not do this for me.

Currently, in another application that implements the use of wad (see here: https://github.com/julianpoy/Flyxer), I was able to set the volume of a wad doing the following:

    //Volume
    $scope.masterVolume = 100;
    $scope.setVolume = function() {

        for(var i=0;i<$scope.tracks.length;i++){
          if($scope.tracks[i].playing) {

              //Making variables in relation to the master volume

              $scope.tracks[i].player.nodes[4].output.gain.value = parseInt($scope.tracks[i].playbackVolume) / 100 * $scope.tracks[i].initVolumeMul * parseInt($scope.masterVolume) / 100;

              console.log(parseInt($scope.tracks[i].playbackVolume));
              console.log(parseInt($scope.masterVolume));
              console.log($scope.tracks[i].player.nodes[4].output.gain.value);
          }
        }
    }

Where the parseInt($scope.tracks[i].playbackVolume) / 100 * $scope.tracks[i].initVolumeMul * parseInt($scope.masterVolume) / 100; represents a slider bounded by angularJS' ngModel.

However, my problem is that I am accessing the node at index 4, where I would not like to assume at the volume node is at index 4. Is there a way that I can access the volume node without it's index? Thank You! I can fix this issue after this is figured out :)

rserota commented 8 years ago

Setting volume on a wad during playback is tricky, because the volume envelope is already scheduled to change the volume during playback. In your code, it looks like you'e modifying the output of a reverb or delay node, which will work, but only if the wad has one of those nodes (and it requires you to know where that node is, as you noted).

One solution that you might find simpler is to wrap the wad in a polywad, and then you can dynamically set volume on the polywad.

It might also work to modify the basic set up for all wads to use two gain nodes by default, instead of one. One of them would be modulated by the volume envelope, and the other could be manually manipulated with setVolume.

torch2424 commented 8 years ago

@rserota Yeah I noticed setting volume was a bit tricky myself!

If I am not mistaken, I am preety sure that was actually a node named the volume envelope (Name appeared in chrome dev tools console).

And I'll play around with polywads once I have the chance!

I'll look into setting two gain nodes, as that would make sense. And to be honest, I make a lot of music myself, so I know a bit of music terms, by I am not completely sure of what you mean by modulated. Do you mean like changed on the fly?

However, There is a javascript map trick @julianpoy and I used before, to set keys to array indexes, that is actually preety powerful, and I think that would help in acessing the nodes added to Wad.nodes. That way, by using a key, we can quickly search for if the node exists, without checking every value. I'll have @julianpoy elaborate, as he is the one that taught the javascript technique to me. And then perhaps you ( @rserota ), @julianpoy, and I can decide on a good solution for this :)

rserota commented 8 years ago

Yeah, by 'modulate', I just meant that the gain node is being changed on the fly by the volume envelope.

julianpoy commented 8 years ago

Forgot that I was ultimately supposed to come up with some sort of better solution for this.

The project involving WAD has been on hold for a bit, but I hope to be back to it soon and improving things.