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

Merge branch 'pr933'

This commit is contained in:
Dubslow 2014-12-16 18:51:21 -06:00
commit 9d193c752e
No known key found for this signature in database
GPG Key ID: 3DB8E05315C220AA
12 changed files with 253 additions and 6 deletions

View File

@ -15,6 +15,7 @@ SODIUM_VER=1.0.0
# directory names of cloned repositories # directory names of cloned repositories
SODIUM_DIR=libsodium-$SODIUM_VER SODIUM_DIR=libsodium-$SODIUM_VER
TOX_CORE_DIR=libtoxcore-latest TOX_CORE_DIR=libtoxcore-latest
FILTER_AUDIO_DIR=filter_audio
# this boolean describes whether the installation of # this boolean describes whether the installation of
# libsodium should be skipped or not # libsodium should be skipped or not
@ -42,6 +43,11 @@ if [ -z "$TOX_CORE_DIR" ]; then
exit 1 exit 1
fi fi
if [ -z "$FILTER_AUDIO_DIR" ]; then
echo "internal error detected!"
echo "FILTER_AUDIO_DIR should not be empty... aborting"
exit 1
fi
########## check input parameters ########## ########## check input parameters ##########
@ -95,7 +101,7 @@ mkdir -p ${BASE_DIR}
# if exists, otherwise cloning them may fail # if exists, otherwise cloning them may fail
rm -rf ${BASE_DIR}/${SODIUM_DIR} rm -rf ${BASE_DIR}/${SODIUM_DIR}
rm -rf ${BASE_DIR}/${TOX_CORE_DIR} rm -rf ${BASE_DIR}/${TOX_CORE_DIR}
rm -rf ${BASE_DIR}/${FILTER_AUDIO_DIR}
############### install step ############### ############### install step ###############
@ -122,6 +128,12 @@ if [[ $TOX_ONLY = "false" ]]; then
fi fi
popd popd
if [[ $GLOBAL = "false" ]]; then
./install_libfilteraudio.sh ${BASE_DIR}/${FILTER_AUDIO_DIR} ${BASE_DIR}
else
./install_libfilteraudio.sh ${BASE_DIR}/${FILTER_AUDIO_DIR}
fi
fi fi
# clone current master of libtoxcore # clone current master of libtoxcore

40
install_libfilteraudio.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/sh
if [ -z $1 ]; then
SOURCE_DIR="filter_audio/"
else
SOURCE_DIR="$1/"
fi
if [ -z "$2" ]; then
LIB_DIR="/usr/local/lib/"
INCLUDE_DIR="/usr/local/include/"
else
LIB_DIR="$2/lib/"
INCLUDE_DIR="$2/include/"
fi
echo "Cloning filter_audio from GitHub.com"
git clone https://github.com/irungentoo/filter_audio.git $SOURCE_DIR
echo "Compiling filter_audio"
cd $SOURCE_DIR
gcc -c -fPIC filter_audio.c aec/*.c agc/*.c ns/*.c other/*.c -lm -lpthread
echo "Creating shared object file"
gcc *.o -shared -o libfilteraudio.so
echo "Cleaning up"
rm *.o
muhcmd="cp libfilteraudio.so $LIB_DIR"
[ -z "$2" ] && muhcmd="sudo $muhcmd"
echo "Installing libfilteraudio.so with $muhcmd"
$muhcmd
muhcmd="cp *.h $INCLUDE_DIR"
[ -z "$2" ] && muhcmd="sudo $muhcmd"
echo "Installing include files with $muhcmd"
$muhcmd
echo "Finished."

View File

@ -59,6 +59,12 @@ contains(DISABLE_PLATFORM_EXT, YES) {
DEFINES += QTOX_PLATFORM_EXT DEFINES += QTOX_PLATFORM_EXT
} }
contains(DISABLE_FILTER_AUDIO, YES) {
} else {
DEFINES += QTOX_FILTER_AUDIO
}
contains(JENKINS,YES) { contains(JENKINS,YES) {
INCLUDEPATH += ./libs/include/ INCLUDEPATH += ./libs/include/
} else { } else {
@ -78,6 +84,7 @@ win32 {
QMAKE_INFO_PLIST = osx/info.plist QMAKE_INFO_PLIST = osx/info.plist
LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui
contains(DEFINES, QTOX_PLATFORM_EXT) { LIBS += -framework IOKit -framework CoreFoundation } contains(DEFINES, QTOX_PLATFORM_EXT) { LIBS += -framework IOKit -framework CoreFoundation }
contains(DEFINES, QTOX_FILTER_AUDIO) { }
} else { } else {
# If we're building a package, static link libtox[core,av] and libsodium, since they are not provided by any package # If we're building a package, static link libtox[core,av] and libsodium, since they are not provided by any package
contains(STATICPKG, YES) { contains(STATICPKG, YES) {
@ -94,8 +101,16 @@ win32 {
LIBS += -lX11 -lXss LIBS += -lX11 -lXss
} }
contains(DEFINES, QTOX_FILTER_AUDIO) {
contains(STATICPKG, YES) {
LIBS += -Wl,-Bstatic -lfilteraudio
} else {
LIBS += -lfilteraudio
}
}
contains(JENKINS, YES) { contains(JENKINS, YES) {
LIBS = ./libs/lib/libtoxav.a ./libs/lib/libvpx.a ./libs/lib/libopus.a ./libs/lib/libtoxdns.a ./libs/lib/libtoxencryptsave.a ./libs/lib/libtoxcore.a ./libs/lib/libsodium.a /usr/lib/libopencv_core.so /usr/lib/libopencv_highgui.so /usr/lib/libopencv_imgproc.so -lopenal -lX11 -lXss -s LIBS = ./libs/lib/libtoxav.a ./libs/lib/libvpx.a ./libs/lib/libopus.a ./libs/lib/libtoxdns.a ./libs/lib/libtoxencryptsave.a ./libs/lib/libtoxcore.a ./libs/lib/libsodium.a ./libs/lib/libfilteraudio.a /usr/lib/libopencv_core.so /usr/lib/libopencv_highgui.so /usr/lib/libopencv_imgproc.so -lopenal -lX11 -lXss -s
} }
} }
} }
@ -234,6 +249,11 @@ SOURCES += \
src/widget/form/settings/advancedform.cpp \ src/widget/form/settings/advancedform.cpp \
src/audio.cpp src/audio.cpp
contains(DEFINES, QTOX_FILTER_AUDIO) {
HEADERS += src/audiofilterer.h
SOURCES += src/audiofilterer.cpp
}
contains(DEFINES, QTOX_PLATFORM_EXT) { contains(DEFINES, QTOX_PLATFORM_EXT) {
HEADERS += src/platform/timer.h HEADERS += src/platform/timer.h
SOURCES += src/platform/timer_osx.cpp \ SOURCES += src/platform/timer_osx.cpp \

53
src/audiofilterer.cpp Normal file
View File

@ -0,0 +1,53 @@
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program 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.
This program 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 COPYING file for more details.
*/
#ifdef QTOX_FILTER_AUDIO
#include "audiofilterer.h"
extern "C"{
#include <filter_audio.h>
}
void AudioFilterer::startFilter(unsigned int fs)
{
closeFilter();
filter = new_filter_audio(fs);
}
void AudioFilterer::closeFilter()
{
if (filter)
kill_filter_audio(filter);
filter = nullptr;
}
void AudioFilterer::filterAudio(int16_t* data, int framesize)
{
if (!filter)
return;
filter_audio(filter, (int16_t*) data, framesize);
}
AudioFilterer::~AudioFilterer()
{
closeFilter();
}
#endif // QTOX_FILTER_AUDIO

41
src/audiofilterer.h Normal file
View File

@ -0,0 +1,41 @@
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program 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.
This program 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 COPYING file for more details.
*/
#ifdef QTOX_FILTER_AUDIO
#ifndef AUDIOFILTERER_H
#define AUDIOFILTERER_H
#include <cstdint>
#ifndef _FILTER_AUDIO
typedef struct Filter_Audio Filter_Audio;
#endif
class AudioFilterer
{
public:
explicit AudioFilterer() = default;
~AudioFilterer();
void startFilter(unsigned int fs);
void filterAudio(int16_t* data, int framesize);
void closeFilter();
private:
struct Filter_Audio* filter{nullptr};
};
#endif // AUDIOFILTERER_H
#endif // QTOX_FILTER_AUDIO

View File

@ -33,6 +33,9 @@ class QTimer;
class QString; class QString;
class CString; class CString;
class VideoSource; class VideoSource;
#ifdef QTOX_FILTER_AUDIO
class AudioFilterer;
#endif
class Core : public QObject class Core : public QObject
{ {
@ -283,6 +286,9 @@ private:
int dhtServerId; int dhtServerId;
static QList<ToxFile> fileSendQueue, fileRecvQueue; static QList<ToxFile> fileSendQueue, fileRecvQueue;
static ToxCall calls[TOXAV_MAX_CALLS]; static ToxCall calls[TOXAV_MAX_CALLS];
#ifdef QTOX_FILTER_AUDIO
static AudioFilterer * filterer[TOXAV_MAX_CALLS];
#endif
static QHash<int, ToxGroupCall> groupCalls; // Maps group IDs to ToxGroupCalls static QHash<int, ToxGroupCall> groupCalls; // Maps group IDs to ToxGroupCalls
QMutex fileSendMutex, messageSendMutex; QMutex fileSendMutex, messageSendMutex;
bool ready; bool ready;

View File

@ -17,10 +17,17 @@
#include "core.h" #include "core.h"
#include "video/camera.h" #include "video/camera.h"
#include "audio.h" #include "audio.h"
#ifdef QTOX_FILTER_AUDIO
#include "audiofilterer.h"
#endif
#include "misc/settings.h"
#include <QDebug> #include <QDebug>
#include <QTimer> #include <QTimer>
ToxCall Core::calls[TOXAV_MAX_CALLS]; ToxCall Core::calls[TOXAV_MAX_CALLS];
#ifdef QTOX_FILTER_AUDIO
AudioFilterer * Core::filterer[TOXAV_MAX_CALLS] { nullptr};
#endif
const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4}; const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4};
uint8_t* Core::videobuf; uint8_t* Core::videobuf;
@ -65,6 +72,19 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled
calls[callId].sendVideoTimer->start(); calls[callId].sendVideoTimer->start();
Camera::getInstance()->subscribe(); Camera::getInstance()->subscribe();
} }
#ifdef QTOX_FILTER_AUDIO
if (Settings::getInstance().getFilterAudio())
{
Core::filterer[callId] = new AudioFilterer();
filterer[callId]->startFilter(48000);
}
else
{
delete filterer[callId];
filterer[callId] = nullptr;
}
#endif
} }
void Core::onAvMediaChange(void* toxav, int32_t callId, void* core) void Core::onAvMediaChange(void* toxav, int32_t callId, void* core)
@ -246,8 +266,16 @@ void Core::sendCallAudio(int callId, ToxAv* toxav)
return; return;
} }
#ifdef QTOX_FILTER_AUDIO
if (filterer[callId])
{
filterer[callId]->filterAudio((int16_t*) buf, framesize);
}
#endif
if ((r = toxav_send_audio(toxav, callId, dest, r)) < 0) if ((r = toxav_send_audio(toxav, callId, dest, r)) < 0)
{
qDebug() << "Core: toxav_send_audio error"; qDebug() << "Core: toxav_send_audio error";
}
} }
calls[callId].sendAudioTimer->start(); calls[callId].sendAudioTimer->start();
} }
@ -294,14 +322,16 @@ void Core::sendCallVideo(int callId)
void Core::micMuteToggle(int callId) void Core::micMuteToggle(int callId)
{ {
if (calls[callId].active) { if (calls[callId].active)
{
calls[callId].muteMic = !calls[callId].muteMic; calls[callId].muteMic = !calls[callId].muteMic;
} }
} }
void Core::volMuteToggle(int callId) void Core::volMuteToggle(int callId)
{ {
if (calls[callId].active) { if (calls[callId].active)
{
calls[callId].muteVol = !calls[callId].muteVol; calls[callId].muteVol = !calls[callId].muteVol;
alSourcef(calls[callId].alSource, AL_GAIN, calls[callId].muteVol ? 0.f : 1.f); alSourcef(calls[callId].alSource, AL_GAIN, calls[callId].muteVol ? 0.f : 1.f);
} }
@ -321,6 +351,15 @@ void Core::onAvCancel(void* _toxav, int32_t callId, void* core)
calls[callId].active = false; calls[callId].active = false;
#ifdef QTOX_FILTER_AUDIO
if (filterer[callId])
{
filterer[callId]->closeFilter();
delete filterer[callId];
filterer[callId] = nullptr;
}
#endif
emit static_cast<Core*>(core)->avCancel(friendId, callId); emit static_cast<Core*>(core)->avCancel(friendId, callId);
} }

View File

@ -198,6 +198,7 @@ void Settings::load()
s.beginGroup("Audio"); s.beginGroup("Audio");
inDev = s.value("inDev", "").toString(); inDev = s.value("inDev", "").toString();
outDev = s.value("outDev", "").toString(); outDev = s.value("outDev", "").toString();
filterAudio = s.value("filterAudio", false).toBool();
s.endGroup(); s.endGroup();
// Read the embedded DHT bootsrap nodes list if needed // Read the embedded DHT bootsrap nodes list if needed
@ -340,6 +341,7 @@ void Settings::save(QString path, bool writeFriends)
s.beginGroup("Audio"); s.beginGroup("Audio");
s.setValue("inDev", inDev); s.setValue("inDev", inDev);
s.setValue("outDev", outDev); s.setValue("outDev", outDev);
s.setValue("filterAudio", filterAudio);
s.endGroup(); s.endGroup();
if (!writeFriends || currentProfile.isEmpty()) // Core::switchConfiguration if (!writeFriends || currentProfile.isEmpty()) // Core::switchConfiguration
@ -898,6 +900,16 @@ void Settings::setOutDev(const QString& deviceSpecifier)
outDev = deviceSpecifier; outDev = deviceSpecifier;
} }
bool Settings::getFilterAudio() const
{
return filterAudio;
}
void Settings::setFilterAudio(bool newValue)
{
filterAudio = newValue;
}
QString Settings::getFriendAdress(const QString &publicKey) const QString Settings::getFriendAdress(const QString &publicKey) const
{ {
QString key = ToxID::fromString(publicKey).publicKey; QString key = ToxID::fromString(publicKey).publicKey;

View File

@ -128,6 +128,9 @@ public:
QString getOutDev() const; QString getOutDev() const;
void setOutDev(const QString& deviceSpecifier); void setOutDev(const QString& deviceSpecifier);
bool getFilterAudio() const;
void setFilterAudio(bool newValue);
// Assume all widgets have unique names // Assume all widgets have unique names
// Don't use it to save every single thing you want to save, use it // Don't use it to save every single thing you want to save, use it
// for some general purpose widgets, such as MainWindows or Splitters, // for some general purpose widgets, such as MainWindows or Splitters,
@ -298,6 +301,7 @@ private:
// Audio // Audio
QString inDev; QString inDev;
QString outDev; QString outDev;
bool filterAudio;
struct friendProp struct friendProp
{ {

View File

@ -33,12 +33,19 @@ AVForm::AVForm() :
bodyUI = new Ui::AVSettings; bodyUI = new Ui::AVSettings;
bodyUI->setupUi(this); bodyUI->setupUi(this);
#ifdef QTOX_FILTER_AUDIO
bodyUI->filterAudio->setChecked(Settings::getInstance().getFilterAudio());
#else
bodyUI->filterAudio->setDisabled(true);
#endif
connect(Camera::getInstance(), &Camera::propProbingFinished, this, &AVForm::onPropProbingFinished); connect(Camera::getInstance(), &Camera::propProbingFinished, this, &AVForm::onPropProbingFinished);
connect(Camera::getInstance(), &Camera::resolutionProbingFinished, this, &AVForm::onResProbingFinished); connect(Camera::getInstance(), &Camera::resolutionProbingFinished, this, &AVForm::onResProbingFinished);
auto qcomboboxIndexChanged = (void(QComboBox::*)(const QString&)) &QComboBox::currentIndexChanged; auto qcomboboxIndexChanged = (void(QComboBox::*)(const QString&)) &QComboBox::currentIndexChanged;
connect(bodyUI->inDevCombobox, qcomboboxIndexChanged, this, &AVForm::onInDevChanged); connect(bodyUI->inDevCombobox, qcomboboxIndexChanged, this, &AVForm::onInDevChanged);
connect(bodyUI->outDevCombobox, qcomboboxIndexChanged, this, &AVForm::onOutDevChanged); connect(bodyUI->outDevCombobox, qcomboboxIndexChanged, this, &AVForm::onOutDevChanged);
connect(bodyUI->filterAudio, SIGNAL(toggled(bool)), this, SLOT(onFilterAudioToggled(bool)));
connect(bodyUI->rescanButton, &QPushButton::clicked, this, [=](){getAudioInDevices(); getAudioOutDevices();}); connect(bodyUI->rescanButton, &QPushButton::clicked, this, [=](){getAudioInDevices(); getAudioOutDevices();});
} }
@ -189,3 +196,8 @@ void AVForm::onOutDevChanged(const QString& deviceDescriptor)
Settings::getInstance().setOutDev(deviceDescriptor); Settings::getInstance().setOutDev(deviceDescriptor);
Audio::openOutput(deviceDescriptor); Audio::openOutput(deviceDescriptor);
} }
void AVForm::onFilterAudioToggled(bool filterAudio)
{
Settings::getInstance().setFilterAudio(filterAudio);
}

View File

@ -52,6 +52,7 @@ private slots:
// audio // audio
void onInDevChanged(const QString& deviceDescriptor); void onInDevChanged(const QString& deviceDescriptor);
void onOutDevChanged(const QString& deviceDescriptor); void onOutDevChanged(const QString& deviceDescriptor);
void onFilterAudioToggled(bool filterAudio);
// camera // camera
void onPropProbingFinished(Camera::Prop prop, double val); void onPropProbingFinished(Camera::Prop prop, double val);

View File

@ -30,8 +30,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>810</width> <width>808</width>
<height>496</height> <height>618</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout" name="verticalLayout_5">
@ -96,6 +96,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0">
<widget class="QCheckBox" name="filterAudio">
<property name="text">
<string>Filter audio</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>