mirror of https://github.com/qTox/qTox.git
9 changed files with 359 additions and 246 deletions
@ -0,0 +1,176 @@
@@ -0,0 +1,176 @@
|
||||
#include "src/audio/audio.h" |
||||
#include "src/core/toxcall.h" |
||||
#include "src/core/coreav.h" |
||||
#include "src/persistence/settings.h" |
||||
#include "src/video/camerasource.h" |
||||
#include "src/video/corevideosource.h" |
||||
#include <QTimer> |
||||
|
||||
#ifdef QTOX_FILTER_AUDIO |
||||
#include "src/audio/audiofilterer.h" |
||||
#endif |
||||
|
||||
using namespace std; |
||||
|
||||
ToxCall::ToxCall(uint32_t CallId) |
||||
: sendAudioTimer{new QTimer}, callId{CallId}, |
||||
inactive{true}, muteMic{false}, muteVol{false}, alSource{0} |
||||
{ |
||||
sendAudioTimer->setInterval(5); |
||||
sendAudioTimer->setSingleShot(true); |
||||
|
||||
Audio::getInstance().subscribeInput(); |
||||
|
||||
#ifdef QTOX_FILTER_AUDIO |
||||
if (Settings::getInstance().getFilterAudio()) |
||||
{ |
||||
filterer = new AudioFilterer(); |
||||
filterer->startFilter(AUDIO_SAMPLE_RATE); |
||||
} |
||||
else |
||||
{ |
||||
filterer = nullptr; |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
ToxCall::ToxCall(ToxCall&& other) |
||||
: sendAudioTimer{other.sendAudioTimer}, callId{other.callId}, |
||||
inactive{other.inactive}, muteMic{other.muteMic}, muteVol{other.muteVol}, |
||||
alSource{other.alSource} |
||||
{ |
||||
other.sendAudioTimer = nullptr; |
||||
other.callId = numeric_limits<decltype(callId)>::max(); |
||||
other.alSource = 0; |
||||
|
||||
#ifdef QTOX_FILTER_AUDIO |
||||
filterer = other.filterer; |
||||
other.filterer = nullptr; |
||||
#endif |
||||
} |
||||
|
||||
ToxCall::~ToxCall() |
||||
{ |
||||
if (sendAudioTimer) |
||||
{ |
||||
QObject::disconnect(sendAudioTimer, nullptr, nullptr, nullptr); |
||||
sendAudioTimer->stop(); |
||||
Audio::getInstance().unsubscribeInput(); |
||||
} |
||||
|
||||
if (alSource) |
||||
Audio::deleteSource(&alSource); |
||||
|
||||
#ifdef QTOX_FILTER_AUDIO |
||||
if (filterer) |
||||
delete filterer; |
||||
#endif |
||||
} |
||||
|
||||
const ToxCall& ToxCall::operator=(ToxCall&& other) |
||||
{ |
||||
sendAudioTimer = other.sendAudioTimer; |
||||
other.sendAudioTimer = nullptr; |
||||
callId = other.callId; |
||||
other.callId = numeric_limits<decltype(callId)>::max(); |
||||
inactive = other.inactive; |
||||
muteMic = other.muteMic; |
||||
muteVol = other.muteVol; |
||||
alSource = other.alSource; |
||||
other.alSource = 0; |
||||
|
||||
#ifdef QTOX_FILTER_AUDIO |
||||
filterer = other.filterer; |
||||
other.filterer = nullptr; |
||||
#endif |
||||
|
||||
return *this; |
||||
} |
||||
|
||||
ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av) |
||||
: ToxCall(FriendNum), |
||||
videoEnabled{VideoEnabled}, videoSource{nullptr}, |
||||
state{static_cast<TOXAV_FRIEND_CALL_STATE>(0)} |
||||
{ |
||||
auto audioTimerCopy = sendAudioTimer; // this might change after a move, but not sendAudioTimer
|
||||
QObject::connect(sendAudioTimer, &QTimer::timeout, [FriendNum,&av,audioTimerCopy]() |
||||
{ |
||||
// If sendCallAudio returns false, there was a serious error and we might as well stop the timer
|
||||
if (av.sendCallAudio(FriendNum)) |
||||
audioTimerCopy->start(); |
||||
}); |
||||
sendAudioTimer->start(); |
||||
|
||||
if (videoEnabled) |
||||
{ |
||||
videoSource = new CoreVideoSource; |
||||
CameraSource& source = CameraSource::getInstance(); |
||||
if (!source.isOpen()) |
||||
source.open(); |
||||
source.subscribe(); |
||||
QObject::connect(&source, &VideoSource::frameAvailable, |
||||
[FriendNum,&av](shared_ptr<VideoFrame> frame){av.sendCallVideo(FriendNum,frame);}); |
||||
} |
||||
} |
||||
|
||||
ToxFriendCall::ToxFriendCall(ToxFriendCall&& other) |
||||
: ToxCall(move(other)), |
||||
videoEnabled{other.videoEnabled}, videoSource{other.videoSource}, |
||||
state{other.state} |
||||
{ |
||||
other.videoEnabled = false; |
||||
other.videoSource = nullptr; |
||||
} |
||||
|
||||
ToxFriendCall::~ToxFriendCall() |
||||
{ |
||||
if (videoEnabled) |
||||
{ |
||||
CameraSource::getInstance().unsubscribe(); |
||||
if (videoSource) |
||||
{ |
||||
videoSource->setDeleteOnClose(true); |
||||
videoSource = nullptr; |
||||
} |
||||
} |
||||
} |
||||
|
||||
const ToxFriendCall& ToxFriendCall::operator=(ToxFriendCall&& other) |
||||
{ |
||||
ToxCall::operator =(move(other)); |
||||
videoEnabled = other.videoEnabled; |
||||
other.videoEnabled = false; |
||||
videoSource = other.videoSource; |
||||
other.videoSource = nullptr; |
||||
state = other.state; |
||||
|
||||
return *this; |
||||
} |
||||
|
||||
ToxGroupCall::ToxGroupCall(int GroupNum, CoreAV &av) |
||||
: ToxCall(static_cast<decltype(callId)>(GroupNum)) |
||||
{ |
||||
static_assert(numeric_limits<decltype(callId)>::max() >= numeric_limits<decltype(GroupNum)>::max(), |
||||
"The callId must be able to represent any group number, change its type if needed"); |
||||
|
||||
auto audioTimerCopy = sendAudioTimer; // this might change after a move, but not sendAudioTimer
|
||||
QObject::connect(sendAudioTimer, &QTimer::timeout, [GroupNum,&av,audioTimerCopy]() |
||||
{ |
||||
// If sendGroupCallAudio returns false, there was a serious error and we might as well stop the timer
|
||||
if (av.sendGroupCallAudio(GroupNum)) |
||||
audioTimerCopy->start(); |
||||
}); |
||||
sendAudioTimer->start(); |
||||
} |
||||
|
||||
ToxGroupCall::ToxGroupCall(ToxGroupCall&& other) |
||||
: ToxCall(move(other)) |
||||
{ |
||||
} |
||||
|
||||
const ToxGroupCall &ToxGroupCall::operator=(ToxGroupCall &&other) |
||||
{ |
||||
ToxCall::operator =(move(other)); |
||||
|
||||
return *this; |
||||
} |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
#ifndef TOXCALL_H |
||||
#define TOXCALL_H |
||||
|
||||
#include <cstdint> |
||||
#include "src/core/indexedlist.h" |
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__) |
||||
#include <OpenAL/al.h> |
||||
#include <OpenAL/alc.h> |
||||
#else |
||||
#include <AL/al.h> |
||||
#include <AL/alc.h> |
||||
#endif |
||||
|
||||
#include <tox/toxav.h> |
||||
|
||||
class QTimer; |
||||
class AudioFilterer; |
||||
class CoreVideoSource; |
||||
class CoreAV; |
||||
|
||||
struct ToxCall |
||||
{ |
||||
protected: |
||||
ToxCall() = default; |
||||
ToxCall(uint32_t CallId); |
||||
~ToxCall(); |
||||
public: |
||||
ToxCall(const ToxCall& other) = delete; |
||||
ToxCall(ToxCall&& other) noexcept; |
||||
|
||||
inline operator int() {return callId;} |
||||
const ToxCall& operator=(const ToxCall& other) = delete; |
||||
const ToxCall& operator=(ToxCall&& other) noexcept; |
||||
|
||||
protected: |
||||
QTimer* sendAudioTimer; |
||||
|
||||
public: |
||||
uint32_t callId; ///< Could be a friendNum or groupNum, must uniquely identify the call
|
||||
bool inactive; ///< True while we're not participating. (stopped group call, ringing but hasn't started yet, ...)
|
||||
bool muteMic; |
||||
bool muteVol; |
||||
ALuint alSource; |
||||
|
||||
#ifdef QTOX_FILTER_AUDIO |
||||
AudioFilterer* filterer; |
||||
#endif |
||||
}; |
||||
|
||||
struct ToxFriendCall : public ToxCall |
||||
{ |
||||
ToxFriendCall() = default; |
||||
ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av); |
||||
ToxFriendCall(ToxFriendCall&& other) noexcept; |
||||
~ToxFriendCall(); |
||||
|
||||
const ToxFriendCall& operator=(ToxFriendCall&& other) noexcept; |
||||
|
||||
bool videoEnabled; ///< True if our user asked for a video call, sending and recving
|
||||
CoreVideoSource* videoSource; |
||||
TOXAV_FRIEND_CALL_STATE state; ///< State of the peer (not ours!)
|
||||
}; |
||||
|
||||
struct ToxGroupCall : public ToxCall |
||||
{ |
||||
ToxGroupCall() = default; |
||||
ToxGroupCall(int GroupNum, CoreAV& av); |
||||
ToxGroupCall(ToxGroupCall&& other) noexcept; |
||||
|
||||
const ToxGroupCall& operator=(ToxGroupCall&& other) noexcept; |
||||
|
||||
// If you add something here, don't forget to override the ctors and move operators!
|
||||
}; |
||||
|
||||
#endif // TOXCALL_H
|
||||
|
Loading…
Reference in new issue