mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
EXPERIMENTAL audio reception in calls
As in, some sounds comes out of your speakers
This commit is contained in:
parent
6114cb66c6
commit
b8af78be32
94
core.cpp
94
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<ToxFile> Core::fileSendQueue;
|
||||
QList<ToxFile> 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*>(core)->toxav);
|
||||
|
||||
emit static_cast<Core*>(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*>(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*>(core)->toxav);
|
||||
|
||||
emit static_cast<Core*>(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*>(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);
|
||||
}
|
||||
}
|
||||
|
|
26
core.h
26
core.h
|
@ -30,6 +30,15 @@
|
|||
#include <QList>
|
||||
#include <QByteArray>
|
||||
#include <QFuture>
|
||||
#include <QBuffer>
|
||||
#include <QAudioOutput>
|
||||
|
||||
#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<void> 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<DhtServer> dhtServerList;
|
||||
int dhtServerId;
|
||||
static QList<ToxFile> fileSendQueue, fileRecvQueue;
|
||||
static ToxCall calls[TOXAV_MAX_CALLS];
|
||||
|
||||
static const QString CONFIG_FILE_NAME;
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
QT += core gui multimedia
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user