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

Merge branch 'v1.17-dev'

This commit is contained in:
Anthony Bilinski 2020-03-28 01:43:40 -07:00
commit ef8c2b7cb3
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C
30 changed files with 43 additions and 696 deletions

View File

@ -24,7 +24,6 @@ cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
option(PLATFORM_EXTENSIONS "Enable platform specific extensions, requires extra dependencies" ON)
option(USE_FILTERAUDIO "Enable the echo canceling backend" ON)
option(UPDATE_CHECK "Enable automatic update check" ON)
option(USE_CCACHE "Use ccache when available" ON)
option(SPELL_CHECK "Enable spell cheching support" ON)
@ -622,19 +621,6 @@ if(AVFOUNDATION_FOUND)
src/platform/camera/avfoundation.h)
endif()
if(${USE_FILTERAUDIO})
search_dependency(FILTERAUDIO LIBRARY filteraudio HEADER filter_audio.h OPTIONAL)
if(${FILTERAUDIO_FOUND})
set(${PROJECT_NAME}_SOURCES ${${PROJECT_NAME}_SOURCES}
src/audio/backend/openal2.cpp
src/audio/backend/openal2.h)
add_definitions(-DUSE_FILTERAUDIO=1)
message(STATUS "using filteraudio")
else()
message(STATUS "not using filteraudio, libfilteraudio not found")
endif()
endif()
if(${UPDATE_CHECK})
add_definitions(-DUPDATE_CHECK_ENABLED=1)
set(${PROJECT_NAME}_SOURCES ${${PROJECT_NAME}_SOURCES}

View File

@ -45,7 +45,6 @@
| [qrencode] | >= 3.0.3 | |
| [sqlcipher] | >= 3.2.0 | |
| [pkg-config] | >= 0.28 | |
| [filteraudio] | >= 0.0.1 | optional dependency |
| [snorenotify] | >= 0.7.0 | optional dependency |
## Optional dependencies
@ -755,6 +754,5 @@ Switches:
[qrencode]: https://fukuchi.org/works/qrencode/
[Qt]: https://www.qt.io/
[toxcore]: https://github.com/TokTok/c-toxcore/
[filteraudio]: https://github.com/irungentoo/filter_audio
[sonnet]: https://github.com/KDE/sonnet
[snorenotify]: https://techbase.kde.org/Projects/Snorenotify

View File

@ -41,7 +41,6 @@ QT_VER=($(ls ${QT_DIR} | sed -n -e 's/^\([0-9]*\.([0-9]*\.([0-9]*\).*/\1/' -e '1
QT_DIR_VER="${QT_DIR}/${QT_VER[1]}"
TOXCORE_DIR="${MAIN_DIR}/toxcore" # Change to Git location
FILTERAUIO_DIR="${MAIN_DIR}/filter_audio" # Change to Git location
LIB_INSTALL_PREFIX="${QTOX_DIR}/libs"
@ -208,12 +207,6 @@ install() {
kill $DOT_PID
fi
fcho "Cloning filter_audio ... "
git clone --branch v0.0.1 --depth=1 https://github.com/irungentoo/filter_audio "$FILTERAUIO_DIR"
cd "$FILTERAUIO_DIR"
fcho "Installing filter_audio ... "
make install PREFIX="$LIB_INSTALL_PREFIX"
QT_VER=($(ls ${QT_DIR} | sed -n -e 's/^\([0-9]*\.([0-9]*\.([0-9]*\).*/\1/' -e '1p;$p'))
QT_DIR_VER="${QT_DIR}/${QT_VER[1]}"

View File

@ -22,9 +22,6 @@
#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
/**
* @brief Select the audio backend
@ -33,14 +30,5 @@
*/
std::unique_ptr<IAudioControl> Audio::makeAudio(IAudioSettings& settings)
{
#ifdef USE_FILTERAUDIO
const bool Backend2 = settings.getEnableBackend2();
if (Backend2) {
return std::unique_ptr<IAudioControl>(new OpenAL2());
} else
#endif
{
return std::unique_ptr<IAudioControl>(new OpenAL());
}
return std::unique_ptr<IAudioControl>(new OpenAL());
}

View File

@ -1,357 +0,0 @@
/*
Copyright © 2017-2019 by The qTox Project Contributors
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
qTox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#include "openal2.h"
#include "src/persistence/settings.h"
#include <QDebug>
#include <QFile>
#include <QMutexLocker>
#include <QPointer>
#include <QThread>
#include <QWaitCondition>
#include <QtMath>
#include <cassert>
extern "C"
{
#include <filter_audio.h>
}
/**
* @class OpenAL
* @brief Provides the OpenAL audio backend
*
* The following graphic describes the audio rendering pipeline with echo canceling
*
* | alProxyContext | | alOutContext |
* peerSources[] | | |
* \ | | |
* -> alProxyDev -> filter_audio -> alProxySource -> alOutDev -> Soundcard
* /
* alMainSource
*
* Without echo cancelling the pipeline is simplified through alProxyDev = alOutDev
* and alProxyContext = alOutContext
*
* | alProxyContext |
* peerSources[] |
* \ |
* -> alOutDev -> Soundcard
* /
* alMainSource
*
* To keep all functions in writing to the correct context, all functions changing
* the context MUST exit with alProxyContext as active context and MUST not be
* interrupted. For this to work, all functions of the base class modifying the
* context have to be overriden.
*/
static const unsigned int PROXY_BUFFER_COUNT = 4;
#define GET_PROC_ADDR(dev, name) name = reinterpret_cast<LP##name>(alcGetProcAddress(dev, #name))
typedef LPALCLOOPBACKOPENDEVICESOFT LPalcLoopbackOpenDeviceSOFT;
typedef LPALCISRENDERFORMATSUPPORTEDSOFT LPalcIsRenderFormatSupportedSOFT;
typedef LPALGETSOURCEDVSOFT LPalGetSourcedvSOFT;
typedef LPALCRENDERSAMPLESSOFT LPalcRenderSamplesSOFT;
OpenAL2::OpenAL2()
: alProxyDev{nullptr}
, alProxyContext{nullptr}
, alProxySource{0}
, alProxyBuffer{0}
{}
bool OpenAL2::initInput(const QString& deviceName)
{
return OpenAL::initInput(deviceName, 1);
}
/**
* @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
GET_PROC_ADDR(dev, alcLoopbackOpenDeviceSOFT);
checkAlcError(dev);
if (!alcLoopbackOpenDeviceSOFT) {
qDebug() << "Failed to load alcLoopbackOpenDeviceSOFT function!";
return false;
}
GET_PROC_ADDR(dev, alcIsRenderFormatSupportedSOFT);
checkAlcError(dev);
if (!alcIsRenderFormatSupportedSOFT) {
qDebug() << "Failed to load alcIsRenderFormatSupportedSOFT function!";
return false;
}
GET_PROC_ADDR(dev, alGetSourcedvSOFT);
checkAlcError(dev);
if (!alGetSourcedvSOFT) {
qDebug() << "Failed to load alGetSourcedvSOFT function!";
return false;
}
GET_PROC_ADDR(dev, alcRenderSamplesSOFT);
checkAlcError(dev);
if (!alcRenderSamplesSOFT) {
qDebug() << "Failed to load alcRenderSamplesSOFT 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,
ALC_MONO_SOFT,
ALC_FORMAT_TYPE_SOFT,
ALC_SHORT_SOFT,
ALC_FREQUENCY,
IAudioControl::AUDIO_SAMPLE_RATE,
0}; // End of List
alProxyDev = alcLoopbackOpenDeviceSOFT(nullptr);
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 cancellation enabled";
return true;
}
/**
* @brief Open an audio output device
*/
bool OpenAL2::initOutput(const QString& deviceName)
{
assert(sinks.empty());
outputInitialized = false;
if (!Settings::getInstance().getAudioOutDevEnabled()) {
return false;
}
qDebug() << "Opening audio output" << deviceName;
assert(!alOutDev);
const QByteArray qDevName = deviceName.toUtf8();
const ALchar* tmpDevName = qDevName.isEmpty() ? nullptr : qDevName.constData();
alOutDev = alcOpenDevice(tmpDevName);
if (!alOutDev) {
qWarning() << "Cannot open audio output device" << deviceName;
return false;
}
qDebug() << "Opened audio output" << deviceName;
alOutContext = alcCreateContext(alOutDev, nullptr);
checkAlcError(alOutDev);
if (!alcMakeContextCurrent(alOutContext)) {
qWarning() << "Cannot create audio output context";
return false;
}
// try to init echo cancellation
echoCancelSupported = initOutputEchoCancel();
if (!echoCancelSupported) {
// fallback to normal, no proxy device needed
qDebug() << "Echo cancellation disabled";
alProxyDev = alOutDev;
alProxyContext = alOutContext;
}
// init master volume
alListenerf(AL_GAIN, Settings::getInstance().getOutVolume() * 0.01f);
checkAlError();
// ensure alProxyContext is active
alcMakeContextCurrent(alProxyContext);
outputInitialized = true;
return true;
}
/**
* @brief Close active audio output device
*/
void OpenAL2::cleanupOutput()
{
OpenAL::cleanupOutput();
if (echoCancelSupported) {
alcMakeContextCurrent(alOutContext);
alSourceStop(alProxySource);
ALint processed = 0;
ALuint bufids[PROXY_BUFFER_COUNT];
alGetSourcei(alProxySource, AL_BUFFERS_PROCESSED, &processed);
alSourceUnqueueBuffers(alProxySource, processed, bufids);
alDeleteBuffers(processed, bufids);
alcMakeContextCurrent(nullptr);
alcDestroyContext(alOutContext);
alOutContext = nullptr;
alcCloseDevice(alOutDev);
alOutDev = nullptr;
} else {
alOutContext = nullptr;
alOutDev = nullptr;
}
}
/**
* @brief Handle audio output
*/
void OpenAL2::doOutput()
{
if (!echoCancelSupported) {
kill_filter_audio(filterer);
filterer = nullptr;
}
alcMakeContextCurrent(alOutContext);
ALuint bufids[PROXY_BUFFER_COUNT];
ALint processed = 0, queued = 0;
alGetSourcei(alProxySource, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(alProxySource, AL_BUFFERS_QUEUED, &queued);
if (processed > 0) {
// unqueue all processed buffers
alSourceUnqueueBuffers(alProxySource, processed, bufids);
// delete all but the first buffer, reuse first for new data
alDeleteBuffers(processed - 1, bufids + 1);
} else if (queued < static_cast<ALint>(PROXY_BUFFER_COUNT)) {
// create new buffer until the maximum is reached
alGenBuffers(1, bufids);
} else {
alcMakeContextCurrent(alProxyContext);
return;
}
ALdouble latency[2] = {0};
if (echoCancelSupported) {
alGetSourcedvSOFT(alProxySource, AL_SEC_OFFSET_LATENCY_SOFT, latency);
}
checkAlError();
ALshort outBuf[AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL] = {0};
if (echoCancelSupported) {
alcMakeContextCurrent(alProxyContext);
alcRenderSamplesSOFT(alProxyDev, outBuf, AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL);
checkAlcError(alProxyDev);
alcMakeContextCurrent(alOutContext);
}
alBufferData(bufids[0], AL_FORMAT_MONO16, outBuf, AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL * 2,
AUDIO_SAMPLE_RATE);
alSourceQueueBuffers(alProxySource, 1, bufids);
// initialize echo canceler if supported
if (echoCancelSupported && !filterer) {
filterer = new_filter_audio(AUDIO_SAMPLE_RATE);
int16_t filterLatency = latency[1] * 1000 * 2 + AUDIO_FRAME_DURATION;
qDebug() << "Setting filter delay to: " << filterLatency << "ms";
set_echo_delay_ms(filterer, filterLatency);
enable_disable_filters(filterer, 1, 1, 1, 0);
}
// do echo cancel
pass_audio_output(filterer, outBuf, AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL);
ALint state;
alGetSourcei(alProxySource, AL_SOURCE_STATE, &state);
if (state != AL_PLAYING) {
qDebug() << "Proxy source underflow detected";
alSourcePlay(alProxySource);
}
alcMakeContextCurrent(alProxyContext);
}
void OpenAL2::captureSamples(ALCdevice* device, int16_t* buffer, ALCsizei samples)
{
alcCaptureSamples(device, buffer, samples);
if (echoCancelSupported && filterer) {
filter_audio(filterer, buffer, samples);
}
}

View File

@ -1,83 +0,0 @@
/*
Copyright © 2014-2019 by The qTox Project Contributors
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
qTox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENAL2_H
#define OPENAL2_H
#include "src/audio/iaudiocontrol.h"
#include "src/audio/backend/openal.h"
#include <atomic>
#include <cmath>
#include <QMutex>
#include <QObject>
#include <QTimer>
#include <cassert>
#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alext.h>
extern "C"
{
#include <filter_audio.h>
}
// needed because Ubuntu 14.04 lacks the AL_SOFT_source_latency extension
#ifndef AL_SOFT_source_latency
#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
extern "C" typedef void(AL_APIENTRY* LPALGETSOURCEDVSOFT)(ALuint, ALenum, const ALdouble*);
#endif
class OpenAL2 : public OpenAL
{
Q_OBJECT
public:
OpenAL2();
protected:
bool initInput(const QString& deviceName) override;
bool initOutput(const QString& outDevDescr) override;
void cleanupOutput() override;
void playMono16SoundCleanup();
void doOutput() override;
bool loadOpenALExtensions(ALCdevice* dev);
bool initOutputEchoCancel();
void captureSamples(ALCdevice* device, int16_t* buffer, ALCsizei samples) override;
private:
ALCdevice* alProxyDev;
ALCcontext* alProxyContext;
ALuint alProxySource;
ALuint alProxyBuffer;
bool echoCancelSupported = false;
Filter_Audio* filterer = nullptr;
LPALCLOOPBACKOPENDEVICESOFT alcLoopbackOpenDeviceSOFT = nullptr;
LPALCISRENDERFORMATSUPPORTEDSOFT alcIsRenderFormatSupportedSOFT = nullptr;
LPALGETSOURCEDVSOFT alGetSourcedvSOFT = nullptr;
LPALCRENDERSAMPLESSOFT alcRenderSamplesSOFT = nullptr;
};
#endif // OPENAL2_H

View File

@ -105,6 +105,7 @@ class IAudioControl : public QObject
Q_OBJECT
public:
virtual ~IAudioControl() = default;
virtual qreal outputVolume() const = 0;
virtual void setOutputVolume(qreal volume) = 0;
virtual qreal maxOutputVolume() const = 0;

View File

@ -26,6 +26,8 @@
class IAudioSettings {
public:
virtual ~IAudioSettings() = default;
virtual QString getInDev() const = 0;
virtual void setInDev(const QString& deviceSpecifier) = 0;
@ -55,9 +57,6 @@ public:
virtual bool getEnableTestSound() const = 0;
virtual void setEnableTestSound(bool newValue) = 0;
virtual bool getEnableBackend2() const = 0;
virtual void setEnableBackend2(bool enabled) = 0;
DECLARE_SIGNAL(inDevChanged, const QString& device);
DECLARE_SIGNAL(audioInDevEnabledChanged, bool enabled);
@ -69,7 +68,6 @@ public:
DECLARE_SIGNAL(outVolumeChanged, int volume);
DECLARE_SIGNAL(audioBitrateChanged, int bitrate);
DECLARE_SIGNAL(enableTestSoundChanged, bool newValue);
DECLARE_SIGNAL(enableBackend2Changed, bool enabled);
};
#endif // I_AUDIO_SETTINGS_H

View File

@ -97,7 +97,7 @@ public:
return {};
}
virtual ~IAudioSink() {}
virtual ~IAudioSink() = default;
virtual void playAudioBuffer(const int16_t* data, int samples, unsigned channels,
int sampleRate) const = 0;
virtual void playMono16Sound(const Sound& sound) = 0;

View File

@ -34,7 +34,7 @@ class IAudioSource : public QObject
{
Q_OBJECT
public:
virtual ~IAudioSource() {}
virtual ~IAudioSource() = default;
virtual operator bool() const = 0;

View File

@ -52,8 +52,8 @@ T clamp(T x, T min, T max)
return x;
}
ChatLog::ChatLog(const bool canRemove, QWidget* parent)
: QGraphicsView(parent), canRemove(canRemove)
ChatLog::ChatLog(QWidget* parent)
: QGraphicsView(parent)
{
// Create the scene
busyScene = new QGraphicsScene(this);
@ -394,7 +394,7 @@ void ChatLog::insertChatlineAtBottom(const QList<ChatLine::Ptr>& newLines)
if (newLines.isEmpty())
return;
if (canRemove && lines.size() + static_cast<int>(DEF_NUM_MSG_TO_LOAD) >= maxMessages) {
if (lines.size() + static_cast<int>(DEF_NUM_MSG_TO_LOAD) >= maxMessages) {
removeFirsts(DEF_NUM_MSG_TO_LOAD);
}
@ -444,7 +444,7 @@ void ChatLog::insertChatlinesOnTop(const QList<ChatLine::Ptr>& newLines)
combLines.push_back(l);
}
if (canRemove && lines.size() + static_cast<int>(DEF_NUM_MSG_TO_LOAD) >= maxMessages) {
if (lines.size() + static_cast<int>(DEF_NUM_MSG_TO_LOAD) >= maxMessages) {
removeLasts(DEF_NUM_MSG_TO_LOAD);
}

View File

@ -41,7 +41,7 @@ class ChatLog : public QGraphicsView
{
Q_OBJECT
public:
explicit ChatLog(const bool canRemove, QWidget* parent = nullptr);
explicit ChatLog(QWidget* parent = nullptr);
virtual ~ChatLog();
void insertChatlineAtBottom(ChatLine::Ptr l);
@ -188,7 +188,6 @@ private:
int numRemove{0};
const int maxMessages{300};
bool canRemove;
};
#endif // CHATLOG_H

View File

@ -35,6 +35,7 @@ public:
ptSOCKS5 = 1,
ptHTTP = 2
};
virtual ~ICoreSettings() = default;
virtual bool getEnableIPv6() const = 0;
virtual void setEnableIPv6(bool enable) = 0;

View File

@ -28,6 +28,7 @@
class IAboutFriend
{
public:
virtual ~IAboutFriend() = default;
virtual QString getName() const = 0;
virtual QString getStatusMessage() const = 0;
virtual ToxPk getPublicKey() const = 0;

View File

@ -33,22 +33,6 @@ bool needsLoadFromHistory(ChatLogIdx idx, const SessionChatLog& sessionChatLog)
return idx < sessionChatLog.getFirstIdx();
}
/**
* @brief Gets the initial chat log index for a sessionChatLog with 0 items loaded from history.
* Needed to keep history indexes in sync with chat log indexes
* @param[in] history
* @param[in] f
* @return Initial chat log index
*/
ChatLogIdx getInitialChatLogIdx(History* history, Friend& f)
{
if (!history) {
return ChatLogIdx(0);
}
return ChatLogIdx(history->getNumMessagesForFriend(f.getPublicKey()));
}
/**
* @brief Finds the first item in sessionChatLog that contains a message
* @param[in] sessionChatLog
@ -90,9 +74,9 @@ ChatHistory::ChatHistory(Friend& f_, History* history_, const ICoreIdHandler& co
const Settings& settings_, IMessageDispatcher& messageDispatcher)
: f(f_)
, history(history_)
, sessionChatLog(getInitialChatLogIdx(history, f), coreIdHandler)
, settings(settings_)
, coreIdHandler(coreIdHandler)
, sessionChatLog(getInitialChatLogIdx(), coreIdHandler)
{
connect(&messageDispatcher, &IMessageDispatcher::messageComplete, this,
&ChatHistory::onMessageComplete);
@ -472,3 +456,18 @@ bool ChatHistory::canUseHistory() const
{
return history && settings.getEnableLogging();
}
/**
* @brief Gets the initial chat log index for a sessionChatLog with 0 items loaded from history.
* Needed to keep history indexes in sync with chat log indexes
* @param[in] history
* @param[in] f
* @return Initial chat log index
*/
ChatLogIdx ChatHistory::getInitialChatLogIdx() const
{
if (canUseHistory()) {
return ChatLogIdx(history->getNumMessagesForFriend(f.getPublicKey()));
}
return ChatLogIdx(0);
}

View File

@ -60,12 +60,13 @@ private:
void handleDispatchedMessage(DispatchedMessageId dispatchId, RowId historyId);
void completeMessage(DispatchedMessageId id);
bool canUseHistory() const;
ChatLogIdx getInitialChatLogIdx() const;
Friend& f;
History* history;
mutable SessionChatLog sessionChatLog;
const Settings& settings;
const ICoreIdHandler& coreIdHandler;
mutable SessionChatLog sessionChatLog;
// If a message completes before it's inserted into history it will end up
// in this set

View File

@ -27,6 +27,7 @@ class ToxPk;
class IDialogs
{
public:
virtual ~IDialogs() = default;
virtual bool hasContact(const ContactId& contactId) const = 0;
virtual bool isContactActive(const ContactId& contactId) const = 0;

View File

@ -28,6 +28,7 @@ class ToxPk;
class IDialogsManager
{
public:
virtual ~IDialogsManager() = default;
virtual IDialogs* getFriendDialogs(const ToxPk& friendPk) const = 0;
virtual IDialogs* getGroupDialogs(const GroupId& groupId) const = 0;
};

View File

@ -37,6 +37,7 @@ public:
enum class SetAvatarResult {
OK, EmptyPath, CanNotOpen, CanNotRead, TooLarge
};
virtual ~IProfileInfo() = default;
virtual bool setPassword(const QString& password) = 0;
virtual bool deletePassword() = 0;

View File

@ -39,6 +39,8 @@ public:
};
Q_DECLARE_FLAGS(AutoAcceptCallFlags, AutoAcceptCall)
virtual ~IFriendSettings() = default;
virtual QString getContactNote(const ToxPk& pk) const = 0;
virtual void setContactNote(const ToxPk& pk, const QString& note) = 0;

View File

@ -243,10 +243,6 @@ void Settings::loadGlobal()
outVolume = s.value("outVolume", 100).toInt();
enableTestSound = s.value("enableTestSound", true).toBool();
audioBitrate = s.value("audioBitrate", 64).toInt();
enableBackend2 = false;
#ifdef USE_FILTERAUDIO
enableBackend2 = s.value("enableBackend2", false).toBool();
#endif
}
s.endGroup();
@ -714,7 +710,6 @@ void Settings::saveGlobal()
s.setValue("outVolume", outVolume);
s.setValue("enableTestSound", enableTestSound);
s.setValue("audioBitrate", audioBitrate);
s.setValue("enableBackend2", enableBackend2);
}
s.endGroup();
@ -2012,22 +2007,6 @@ void Settings::setAudioBitrate(int bitrate)
}
}
bool Settings::getEnableBackend2() const
{
QMutexLocker locker{&bigLock};
return enableBackend2;
}
void Settings::setEnableBackend2(bool enabled)
{
QMutexLocker locker{&bigLock};
if (enabled != enableBackend2) {
enableBackend2 = enabled;
emit enableBackend2Changed(enabled);
}
}
QRect Settings::getScreenRegion() const
{
QMutexLocker locker(&bigLock);

View File

@ -118,8 +118,6 @@ class Settings : public QObject,
audioOutDevEnabledChanged FINAL)
Q_PROPERTY(int outVolume READ getOutVolume WRITE setOutVolume NOTIFY outVolumeChanged FINAL)
Q_PROPERTY(int audioBitrate READ getAudioBitrate WRITE setAudioBitrate NOTIFY audioBitrateChanged FINAL)
Q_PROPERTY(bool enableBackend2 READ getEnableBackend2 WRITE setEnableBackend2 NOTIFY
enableBackend2Changed FINAL)
// Video
Q_PROPERTY(QString videoDev READ getVideoDev WRITE setVideoDev NOTIFY videoDevChanged FINAL)
@ -371,9 +369,6 @@ public:
bool getEnableTestSound() const override;
void setEnableTestSound(bool newValue) override;
bool getEnableBackend2() const override;
void setEnableBackend2(bool enabled) override;
SIGNAL_IMPL(Settings, inDevChanged, const QString& device)
SIGNAL_IMPL(Settings, audioInDevEnabledChanged, bool enabled)
@ -385,7 +380,6 @@ public:
SIGNAL_IMPL(Settings, outVolumeChanged, int volume)
SIGNAL_IMPL(Settings, audioBitrateChanged, int bitrate)
SIGNAL_IMPL(Settings, enableTestSoundChanged, bool newValue)
SIGNAL_IMPL(Settings, enableBackend2Changed, bool enabled)
QString getVideoDev() const override;
void setVideoDev(const QString& deviceSpecifier) override;
@ -673,7 +667,6 @@ private:
int outVolume;
int audioBitrate;
bool enableTestSound;
bool enableBackend2;
// Video
QString videoDev;

View File

@ -27,6 +27,8 @@
class IVideoSettings {
public:
virtual ~IVideoSettings() = default;
virtual QString getVideoDev() const = 0;
virtual void setVideoDev(const QString& deviceSpecifier) = 0;

View File

@ -258,7 +258,7 @@ GenericChatForm::GenericChatForm(const Contact* contact, IChatLog& chatLog,
headWidget = new ChatFormHeader();
searchForm = new SearchForm();
dateInfo = new QLabel(this);
chatWidget = new ChatLog(contact->useHistory(), this);
chatWidget = new ChatLog(this);
chatWidget->setBusyNotification(ChatMessage::createBusyNotification());
searchForm->hide();
dateInfo->setAlignment(Qt::AlignHCenter);

View File

@ -62,11 +62,6 @@ AVForm::AVForm(IAudioControl& audio, CoreAV* coreAV, CameraSource& camera,
cbEnableTestSound->setChecked(audioSettings->getEnableTestSound());
cbEnableTestSound->setToolTip(tr("Play a test sound while changing the output volume."));
#ifndef USE_FILTERAUDIO
cbEnableBackend2->setVisible(false);
#endif
cbEnableBackend2->setChecked(audioSettings->getEnableBackend2());
connect(rescanButton, &QPushButton::clicked, this, &AVForm::rescanDevices);
playbackSlider->setTracking(false);
@ -179,11 +174,6 @@ void AVForm::setVolume(float value)
volumeDisplay->setValue(getStepsFromValue(value, audio.minOutputVolume(), audio.maxOutputVolume()));
}
void AVForm::on_cbEnableBackend2_stateChanged()
{
audioSettings->setEnableBackend2(cbEnableBackend2->isChecked());
}
void AVForm::on_videoModescomboBox_currentIndexChanged(int index)
{
assert(0 <= index && index < videoModes.size());

View File

@ -84,8 +84,6 @@ private slots:
void rescanDevices();
void setVolume(float value);
void on_cbEnableBackend2_stateChanged();
protected:
void updateVideoModes(int curIndex);

View File

@ -124,12 +124,12 @@
</item>
<item row="5" column="1" colspan="2">
<widget class="QProgressBar" name="volumeDisplay">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0">
@ -159,19 +159,6 @@
</property>
</widget>
</item>
<item row="7" column="0" colspan="3">
<widget class="QCheckBox" name="cbEnableBackend2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Enables the experimental audio backend with echo cancelling support, needs qTox restart to take effect.</string>
</property>
<property name="text">
<string>Enable experimental audio backend</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -109,7 +109,7 @@ float Identicon::bytesToColor(QByteArray bytes)
// normalize to 0.0 ... 1.0
return (static_cast<float>(hue))
/ (((static_cast<uint64_t>(1)) << (8 * IDENTICON_COLOR_BYTES)) - 1);
/ (static_cast<float>(((static_cast<uint64_t>(1)) << (8 * IDENTICON_COLOR_BYTES)) - 1));
}
/**

View File

@ -95,7 +95,6 @@ workspace
│   ├── dep-cache
│   │   ├── libexif
│   │   ├── libffmpeg
│   │   ├── libfilteraudio
│   │   ├── libopenal
│   │   ├── libopenssl
│   │   ├── libopus
@ -114,7 +113,6 @@ workspace
├── dep-cache
│   ├── libexif
│   ├── libffmpeg
│   ├── libfilteraudio
│   ├── libopenal
│   ├── libopenssl
│   ├── libopus

View File

@ -611,136 +611,6 @@ else
fi
# Filteraudio
FILTERAUDIO_PREFIX_DIR="$DEP_DIR/libfilteraudio"
FILTERAUDIO_VERSION=ada2f4fdc04940cdeee47caffe43add4fa017096
FILTERAUDIO_HASH="cf481e87c860aaf28b50d125195d84556f36d0ebb529d7ebdac39f8cc497256a"
if [ ! -f "$FILTERAUDIO_PREFIX_DIR/done" ]
then
rm -rf "$FILTERAUDIO_PREFIX_DIR"
mkdir -p "$FILTERAUDIO_PREFIX_DIR"
git clone https://github.com/irungentoo/filter_audio filter_audio
cd filter*
git checkout $FILTERAUDIO_VERSION
check_sha256_git "$FILTERAUDIO_HASH"
$ARCH-w64-mingw32-gcc -O2 -g0 -c \
aec/aec_core.c \
aec/aec_core_sse2.c \
aec/aec_rdft.c \
aec/aec_rdft_sse2.c \
aec/aec_resampler.c \
aec/echo_cancellation.c \
agc/analog_agc.c \
agc/digital_agc.c \
ns/ns_core.c \
ns/nsx_core_c.c \
ns/nsx_core.c \
ns/noise_suppression_x.c \
ns/noise_suppression.c \
other/get_scaling_square.c \
other/resample_by_2.c \
other/spl_sqrt.c \
other/delay_estimator.c \
other/complex_bit_reverse.c \
other/dot_product_with_scale.c \
other/cross_correlation.c \
other/min_max_operations.c \
other/resample_48khz.c \
other/high_pass_filter.c \
other/energy.c \
other/randomization_functions.c \
other/speex_resampler.c \
other/copy_set_operations.c \
other/downsample_fast.c \
other/complex_fft.c \
other/vector_scaling_operations.c \
other/resample_by_2_internal.c \
other/delay_estimator_wrapper.c \
other/real_fft.c \
other/spl_sqrt_floor.c \
other/resample_fractional.c \
other/ring_buffer.c \
other/splitting_filter.c \
other/fft4g.c \
other/division_operations.c \
other/spl_init.c \
other/float_util.c \
zam/filters.c \
vad/vad_sp.c \
vad/vad_core.c \
vad/webrtc_vad.c \
vad/vad_gmm.c \
vad/vad_filterbank.c \
filter_audio.c \
-lpthread \
-lm
ar rcs libfilteraudio.a \
aec_core.o \
aec_core_sse2.o \
aec_rdft.o \
aec_rdft_sse2.o \
aec_resampler.o \
echo_cancellation.o \
analog_agc.o \
digital_agc.o \
ns_core.o \
nsx_core_c.o \
nsx_core.o \
noise_suppression_x.o \
noise_suppression.o \
get_scaling_square.o \
resample_by_2.o \
spl_sqrt.o \
delay_estimator.o \
complex_bit_reverse.o \
dot_product_with_scale.o \
cross_correlation.o \
min_max_operations.o \
resample_48khz.o \
high_pass_filter.o \
energy.o \
randomization_functions.o \
speex_resampler.o \
copy_set_operations.o \
downsample_fast.o \
complex_fft.o \
vector_scaling_operations.o \
resample_by_2_internal.o \
delay_estimator_wrapper.o \
real_fft.o \
spl_sqrt_floor.o \
resample_fractional.o \
ring_buffer.o \
splitting_filter.o \
fft4g.o \
division_operations.o \
spl_init.o \
float_util.o \
filters.o \
vad_sp.o \
vad_core.o \
webrtc_vad.o \
vad_gmm.o \
vad_filterbank.o \
filter_audio.o
mkdir $FILTERAUDIO_PREFIX_DIR/include
mkdir $FILTERAUDIO_PREFIX_DIR/lib
cp filter_audio.h $FILTERAUDIO_PREFIX_DIR/include
cp libfilteraudio.a $FILTERAUDIO_PREFIX_DIR/lib
echo -n $FILTERAUDIO_VERSION > $FILTERAUDIO_PREFIX_DIR/done
cd ..
rm -rf ./filter*
else
echo "Using cached build of Filteraudio `cat $FILTERAUDIO_PREFIX_DIR/done`"
fi
# QREncode
QRENCODE_PREFIX_DIR="$DEP_DIR/libqrencode"