1
Audio / Re: How to make main thread wait for SoundRecorder to finish
« on: January 22, 2018, 04:18:45 pm »
My current version of MinGW doesn't support futures or promises, so I am using atomic temporarily. I tried a new way of waiting for the audio thread to finish, and I found that returning false from onProccessSamples() somehow causes onStop() not to be called. Am I missing something? By always returning true from onProccessSamples(), I can manually call stop() from the main thread and have onStop() get called.
#include <atomic>
#include <iostream>
#include <SFML/Audio.hpp>
struct CustomRecorder : sf::SoundRecorder
{
CustomRecorder() { }
~CustomRecorder() { stop(); }
void waitJoin() const
{
while (signalJoin() == false) wait();
}
void waitStop() const
{
while (signalStop() == false) wait();
}
private:
bool onProcessSamples(const int16_t* samples,
const size_t sampleCount)
{
if (signalStop() == false)
{
std::cout << "CustomRecorder::onProcessSamples() [samples:" << sampleCount << "]" << std::endl;
count += sampleCount;
if (count >= 22050) atomicStop.store(1, std::memory_order_relaxed);
}
else
{
std::cout << "CustomRecorder::onProcessSamples() [in flight before stop()]" << std::endl;
}
return true;
}
bool onStart()
{
std::cout << "CustomRecorder::onStart();" << std::endl;
atomicJoin.store(0, std::memory_order_relaxed);
atomicStop.store(0, std::memory_order_relaxed);
return true;
}
void onStop()
{
std::cout << "CustomRecorder::onStop();" << std::endl;
atomicJoin.store(1, std::memory_order_relaxed);
}
bool signalJoin() const
{
return atomicJoin.load(std::memory_order_relaxed);
}
bool signalStop() const
{
return atomicStop.load(std::memory_order_relaxed);
}
void wait() const
{
sf::sleep(sf::milliseconds(15));
}
size_t count = 0;
std::atomic<int32_t> atomicJoin;
std::atomic<int32_t> atomicStop;
};
int main()
{
std::cout << "starting audio capture" << std::endl;
CustomRecorder r;
r.start();
r.waitStop();
r.stop();
r.waitJoin();
return 0;
}
#include <iostream>
#include <SFML/Audio.hpp>
struct CustomRecorder : sf::SoundRecorder
{
CustomRecorder() { }
~CustomRecorder() { stop(); }
void waitJoin() const
{
while (signalJoin() == false) wait();
}
void waitStop() const
{
while (signalStop() == false) wait();
}
private:
bool onProcessSamples(const int16_t* samples,
const size_t sampleCount)
{
if (signalStop() == false)
{
std::cout << "CustomRecorder::onProcessSamples() [samples:" << sampleCount << "]" << std::endl;
count += sampleCount;
if (count >= 22050) atomicStop.store(1, std::memory_order_relaxed);
}
else
{
std::cout << "CustomRecorder::onProcessSamples() [in flight before stop()]" << std::endl;
}
return true;
}
bool onStart()
{
std::cout << "CustomRecorder::onStart();" << std::endl;
atomicJoin.store(0, std::memory_order_relaxed);
atomicStop.store(0, std::memory_order_relaxed);
return true;
}
void onStop()
{
std::cout << "CustomRecorder::onStop();" << std::endl;
atomicJoin.store(1, std::memory_order_relaxed);
}
bool signalJoin() const
{
return atomicJoin.load(std::memory_order_relaxed);
}
bool signalStop() const
{
return atomicStop.load(std::memory_order_relaxed);
}
void wait() const
{
sf::sleep(sf::milliseconds(15));
}
size_t count = 0;
std::atomic<int32_t> atomicJoin;
std::atomic<int32_t> atomicStop;
};
int main()
{
std::cout << "starting audio capture" << std::endl;
CustomRecorder r;
r.start();
r.waitStop();
r.stop();
r.waitJoin();
return 0;
}