Added support for selecting audio capture device (fixes #220)

This commit is contained in:
Foaly 2013-09-19 01:44:59 +02:00
parent 718588ff1d
commit b1ad9dceac
2 changed files with 161 additions and 15 deletions

View file

@ -30,6 +30,7 @@
#include <SFML/Audio/ALCheck.hpp>
#include <SFML/System/Sleep.hpp>
#include <SFML/System/Err.hpp>
#include <cstring>
#ifdef _MSC_VER
#pragma warning(disable : 4355) // 'this' used in base member initializer list
@ -51,6 +52,9 @@ m_isCapturing (false),
m_processingInterval(milliseconds(100))
{
priv::ensureALInit();
// Set the device name to the default device
m_deviceName = getDefaultDevice();
}
@ -62,28 +66,28 @@ SoundRecorder::~SoundRecorder()
////////////////////////////////////////////////////////////
void SoundRecorder::start(unsigned int sampleRate)
bool SoundRecorder::start(unsigned int sampleRate)
{
// Check if the device can do audio capture
if (!isAvailable())
{
err() << "Failed to start capture : your system cannot capture audio data (call SoundRecorder::isAvailable to check it)" << std::endl;
return;
return false;
}
// Check that another capture is not already running
if (captureDevice)
{
err() << "Trying to start audio capture, but another capture is already running" << std::endl;
return;
return false;
}
// Open the capture device for capturing 16 bits mono samples
captureDevice = alcCaptureOpenDevice(NULL, sampleRate, AL_FORMAT_MONO16, sampleRate);
captureDevice = alcCaptureOpenDevice(m_deviceName.c_str(), sampleRate, AL_FORMAT_MONO16, sampleRate);
if (!captureDevice)
{
err() << "Failed to open the audio capture device" << std::endl;
return;
err() << "Failed to open the audio capture device with the name: " << m_deviceName << std::endl;
return false;
}
// Clear the array of samples
@ -101,7 +105,11 @@ void SoundRecorder::start(unsigned int sampleRate)
// Start the capture in a new thread, to avoid blocking the main thread
m_isCapturing = true;
m_thread.launch();
return true;
}
return false;
}
@ -111,6 +119,9 @@ void SoundRecorder::stop()
// Stop the capturing thread
m_isCapturing = false;
m_thread.wait();
// Notify derived class
onStop();
}
@ -121,6 +132,77 @@ unsigned int SoundRecorder::getSampleRate() const
}
////////////////////////////////////////////////////////////
std::vector<std::string> SoundRecorder::getAvailableDevices()
{
std::vector<std::string> deviceNameList;
const ALchar *deviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
if (deviceList)
{
while (*deviceList)
{
deviceNameList.push_back(deviceList);
deviceList += std::strlen(deviceList) + 1;
}
}
return deviceNameList;
}
////////////////////////////////////////////////////////////
std::string SoundRecorder::getDefaultDevice()
{
return alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
}
////////////////////////////////////////////////////////////
bool SoundRecorder::setDevice(const std::string& name)
{
// Store the device name
if (name.empty())
m_deviceName = getDefaultDevice();
else
m_deviceName = name;
if (m_isCapturing)
{
// Stop the capturing thread
m_isCapturing = false;
m_thread.wait();
// Open the requested capture device for capturing 16 bits mono samples
captureDevice = alcCaptureOpenDevice(name.c_str(), m_sampleRate, AL_FORMAT_MONO16, m_sampleRate);
if (!captureDevice)
{
// Notify derived class
onStop();
err() << "Failed to open the audio capture device with the name: " << m_deviceName << std::endl;
return false;
}
// Start the capture
alcCaptureStart(captureDevice);
// Start the capture in a new thread, to avoid blocking the main thread
m_isCapturing = true;
m_thread.launch();
}
return true;
}
////////////////////////////////////////////////////////////
const std::string& SoundRecorder::getDevice() const
{
return m_deviceName;
}
////////////////////////////////////////////////////////////
bool SoundRecorder::isAvailable()
{
@ -165,9 +247,6 @@ void SoundRecorder::record()
// Capture is finished : clean up everything
cleanup();
// Notify derived class
onStop();
}