1
Audio / How to make main thread wait for SoundRecorder to finish
« on: January 21, 2018, 12:53:21 pm »
What would be a good way to make the main thread wait for the audio thread to finish?
In the following code I use sf::sleep to wait to make sure that the audio thread has actually finished its work, but I'm not really happy with this solution because it precludes me from instantiating a temporary CRecorder in a function.
In the following code I use sf::sleep to wait to make sure that the audio thread has actually finished its work, but I'm not really happy with this solution because it precludes me from instantiating a temporary CRecorder in a function.
#include <atomic>
#include <iostream>
#include <SFML/Audio.hpp>
struct CRecorder : sf::SoundRecorder
{
CRecorder() { }
~CRecorder() { stop(); }
bool onProcessSamples(const int16_t* samples, const size_t sampleCount)
{
std::cout << "CustomRecorder::onProcessSamples() [samples:" << sampleCount << ", done: ";
std::cout << finished.load(std::memory_order_relaxed) << "]" << std::endl;
if (finished.load(std::memory_order_relaxed) == 1) { return false; }
// collect samples
count += sampleCount;
// return false when 22050 or more have been collected, otherwise return true
if (count >= 22050)
{
// tell the main thread to stop waiting
finished.store(1, std::memory_order_relaxed);
// note that onProcessSamples may be called again (sometimes) even though we return false
return false;
}
return true;
}
bool onStart()
{
std::cout << "CustomRecorder::onStart();" << std::endl;
finished.store(0, std::memory_order_relaxed);
setProcessingInterval(sf::milliseconds(25));
return true;
}
void onStop()
{
std::cout << "CustomRecorder::onStop();" << std::endl;
}
size_t count = 0;
std::atomic<int32_t> finished;
};
int main()
{
CRecorder r;
std::cout << "starting audio capture" << std::endl;
r.start();
while (r.finished.load(std::memory_order_relaxed) == 0)
{
sf::sleep(sf::milliseconds(25));
}
// guard against the "pure virtual method called" exception (might not be totally foolproof)
//sf::sleep(sf::milliseconds(1000));
return 0;
}
#include <iostream>
#include <SFML/Audio.hpp>
struct CRecorder : sf::SoundRecorder
{
CRecorder() { }
~CRecorder() { stop(); }
bool onProcessSamples(const int16_t* samples, const size_t sampleCount)
{
std::cout << "CustomRecorder::onProcessSamples() [samples:" << sampleCount << ", done: ";
std::cout << finished.load(std::memory_order_relaxed) << "]" << std::endl;
if (finished.load(std::memory_order_relaxed) == 1) { return false; }
// collect samples
count += sampleCount;
// return false when 22050 or more have been collected, otherwise return true
if (count >= 22050)
{
// tell the main thread to stop waiting
finished.store(1, std::memory_order_relaxed);
// note that onProcessSamples may be called again (sometimes) even though we return false
return false;
}
return true;
}
bool onStart()
{
std::cout << "CustomRecorder::onStart();" << std::endl;
finished.store(0, std::memory_order_relaxed);
setProcessingInterval(sf::milliseconds(25));
return true;
}
void onStop()
{
std::cout << "CustomRecorder::onStop();" << std::endl;
}
size_t count = 0;
std::atomic<int32_t> finished;
};
int main()
{
CRecorder r;
std::cout << "starting audio capture" << std::endl;
r.start();
while (r.finished.load(std::memory_order_relaxed) == 0)
{
sf::sleep(sf::milliseconds(25));
}
// guard against the "pure virtual method called" exception (might not be totally foolproof)
//sf::sleep(sf::milliseconds(1000));
return 0;
}