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

implement actual audio in/out subscription management

This commit is contained in:
Nils Fenner 2015-11-14 21:02:29 +01:00
parent 137eca86d6
commit c23cb0043f
No known key found for this signature in database
GPG Key ID: 9591A163FF9BE04C
4 changed files with 41 additions and 43 deletions

View File

@ -32,7 +32,6 @@
#include "src/core/coreav.h"
#include <QDebug>
#include <QTimer>
#include <QThread>
#include <QMutexLocker>
#include <QFile>
@ -56,8 +55,6 @@ Audio& Audio::getInstance()
Audio::Audio()
: audioThread(new QThread())
, inputSubscriptions(0)
, outputSubscriptions(0)
, alOutDev(nullptr)
, alInDev(nullptr)
, mInputInitialized(false)
@ -138,15 +135,17 @@ void Audio::setInputVolume(qreal volume)
If the input device is not open, it will be opened before capturing.
*/
void Audio::subscribeInput()
void Audio::subscribeInput(const void* inListener)
{
QMutexLocker locker(&mAudioLock);
if (!alInDev)
initInput(Settings::getInstance().getInDev());
inputSubscriptions++;
qDebug() << "Subscribed to audio input device [" << inputSubscriptions << " subscriptions ]";
if (!inputSubscriptions.contains(inListener)) {
inputSubscriptions << inListener;
qDebug() << "Subscribed to audio input device [" << inputSubscriptions.size() << "subscriptions ]";
}
}
/**
@ -154,46 +153,44 @@ void Audio::subscribeInput()
If the input device has no more subscriptions, it will be closed.
*/
void Audio::unsubscribeInput()
void Audio::unsubscribeInput(const void* inListener)
{
QMutexLocker locker(&mAudioLock);
if (inputSubscriptions > 0)
if (inListener && inputSubscriptions.size())
{
inputSubscriptions--;
qDebug() << "Unsubscribed from audio input device [" << inputSubscriptions << " subscriptions]";
inputSubscriptions.removeOne(inListener);
qDebug() << "Unsubscribed from audio input device [" << inputSubscriptions.size() << "subscriptions left ]";
}
if (!inputSubscriptions)
if (inputSubscriptions.isEmpty())
cleanupInput();
}
void Audio::subscribeOutput()
void Audio::subscribeOutput(const void* outListener)
{
QMutexLocker locker(&mAudioLock);
internalSubscribeOutput();
}
void Audio::internalSubscribeOutput()
{
if (!alOutDev)
initOutput(Settings::getInstance().getOutDev());
outputSubscriptions++;
qDebug() << "Subscribed to audio output device [" << outputSubscriptions << " subscriptions ]";
if (!outputSubscriptions.contains(outListener)) {
outputSubscriptions << outListener;
qDebug() << "Subscribed to audio output device [" << outputSubscriptions.size() << "subscriptions ]";
}
}
void Audio::unsubscribeOutput()
void Audio::unsubscribeOutput(const void* outListener)
{
QMutexLocker locker(&mAudioLock);
if (outputSubscriptions > 0)
if (outListener && outputSubscriptions.size())
{
outputSubscriptions--;
qDebug() << "Unsubscribed from audio output device [" << outputSubscriptions << " subscriptions]";
outputSubscriptions.removeOne(outListener);
qDebug() << "Unsubscribed from audio output device [" << outputSubscriptions.size() << " subscriptions left ]";
}
if (!outputSubscriptions)
if (outputSubscriptions.isEmpty())
cleanupOutput();
}
@ -335,7 +332,8 @@ void Audio::playMono16Sound(const QByteArray& data)
{
QMutexLocker locker(&mAudioLock);
internalSubscribeOutput();
if (!alOutDev)
initOutput(Settings::getInstance().getOutDev());
ALuint buffer;
alGenBuffers(1, &buffer);
@ -351,12 +349,14 @@ void Audio::playMono16Sound(const QByteArray& data)
alGetBufferi(buffer, AL_SIZE, &sizeInBytes);
alGetBufferi(buffer, AL_CHANNELS, &channels);
alGetBufferi(buffer, AL_BITS, &bits);
int lengthInSamples = sizeInBytes * 8 / (channels * bits);
ALint frequency;
alGetBufferi(buffer, AL_FREQUENCY, &frequency);
alDeleteBuffers(1, &buffer);
if (outputSubscriptions.isEmpty())
cleanupOutput();
}
/**

View File

@ -35,7 +35,6 @@
#include <AL/alext.h>
#endif
class QTimer;
struct Tox;
class AudioFilterer;
@ -49,6 +48,8 @@ class Audio : public QObject
{
Q_OBJECT
typedef QList<const void*> PtrList;
public:
static Audio& getInstance();
@ -96,10 +97,10 @@ public:
#endif
public slots:
void subscribeInput();
void subscribeOutput();
void unsubscribeInput();
void unsubscribeOutput();
void subscribeInput(const void* inListener);
void subscribeOutput(const void* outListener);
void unsubscribeInput(const void* inListener);
void unsubscribeOutput(const void* outListener);
void playGroupAudio(int group, int peer, const int16_t* data,
unsigned samples, uint8_t channels, unsigned sample_rate);
@ -110,8 +111,6 @@ private:
Audio();
~Audio();
void internalSubscribeOutput();
void initInput(const QString& inDevDescr);
bool initOutput(const QString& outDevDescr);
void cleanupInput();
@ -122,9 +121,9 @@ private:
private:
QThread* audioThread;
std::atomic<int> inputSubscriptions;
std::atomic<int> outputSubscriptions;
QMutex mAudioLock;
PtrList inputSubscriptions;
PtrList outputSubscriptions;
ALCdevice* alOutDev;
ALCdevice* alInDev;
bool mInputInitialized;
@ -133,7 +132,6 @@ private:
qreal inputVolume;
ALuint alMainSource;
ALCcontext* alContext;
QTimer* timer;
};
#endif // AUDIO_H

View File

@ -21,8 +21,8 @@ ToxCall::ToxCall(uint32_t CallId)
sendAudioTimer->setSingleShot(true);
Audio& audio = Audio::getInstance();
audio.subscribeInput();
audio.subscribeOutput();
audio.subscribeInput(this);
audio.subscribeOutput(this);
#ifdef QTOX_FILTER_AUDIO
if (Settings::getInstance().getFilterAudio())
@ -59,8 +59,8 @@ ToxCall::~ToxCall()
QObject::disconnect(sendAudioTimer, nullptr, nullptr, nullptr);
sendAudioTimer->stop();
Audio& audio = Audio::getInstance();
audio.unsubscribeInput();
audio.unsubscribeOutput();
audio.unsubscribeInput(this);
audio.unsubscribeOutput(this);
}
if (alSource)

View File

@ -105,8 +105,8 @@ void AVForm::showEvent(QShowEvent*)
createVideoSurface();
getVideoDevices();
Audio& audio = Audio::getInstance();
audio.subscribeInput();
audio.subscribeOutput();
audio.subscribeInput(this);
audio.subscribeOutput(this);
}
void AVForm::onVideoModesIndexChanged(int index)
@ -244,8 +244,8 @@ void AVForm::hideEvent(QHideEvent *)
}
videoDeviceList.clear();
Audio& audio = Audio::getInstance();
audio.unsubscribeInput();
audio.unsubscribeOutput();
audio.unsubscribeInput(this);
audio.unsubscribeOutput(this);
}
void AVForm::getVideoDevices()