mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
refactor(audio): Remove Audio singleton
This commit finally removes the Audio singleton and allocates the audio backend in main.cpp.
This commit is contained in:
parent
17048c9cc4
commit
22362d2940
|
@ -243,6 +243,7 @@ set(${PROJECT_NAME}_SOURCES
|
|||
src/audio/backend/openal.cpp
|
||||
src/audio/backend/openal.h
|
||||
src/audio/iaudiosettings.h
|
||||
src/audio/iaudiocontrol.h
|
||||
src/audio/iaudiosink.h
|
||||
src/audio/iaudiosource.h
|
||||
src/chatlog/chatlinecontent.cpp
|
||||
|
|
|
@ -17,109 +17,30 @@
|
|||
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "audio.h"
|
||||
#include <memory>
|
||||
|
||||
#include "src/audio/audio.h"
|
||||
#include "src/audio/iaudiosettings.h"
|
||||
#include "src/audio/backend/openal.h"
|
||||
#ifdef USE_FILTERAUDIO
|
||||
#include "src/audio/backend/openal2.h"
|
||||
#endif
|
||||
#include "src/persistence/settings.h"
|
||||
|
||||
/**
|
||||
* @class Audio
|
||||
*
|
||||
* @var Audio::AUDIO_SAMPLE_RATE
|
||||
* @brief The next best Opus would take is 24k
|
||||
*
|
||||
* @var Audio::AUDIO_FRAME_DURATION
|
||||
* @brief In milliseconds
|
||||
*
|
||||
* @var Audio::AUDIO_FRAME_SAMPLE_COUNT
|
||||
* @brief Frame sample count
|
||||
*
|
||||
* @fn qreal Audio::outputVolume() const
|
||||
* @brief Returns the current output volume (between 0 and 1)
|
||||
*
|
||||
* @fn void Audio::setOutputVolume(qreal volume)
|
||||
* @brief Set the master output volume.
|
||||
*
|
||||
* @param[in] volume the master volume (between 0 and 1)
|
||||
*
|
||||
* @fn qreal Audio::minInputGain() const
|
||||
* @brief The minimum gain value for an input device.
|
||||
*
|
||||
* @return minimum gain value in dB
|
||||
*
|
||||
* @fn void Audio::setMinInputGain(qreal dB)
|
||||
* @brief Set the minimum allowed gain value in dB.
|
||||
*
|
||||
* @note Default is -30dB; usually you don't need to alter this value;
|
||||
*
|
||||
* @fn qreal Audio::maxInputGain() const
|
||||
* @brief The maximum gain value for an input device.
|
||||
*
|
||||
* @return maximum gain value in dB
|
||||
*
|
||||
* @fn void Audio::setMaxInputGain(qreal dB)
|
||||
* @brief Set the maximum allowed gain value in dB.
|
||||
*
|
||||
* @note Default is 30dB; usually you don't need to alter this value.
|
||||
*
|
||||
* @fn bool Audio::isOutputReady() const
|
||||
* @brief check if the output is ready to play audio
|
||||
*
|
||||
* @return true if the output device is open, false otherwise
|
||||
*
|
||||
* @fn QStringList Audio::outDeviceNames()
|
||||
* @brief Get the names of available output devices
|
||||
*
|
||||
* @return list of output devices
|
||||
*
|
||||
* @fn QStringList Audio::inDeviceNames()
|
||||
* @brief Get the names of available input devices
|
||||
*
|
||||
* @return list of input devices
|
||||
*
|
||||
* @fn qreal Audio::inputGain() const
|
||||
* @brief get the current input gain
|
||||
*
|
||||
* @return current input gain in dB
|
||||
*
|
||||
* @fn void Audio::setInputGain(qreal dB)
|
||||
* @brief set the input gain
|
||||
*
|
||||
* @fn void Audio::getInputThreshold()
|
||||
* @brief get the current input threshold
|
||||
*
|
||||
* @return current input threshold percentage
|
||||
*
|
||||
* @fn void Audio::setInputThreshold(qreal percent)
|
||||
* @brief set the input threshold
|
||||
*
|
||||
* @param[in] percent the new input threshold percentage
|
||||
* @brief Select the audio backend
|
||||
* @param settings Audio settings to use
|
||||
* @return Audio backend selection based on settings
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Returns the singleton instance.
|
||||
*/
|
||||
Audio& Audio::getInstance()
|
||||
std::unique_ptr<IAudioControl> Audio::makeAudio(IAudioSettings& settings)
|
||||
{
|
||||
// TODO: replace backend selection by inversion of control
|
||||
#ifdef USE_FILTERAUDIO
|
||||
static bool initialized = false;
|
||||
static bool Backend2 = false;
|
||||
|
||||
if (!initialized) {
|
||||
Backend2 = Settings::getInstance().getEnableBackend2();
|
||||
initialized = true;
|
||||
}
|
||||
const bool Backend2 = settings.getEnableBackend2();
|
||||
|
||||
if (Backend2) {
|
||||
static OpenAL2 instance;
|
||||
return instance;
|
||||
return std::unique_ptr<IAudioControl>(new OpenAL2());
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
static OpenAL instance;
|
||||
return instance;
|
||||
return std::unique_ptr<IAudioControl>(new OpenAL());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,57 +21,14 @@
|
|||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
class IAudioSink;
|
||||
class IAudioSource;
|
||||
class Audio : public QObject
|
||||
class IAudioControl;
|
||||
class IAudioSettings;
|
||||
class Audio
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static Audio& getInstance();
|
||||
|
||||
virtual qreal outputVolume() const = 0;
|
||||
virtual void setOutputVolume(qreal volume) = 0;
|
||||
virtual qreal maxOutputVolume() const = 0;
|
||||
virtual qreal minOutputVolume() const = 0;
|
||||
|
||||
virtual qreal minInputGain() const = 0;
|
||||
virtual void setMinInputGain(qreal dB) = 0;
|
||||
|
||||
virtual qreal maxInputGain() const = 0;
|
||||
virtual void setMaxInputGain(qreal dB) = 0;
|
||||
|
||||
virtual qreal inputGain() const = 0;
|
||||
virtual void setInputGain(qreal dB) = 0;
|
||||
|
||||
virtual qreal minInputThreshold() const = 0;
|
||||
virtual qreal maxInputThreshold() const = 0;
|
||||
|
||||
virtual qreal getInputThreshold() const = 0;
|
||||
virtual void setInputThreshold(qreal percent) = 0;
|
||||
|
||||
virtual void reinitInput(const QString& inDevDesc) = 0;
|
||||
virtual bool reinitOutput(const QString& outDevDesc) = 0;
|
||||
|
||||
virtual bool isOutputReady() const = 0;
|
||||
|
||||
virtual QStringList outDeviceNames() = 0;
|
||||
virtual QStringList inDeviceNames() = 0;
|
||||
|
||||
virtual std::unique_ptr<IAudioSink> makeSink() = 0;
|
||||
virtual std::unique_ptr<IAudioSource> makeSource() = 0;
|
||||
|
||||
protected:
|
||||
// Public default audio settings
|
||||
// Samplerate for Tox calls and sounds
|
||||
static constexpr uint32_t AUDIO_SAMPLE_RATE = 48000;
|
||||
static constexpr uint32_t AUDIO_FRAME_DURATION = 20;
|
||||
static constexpr uint32_t AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL =
|
||||
AUDIO_FRAME_DURATION * AUDIO_SAMPLE_RATE / 1000;
|
||||
uint32_t AUDIO_FRAME_SAMPLE_COUNT_TOTAL = 0;
|
||||
static std::unique_ptr<IAudioControl> makeAudio(IAudioSettings& settings);
|
||||
};
|
||||
|
||||
#endif // AUDIO_H
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef OPENAL_H
|
||||
#define OPENAL_H
|
||||
|
||||
#include "src/audio/audio.h"
|
||||
#include "src/audio/iaudiocontrol.h"
|
||||
#include "src/audio/backend/alsink.h"
|
||||
#include "src/audio/backend/alsource.h"
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
|||
#include <AL/alext.h>
|
||||
#endif
|
||||
|
||||
class OpenAL : public Audio
|
||||
class OpenAL : public IAudioControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ bool OpenAL2::initOutputEchoCancel()
|
|||
ALC_FORMAT_TYPE_SOFT,
|
||||
ALC_SHORT_SOFT,
|
||||
ALC_FREQUENCY,
|
||||
Audio::AUDIO_SAMPLE_RATE,
|
||||
IAudioControl::AUDIO_SAMPLE_RATE,
|
||||
0}; // End of List
|
||||
|
||||
alProxyDev = alcLoopbackOpenDeviceSOFT(nullptr);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef OPENAL2_H
|
||||
#define OPENAL2_H
|
||||
|
||||
#include "src/audio/audio.h"
|
||||
#include "src/audio/iaudiocontrol.h"
|
||||
#include "src/audio/backend/openal.h"
|
||||
|
||||
#include <atomic>
|
||||
|
|
131
src/audio/iaudiocontrol.h
Normal file
131
src/audio/iaudiocontrol.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
#ifndef IAUDIOCONTROL_H
|
||||
#define IAUDIOCONTROL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* @class IAudioControl
|
||||
*
|
||||
* @var IAudioControl::AUDIO_SAMPLE_RATE
|
||||
* @brief The next best Opus would take is 24k
|
||||
*
|
||||
* @var IAudioControl::AUDIO_FRAME_DURATION
|
||||
* @brief In milliseconds
|
||||
*
|
||||
* @var IAudioControl::AUDIO_FRAME_SAMPLE_COUNT
|
||||
* @brief Frame sample count
|
||||
*
|
||||
* @fn qreal IAudioControl::outputVolume() const
|
||||
* @brief Returns the current output volume (between 0 and 1)
|
||||
*
|
||||
* @fn void IAudioControl::setOutputVolume(qreal volume)
|
||||
* @brief Set the master output volume.
|
||||
*
|
||||
* @param[in] volume the master volume (between 0 and 1)
|
||||
*
|
||||
* @fn qreal IAudioControl::minInputGain() const
|
||||
* @brief The minimum gain value for an input device.
|
||||
*
|
||||
* @return minimum gain value in dB
|
||||
*
|
||||
* @fn void IAudioControl::setMinInputGain(qreal dB)
|
||||
* @brief Set the minimum allowed gain value in dB.
|
||||
*
|
||||
* @note Default is -30dB; usually you don't need to alter this value;
|
||||
*
|
||||
* @fn qreal IAudioControl::maxInputGain() const
|
||||
* @brief The maximum gain value for an input device.
|
||||
*
|
||||
* @return maximum gain value in dB
|
||||
*
|
||||
* @fn void IAudioControl::setMaxInputGain(qreal dB)
|
||||
* @brief Set the maximum allowed gain value in dB.
|
||||
*
|
||||
* @note Default is 30dB; usually you don't need to alter this value.
|
||||
*
|
||||
* @fn bool IAudioControl::isOutputReady() const
|
||||
* @brief check if the output is ready to play audio
|
||||
*
|
||||
* @return true if the output device is open, false otherwise
|
||||
*
|
||||
* @fn QStringList IAudioControl::outDeviceNames()
|
||||
* @brief Get the names of available output devices
|
||||
*
|
||||
* @return list of output devices
|
||||
*
|
||||
* @fn QStringList IAudioControl::inDeviceNames()
|
||||
* @brief Get the names of available input devices
|
||||
*
|
||||
* @return list of input devices
|
||||
*
|
||||
* @fn qreal IAudioControl::inputGain() const
|
||||
* @brief get the current input gain
|
||||
*
|
||||
* @return current input gain in dB
|
||||
*
|
||||
* @fn void IAudioControl::setInputGain(qreal dB)
|
||||
* @brief set the input gain
|
||||
*
|
||||
* @fn void IAudioControl::getInputThreshold()
|
||||
* @brief get the current input threshold
|
||||
*
|
||||
* @return current input threshold percentage
|
||||
*
|
||||
* @fn void IAudioControl::setInputThreshold(qreal percent)
|
||||
* @brief set the input threshold
|
||||
*
|
||||
* @param[in] percent the new input threshold percentage
|
||||
*/
|
||||
|
||||
class IAudioSink;
|
||||
class IAudioSource;
|
||||
class IAudioControl : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual qreal outputVolume() const = 0;
|
||||
virtual void setOutputVolume(qreal volume) = 0;
|
||||
virtual qreal maxOutputVolume() const = 0;
|
||||
virtual qreal minOutputVolume() const = 0;
|
||||
|
||||
virtual qreal minInputGain() const = 0;
|
||||
virtual void setMinInputGain(qreal dB) = 0;
|
||||
|
||||
virtual qreal maxInputGain() const = 0;
|
||||
virtual void setMaxInputGain(qreal dB) = 0;
|
||||
|
||||
virtual qreal inputGain() const = 0;
|
||||
virtual void setInputGain(qreal dB) = 0;
|
||||
|
||||
virtual qreal minInputThreshold() const = 0;
|
||||
virtual qreal maxInputThreshold() const = 0;
|
||||
|
||||
virtual qreal getInputThreshold() const = 0;
|
||||
virtual void setInputThreshold(qreal percent) = 0;
|
||||
|
||||
virtual void reinitInput(const QString& inDevDesc) = 0;
|
||||
virtual bool reinitOutput(const QString& outDevDesc) = 0;
|
||||
|
||||
virtual bool isOutputReady() const = 0;
|
||||
|
||||
virtual QStringList outDeviceNames() = 0;
|
||||
virtual QStringList inDeviceNames() = 0;
|
||||
|
||||
virtual std::unique_ptr<IAudioSink> makeSink() = 0;
|
||||
virtual std::unique_ptr<IAudioSource> makeSource() = 0;
|
||||
|
||||
protected:
|
||||
// Public default audio settings
|
||||
// Samplerate for Tox calls and sounds
|
||||
static constexpr uint32_t AUDIO_SAMPLE_RATE = 48000;
|
||||
static constexpr uint32_t AUDIO_FRAME_DURATION = 20;
|
||||
static constexpr uint32_t AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL =
|
||||
AUDIO_FRAME_DURATION * AUDIO_SAMPLE_RATE / 1000;
|
||||
uint32_t AUDIO_FRAME_SAMPLE_COUNT_TOTAL = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // IAUDIOCONTROL_H
|
|
@ -281,6 +281,7 @@ ToxCorePtr Core::makeToxCore(const QByteArray& savedata, const ICoreSettings* co
|
|||
assert(core->tox != nullptr);
|
||||
|
||||
// toxcore is successfully created, create toxav
|
||||
// TODO(sudden6): don't create CoreAv here, Core should be usable without CoreAV
|
||||
core->av = CoreAV::makeCoreAV(core->tox.get());
|
||||
if (!core->av) {
|
||||
qCritical() << "Toxav failed to start";
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
class CoreAV;
|
||||
class CoreFile;
|
||||
class IAudioControl;
|
||||
class ICoreSettings;
|
||||
class GroupInvite;
|
||||
class Profile;
|
||||
|
|
|
@ -81,7 +81,8 @@ std::map<uint32_t, CoreAV::ToxFriendCallPtr> CoreAV::calls;
|
|||
std::map<int, CoreAV::ToxGroupCallPtr> CoreAV::groupCalls;
|
||||
|
||||
CoreAV::CoreAV(std::unique_ptr<ToxAV, ToxAVDeleter> toxav)
|
||||
: toxav{std::move(toxav)}
|
||||
: audio{nullptr}
|
||||
, toxav{std::move(toxav)}
|
||||
, coreavThread{new QThread{this}}
|
||||
, iterateTimer{new QTimer{this}}
|
||||
, threadSwitchLock{false}
|
||||
|
@ -102,7 +103,8 @@ CoreAV::CoreAV(std::unique_ptr<ToxAV, ToxAVDeleter> toxav)
|
|||
coreavThread->start();
|
||||
}
|
||||
|
||||
void CoreAV::connectCallbacks(ToxAV& toxav) {
|
||||
void CoreAV::connectCallbacks(ToxAV& toxav)
|
||||
{
|
||||
toxav_callback_call(&toxav, CoreAV::callCallback, this);
|
||||
toxav_callback_call_state(&toxav, CoreAV::stateCallback, this);
|
||||
toxav_callback_audio_bit_rate(&toxav, CoreAV::audioBitrateCallback, this);
|
||||
|
@ -139,6 +141,27 @@ CoreAV::CoreAVPtr CoreAV::makeCoreAV(Tox* core)
|
|||
return CoreAVPtr{new CoreAV{std::move(toxav)}};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the audio backend
|
||||
* @param audio The audio backend to use
|
||||
* @note This must be called before starting CoreAV and audio must outlive CoreAV
|
||||
*/
|
||||
void CoreAV::setAudio(IAudioControl& newAudio)
|
||||
{
|
||||
audio.exchange(&newAudio);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the audio backend used
|
||||
* @return Pointer to the audio backend
|
||||
* @note This is needed only for the case CoreAV needs to restart and the restarting class doesn't
|
||||
* have access to the audio backend and wants to keep it the same.
|
||||
*/
|
||||
IAudioControl* CoreAV::getAudio()
|
||||
{
|
||||
return audio;
|
||||
}
|
||||
|
||||
CoreAV::~CoreAV()
|
||||
{
|
||||
for (const auto& call : calls) {
|
||||
|
@ -253,7 +276,8 @@ bool CoreAV::answerCall(uint32_t friendNum, bool video)
|
|||
TOXAV_ERR_ANSWER err;
|
||||
|
||||
const uint32_t videoBitrate = video ? VIDEO_DEFAULT_BITRATE : 0;
|
||||
if (toxav_answer(toxav.get(), friendNum, Settings::getInstance().getAudioBitrate(), videoBitrate, &err)) {
|
||||
if (toxav_answer(toxav.get(), friendNum, Settings::getInstance().getAudioBitrate(),
|
||||
videoBitrate, &err)) {
|
||||
it->second->setActive(true);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -289,10 +313,13 @@ bool CoreAV::startCall(uint32_t friendNum, bool video)
|
|||
}
|
||||
|
||||
uint32_t videoBitrate = video ? VIDEO_DEFAULT_BITRATE : 0;
|
||||
if (!toxav_call(toxav.get(), friendNum, Settings::getInstance().getAudioBitrate(), videoBitrate, nullptr))
|
||||
if (!toxav_call(toxav.get(), friendNum, Settings::getInstance().getAudioBitrate(), videoBitrate,
|
||||
nullptr))
|
||||
return false;
|
||||
|
||||
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall(friendNum, video, *this));
|
||||
// Audio backend must be set before making a call
|
||||
assert(audio != nullptr);
|
||||
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall(friendNum, video, *this, *audio));
|
||||
assert(call != nullptr);
|
||||
auto ret = calls.emplace(friendNum, std::move(call));
|
||||
ret.first->second->startTimeout(friendNum);
|
||||
|
@ -420,8 +447,8 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe)
|
|||
TOXAV_ERR_SEND_FRAME err;
|
||||
int retries = 0;
|
||||
do {
|
||||
if (!toxav_video_send_frame(toxav.get(), callId, frame.width, frame.height, frame.y, frame.u,
|
||||
frame.v, &err)) {
|
||||
if (!toxav_video_send_frame(toxav.get(), callId, frame.width, frame.height, frame.y,
|
||||
frame.u, frame.v, &err)) {
|
||||
if (err == TOXAV_ERR_SEND_FRAME_SYNC) {
|
||||
++retries;
|
||||
QThread::usleep(500);
|
||||
|
@ -544,7 +571,9 @@ void CoreAV::joinGroupCall(int groupId)
|
|||
{
|
||||
qDebug() << QString("Joining group call %1").arg(groupId);
|
||||
|
||||
ToxGroupCallPtr groupcall = ToxGroupCallPtr(new ToxGroupCall{groupId, *this});
|
||||
// Audio backend must be set before starting a call
|
||||
assert(audio != nullptr);
|
||||
ToxGroupCallPtr groupcall = ToxGroupCallPtr(new ToxGroupCall{groupId, *this, *audio});
|
||||
assert(groupcall != nullptr);
|
||||
auto ret = groupCalls.emplace(groupId, std::move(groupcall));
|
||||
if (ret.second == false) {
|
||||
|
@ -708,7 +737,9 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid
|
|||
return;
|
||||
}
|
||||
|
||||
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall{friendNum, video, *self});
|
||||
// Audio backend must be set before receiving a call
|
||||
assert(self->audio != nullptr);
|
||||
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall{friendNum, video, *self, *self->audio});
|
||||
assert(call != nullptr);
|
||||
|
||||
auto it = self->calls.emplace(friendNum, std::move(call));
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
class Friend;
|
||||
class Group;
|
||||
class IAudioControl;
|
||||
class QThread;
|
||||
class QTimer;
|
||||
class CoreVideoSource;
|
||||
|
@ -43,10 +44,12 @@ class CoreAV : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
using CoreAVPtr = std::unique_ptr<CoreAV>;
|
||||
static CoreAVPtr makeCoreAV(Tox* core);
|
||||
|
||||
void setAudio(IAudioControl& newAudio);
|
||||
IAudioControl* getAudio();
|
||||
|
||||
~CoreAV();
|
||||
|
||||
bool anyActiveCalls() const;
|
||||
|
@ -124,7 +127,8 @@ private:
|
|||
static constexpr uint32_t VIDEO_DEFAULT_BITRATE = 2500;
|
||||
|
||||
private:
|
||||
|
||||
// atomic because potentially accessed by different threads
|
||||
std::atomic<IAudioControl*> audio;
|
||||
std::unique_ptr<ToxAV, ToxAVDeleter> toxav;
|
||||
std::unique_ptr<QThread> coreavThread;
|
||||
QTimer* iterateTimer = nullptr;
|
||||
|
@ -133,8 +137,6 @@ private:
|
|||
using ToxGroupCallPtr = std::unique_ptr<ToxGroupCall>;
|
||||
static std::map<int, ToxGroupCallPtr> groupCalls;
|
||||
std::atomic_flag threadSwitchLock;
|
||||
|
||||
friend class Audio;
|
||||
};
|
||||
|
||||
#endif // COREAV_H
|
||||
|
|
|
@ -28,10 +28,11 @@
|
|||
* @brief Keeps sources for users in group calls.
|
||||
*/
|
||||
|
||||
ToxCall::ToxCall(bool VideoEnabled, CoreAV& av)
|
||||
ToxCall::ToxCall(bool VideoEnabled, CoreAV& av, IAudioControl& audio)
|
||||
: av{&av}
|
||||
, audio(audio)
|
||||
, videoEnabled{VideoEnabled}
|
||||
, audioSource{Audio::getInstance().makeSource()}
|
||||
, audioSource(audio.makeSource())
|
||||
{}
|
||||
|
||||
ToxCall::~ToxCall()
|
||||
|
@ -100,9 +101,9 @@ CoreVideoSource* ToxCall::getVideoSource() const
|
|||
return videoSource;
|
||||
}
|
||||
|
||||
ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av)
|
||||
: ToxCall(VideoEnabled, av)
|
||||
, sink(Audio::getInstance().makeSink())
|
||||
ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av, IAudioControl& audio)
|
||||
: ToxCall(VideoEnabled, av, audio)
|
||||
, sink(audio.makeSink())
|
||||
, friendId{FriendNum}
|
||||
{
|
||||
// TODO(sudden6): move this to audio source
|
||||
|
@ -149,7 +150,7 @@ ToxFriendCall::~ToxFriendCall()
|
|||
|
||||
void ToxFriendCall::onAudioSourceInvalidated()
|
||||
{
|
||||
auto newSrc = Audio::getInstance().makeSource();
|
||||
auto newSrc = audio.makeSource();
|
||||
audioInConn =
|
||||
QObject::connect(newSrc.get(), &IAudioSource::frameAvailable,
|
||||
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
|
||||
|
@ -163,7 +164,7 @@ void ToxFriendCall::onAudioSourceInvalidated()
|
|||
|
||||
void ToxFriendCall::onAudioSinkInvalidated()
|
||||
{
|
||||
auto newSink = Audio::getInstance().makeSink();
|
||||
auto newSink = audio.makeSink();
|
||||
|
||||
audioSinkInvalid = QObject::connect(newSink.get(), &IAudioSink::invalidated,
|
||||
[this]() { this->onAudioSinkInvalidated(); });
|
||||
|
@ -211,8 +212,8 @@ void ToxFriendCall::playAudioBuffer(const int16_t* data, int samples, unsigned c
|
|||
}
|
||||
}
|
||||
|
||||
ToxGroupCall::ToxGroupCall(int GroupNum, CoreAV& av)
|
||||
: ToxCall(false, av)
|
||||
ToxGroupCall::ToxGroupCall(int GroupNum, CoreAV& av, IAudioControl& audio)
|
||||
: ToxCall(false, av, audio)
|
||||
, groupId{GroupNum}
|
||||
{
|
||||
// register audio
|
||||
|
@ -238,7 +239,7 @@ ToxGroupCall::~ToxGroupCall()
|
|||
|
||||
void ToxGroupCall::onAudioSourceInvalidated()
|
||||
{
|
||||
auto newSrc = Audio::getInstance().makeSource();
|
||||
auto newSrc = audio.makeSource();
|
||||
// TODO(sudden6): move this to audio source
|
||||
audioInConn =
|
||||
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
|
||||
|
@ -274,7 +275,6 @@ void ToxGroupCall::removePeer(ToxPk peerId)
|
|||
|
||||
void ToxGroupCall::addPeer(ToxPk peerId)
|
||||
{
|
||||
auto& audio = Audio::getInstance();
|
||||
std::unique_ptr<IAudioSink> newSink = audio.makeSink();
|
||||
peers.emplace(peerId, std::move(newSink));
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef TOXCALL_H
|
||||
#define TOXCALL_H
|
||||
|
||||
#include "src/audio/iaudiocontrol.h"
|
||||
#include "src/audio/iaudiosink.h"
|
||||
#include "src/audio/iaudiosource.h"
|
||||
#include <src/core/toxpk.h>
|
||||
|
@ -22,7 +23,7 @@ class ToxCall
|
|||
{
|
||||
protected:
|
||||
ToxCall() = delete;
|
||||
ToxCall(bool VideoEnabled, CoreAV& av);
|
||||
ToxCall(bool VideoEnabled, CoreAV& av, IAudioControl& audio);
|
||||
~ToxCall();
|
||||
|
||||
public:
|
||||
|
@ -53,6 +54,7 @@ protected:
|
|||
bool active{false};
|
||||
CoreAV* av{nullptr};
|
||||
// audio
|
||||
IAudioControl& audio;
|
||||
QMetaObject::Connection audioInConn;
|
||||
bool muteMic{false};
|
||||
bool muteVol{false};
|
||||
|
@ -69,7 +71,7 @@ class ToxFriendCall : public ToxCall
|
|||
{
|
||||
public:
|
||||
ToxFriendCall() = delete;
|
||||
ToxFriendCall(uint32_t friendId, bool VideoEnabled, CoreAV& av);
|
||||
ToxFriendCall(uint32_t friendId, bool VideoEnabled, CoreAV& av, IAudioControl& audio);
|
||||
ToxFriendCall(ToxFriendCall&& other) = delete;
|
||||
ToxFriendCall& operator=(ToxFriendCall&& other) = delete;
|
||||
~ToxFriendCall();
|
||||
|
@ -101,7 +103,7 @@ class ToxGroupCall : public ToxCall
|
|||
{
|
||||
public:
|
||||
ToxGroupCall() = delete;
|
||||
ToxGroupCall(int GroupNum, CoreAV& av);
|
||||
ToxGroupCall(int GroupNum, CoreAV& av, IAudioControl& audio);
|
||||
ToxGroupCall(ToxGroupCall&& other) = delete;
|
||||
~ToxGroupCall();
|
||||
|
||||
|
|
14
src/main.cpp
14
src/main.cpp
|
@ -17,11 +17,13 @@
|
|||
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "persistence/settings.h"
|
||||
#include "src/audio/audio.h"
|
||||
#include "src/core/coreav.h"
|
||||
#include "src/ipc.h"
|
||||
#include "src/net/toxuri.h"
|
||||
#include "src/nexus.h"
|
||||
#include "src/persistence/profile.h"
|
||||
#include "src/persistence/settings.h"
|
||||
#include "src/persistence/toxsave.h"
|
||||
#include "src/video/camerasource.h"
|
||||
#include "src/widget/loginscreen.h"
|
||||
|
@ -347,9 +349,17 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
Nexus::getInstance().setProfile(profile);
|
||||
Settings::getInstance().setCurrentProfile(profileName);
|
||||
Settings& s = Settings::getInstance();
|
||||
s.setCurrentProfile(profileName);
|
||||
|
||||
auto audio = Audio::makeAudio(s);
|
||||
assert(audio != nullptr);
|
||||
// TODO(sudden6): init CoreAV audio backend somewhere else so main doesn't depend on coreav.h
|
||||
profile->getCore()->getAv()->setAudio(*audio);
|
||||
|
||||
Nexus& nexus = Nexus::getInstance();
|
||||
// TODO(sudden6): remove once we get rid of Nexus
|
||||
nexus.audio = audio.get();
|
||||
nexus.start();
|
||||
|
||||
// Start to accept Inter-process communication
|
||||
|
|
|
@ -175,7 +175,7 @@ void Nexus::showMainGUI()
|
|||
assert(profile);
|
||||
|
||||
// Create GUI
|
||||
widget = Widget::getInstance();
|
||||
widget = Widget::getInstance(audio);
|
||||
|
||||
// Start GUI
|
||||
widget->init();
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
#include "src/audio/iaudiocontrol.h"
|
||||
|
||||
class Widget;
|
||||
class Profile;
|
||||
class Core;
|
||||
|
@ -79,6 +81,9 @@ private:
|
|||
QSignalMapper* windowMapper;
|
||||
QActionGroup* windowActions = nullptr;
|
||||
#endif
|
||||
public:
|
||||
// TODO(sudden6): hack to pass the audio instance
|
||||
IAudioControl* audio = nullptr;
|
||||
|
||||
private:
|
||||
explicit Nexus(QObject* parent = nullptr);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "profilelocker.h"
|
||||
#include "settings.h"
|
||||
#include "src/core/core.h"
|
||||
#include "src/core/coreav.h"
|
||||
#include "src/core/corefile.h"
|
||||
#include "src/net/avatarbroadcaster.h"
|
||||
#include "src/nexus.h"
|
||||
|
@ -96,7 +97,8 @@ void Profile::initCore(const QByteArray& toxsave, ICoreSettings& s, bool isNewPr
|
|||
Qt::ConnectionType::QueuedConnection);
|
||||
}
|
||||
|
||||
Profile::Profile(QString name, const QString& password, bool isNewProfile, const QByteArray& toxsave, std::unique_ptr<ToxEncrypt> passkey)
|
||||
Profile::Profile(QString name, const QString& password, bool isNewProfile,
|
||||
const QByteArray& toxsave, std::unique_ptr<ToxEncrypt> passkey)
|
||||
: name{name}
|
||||
, passkey{std::move(passkey)}
|
||||
, isRemoved{false}
|
||||
|
@ -797,7 +799,10 @@ void Profile::restartCore()
|
|||
if (saveToxSave(savedata)) {
|
||||
qDebug() << "Restarting Core";
|
||||
const bool isNewProfile{false};
|
||||
IAudioControl* audioBak = core->getAv()->getAudio();
|
||||
assert(audioBak != nullptr);
|
||||
initCore(savedata, Settings::getInstance(), isNewProfile);
|
||||
core->getAv()->setAudio(*audioBak);
|
||||
core->start();
|
||||
} else {
|
||||
qCritical() << "Failed to save, not restarting core";
|
||||
|
|
|
@ -44,10 +44,10 @@
|
|||
#define ALC_ALL_DEVICES_SPECIFIER ALC_DEVICE_SPECIFIER
|
||||
#endif
|
||||
|
||||
AVForm::AVForm(Audio* audio, CoreAV* coreAV, CameraSource& camera, IAudioSettings* audioSettings,
|
||||
IVideoSettings* videoSettings)
|
||||
AVForm::AVForm(IAudioControl& audio, CoreAV* coreAV, CameraSource& camera,
|
||||
IAudioSettings* audioSettings, IVideoSettings* videoSettings)
|
||||
: GenericForm(QPixmap(":/img/settings/av.png"))
|
||||
, audio{audio}
|
||||
, audio(audio)
|
||||
, coreAV{coreAV}
|
||||
, audioSettings{audioSettings}
|
||||
, videoSettings{videoSettings}
|
||||
|
@ -78,8 +78,8 @@ AVForm::AVForm(Audio* audio, CoreAV* coreAV, CameraSource& camera, IAudioSetting
|
|||
|
||||
microphoneSlider->setToolTip(tr("Use slider to set the gain of your input device ranging"
|
||||
" from %1dB to %2dB.")
|
||||
.arg(audio->minInputGain())
|
||||
.arg(audio->maxInputGain()));
|
||||
.arg(audio.minInputGain())
|
||||
.arg(audio.maxInputGain()));
|
||||
microphoneSlider->setMaximum(totalSliderSteps);
|
||||
microphoneSlider->setTickPosition(QSlider::TicksBothSides);
|
||||
static const int numTicks = 4;
|
||||
|
@ -87,14 +87,14 @@ AVForm::AVForm(Audio* audio, CoreAV* coreAV, CameraSource& camera, IAudioSetting
|
|||
microphoneSlider->setTracking(false);
|
||||
microphoneSlider->installEventFilter(this);
|
||||
microphoneSlider->setValue(
|
||||
getStepsFromValue(audio->inputGain(), audio->minInputGain(), audio->maxInputGain()));
|
||||
getStepsFromValue(audio.inputGain(), audio.minInputGain(), audio.maxInputGain()));
|
||||
|
||||
audioThresholdSlider->setToolTip(tr("Use slider to set the activation volume for your"
|
||||
" input device."));
|
||||
audioThresholdSlider->setMaximum(totalSliderSteps);
|
||||
audioThresholdSlider->setValue(getStepsFromValue(audioSettings->getAudioThreshold(),
|
||||
audio->minInputThreshold(),
|
||||
audio->maxInputThreshold()));
|
||||
audio.minInputThreshold(),
|
||||
audio.maxInputThreshold()));
|
||||
audioThresholdSlider->setTracking(false);
|
||||
audioThresholdSlider->installEventFilter(this);
|
||||
|
||||
|
@ -139,12 +139,12 @@ void AVForm::showEvent(QShowEvent* event)
|
|||
getVideoDevices();
|
||||
|
||||
if (audioSrc == nullptr) {
|
||||
audioSrc = audio->makeSource();
|
||||
audioSrc = audio.makeSource();
|
||||
connect(audioSrc.get(), &IAudioSource::volumeAvailable, this, &AVForm::setVolume);
|
||||
}
|
||||
|
||||
if (audioSink == nullptr) {
|
||||
audioSink = audio->makeSink();
|
||||
audioSink = audio.makeSink();
|
||||
}
|
||||
|
||||
GenericForm::showEvent(event);
|
||||
|
@ -167,8 +167,7 @@ void AVForm::rescanDevices()
|
|||
|
||||
void AVForm::setVolume(float value)
|
||||
{
|
||||
volumeDisplay->setValue(
|
||||
getStepsFromValue(value, audio->minOutputVolume(), audio->maxOutputVolume()));
|
||||
volumeDisplay->setValue(getStepsFromValue(value, audio.minOutputVolume(), audio.maxOutputVolume()));
|
||||
}
|
||||
|
||||
void AVForm::on_cbEnableBackend2_stateChanged()
|
||||
|
@ -493,7 +492,7 @@ int AVForm::getModeSize(VideoMode mode)
|
|||
void AVForm::getAudioInDevices()
|
||||
{
|
||||
QStringList deviceNames;
|
||||
deviceNames << tr("Disabled") << audio->inDeviceNames();
|
||||
deviceNames << tr("Disabled") << audio.inDeviceNames();
|
||||
|
||||
inDevCombobox->blockSignals(true);
|
||||
inDevCombobox->clear();
|
||||
|
@ -512,7 +511,7 @@ void AVForm::getAudioInDevices()
|
|||
void AVForm::getAudioOutDevices()
|
||||
{
|
||||
QStringList deviceNames;
|
||||
deviceNames << tr("Disabled") << audio->outDeviceNames();
|
||||
deviceNames << tr("Disabled") << audio.outDeviceNames();
|
||||
|
||||
outDevCombobox->blockSignals(true);
|
||||
outDevCombobox->clear();
|
||||
|
@ -541,8 +540,8 @@ void AVForm::on_inDevCombobox_currentIndexChanged(int deviceIndex)
|
|||
const QString oldName = audioSettings->getInDev();
|
||||
if (oldName != deviceName) {
|
||||
audioSettings->setInDev(deviceName);
|
||||
audio->reinitInput(deviceName);
|
||||
audioSrc = audio->makeSource();
|
||||
audio.reinitInput(deviceName);
|
||||
audioSrc = audio.makeSource();
|
||||
connect(audioSrc.get(), &IAudioSource::volumeAvailable, this, &AVForm::setVolume);
|
||||
}
|
||||
|
||||
|
@ -566,8 +565,8 @@ void AVForm::on_outDevCombobox_currentIndexChanged(int deviceIndex)
|
|||
|
||||
if (oldName != deviceName) {
|
||||
audioSettings->setOutDev(deviceName);
|
||||
audio->reinitOutput(deviceName);
|
||||
audioSink = Audio::getInstance().makeSink();
|
||||
audio.reinitOutput(deviceName);
|
||||
audioSink = audio.makeSink();
|
||||
}
|
||||
|
||||
playbackSlider->setEnabled(outputEnabled);
|
||||
|
@ -579,10 +578,10 @@ void AVForm::on_playbackSlider_valueChanged(int sliderSteps)
|
|||
audioSettings->getOutVolumeMax());
|
||||
audioSettings->setOutVolume(settingsVolume);
|
||||
|
||||
if (audio->isOutputReady()) {
|
||||
if (audio.isOutputReady()) {
|
||||
const qreal volume =
|
||||
getValueFromSteps(sliderSteps, audio->minOutputVolume(), audio->maxOutputVolume());
|
||||
audio->setOutputVolume(volume);
|
||||
getValueFromSteps(sliderSteps, audio.minOutputVolume(), audio.maxOutputVolume());
|
||||
audio.setOutputVolume(volume);
|
||||
|
||||
if (cbEnableTestSound->isChecked() && audioSink) {
|
||||
audioSink->playMono16Sound(IAudioSink::Sound::Test);
|
||||
|
@ -594,24 +593,24 @@ void AVForm::on_cbEnableTestSound_stateChanged()
|
|||
{
|
||||
audioSettings->setEnableTestSound(cbEnableTestSound->isChecked());
|
||||
|
||||
if (cbEnableTestSound->isChecked() && audio->isOutputReady() && audioSink) {
|
||||
if (cbEnableTestSound->isChecked() && audio.isOutputReady() && audioSink) {
|
||||
audioSink->playMono16Sound(IAudioSink::Sound::Test);
|
||||
}
|
||||
}
|
||||
|
||||
void AVForm::on_microphoneSlider_valueChanged(int sliderSteps)
|
||||
{
|
||||
const qreal dB = getValueFromSteps(sliderSteps, audio->minInputGain(), audio->maxInputGain());
|
||||
const qreal dB = getValueFromSteps(sliderSteps, audio.minInputGain(), audio.maxInputGain());
|
||||
audioSettings->setAudioInGainDecibel(dB);
|
||||
audio->setInputGain(dB);
|
||||
audio.setInputGain(dB);
|
||||
}
|
||||
|
||||
void AVForm::on_audioThresholdSlider_valueChanged(int sliderSteps)
|
||||
{
|
||||
const qreal normThreshold =
|
||||
getValueFromSteps(sliderSteps, audio->minInputThreshold(), audio->maxInputThreshold());
|
||||
getValueFromSteps(sliderSteps, audio.minInputThreshold(), audio.maxInputThreshold());
|
||||
audioSettings->setAudioThreshold(normThreshold);
|
||||
Audio::getInstance().setInputThreshold(normThreshold);
|
||||
audio.setInputThreshold(normThreshold);
|
||||
}
|
||||
void AVForm::createVideoSurface()
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
class Audio;
|
||||
class IAudioControl;
|
||||
class IAudioSettings;
|
||||
class IAudioSink;
|
||||
class IAudioSource;
|
||||
|
@ -42,8 +42,8 @@ class AVForm : public GenericForm, private Ui::AVForm
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AVForm(Audio* audio, CoreAV* coreAV, CameraSource& camera, IAudioSettings* audioSettings,
|
||||
IVideoSettings* videoSettings);
|
||||
AVForm(IAudioControl& audio, CoreAV* coreAV, CameraSource& camera,
|
||||
IAudioSettings* audioSettings, IVideoSettings* videoSettings);
|
||||
~AVForm() override;
|
||||
QString getFormName() final override
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ private:
|
|||
qreal getValueFromSteps(int steps, qreal valMin, qreal valMax);
|
||||
|
||||
private:
|
||||
Audio* audio;
|
||||
IAudioControl& audio;
|
||||
CoreAV* coreAV;
|
||||
IAudioSettings* audioSettings;
|
||||
IVideoSettings* videoSettings;
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "settingswidget.h"
|
||||
|
||||
#include "src/audio/audio.h"
|
||||
#include "src/core/coreav.h"
|
||||
#include "src/core/core.h"
|
||||
#include "src/core/coreav.h"
|
||||
#include "src/net/updatecheck.h"
|
||||
#include "src/persistence/settings.h"
|
||||
#include "src/video/camerasource.h"
|
||||
|
@ -41,10 +41,9 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
SettingsWidget::SettingsWidget(UpdateCheck* updateCheck, QWidget* parent)
|
||||
SettingsWidget::SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio, QWidget* parent)
|
||||
: QWidget(parent, Qt::Window)
|
||||
{
|
||||
Audio* audio = &Audio::getInstance();
|
||||
CoreAV* coreAV = Core::getInstance()->getAv();
|
||||
IAudioSettings* audioSettings = &Settings::getInstance();
|
||||
IVideoSettings* videoSettings = &Settings::getInstance();
|
||||
|
@ -74,7 +73,8 @@ SettingsWidget::SettingsWidget(UpdateCheck* updateCheck, QWidget* parent)
|
|||
}
|
||||
#endif
|
||||
|
||||
cfgForms = {{std::move(gfrm), std::move(uifrm), std::move(pfrm), std::move(avfrm), std::move(expfrm), std::move(abtfrm)}};
|
||||
cfgForms = {{std::move(gfrm), std::move(uifrm), std::move(pfrm), std::move(avfrm),
|
||||
std::move(expfrm), std::move(abtfrm)}};
|
||||
for (auto& cfgForm : cfgForms)
|
||||
settingsWidgets->addTab(cfgForm.get(), cfgForm->getFormIcon(), cfgForm->getFormName());
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
class Camera;
|
||||
class GenericForm;
|
||||
class GeneralForm;
|
||||
class IAudioControl;
|
||||
class PrivacyForm;
|
||||
class AVForm;
|
||||
class QLabel;
|
||||
|
@ -41,7 +42,7 @@ class SettingsWidget : public QWidget
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SettingsWidget(UpdateCheck* updateCheck, QWidget* parent = nullptr);
|
||||
SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio, QWidget* parent = nullptr);
|
||||
~SettingsWidget();
|
||||
|
||||
bool isShown() const;
|
||||
|
|
|
@ -52,16 +52,15 @@
|
|||
#include "src/core/core.h"
|
||||
#include "src/core/coreav.h"
|
||||
#include "src/core/corefile.h"
|
||||
#include "src/friendlist.h"
|
||||
#include "src/grouplist.h"
|
||||
#include "src/model/chatroom/friendchatroom.h"
|
||||
#include "src/model/chatroom/groupchatroom.h"
|
||||
#include "src/model/friend.h"
|
||||
#include "src/friendlist.h"
|
||||
#include "src/grouplist.h"
|
||||
#include "src/model/friend.h"
|
||||
#include "src/model/group.h"
|
||||
#include "src/model/groupinvite.h"
|
||||
#include "src/model/status.h"
|
||||
#include "src/model/profile/profileinfo.h"
|
||||
#include "src/model/status.h"
|
||||
#include "src/net/updatecheck.h"
|
||||
#include "src/nexus.h"
|
||||
#include "src/persistence/offlinemsgengine.h"
|
||||
|
@ -95,7 +94,7 @@ bool toxActivateEventHandler(const QByteArray&)
|
|||
|
||||
Widget* Widget::instance{nullptr};
|
||||
|
||||
Widget::Widget(QWidget* parent)
|
||||
Widget::Widget(IAudioControl& audio, QWidget* parent)
|
||||
: QMainWindow(parent)
|
||||
, icon{nullptr}
|
||||
, trayMenu{nullptr}
|
||||
|
@ -103,6 +102,7 @@ Widget::Widget(QWidget* parent)
|
|||
, activeChatroomWidget{nullptr}
|
||||
, eventFlag(false)
|
||||
, eventIcon(false)
|
||||
, audio(audio)
|
||||
, settings(Settings::getInstance())
|
||||
{
|
||||
installEventFilter(this);
|
||||
|
@ -129,7 +129,8 @@ void Widget::init()
|
|||
|
||||
// Preparing icons and set their size
|
||||
statusOnline = new QAction(this);
|
||||
statusOnline->setIcon(prepareIcon(Status::getIconPath(Status::Status::Online), icon_size, icon_size));
|
||||
statusOnline->setIcon(
|
||||
prepareIcon(Status::getIconPath(Status::Status::Online), icon_size, icon_size));
|
||||
connect(statusOnline, &QAction::triggered, this, &Widget::setStatusOnline);
|
||||
|
||||
statusAway = new QAction(this);
|
||||
|
@ -148,7 +149,8 @@ void Widget::init()
|
|||
actionQuit->setMenuRole(QAction::QuitRole);
|
||||
#endif
|
||||
|
||||
actionQuit->setIcon(prepareIcon(Style::getImagePath("rejectCall/rejectCall.svg"), icon_size, icon_size));
|
||||
actionQuit->setIcon(
|
||||
prepareIcon(Style::getImagePath("rejectCall/rejectCall.svg"), icon_size, icon_size));
|
||||
connect(actionQuit, &QAction::triggered, qApp, &QApplication::quit);
|
||||
|
||||
layout()->setContentsMargins(0, 0, 0, 0);
|
||||
|
@ -233,7 +235,7 @@ void Widget::init()
|
|||
updateCheck = std::unique_ptr<UpdateCheck>(new UpdateCheck(settings));
|
||||
connect(updateCheck.get(), &UpdateCheck::updateAvailable, this, &Widget::onUpdateAvailable);
|
||||
#endif
|
||||
settingsWidget = new SettingsWidget(updateCheck.get(), this);
|
||||
settingsWidget = new SettingsWidget(updateCheck.get(), audio, this);
|
||||
#if UPDATE_CHECK_ENABLED
|
||||
updateCheck->checkForUpdate();
|
||||
#endif
|
||||
|
@ -444,7 +446,6 @@ void Widget::updateIcons()
|
|||
Status::getAssetSuffix(static_cast<Status::Status>(ui->statusButton->property("status").toInt()))
|
||||
+ (eventIcon ? "_event" : "");
|
||||
|
||||
|
||||
// Some builds of Qt appear to have a bug in icon loading:
|
||||
// QIcon::hasThemeIcon is sometimes unaware that the icon returned
|
||||
// from QIcon::fromTheme was a fallback icon, causing hasThemeIcon to
|
||||
|
@ -538,12 +539,17 @@ Widget::~Widget()
|
|||
}
|
||||
|
||||
/**
|
||||
* @param audio Only used for initialization from Nexus, to pass IAudioControl
|
||||
* @brief Returns the singleton instance.
|
||||
*/
|
||||
Widget* Widget::getInstance()
|
||||
Widget* Widget::getInstance(IAudioControl* audio)
|
||||
{
|
||||
if (!instance) {
|
||||
instance = new Widget();
|
||||
// Passing audio via pointer here is a hack
|
||||
// to allow for default paramters.
|
||||
// once Widget::getInstance is removed it won't be neccessary
|
||||
assert(audio != nullptr);
|
||||
instance = new Widget(*audio);
|
||||
}
|
||||
|
||||
return instance;
|
||||
|
@ -587,8 +593,7 @@ void Widget::closeEvent(QCloseEvent* event)
|
|||
void Widget::changeEvent(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::WindowStateChange) {
|
||||
if (isMinimized() && settings.getShowSystemTray()
|
||||
&& settings.getMinimizeToTray()) {
|
||||
if (isMinimized() && settings.getShowSystemTray() && settings.getMinimizeToTray()) {
|
||||
this->hide();
|
||||
}
|
||||
}
|
||||
|
@ -916,8 +921,7 @@ void Widget::setStatusMessage(const QString& statusMessage)
|
|||
ui->statusLabel->setText(statusMessage);
|
||||
// escape HTML from tooltips and preserve newlines
|
||||
// TODO: move newspace preservance to a generic function
|
||||
ui->statusLabel->setToolTip("<p style='white-space:pre'>" + statusMessage.toHtmlEscaped()
|
||||
+ "</p>");
|
||||
ui->statusLabel->setToolTip("<p style='white-space:pre'>" + statusMessage.toHtmlEscaped() + "</p>");
|
||||
}
|
||||
|
||||
void Widget::reloadHistory()
|
||||
|
@ -932,19 +936,20 @@ void Widget::reloadHistory()
|
|||
* @param sound Sound to play
|
||||
* @param loop if true, loop the sound until onStopNotification() is called
|
||||
*/
|
||||
void Widget::playNotificationSound(IAudioSink::Sound sound, bool loop) {
|
||||
if(audioNotification == nullptr) {
|
||||
audioNotification = std::unique_ptr<IAudioSink>(Audio::getInstance().makeSink());
|
||||
if(audioNotification == nullptr) {
|
||||
void Widget::playNotificationSound(IAudioSink::Sound sound, bool loop)
|
||||
{
|
||||
if (audioNotification == nullptr) {
|
||||
audioNotification = std::unique_ptr<IAudioSink>(audio.makeSink());
|
||||
if (audioNotification == nullptr) {
|
||||
qDebug() << "Failed to allocate AudioSink";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
connect(audioNotification.get(), &IAudioSink::finishedPlaying,
|
||||
this, &Widget::cleanupNotificationSound);
|
||||
connect(audioNotification.get(), &IAudioSink::finishedPlaying, this,
|
||||
&Widget::cleanupNotificationSound);
|
||||
|
||||
if(loop) {
|
||||
if (loop) {
|
||||
audioNotification->startLoop();
|
||||
}
|
||||
|
||||
|
@ -1011,7 +1016,8 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk)
|
|||
settings.setFriendActivity(friendPk, chatTime);
|
||||
}
|
||||
|
||||
contactListWidget->addFriendWidget(widget, Status::Status::Offline, settings.getFriendCircleID(friendPk));
|
||||
contactListWidget->addFriendWidget(widget, Status::Status::Offline,
|
||||
settings.getFriendCircleID(friendPk));
|
||||
|
||||
connect(newfriend, &Friend::aliasChanged, this, &Widget::onFriendAliasChanged);
|
||||
connect(newfriend, &Friend::displayedNameChanged, this, &Widget::onFriendDisplayedNameChanged);
|
||||
|
@ -1249,7 +1255,8 @@ void Widget::addFriendDialog(const Friend* frnd, ContentDialog* dialog)
|
|||
|
||||
auto form = chatForms[friendPk];
|
||||
auto chatroom = friendChatrooms[friendPk];
|
||||
FriendWidget* friendWidget = ContentDialogManager::getInstance()->addFriendToDialog(dialog, chatroom, form);
|
||||
FriendWidget* friendWidget =
|
||||
ContentDialogManager::getInstance()->addFriendToDialog(dialog, chatroom, form);
|
||||
|
||||
friendWidget->setStatusMsg(widget->getStatusMsg());
|
||||
|
||||
|
@ -1305,7 +1312,8 @@ void Widget::addGroupDialog(Group* group, ContentDialog* dialog)
|
|||
|
||||
auto chatForm = groupChatForms[groupId].data();
|
||||
auto chatroom = groupChatrooms[groupId];
|
||||
auto groupWidget = ContentDialogManager::getInstance()->addGroupToDialog(dialog, chatroom, chatForm);
|
||||
auto groupWidget =
|
||||
ContentDialogManager::getInstance()->addGroupToDialog(dialog, chatroom, chatForm);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
|
||||
auto removeGroup = QOverload<const GroupId&>::of(&Widget::removeGroup);
|
||||
|
@ -1610,7 +1618,8 @@ ContentDialog* Widget::createContentDialog() const
|
|||
connect(contentDialog, &ContentDialog::friendDialogShown, this, &Widget::onFriendDialogShown);
|
||||
connect(contentDialog, &ContentDialog::groupDialogShown, this, &Widget::onGroupDialogShown);
|
||||
connect(core, &Core::usernameSet, contentDialog, &ContentDialog::setUsername);
|
||||
connect(&settings, &Settings::groupchatPositionChanged, contentDialog, &ContentDialog::reorderLayouts);
|
||||
connect(&settings, &Settings::groupchatPositionChanged, contentDialog,
|
||||
&ContentDialog::reorderLayouts);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
Nexus& n = Nexus::getInstance();
|
||||
|
@ -1652,8 +1661,7 @@ ContentLayout* Widget::createContentDialog(DialogType type) const
|
|||
|
||||
void retranslateUi()
|
||||
{
|
||||
setWindowTitle(core->getUsername() + QStringLiteral(" - ")
|
||||
+ Widget::fromDialogType(type));
|
||||
setWindowTitle(core->getUsername() + QStringLiteral(" - ") + Widget::fromDialogType(type));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -1761,7 +1769,8 @@ void Widget::onGroupMessageReceived(int groupnumber, int peernumber, const QStri
|
|||
return;
|
||||
}
|
||||
|
||||
const auto mention = !core->getUsername().isEmpty() && (message.contains(nameMention) || message.contains(sanitizedNameMention));
|
||||
const auto mention = !core->getUsername().isEmpty()
|
||||
&& (message.contains(nameMention) || message.contains(sanitizedNameMention));
|
||||
const auto targeted = !isSelf && mention;
|
||||
const auto date = QDateTime::currentDateTime();
|
||||
auto form = groupChatForms[groupId].data();
|
||||
|
@ -1883,7 +1892,8 @@ Group* Widget::createGroup(uint32_t groupnumber, const GroupId& groupId)
|
|||
|
||||
const auto groupName = tr("Groupchat #%1").arg(groupnumber);
|
||||
bool enabled = core->getGroupAvEnabled(groupnumber);
|
||||
Group* newgroup = GroupList::addGroup(groupnumber, groupId, groupName, enabled, core->getUsername());
|
||||
Group* newgroup =
|
||||
GroupList::addGroup(groupnumber, groupId, groupName, enabled, core->getUsername());
|
||||
std::shared_ptr<GroupChatroom> chatroom(new GroupChatroom(newgroup));
|
||||
const auto compact = settings.getCompactLayout();
|
||||
auto widget = new GroupWidget(chatroom, compact);
|
||||
|
@ -1990,7 +2000,8 @@ void Widget::onUserAwayCheck()
|
|||
{
|
||||
#ifdef QTOX_PLATFORM_EXT
|
||||
uint32_t autoAwayTime = settings.getAutoAwayTime() * 60 * 1000;
|
||||
bool online = static_cast<Status::Status>(ui->statusButton->property("status").toInt()) == Status::Status::Online;
|
||||
bool online = static_cast<Status::Status>(ui->statusButton->property("status").toInt())
|
||||
== Status::Status::Online;
|
||||
bool away = autoAwayTime && Platform::getIdleTime() >= autoAwayTime;
|
||||
|
||||
if (online && away) {
|
||||
|
@ -2453,7 +2464,7 @@ void Widget::focusChatInput()
|
|||
}
|
||||
}
|
||||
|
||||
void Widget::refreshPeerListsLocal(const QString &username)
|
||||
void Widget::refreshPeerListsLocal(const QString& username)
|
||||
{
|
||||
for (Group* g : GroupList::getAllGroups()) {
|
||||
g->updateUsername(core->getSelfPublicKey(), username);
|
||||
|
|
|
@ -29,12 +29,13 @@
|
|||
|
||||
#include "genericchatitemwidget.h"
|
||||
|
||||
#include "src/audio/iaudiocontrol.h"
|
||||
#include "src/audio/iaudiosink.h"
|
||||
#include "src/core/core.h"
|
||||
#include "src/core/toxfile.h"
|
||||
#include "src/core/groupid.h"
|
||||
#include "src/core/toxpk.h"
|
||||
#include "src/core/toxfile.h"
|
||||
#include "src/core/toxid.h"
|
||||
#include "src/core/toxpk.h"
|
||||
#if DESKTOP_NOTIFICATIONS
|
||||
#include "src/platform/desktop_notifications/desktopnotify.h"
|
||||
#endif
|
||||
|
@ -112,13 +113,13 @@ private:
|
|||
};
|
||||
|
||||
public:
|
||||
explicit Widget(QWidget* parent = nullptr);
|
||||
explicit Widget(IAudioControl& audio, QWidget* parent = nullptr);
|
||||
~Widget() override;
|
||||
void init();
|
||||
void setCentralWidget(QWidget* widget, const QString& widgetName);
|
||||
QString getUsername();
|
||||
Camera* getCamera();
|
||||
static Widget* getInstance();
|
||||
static Widget* getInstance(IAudioControl* audio = nullptr);
|
||||
void showUpdateDownloadProgress();
|
||||
void addFriendDialog(const Friend* frnd, ContentDialog* dialog);
|
||||
void addGroupDialog(Group* group, ContentDialog* dialog);
|
||||
|
@ -185,7 +186,7 @@ public slots:
|
|||
void onFriendDialogShown(const Friend* f);
|
||||
void onGroupDialogShown(Group* g);
|
||||
void toggleFullscreen();
|
||||
void refreshPeerListsLocal(const QString &username);
|
||||
void refreshPeerListsLocal(const QString& username);
|
||||
void onUpdateAvailable(QString latestVersion, QUrl link);
|
||||
|
||||
signals:
|
||||
|
@ -312,6 +313,8 @@ private:
|
|||
QPushButton* groupInvitesButton;
|
||||
unsigned int unreadGroupInvites;
|
||||
int icon_size;
|
||||
|
||||
IAudioControl& audio;
|
||||
std::unique_ptr<IAudioSink> audioNotification = nullptr;
|
||||
Settings& settings;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user