rserota / wad

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

Mute mic output when recording #147

Closed Kris-rmw closed 1 year ago

Kris-rmw commented 1 year ago

Is there an option to mute the mic output when recording, similar to how we can set Tuner.setVolume(0) for the tuner? (to avoid feedback and avoid having the user listen to their mic signal with latency)

I have tried both play({volume:0}) and setVolume(0) - see below. At best I manage to completely kill the mic signal which results in a silent recording.

  let voice = new Wad({source: 'mic'})
   let polywad = new Wad.Poly({
       recorder: {
           options: { mimeType : 'audio/webm' },
           onstop: function(event) {
               let blob = new Blob(this.recorder.chunks, { 'type' : 'audio/webm;codecs=opus' });
               window.open(URL.createObjectURL(blob));
           }
       }
   })
   polywad.add(voice)
   voice.play()
   // voice.play({volume:0})  //tested this
   // polywad.setVolume(0);  //tested this
   polywad.recorder.start()
   setTimeout(function(){
     polywad.recorder.stop() 
   }, 5000);
rserota commented 1 year ago

The recorder on the PolyWad captures its output, so muting the PolyWad will result in a silent recording, as you noted. If you download the latest version of WadJS (4.13.2) , you can solve this issue by wrapping the recorder in another PolyWad.

let voice = new Wad({source: 'mic'})
let recorder = new Wad.Poly({
    recorder: {
        options: { mimeType : 'audio/webm' },
        onstop: function(event) {
            let blob = new Blob(this.recorder.chunks, { 'type' : 'audio/webm;codecs=opus' });
            window.open(URL.createObjectURL(blob));
        }
    }
})
let mute = new Wad.Poly({volume:0})
recorder.add(voice)
mute.add(recorder)
voice.play()

recorder.recorder.start()

Thanks for raising this issue. I hope you're enjoying WadJS.

Kris-rmw commented 1 year ago

Wow thanks so much for the fix, I was able to solve it in a quick test run with the new version. Keep up the amazing work! 👌

Kris-rmw commented 1 year ago

After further testing, it seems to me it is not possible to use both tuner.setVolume(0) and record mute at the same time. The code below results in a silent recording.

  let voice = new Wad({source: 'mic'})
   let recorder = new Wad.Poly({
       recorder: {
           options: { mimeType : 'audio/webm' },
           onstop: function(event) {
               let blob = new Blob(this.recorder.chunks, { 'type' : 'audio/webm;codecs=opus' });
               window.open(URL.createObjectURL(blob));
           }
       }
   })
   recorder.add(voice)

   var tuner = new Wad.Poly();
   tuner.setVolume(0); // If you're not using headphones, you can eliminate microphone feedback by muting the output from the tuner.
   tuner.add(voice);

   tuner.updatePitch()

   var logPitch = function(){
       console.log(tuner.pitch, tuner.noteName)
       requestAnimationFrame(logPitch)
   };
   logPitch();

   voice.play()

   let mute = new Wad.Poly({volume:0})
   mute.add(recorder)

   recorder.recorder.start()
   setTimeout(function(){
     recorder.recorder.stop()
      tuner.stopUpdatingPitch();
   }, 5000);
rserota commented 1 year ago

Think of the PolyWads like containers. When you add the voice to the tuner polywad, that implicitly removes it from the recorder polywad. Also, you could probably achieve what you want with only 2 polywads, instead of 3. Try something like this:

  let voice = new Wad({source: 'mic'})
  let recorder = new Wad.Poly({
      recorder: {
          options: { mimeType : 'audio/webm' },
          onstop: function(event) {
              let blob = new Blob(this.recorder.chunks, { 'type' : 'audio/webm;codecs=opus' });
              window.open(URL.createObjectURL(blob));
          }
      }
  })
  recorder.add(voice)

  recorder.updatePitch()

  var logPitch = function(){
      console.log(recorder.pitch, recorder.noteName)
      requestAnimationFrame(logPitch)
  };
  logPitch();

  let mute = new Wad.Poly({volume:0})
  mute.add(recorder)

  voice.play()

  recorder.recorder.start()
  setTimeout(function(){
    recorder.recorder.stop()
     recorder.stopUpdatingPitch();
  }, 5000);
Kris-rmw commented 1 year ago

Ah got it now, I can confirm both tuner.setVolume(0) and record mute at the same time works. Thanks 👊