1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

privatized audio interface

This commit is contained in:
Nils Fenner 2015-12-11 00:16:21 +01:00
parent c23cb0043f
commit bb7d2a72b7
No known key found for this signature in database
GPG Key ID: 9591A163FF9BE04C
7 changed files with 152 additions and 142 deletions

View File

@ -38,6 +38,36 @@
#include <cassert> #include <cassert>
#if defined(__APPLE__) && defined(__MACH__)
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
class AudioPrivate
{
public:
AudioPrivate()
: alInDev(nullptr)
, alOutDev(nullptr)
, alContext(nullptr)
, inputVolume(1.f)
, outputVolume(1.f)
{
}
public:
ALCdevice* alInDev;
ALCdevice* alOutDev;
ALCcontext* alContext;
ALuint alMainSource;
qreal inputVolume;
qreal outputVolume;
};
Audio* Audio::instance{nullptr}; Audio* Audio::instance{nullptr};
/** /**
@ -54,15 +84,10 @@ Audio& Audio::getInstance()
} }
Audio::Audio() Audio::Audio()
: audioThread(new QThread()) : d(new AudioPrivate)
, alOutDev(nullptr) , audioThread(new QThread())
, alInDev(nullptr)
, mInputInitialized(false) , mInputInitialized(false)
, mOutputInitialized(false) , mOutputInitialized(false)
, outputVolume(1.0)
, inputVolume(1.0)
, alMainSource(0)
, alContext(nullptr)
{ {
audioThread->setObjectName("qTox Audio"); audioThread->setObjectName("qTox Audio");
connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater);
@ -94,10 +119,10 @@ void Audio::startAudioThread()
/** /**
Returns the current output volume, between 0 and 1 Returns the current output volume, between 0 and 1
*/ */
qreal Audio::getOutputVolume() qreal Audio::outputVolume()
{ {
QMutexLocker locker(&mAudioLock); QMutexLocker locker(&mAudioLock);
return outputVolume; return d->outputVolume;
} }
/** /**
@ -107,27 +132,31 @@ void Audio::setOutputVolume(qreal volume)
{ {
QMutexLocker locker(&mAudioLock); QMutexLocker locker(&mAudioLock);
outputVolume = volume; d->outputVolume = volume;
alSourcef(alMainSource, AL_GAIN, outputVolume); alSourcef(d->alMainSource, AL_GAIN, volume);
for (const ToxGroupCall& call : CoreAV::groupCalls) for (const ToxGroupCall& call : CoreAV::groupCalls)
{ {
alSourcef(call.alSource, AL_GAIN, outputVolume); alSourcef(call.alSource, AL_GAIN, volume);
} }
for (const ToxFriendCall& call : CoreAV::calls) for (const ToxFriendCall& call : CoreAV::calls)
{ {
alSourcef(call.alSource, AL_GAIN, outputVolume); alSourcef(call.alSource, AL_GAIN, volume);
} }
} }
/** qreal Audio::inputVolume()
The volume must be between 0 and 2 {
*/ QMutexLocker locker(&mAudioLock);
return d->inputVolume;
}
void Audio::setInputVolume(qreal volume) void Audio::setInputVolume(qreal volume)
{ {
QMutexLocker locker(&mAudioLock); QMutexLocker locker(&mAudioLock);
inputVolume = volume; d->inputVolume = volume;
} }
/** /**
@ -139,7 +168,7 @@ void Audio::subscribeInput(const void* inListener)
{ {
QMutexLocker locker(&mAudioLock); QMutexLocker locker(&mAudioLock);
if (!alInDev) if (!d->alInDev)
initInput(Settings::getInstance().getInDev()); initInput(Settings::getInstance().getInDev());
if (!inputSubscriptions.contains(inListener)) { if (!inputSubscriptions.contains(inListener)) {
@ -171,7 +200,7 @@ void Audio::subscribeOutput(const void* outListener)
{ {
QMutexLocker locker(&mAudioLock); QMutexLocker locker(&mAudioLock);
if (!alOutDev) if (!d->alOutDev)
initOutput(Settings::getInstance().getOutDev()); initOutput(Settings::getInstance().getOutDev());
if (!outputSubscriptions.contains(outListener)) { if (!outputSubscriptions.contains(outListener)) {
@ -202,7 +231,7 @@ void Audio::initInput(const QString& inDevDescr)
if (inDevDescr == "none") if (inDevDescr == "none")
return; return;
assert(!alInDev); assert(!d->alInDev);
/// TODO: Try to actually detect if our audio source is stereo /// TODO: Try to actually detect if our audio source is stereo
int stereoFlag = AUDIO_CHANNELS == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; int stereoFlag = AUDIO_CHANNELS == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
@ -230,10 +259,10 @@ void Audio::initInput(const QString& inDevDescr)
} }
} }
else else
alInDev = alcCaptureOpenDevice(inDevDescr.toStdString().c_str(), d->alInDev = alcCaptureOpenDevice(inDevDescr.toStdString().c_str(),
sampleRate, stereoFlag, bufSize); sampleRate, stereoFlag, bufSize);
if (alInDev) if (d->alInDev)
qDebug() << "Opened audio input" << inDevDescr; qDebug() << "Opened audio input" << inDevDescr;
else else
qWarning() << "Cannot open input audio device" << inDevDescr; qWarning() << "Cannot open input audio device" << inDevDescr;
@ -243,9 +272,9 @@ void Audio::initInput(const QString& inDevDescr)
core->getAv()->resetCallSources(); // Force to regen each group call's sources core->getAv()->resetCallSources(); // Force to regen each group call's sources
// Restart the capture if necessary // Restart the capture if necessary
if (alInDev) if (d->alInDev)
{ {
alcCaptureStart(alInDev); alcCaptureStart(d->alInDev);
} }
else else
{ {
@ -270,7 +299,7 @@ bool Audio::initOutput(const QString& outDevDescr)
if (outDevDescr == "none") if (outDevDescr == "none")
return true; return true;
assert(!alOutDev); assert(!d->alOutDev);
if (outDevDescr.isEmpty()) if (outDevDescr.isEmpty())
{ {
@ -297,14 +326,15 @@ bool Audio::initOutput(const QString& outDevDescr)
} }
} }
else else
alOutDev = alcOpenDevice(outDevDescr.toStdString().c_str()); d->alOutDev = alcOpenDevice(outDevDescr.toStdString().c_str());
if (alOutDev) if (d->alOutDev)
{ {
alContext = alcCreateContext(alOutDev, nullptr); d->alContext = alcCreateContext(d->alOutDev, nullptr);
if (alcMakeContextCurrent(alContext)) if (alcMakeContextCurrent(d->alContext))
{ {
alGenSources(1, &alMainSource); alGenSources(1, &d->alMainSource);
alSourcef(d->alMainSource, AL_GAIN, d->outputVolume);
} }
else else
{ {
@ -332,26 +362,28 @@ void Audio::playMono16Sound(const QByteArray& data)
{ {
QMutexLocker locker(&mAudioLock); QMutexLocker locker(&mAudioLock);
if (!alOutDev) if (!d->alOutDev)
initOutput(Settings::getInstance().getOutDev()); initOutput(Settings::getInstance().getOutDev());
alSourcei(d->alMainSource, AL_LOOPING, false);
alSourcef(d->alMainSource, AL_GAIN, d->outputVolume);
alSource3f(d->alMainSource, AL_POSITION, 0, 0, 0);
alSource3f(d->alMainSource, AL_VELOCITY, 0, 0, 0);
ALuint buffer; ALuint buffer;
alGenBuffers(1, &buffer); alGenBuffers(1, &buffer);
alBufferData(buffer, AL_FORMAT_MONO16, data.data(), data.size(), 44100); alBufferData(buffer, AL_FORMAT_MONO16, data.constData(), data.size(), 44100);
alSourcef(alMainSource, AL_GAIN, outputVolume);
alSourcei(alMainSource, AL_BUFFER, buffer);
alSourcePlay(alMainSource);
ALint sizeInBytes; alSourcei(d->alMainSource, AL_BUFFER, buffer);
ALint channels;
ALint bits;
alGetBufferi(buffer, AL_SIZE, &sizeInBytes); alSourceRewind(d->alMainSource);
alGetBufferi(buffer, AL_CHANNELS, &channels); alSourcePlay(d->alMainSource);
alGetBufferi(buffer, AL_BITS, &bits);
ALint frequency; ALint state;
alGetBufferi(buffer, AL_FREQUENCY, &frequency); alGetSourcei(d->alMainSource, AL_SOURCE_STATE, &state);
while (state == AL_PLAYING) {
alGetSourcei(d->alMainSource, AL_SOURCE_STATE, &state);
}
alDeleteBuffers(1, &buffer); alDeleteBuffers(1, &buffer);
@ -403,7 +435,7 @@ void Audio::playGroupAudio(int group, int peer, const int16_t* data,
if (!call.alSource) if (!call.alSource)
{ {
alGenSources(1, &call.alSource); alGenSources(1, &call.alSource);
alSourcef(call.alSource, AL_GAIN, outputVolume); alSourcef(call.alSource, AL_GAIN, d->outputVolume);
} }
qreal volume = 0.; qreal volume = 0.;
@ -416,11 +448,10 @@ void Audio::playGroupAudio(int group, int peer, const int16_t* data,
playAudioBuffer(call.alSource, data, samples, channels, sample_rate); playAudioBuffer(call.alSource, data, samples, channels, sample_rate);
} }
void Audio::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, unsigned channels, int sampleRate) void Audio::playAudioBuffer(quint32 alSource, const int16_t *data, int samples, unsigned channels, int sampleRate)
{ {
assert(channels == 1 || channels == 2); assert(channels == 1 || channels == 2);
QMutexLocker locker(&mAudioLock);
QMutexLocker locker(&getInstance().mAudioLock);
ALuint bufid; ALuint bufid;
ALint processed = 0, queued = 16; ALint processed = 0, queued = 16;
@ -450,7 +481,7 @@ void Audio::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, u
ALint state; ALint state;
alGetSourcei(alSource, AL_SOURCE_STATE, &state); alGetSourcei(alSource, AL_SOURCE_STATE, &state);
alSourcef(alSource, AL_GAIN, getInstance().outputVolume); alSourcef(alSource, AL_GAIN, d->outputVolume);
if (state != AL_PLAYING) if (state != AL_PLAYING)
alSourcePlay(alSource); alSourcePlay(alSource);
} }
@ -464,16 +495,16 @@ void Audio::cleanupInput()
{ {
mInputInitialized = false; mInputInitialized = false;
if (alInDev) if (d->alInDev)
{ {
#if (!FIX_SND_PCM_PREPARE_BUG) #if (!FIX_SND_PCM_PREPARE_BUG)
qDebug() << "stopping audio capture"; qDebug() << "stopping audio capture";
alcCaptureStop(alInDev); alcCaptureStop(d->alInDev);
#endif #endif
qDebug() << "Closing audio input"; qDebug() << "Closing audio input";
if (alcCaptureCloseDevice(alInDev) == ALC_TRUE) if (alcCaptureCloseDevice(d->alInDev) == ALC_TRUE)
alInDev = nullptr; d->alInDev = nullptr;
else else
qWarning() << "Failed to close input"; qWarning() << "Failed to close input";
} }
@ -488,20 +519,20 @@ void Audio::cleanupOutput()
{ {
mOutputInitialized = false; mOutputInitialized = false;
if (alOutDev) { if (d->alOutDev) {
qDebug() << "Closing audio output"; qDebug() << "Closing audio output";
alSourcei(alMainSource, AL_LOOPING, AL_FALSE); alSourcei(d->alMainSource, AL_LOOPING, AL_FALSE);
alSourceStop(alMainSource); alSourceStop(d->alMainSource);
alDeleteSources(1, &alMainSource); alDeleteSources(1, &d->alMainSource);
if (!alcMakeContextCurrent(nullptr)) if (!alcMakeContextCurrent(nullptr))
qWarning("Failed to clear current audio context."); qWarning("Failed to clear current audio context.");
alcDestroyContext(alContext); alcDestroyContext(d->alContext);
alContext = nullptr; d->alContext = nullptr;
if (alcCloseDevice(alOutDev)) if (alcCloseDevice(d->alOutDev))
alOutDev = nullptr; d->alOutDev = nullptr;
else else
qWarning("Failed to close output."); qWarning("Failed to close output.");
} }
@ -513,7 +544,7 @@ Returns true if the input device is open and suscribed to
bool Audio::isInputReady() bool Audio::isInputReady()
{ {
QMutexLocker locker(&mAudioLock); QMutexLocker locker(&mAudioLock);
return alInDev && mInputInitialized; return d->alInDev && mInputInitialized;
} }
/** /**
@ -522,32 +553,49 @@ Returns true if the output device is open
bool Audio::isOutputReady() bool Audio::isOutputReady()
{ {
QMutexLocker locker(&mAudioLock); QMutexLocker locker(&mAudioLock);
return alOutDev && mOutputInitialized; return d->alOutDev && mOutputInitialized;
} }
void Audio::createSource(ALuint* source) const char* Audio::outDeviceNames()
{ {
alGenSources(1, source); const char* pDeviceList;
alSourcef(*source, AL_GAIN, getInstance().outputVolume); if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
} pDeviceList = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
void Audio::deleteSource(ALuint* source)
{
if (alIsSource(*source))
alDeleteSources(1, source);
else else
qWarning() << "Trying to delete invalid audio source"<<*source; pDeviceList = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
return pDeviceList;
}
const char* Audio::inDeviceNames()
{
return alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
}
void Audio::createSource(quint32* sid)
{
alGenSources(1, sid);
alSourcef(*sid, AL_GAIN, 1.f);
}
void Audio::deleteSource(quint32 sid)
{
if (alIsSource(sid)) {
alDeleteSources(1, &sid);
} else {
qWarning() << "Trying to delete invalid audio source" << sid;
}
} }
void Audio::startLoop() void Audio::startLoop()
{ {
alSourcei(alMainSource, AL_LOOPING, AL_TRUE); alSourcei(d->alMainSource, AL_LOOPING, AL_TRUE);
} }
void Audio::stopLoop() void Audio::stopLoop()
{ {
alSourcei(alMainSource, AL_LOOPING, AL_FALSE); alSourcei(d->alMainSource, AL_LOOPING, AL_FALSE);
alSourceStop(alMainSource); alSourceStop(d->alMainSource);
} }
/** /**
@ -557,19 +605,19 @@ bool Audio::tryCaptureSamples(int16_t* buf, int samples)
{ {
QMutexLocker lock(&mAudioLock); QMutexLocker lock(&mAudioLock);
if (!(alInDev && mInputInitialized)) if (!(d->alInDev && mInputInitialized))
return false; return false;
ALint curSamples=0; ALint curSamples=0;
alcGetIntegerv(alInDev, ALC_CAPTURE_SAMPLES, sizeof(curSamples), &curSamples); alcGetIntegerv(d->alInDev, ALC_CAPTURE_SAMPLES, sizeof(curSamples), &curSamples);
if (curSamples < samples) if (curSamples < samples)
return false; return false;
alcCaptureSamples(alInDev, buf, samples); alcCaptureSamples(d->alInDev, buf, samples);
for (size_t i = 0; i < samples * AUDIO_CHANNELS; ++i) for (size_t i = 0; i < samples * AUDIO_CHANNELS; ++i)
{ {
int sample = buf[i] * pow(inputVolume, 2); int sample = buf[i] * pow(d->inputVolume, 2);
if (sample < std::numeric_limits<int16_t>::min()) if (sample < std::numeric_limits<int16_t>::min())
sample = std::numeric_limits<int16_t>::min(); sample = std::numeric_limits<int16_t>::min();

View File

@ -26,17 +26,9 @@
#include <atomic> #include <atomic>
#include <cmath> #include <cmath>
#if defined(__APPLE__) && defined(__MACH__)
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alext.h>
#endif
struct Tox; struct Tox;
class AudioFilterer; class AudioFilterer;
class AudioPrivate;
// Public default audio settings // Public default audio settings
static constexpr uint32_t AUDIO_SAMPLE_RATE = 48000; ///< The next best Opus would take is 24k static constexpr uint32_t AUDIO_SAMPLE_RATE = 48000; ///< The next best Opus would take is 24k
@ -56,9 +48,10 @@ public:
public: public:
void startAudioThread(); void startAudioThread();
qreal getOutputVolume(); qreal outputVolume();
void setOutputVolume(qreal volume); void setOutputVolume(qreal volume);
qreal inputVolume();
void setInputVolume(qreal volume); void setInputVolume(qreal volume);
inline void reinitInput(const QString& inDevDesc) inline void reinitInput(const QString& inDevDesc)
@ -77,8 +70,10 @@ public:
bool isInputReady(); bool isInputReady();
bool isOutputReady(); bool isOutputReady();
static void createSource(ALuint* source); static const char* outDeviceNames();
static void deleteSource(ALuint* source); static const char* inDeviceNames();
void createSource(quint32* sid);
void deleteSource(quint32 sid);
void startLoop(); void startLoop();
void stopLoop(); void stopLoop();
@ -86,7 +81,8 @@ public:
void playMono16Sound(const char* path); void playMono16Sound(const char* path);
bool tryCaptureSamples(int16_t *buf, int samples); bool tryCaptureSamples(int16_t *buf, int samples);
static void playAudioBuffer(ALuint alSource, const int16_t *data, int samples, unsigned channels, int sampleRate); void playAudioBuffer(quint32 alSource, const int16_t *data, int samples,
unsigned channels, int sampleRate);
static void playGroupAudioQueued(void *, int group, int peer, const int16_t* data, static void playGroupAudioQueued(void *, int group, int peer, const int16_t* data,
unsigned samples, uint8_t channels, unsigned sample_rate, void*); unsigned samples, uint8_t channels, unsigned sample_rate, void*);
@ -124,14 +120,8 @@ private:
QMutex mAudioLock; QMutex mAudioLock;
PtrList inputSubscriptions; PtrList inputSubscriptions;
PtrList outputSubscriptions; PtrList outputSubscriptions;
ALCdevice* alOutDev;
ALCdevice* alInDev;
bool mInputInitialized; bool mInputInitialized;
bool mOutputInitialized; bool mOutputInitialized;
qreal outputVolume;
qreal inputVolume;
ALuint alMainSource;
ALCcontext* alContext;
}; };
#endif // AUDIO_H #endif // AUDIO_H

View File

@ -474,8 +474,8 @@ void CoreAV::resetCallSources()
{ {
if (call.alSource) if (call.alSource)
{ {
Audio::deleteSource(&call.alSource); Audio::getInstance().deleteSource(call.alSource);
Audio::createSource(&call.alSource); Audio::getInstance().createSource(&call.alSource);
} }
} }
@ -483,8 +483,8 @@ void CoreAV::resetCallSources()
{ {
if (call.alSource) if (call.alSource)
{ {
Audio::deleteSource(&call.alSource); Audio::getInstance().deleteSource(call.alSource);
Audio::createSource(&call.alSource); Audio::getInstance().createSource(&call.alSource);
} }
} }
} }
@ -645,9 +645,9 @@ void CoreAV::audioFrameCallback(ToxAV *, uint32_t friendNum, const int16_t *pcm,
return; return;
if (!call.alSource) if (!call.alSource)
alGenSources(1, &call.alSource); Audio::getInstance().createSource(&call.alSource);
Audio::playAudioBuffer(call.alSource, pcm, sampleCount, channels, samplingRate); Audio::getInstance().playAudioBuffer(call.alSource, pcm, sampleCount, channels, samplingRate);
} }
void CoreAV::videoFrameCallback(ToxAV *, uint32_t friendNum, uint16_t w, uint16_t h, void CoreAV::videoFrameCallback(ToxAV *, uint32_t friendNum, uint16_t w, uint16_t h,

View File

@ -24,17 +24,8 @@
#include <QObject> #include <QObject>
#include <memory> #include <memory>
#include <atomic> #include <atomic>
#include <tox/toxav.h>
#if defined(__APPLE__) && defined(__MACH__)
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
#include "src/core/toxcall.h" #include "src/core/toxcall.h"
#include <tox/toxav.h>
#ifdef QTOX_FILTER_AUDIO #ifdef QTOX_FILTER_AUDIO
class AudioFilterer; class AudioFilterer;

View File

@ -54,6 +54,9 @@ ToxCall::ToxCall(ToxCall&& other) noexcept
ToxCall::~ToxCall() ToxCall::~ToxCall()
{ {
if (alSource)
Audio::getInstance().deleteSource(alSource);
if (sendAudioTimer) if (sendAudioTimer)
{ {
QObject::disconnect(sendAudioTimer, nullptr, nullptr, nullptr); QObject::disconnect(sendAudioTimer, nullptr, nullptr, nullptr);
@ -63,9 +66,6 @@ ToxCall::~ToxCall()
audio.unsubscribeOutput(this); audio.unsubscribeOutput(this);
} }
if (alSource)
Audio::deleteSource(&alSource);
#ifdef QTOX_FILTER_AUDIO #ifdef QTOX_FILTER_AUDIO
if (filterer) if (filterer)
delete filterer; delete filterer;

View File

@ -2,16 +2,9 @@
#define TOXCALL_H #define TOXCALL_H
#include <cstdint> #include <cstdint>
#include "src/audio/audio.h"
#include "src/core/indexedlist.h" #include "src/core/indexedlist.h"
#if defined(__APPLE__) && defined(__MACH__)
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
#include <tox/toxav.h> #include <tox/toxav.h>
class QTimer; class QTimer;
@ -41,7 +34,7 @@ public:
bool inactive; ///< True while we're not participating. (stopped group call, ringing but hasn't started yet, ...) bool inactive; ///< True while we're not participating. (stopped group call, ringing but hasn't started yet, ...)
bool muteMic; bool muteMic;
bool muteVol; bool muteVol;
ALuint alSource; quint32 alSource;
#ifdef QTOX_FILTER_AUDIO #ifdef QTOX_FILTER_AUDIO
AudioFilterer* filterer; AudioFilterer* filterer;

View File

@ -19,8 +19,8 @@
#include "avform.h" #include "avform.h"
#include "ui_avsettings.h" #include "ui_avsettings.h"
#include "src/persistence/settings.h"
#include "src/audio/audio.h" #include "src/audio/audio.h"
#include "src/persistence/settings.h"
#include "src/video/camerasource.h" #include "src/video/camerasource.h"
#include "src/video/cameradevice.h" #include "src/video/cameradevice.h"
#include "src/video/videosurface.h" #include "src/video/videosurface.h"
@ -28,14 +28,6 @@
#include "src/core/core.h" #include "src/core/core.h"
#include "src/core/coreav.h" #include "src/core/coreav.h"
#if defined(__APPLE__) && defined(__MACH__)
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/alc.h>
#include <AL/al.h>
#endif
#include <QDebug> #include <QDebug>
#ifndef ALC_ALL_DEVICES_SPECIFIER #ifndef ALC_ALL_DEVICES_SPECIFIER
@ -274,7 +266,7 @@ void AVForm::getAudioInDevices()
bodyUI->inDevCombobox->blockSignals(true); bodyUI->inDevCombobox->blockSignals(true);
bodyUI->inDevCombobox->clear(); bodyUI->inDevCombobox->clear();
bodyUI->inDevCombobox->addItem(tr("None")); bodyUI->inDevCombobox->addItem(tr("None"));
const ALchar *pDeviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); const char* pDeviceList = Audio::inDeviceNames();
if (pDeviceList) if (pDeviceList)
{ {
//prevent currentIndexChanged to be fired while adding items //prevent currentIndexChanged to be fired while adding items
@ -305,11 +297,7 @@ void AVForm::getAudioOutDevices()
bodyUI->outDevCombobox->blockSignals(true); bodyUI->outDevCombobox->blockSignals(true);
bodyUI->outDevCombobox->clear(); bodyUI->outDevCombobox->clear();
bodyUI->outDevCombobox->addItem(tr("None")); bodyUI->outDevCombobox->addItem(tr("None"));
const ALchar *pDeviceList; const char* pDeviceList = Audio::outDeviceNames();
if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
pDeviceList = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
else
pDeviceList = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
if (pDeviceList) if (pDeviceList)
{ {
//prevent currentIndexChanged to be fired while adding items //prevent currentIndexChanged to be fired while adding items