audify icon indicating copy to clipboard operation
audify copied to clipboard

RtAudio input stops after ~7 seconds, when output is not opened

Open bradisbell opened this issue 3 years ago • 6 comments

I'm having trouble with the basic audio input example. The audio input callback stops being called after about 7 seconds. Some notes:

  • This occurs with both WASAPI and DirectShow audio APIs.
  • It doesn't matter which audio device I use.
  • The exact time duration before failure varies from run to run, slightly, as does the number of times the input callback is called.
  • DirectShow devices fail 1-2 seconds sooner than WASAPI devices, even if the same physical device is used.
  • Changing the frame size option will change the number of times the callback is called, but will not change the time duration or number of bytes received. That is, if I double the frame size, the callback is called about half the number of times, but the total time duration and byte count is about the same.
  • Changing the sample format option of course changes the number of bytes I receive, but the number of times the callback is called is not changed, and neither is the total time duration.
  • I'm not using an audio output. Input only.
  • The error callback is never called.
  • None of the RtAudioStreamFlags have any impact on this problem.
  • Windows 10 x64. Node.js 18.3.0. Audify 1.7.1.

Any thoughts as to the cause of this and how it can be solved?

bradisbell avatar Jun 16 '22 06:06 bradisbell

The problem also occurs on Node.js v16.15.1.

bradisbell avatar Jun 16 '22 09:06 bradisbell

I've found that this problem doesn't occur as long as I have an output running too. It seems rtAudio.write() must be called regularly for the input to work.

Using null for the output options doesn't work, because calls to .write() cause a crash.

bradisbell avatar Jun 16 '22 19:06 bradisbell

I have almost the same exact same issue on Linux with PulseAudio. Based on your workaround I implemented a very dumb way of dealing with it after some experimentation.

// Start the stream
rtAudio.start();
setTimeout(() => {
    try {
        rtAudio.write(null);
    } catch {
        console.log("RTAudio fixed, enjoy your stream.");
    }
})

Calling it once without setTimeout does not work. Putting it in setTimeout and the default 0ms timeout will make it work. I did not have to call it anymore after this.

TibixDev avatar Jul 16 '22 00:07 TibixDev

I found out that it's not really related with the write method, you can actually call isStreamOpen or isStreamRunning methods to keep it running. It almost feels like a reference counter or something that goes to zero if you don't reference it. I'm pretty sure it's about the C++ implementation of the binding.

hamitzor avatar Dec 10 '23 15:12 hamitzor

Actually, even this worked for me:

//  Not even calling the foo function, just declaring it.
const foo = () => {
    recorder.isStreamOpen() // keeps the recorder stream running.
}

hamitzor avatar Dec 10 '23 15:12 hamitzor

It's a Schrödinger's stream: if nobody is measuring if it's open or not, it declines to collapse its superposition into a concrete state of existence 🤣

o0101 avatar Dec 27 '23 16:12 o0101