Can't open `RtAudio` object from a different thread
Foaly opened this issue · 6 comments
Hello!
I think I found a bug in RtAudio
, although I am not sure and it might just be undocumented behaviour.
If I instanciate a RtAudio
object in one thread and then call openStream
on that object from another thread, the connection to the sound card can not be established. I did not read read anywhere that this is not possible, so I am assuming it might be bug. The output I am getting with the following minimal example is:
RtApiAsio::getDeviceInfo: unable to load driver (ASIO MADIface USB).
RtApiAsio::getDeviceInfo: unable to load driver (Realtek ASIO).
RtApiAsio::probeDeviceOpen: unable to load driver (ASIO MADIface USB).
Does anybody have an idea how to fix this? Thank you some much in advance!
Minimal example:
#include <RtAudio.h>
#include <chrono>
#include <thread>
RtAudio audioOutputStream( RtAudio::WINDOWS_ASIO );
int audioCallback(void* /*outputBuffer*/, void* /*inputBuffer*/, unsigned int /*frameCount*/, double /*streamTime*/, RtAudioStreamStatus /*status*/, void* /*userData*/)
{
return 0;
}
void threadFunction()
{
constexpr std::size_t sampleRate = 48000;
unsigned int bufferSize = 512;
constexpr unsigned int channelCount = 2;
constexpr RtAudioFormat format = RTAUDIO_FLOAT32;
RtAudio::StreamParameters outputStreamParams;
outputStreamParams.deviceId = 0;
outputStreamParams.nChannels = channelCount;
try
{
audioOutputStream.openStream(&outputStreamParams,
nullptr,
format,
static_cast<unsigned int>(sampleRate),
&bufferSize,
audioCallback);
audioOutputStream.startStream();
}
catch (RtAudioError& e)
{
e.printMessage();
}
}
int main()
{
using namespace std::chrono_literals;
std::thread t (threadFunction);
std::this_thread::sleep_for(3s);
t.join();
}
I tried this on OS-X and it worked fine. I don't know if it may be an issue with the ASIO API or the configuration on your particular computer.
Ah forgot to add I am not of macos but on windows 11.
Does it work from same thread?
@sonoro1234 Yes it does indeed. If my main function in the minimal example above looks like the following everything works as expected and no errors are printed.
int main()
{
using namespace std::chrono_literals;
threadFunction();
std::this_thread::sleep_for(3s);
audioOutputStream.closeStream();
}
The first example worked for me in Mac OS-X but not in Windows ASIO. I see in the RtApiAsio constructor that it says:
// ASIO cannot run on a multi-threaded apartment. You can call
// CoInitialize beforehand, but it must be for apartment threading
// (in which case, CoInitilialize will return S_FALSE here).
So, this seems to be a limitation of the ASIO API.
Alright, if it is a limitation of the windows ASIO API, then it would be great if you could add a description of the behaviour to the documentation. I couldn't find anything about it anywhere here: https://www.music.mcgill.ca/~gary/rtaudio/
That would be fantastic! Thank you so much for investigating :)