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

refactor(audio): simplify the code

This commit is contained in:
sudden6 2017-04-27 20:43:51 +02:00
parent 5d60f09df4
commit c34999c9d0
No known key found for this signature in database
GPG Key ID: 279509B499E032B9
2 changed files with 116 additions and 40 deletions

View File

@ -283,6 +283,112 @@ bool OpenAL2::initInput(const QString& deviceName)
return true;
}
/**
* @brief Loads the OpenAL extension methods needed for echo cancellation
* @param dev OpenAL device used for the output
* @return True when functions successfully loaded, false otherwise
*/
bool OpenAL2::loadOpenALExtensions(ALCdevice* dev)
{
// load OpenAL extension functions
alcLoopbackOpenDeviceSOFT = reinterpret_cast<LPALCLOOPBACKOPENDEVICESOFT>
(alcGetProcAddress(dev, "alcLoopbackOpenDeviceSOFT"));
checkAlcError(dev);
if(!alcLoopbackOpenDeviceSOFT) {
qDebug() << "Failed to load alcLoopbackOpenDeviceSOFT function!";
return false;
}
alcIsRenderFormatSupportedSOFT = reinterpret_cast<LPALCISRENDERFORMATSUPPORTEDSOFT>
(alcGetProcAddress(dev, "alcIsRenderFormatSupportedSOFT"));
checkAlcError(dev);
if(!alcIsRenderFormatSupportedSOFT) {
qDebug() << "Failed to load alcIsRenderFormatSupportedSOFT function!";
return false;
}
alGetSourcedvSOFT = reinterpret_cast<LPALGETSOURCEDVSOFT>
(alcGetProcAddress(dev, "alGetSourcedvSOFT"));
checkAlcError(dev);
if(!alGetSourcedvSOFT) {
qDebug() << "Failed to load alGetSourcedvSOFT function!";
return false;
}
return true;
}
/**
* @brief Initializes the output with echo cancelling enabled
* @return true on success, false otherwise
* Creates a loopback device and a proxy source on the main output device.
* If this function returns true only the proxy source should be used for
* audio output.
*/
bool OpenAL2::initOutputEchoCancel()
{
// check for the needed extensions for echo cancelation
if (alcIsExtensionPresent(alOutDev, "ALC_SOFT_loopback") != AL_TRUE) {
qDebug() << "Device doesn't support loopback";
return false;
}
if (alIsExtensionPresent("AL_SOFT_source_latency") != AL_TRUE) {
qDebug() << "Device doesn't support source latency";
return false;
}
if(!loadOpenALExtensions(alOutDev)) {
qDebug() << "Couldn't load needed OpenAL extensions";
return false;
}
// source for proxy output
alGenSources(1, &alProxySource);
checkAlError();
// configuration for the loopback device
ALCint attrs[] = { ALC_FORMAT_CHANNELS_SOFT, AUDIO_CHANNELS == 1 ? ALC_MONO_SOFT : ALC_STEREO_SOFT,
ALC_FORMAT_TYPE_SOFT, ALC_SHORT_SOFT,
ALC_FREQUENCY, Audio::AUDIO_SAMPLE_RATE,
0 }; // End of List
alProxyDev = alcLoopbackOpenDeviceSOFT(NULL);
checkAlcError(alProxyDev);
if(!alProxyDev) {
qDebug() << "Couldn't create proxy device";
alDeleteSources(1, &alProxySource); // cleanup source
return false;
}
if(!alcIsRenderFormatSupportedSOFT(alProxyDev, attrs[5], attrs[1], attrs[3])) {
qDebug() << "Unsupported format for loopback";
alcCloseDevice(alProxyDev); // cleanup loopback dev
alDeleteSources(1, &alProxySource); // cleanup source
return false;
}
alProxyContext = alcCreateContext(alProxyDev, attrs);
checkAlcError(alProxyDev);
if(!alProxyContext) {
qDebug() << "Couldn't create proxy context";
alcCloseDevice(alProxyDev); // cleanup loopback dev
alDeleteSources(1, &alProxySource); // cleanup source
return false;
}
if (!alcMakeContextCurrent(alProxyContext)) {
qDebug() << "Cannot activate proxy context";
alcDestroyContext(alProxyContext);
alcCloseDevice(alProxyDev); // cleanup loopback dev
alDeleteSources(1, &alProxySource); // cleanup source
return false;
}
qDebug() << "Echo cancelation enabled";
return true;
}
/**
* @brief Open an audio output device
*/
@ -315,45 +421,12 @@ bool OpenAL2::initOutput(const QString& deviceName)
return false;
}
// check for the needed extensions for echo cancelation
if (echoCancelSupported = (alcIsExtensionPresent(alOutDev, "ALC_SOFT_loopback") == AL_TRUE)) {
qDebug() << "Device supports loopback";
}
if (alIsExtensionPresent("AL_SOFT_source_latency") == AL_TRUE) {
qDebug() << "Device supports source latency";
}
else
{
echoCancelSupported = false;
}
// try to init echo cancellation
echoCancelSupported = initOutputEchoCancel();
if(echoCancelSupported) {
qDebug() << "Echo cancelation supported with this device";
// source for proxy output
alGenSources(1, &alProxySource);
LPALCLOOPBACKOPENDEVICESOFT alcLoopbackOpenDeviceSOFT =
reinterpret_cast<LPALCLOOPBACKOPENDEVICESOFT> (alcGetProcAddress(alOutDev, "alcLoopbackOpenDeviceSOFT"));
LPALCISRENDERFORMATSUPPORTEDSOFT alcIsRenderFormatSupportedSOFT =
reinterpret_cast<LPALCISRENDERFORMATSUPPORTEDSOFT> (alcGetProcAddress(alOutDev, "alcIsRenderFormatSupportedSOFT"));
ALCint attrs[] = { ALC_FORMAT_CHANNELS_SOFT, AUDIO_CHANNELS == 1 ? ALC_MONO_SOFT : ALC_STEREO_SOFT,
ALC_FORMAT_TYPE_SOFT, ALC_SHORT_SOFT,
ALC_FREQUENCY, Audio::AUDIO_SAMPLE_RATE,
0 }; // End of List
alProxyDev = alcLoopbackOpenDeviceSOFT(NULL);
checkAlcError(alProxyDev);
if(!alcIsRenderFormatSupportedSOFT(alProxyDev, attrs[5], attrs[1], attrs[3])) {
qDebug() << "Unsupported format for loopback";
}
alProxyContext = alcCreateContext(alProxyDev, attrs);
checkAlcError(alProxyDev);
alcMakeContextCurrent(alProxyContext);
}
else {
// no proxy device needed
if(!echoCancelSupported) {
// fallback to normal, no proxy device needed
qDebug() << "Echo cancellation disabled";
alProxyDev = alOutDev;
alProxyContext = alOutContext;
}
@ -562,8 +635,6 @@ void OpenAL2::doOutput()
return;
}
LPALGETSOURCEDVSOFT alGetSourcedvSOFT =
reinterpret_cast<LPALGETSOURCEDVSOFT> (alcGetProcAddress(alOutDev, "alGetSourcedvSOFT"));
ALdouble latency[2] = {0};
if(alGetSourcedvSOFT) {
alGetSourcedvSOFT(alProxySource, AL_SEC_OFFSET_LATENCY_SOFT, latency);

View File

@ -108,6 +108,8 @@ private:
qreal inputGainFactor() const;
void doInput();
void doOutput();
bool loadOpenALExtensions(ALCdevice* dev);
bool initOutputEchoCancel();
private:
QThread* audioThread;
@ -134,6 +136,9 @@ private:
qreal minInGain = -30;
qreal maxInGain = 30;
Filter_Audio* filterer = nullptr;
LPALCLOOPBACKOPENDEVICESOFT alcLoopbackOpenDeviceSOFT = nullptr;
LPALCISRENDERFORMATSUPPORTEDSOFT alcIsRenderFormatSupportedSOFT = nullptr;
LPALGETSOURCEDVSOFT alGetSourcedvSOFT = nullptr;
};
#endif // OPENAL2_H