mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Audio: Open output only when necessary
This commit is contained in:
parent
a2a32b61c4
commit
a311b96376
|
@ -28,10 +28,12 @@
|
|||
|
||||
#include "audio.h"
|
||||
#include "src/core/core.h"
|
||||
#include "src/persistence/settings.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QThread>
|
||||
#include <QMutexLocker>
|
||||
#include <QTimer>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
@ -46,6 +48,7 @@ ALCcontext* Audio::alContext{nullptr};
|
|||
ALuint Audio::alMainSource{0};
|
||||
float Audio::outputVolume{1.0};
|
||||
float Audio::inputVolume{1.0};
|
||||
QTimer* Audio::timer{nullptr};
|
||||
|
||||
Audio& Audio::getInstance()
|
||||
{
|
||||
|
@ -58,6 +61,9 @@ Audio& Audio::getInstance()
|
|||
audioInLock = new QMutex(QMutex::Recursive);
|
||||
audioOutLock = new QMutex(QMutex::Recursive);
|
||||
instance->moveToThread(audioThread);
|
||||
timer = new QTimer(instance);
|
||||
timer->setSingleShot(true);
|
||||
instance->connect(timer, &QTimer::timeout, instance, &Audio::closeOutput);
|
||||
}
|
||||
return *instance;
|
||||
}
|
||||
|
@ -115,11 +121,17 @@ void Audio::suscribeInput()
|
|||
|
||||
qDebug() << "suscribing input";
|
||||
QMutexLocker lock(audioInLock);
|
||||
if (!userCount++ && alInDev)
|
||||
if (!userCount++)
|
||||
{
|
||||
timer->stop();
|
||||
openOutput(Settings::getInstance().getOutDev());
|
||||
|
||||
#if (!FIX_SND_PCM_PREPARE_BUG)
|
||||
qDebug() << "starting capture";
|
||||
alcCaptureStart(alInDev);
|
||||
if (alInDev)
|
||||
{
|
||||
qDebug() << "starting capture";
|
||||
alcCaptureStart(alInDev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -134,11 +146,15 @@ void Audio::unsuscribeInput()
|
|||
|
||||
qDebug() << "unsuscribing input";
|
||||
QMutexLocker lock(audioInLock);
|
||||
if (!--userCount && alInDev)
|
||||
if (!--userCount)
|
||||
{
|
||||
closeOutput();
|
||||
#if (!FIX_SND_PCM_PREPARE_BUG)
|
||||
qDebug() << "stopping capture";
|
||||
alcCaptureStop(alInDev);
|
||||
if (alInDev)
|
||||
{
|
||||
qDebug() << "stopping capture";
|
||||
alcCaptureStop(alInDev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -263,7 +279,7 @@ void Audio::playMono16Sound(const QByteArray& data)
|
|||
{
|
||||
QMutexLocker lock(audioOutLock);
|
||||
if (!alOutDev)
|
||||
return;
|
||||
openOutput(Settings::getInstance().getOutDev());
|
||||
|
||||
ALuint buffer;
|
||||
alGenBuffers(1, &buffer);
|
||||
|
@ -271,6 +287,25 @@ void Audio::playMono16Sound(const QByteArray& data)
|
|||
alSourcef(alMainSource, AL_GAIN, outputVolume);
|
||||
alSourcei(alMainSource, AL_BUFFER, buffer);
|
||||
alSourcePlay(alMainSource);
|
||||
|
||||
ALint sizeInBytes;
|
||||
ALint channels;
|
||||
ALint bits;
|
||||
|
||||
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);
|
||||
float duration = (lengthInSamples / static_cast<float>(frequency)) * 1000;
|
||||
|
||||
int remaining = timer->interval();
|
||||
|
||||
if (duration > remaining)
|
||||
timer->start(duration);
|
||||
|
||||
alDeleteBuffers(1, &buffer);
|
||||
}
|
||||
|
||||
|
@ -392,6 +427,14 @@ bool Audio::tryCaptureSamples(uint8_t* buf, int framesize)
|
|||
return true;
|
||||
}
|
||||
|
||||
void Audio::pauseOutput()
|
||||
{
|
||||
QMutexLocker lock(audioInLock);
|
||||
|
||||
if (!userCount)
|
||||
closeOutput();
|
||||
}
|
||||
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
#include "audiofilterer.h"
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ public slots:
|
|||
/// Must be called from the audio thread, plays a group call's received audio
|
||||
void playGroupAudio(int group, int peer, const int16_t* data,
|
||||
unsigned samples, uint8_t channels, unsigned sample_rate);
|
||||
static void pauseOutput();
|
||||
|
||||
signals:
|
||||
void groupAudioPlayed(int group, int peer, unsigned short volume);
|
||||
|
@ -100,6 +101,7 @@ private:
|
|||
static ALuint alMainSource;
|
||||
static QThread* audioThread;
|
||||
static ALCcontext* alContext;
|
||||
static QTimer* timer;
|
||||
};
|
||||
|
||||
#endif // AUDIO_H
|
||||
|
|
|
@ -82,8 +82,8 @@ Core::Core(QThread *CoreThread, Profile& profile) :
|
|||
}
|
||||
|
||||
// OpenAL init
|
||||
QString outDevDescr = Settings::getInstance().getOutDev();
|
||||
Audio::openOutput(outDevDescr);
|
||||
//QString outDevDescr = Settings::getInstance().getOutDev();
|
||||
//Audio::openOutput(outDevDescr);
|
||||
QString inDevDescr = Settings::getInstance().getInDev();
|
||||
Audio::openInput(inDevDescr);
|
||||
}
|
||||
|
|
|
@ -119,11 +119,10 @@
|
|||
<item row="5" column="2">
|
||||
<widget class="QSlider" name="microphoneSlider">
|
||||
<property name="toolTip">
|
||||
<string>Use slider to set volume of your microphone.
|
||||
WARNING: slider is not supposed to work yet.</string>
|
||||
<string>Use slider to set volume of your microphone.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
<number>400</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
MicFeedbackWidget::MicFeedbackWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
setFixedHeight(20);
|
||||
startTimer(60);
|
||||
Audio::suscribeInput();
|
||||
Audio::setOutputVolume(1.0f);
|
||||
}
|
||||
|
||||
void MicFeedbackWidget::paintEvent(QPaintEvent*)
|
||||
|
@ -36,7 +33,8 @@ void MicFeedbackWidget::paintEvent(QPaintEvent*)
|
|||
painter.setPen(QPen(Qt::black));
|
||||
painter.drawRect(QRect(0, 0, width() - 1, height() - 1));
|
||||
|
||||
int gradientWidth = round(width() * rms) - 4;
|
||||
int gradientWidth = round(width() * current) - 4;
|
||||
|
||||
if (gradientWidth < 0)
|
||||
gradientWidth = 0;
|
||||
|
||||
|
@ -68,16 +66,28 @@ void MicFeedbackWidget::timerEvent(QTimerEvent*)
|
|||
if (Audio::tryCaptureSamples(buff, framesize))
|
||||
{
|
||||
double max = 0;
|
||||
int16_t* buffReal = (int16_t*)(&buff[0]);
|
||||
int16_t* buffReal = reinterpret_cast<int16_t*>(&buff[0]);
|
||||
|
||||
for (int i = 0; i < bufsize / 2; ++i)
|
||||
max = std::max(max, fabs(buffReal[i] / 32767.0));
|
||||
|
||||
if (max > rms)
|
||||
rms = max;
|
||||
if (max > current)
|
||||
current = max;
|
||||
else
|
||||
rms -= 0.05;
|
||||
current -= 0.05;
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void MicFeedbackWidget::showEvent(QShowEvent*)
|
||||
{
|
||||
Audio::suscribeInput();
|
||||
int timerId = startTimer(60);
|
||||
}
|
||||
|
||||
void MicFeedbackWidget::hideEvent(QHideEvent*)
|
||||
{
|
||||
Audio::unsuscribeInput();
|
||||
killTimer(timerId);
|
||||
}
|
||||
|
|
|
@ -31,11 +31,12 @@ public:
|
|||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void timerEvent(QTimerEvent* event) override;
|
||||
void showEvent(QShowEvent* event) override;
|
||||
void hideEvent(QHideEvent* event) override;
|
||||
|
||||
private:
|
||||
double rms;
|
||||
static const int previousNum = 4;
|
||||
double previous[previousNum];
|
||||
double current;
|
||||
int timerId;
|
||||
};
|
||||
|
||||
#endif // MICFEEDBACKWIDGET_H
|
||||
|
|
Loading…
Reference in New Issue
Block a user