Make sure the recording thread in sf::SoundRecorder is stopped before sf::SoundBufferRecorder is destroyed.
Fixes a "pure virtual method called" crash. Also updated the documentation and the VoIP example.
This commit is contained in:
parent
e00d160224
commit
1ee6d1dbc6
@ -32,10 +32,22 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Destructor
|
||||||
|
///
|
||||||
|
/// \see SoundRecorder::~SoundRecorder()
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
~NetworkRecorder()
|
||||||
|
{
|
||||||
|
// Make sure to stop the recording thread
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// /see SoundRecorder::OnStart
|
/// \see SoundRecorder::onStart
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual bool onStart()
|
virtual bool onStart()
|
||||||
@ -52,7 +64,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// /see SoundRecorder::ProcessSamples
|
/// \see SoundRecorder::onProcessSamples
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual bool onProcessSamples(const sf::Int16* samples, std::size_t sampleCount)
|
virtual bool onProcessSamples(const sf::Int16* samples, std::size_t sampleCount)
|
||||||
@ -67,7 +79,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// /see SoundRecorder::OnStop
|
/// \see SoundRecorder::onStop
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void onStop()
|
virtual void onStop()
|
||||||
@ -98,7 +110,7 @@ private:
|
|||||||
void doClient(unsigned short port)
|
void doClient(unsigned short port)
|
||||||
{
|
{
|
||||||
// Check that the device can capture audio
|
// Check that the device can capture audio
|
||||||
if (sf::SoundRecorder::isAvailable() == false)
|
if (!sf::SoundRecorder::isAvailable())
|
||||||
{
|
{
|
||||||
std::cout << "Sorry, audio capture is not supported by your system" << std::endl;
|
std::cout << "Sorry, audio capture is not supported by your system" << std::endl;
|
||||||
return;
|
return;
|
||||||
|
@ -45,6 +45,12 @@ class SFML_AUDIO_API SoundBufferRecorder : public SoundRecorder
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief destructor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
~SoundBufferRecorder();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the sound buffer containing the captured audio data
|
/// \brief Get the sound buffer containing the captured audio data
|
||||||
///
|
///
|
||||||
|
@ -316,11 +316,20 @@ private:
|
|||||||
/// from this separate thread. It is important to keep this in
|
/// from this separate thread. It is important to keep this in
|
||||||
/// mind, because you may have to take care of synchronization
|
/// mind, because you may have to take care of synchronization
|
||||||
/// issues if you share data between threads.
|
/// issues if you share data between threads.
|
||||||
|
/// Another thing to bear in mind is that you must call stop()
|
||||||
|
/// in the destructor of your derived class, so that the recording
|
||||||
|
/// thread finishes before your object is destroyed.
|
||||||
///
|
///
|
||||||
/// Usage example:
|
/// Usage example:
|
||||||
/// \code
|
/// \code
|
||||||
/// class CustomRecorder : public sf::SoundRecorder
|
/// class CustomRecorder : public sf::SoundRecorder
|
||||||
/// {
|
/// {
|
||||||
|
/// ~CustomRecorder()
|
||||||
|
/// {
|
||||||
|
/// // Make sure to stop the recording thread
|
||||||
|
/// stop();
|
||||||
|
/// }
|
||||||
|
///
|
||||||
/// virtual bool onStart() // optional
|
/// virtual bool onStart() // optional
|
||||||
/// {
|
/// {
|
||||||
/// // Initialize whatever has to be done before the capture starts
|
/// // Initialize whatever has to be done before the capture starts
|
||||||
|
@ -32,6 +32,14 @@
|
|||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
SoundBufferRecorder::~SoundBufferRecorder()
|
||||||
|
{
|
||||||
|
// Make sure to stop the recording thread
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool SoundBufferRecorder::onStart()
|
bool SoundBufferRecorder::onStart()
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <SFML/System/Sleep.hpp>
|
#include <SFML/System/Sleep.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable: 4355) // 'this' used in base member initializer list
|
#pragma warning(disable: 4355) // 'this' used in base member initializer list
|
||||||
@ -59,7 +60,12 @@ m_deviceName (getDefaultDevice())
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SoundRecorder::~SoundRecorder()
|
SoundRecorder::~SoundRecorder()
|
||||||
{
|
{
|
||||||
// Nothing to do
|
// This assertion is triggered if the recording is still running while
|
||||||
|
// the object is destroyed. It ensures that stop() is called in the
|
||||||
|
// destructor of the derived class, which makes sure that the recording
|
||||||
|
// thread finishes before the derived object is destroyed. Otherwise a
|
||||||
|
// "pure virtual method called" exception is triggered.
|
||||||
|
assert(!m_isCapturing && "You must call stop() in the destructor of your derived class, so that the recording thread finishes before your object is destroyed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -114,12 +120,15 @@ bool SoundRecorder::start(unsigned int sampleRate)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SoundRecorder::stop()
|
void SoundRecorder::stop()
|
||||||
{
|
{
|
||||||
// Stop the capturing thread
|
// Stop the capturing thread if there is one
|
||||||
|
if (m_isCapturing)
|
||||||
|
{
|
||||||
m_isCapturing = false;
|
m_isCapturing = false;
|
||||||
m_thread.wait();
|
m_thread.wait();
|
||||||
|
|
||||||
// Notify derived class
|
// Notify derived class
|
||||||
onStop();
|
onStop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user