From b8af78be326f9fed93be4b9c65a28971ccfe193e Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 27 Jun 2014 15:16:39 +0200 Subject: [PATCH] EXPERIMENTAL audio reception in calls As in, some sounds comes out of your speakers --- core.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++---- core.h | 26 +++++++++++++++ toxgui.pro | 2 +- 3 files changed, 114 insertions(+), 8 deletions(-) diff --git a/core.cpp b/core.cpp index acfa0b150..de6fe8306 100644 --- a/core.cpp +++ b/core.cpp @@ -29,16 +29,10 @@ #include "settings.h" -#define GROUPCHAT_MAX_SIZE 32 -#define TOX_SAVE_INTERVAL 30*1000 -#define TOX_FILE_INTERVAL 20 -#define TOX_BOOTSTRAP_INTERVAL 10*1000 -#define TOXAV_MAX_CALLS 32 -#define TOXAV_RINGING_TIME 15 - const QString Core::CONFIG_FILE_NAME = "tox_save"; QList Core::fileSendQueue; QList Core::fileRecvQueue; +ToxCall Core::calls[TOXAV_MAX_CALLS]; Core::Core() : tox(nullptr) @@ -899,6 +893,8 @@ void Core::onAvStart(int32_t call_index, void* core) } qDebug() << QString("Core: AV start from %1").arg(friendId); + prepareCall(friendId, call_index, static_cast(core)->toxav); + emit static_cast(core)->avStart(friendId, call_index); } @@ -930,6 +926,8 @@ void Core::onAvEnd(int32_t call_index, void* core) } qDebug() << QString("Core: AV end from %1").arg(friendId); + cleanupCall(call_index); + emit static_cast(core)->avEnd(friendId, call_index); } @@ -956,6 +954,8 @@ void Core::onAvStarting(int32_t call_index, void* core) } qDebug() << QString("Core: AV starting %1").arg(friendId); + prepareCall(friendId, call_index, static_cast(core)->toxav); + emit static_cast(core)->avStarting(friendId, call_index); } @@ -969,6 +969,8 @@ void Core::onAvEnding(int32_t call_index, void* core) } qDebug() << QString("Core: AV ending from %1").arg(friendId); + cleanupCall(call_index); + emit static_cast(core)->avEnding(friendId, call_index); } @@ -1019,3 +1021,81 @@ void Core::cancelCall(int callId, int friendId) qDebug() << QString("Core: Cancelling call with %1").arg(friendId); toxav_cancel(toxav, callId, friendId, 0); } + +void Core::prepareCall(int friendId, int callId, ToxAv* toxav) +{ + qDebug() << QString("Core: preparing call %1").arg(callId); + calls[callId].callId = callId; + calls[callId].friendId = friendId; + calls[callId].audioBuffer.open(QBuffer::ReadWrite); + calls[callId].codecSettings = av_DefaultSettings; + toxav_prepare_transmission(toxav, callId, &calls[callId].codecSettings, false); + QAudioFormat format; + format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); + format.setChannelCount(calls[callId].codecSettings.audio_channels); + format.setSampleSize(16); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::SignedInt); + QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); + if (!info.isFormatSupported(format)) { + calls[callId].audioOutput = nullptr; + qWarning() << "Core: Raw audio format not supported by backend, cannot play audio."; + return; + } + + calls[callId].audioOutput = new QAudioOutput(format); + calls[callId].active = true; + + QtConcurrent::run(playCallAudio, callId, toxav); + calls[callId].audioOutput->start(&calls[callId].audioBuffer); + if (calls[callId].audioOutput->state() == QAudio::StoppedState + && calls[callId].audioOutput->error() == QAudio::OpenError) + qWarning() << "Core: Unable to start audio"; +} + +void Core::cleanupCall(int callId) +{ + qDebug() << QString("Core: cleaning up call %1").arg(callId); + calls[callId].active = false; + if (calls[callId].audioOutput != nullptr) + { + delete calls[callId].audioOutput; + } + calls[callId].audioBuffer.close(); +} + +void Core::playCallAudio(int callId, ToxAv* toxav) +{ + while (calls[callId].active) + { + int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000; + int16_t buf[framesize]; + int len = toxav_recv_audio(toxav, callId, framesize, buf); + if (len < 0) + { + qDebug() << "Core::playCallAudio: Error receiving audio"; + QThread::msleep(calls[callId].codecSettings.audio_frame_duration / 2); + continue; + } + if (len == 0) + continue; + qDebug() << QString("Core::playCallAudio: Playing %1 frames/sample").arg(len); + calls[callId].audioBuffer.write((char*)buf, len*2); + calls[callId].audioBuffer.seek(0); + calls[callId].audioOutput->resume(); + int error = calls[callId].audioOutput->error(); + if (error != QAudio::NoError) + qWarning() << QString("Core::playCallAudio: Error: %1").arg(error); + + QThread::msleep(calls[callId].codecSettings.audio_frame_duration / 2); + } +} + +void Core::sendCallAudio(int callId, ToxAv* toxav) +{ + while (calls[callId].active) + { + QThread::msleep(calls[callId].codecSettings.audio_frame_duration / 2); + } +} diff --git a/core.h b/core.h index 7ea1fe1aa..197ccc480 100644 --- a/core.h +++ b/core.h @@ -30,6 +30,15 @@ #include #include #include +#include +#include + +#define TOXAV_MAX_CALLS 32 +#define GROUPCHAT_MAX_SIZE 32 +#define TOX_SAVE_INTERVAL 30*1000 +#define TOX_FILE_INTERVAL 20 +#define TOX_BOOTSTRAP_INTERVAL 10*1000 +#define TOXAV_RINGING_TIME 15 struct DhtServer { @@ -70,6 +79,17 @@ struct ToxFile QFuture sendFuture; }; +struct ToxCall +{ +public: + QBuffer audioBuffer; + QAudioOutput* audioOutput; + ToxAvCodecSettings codecSettings; + int callId; + int friendId; + bool active; +}; + class Core : public QObject { Q_OBJECT @@ -208,6 +228,11 @@ private: static void onAvRequestTimeout(int32_t call_index, void* toxav); static void onAvPeerTimeout(int32_t call_index, void* toxav); + static void prepareCall(int friendId, int callId, ToxAv *toxav); + static void cleanupCall(int callId); + static void playCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread + static void sendCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread + void checkConnection(); void onBootstrapTimer(); @@ -227,6 +252,7 @@ private: QList dhtServerList; int dhtServerId; static QList fileSendQueue, fileRecvQueue; + static ToxCall calls[TOXAV_MAX_CALLS]; static const QString CONFIG_FILE_NAME; }; diff --git a/toxgui.pro b/toxgui.pro index 3911304db..8f5246083 100644 --- a/toxgui.pro +++ b/toxgui.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += core gui +QT += core gui multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets