Audio call reception

Can hear, but can't talk

Uses a hardwired tox_do() interval of 50ms until to_do_interval() gets fixed
pull/9/head^2
Tux3 / Mlkj / !Lev.uXFMLA 2014-06-27 18:51:08 +02:00
parent 749f4c9ed7
commit f5a628fafb
5 changed files with 94 additions and 19 deletions

36
audiobuffer.cpp Normal file
View File

@ -0,0 +1,36 @@
#include "audiobuffer.h"
AudioBuffer::AudioBuffer() :
QIODevice(0)
{
open(QIODevice::ReadOnly);
}
AudioBuffer::~AudioBuffer()
{
close();
}
qint64 AudioBuffer::readData(char *data, qint64 len)
{
const qint64 total = qMin((qint64)buffer.size(), len);
memcpy(data, buffer.constData(), total);
buffer = buffer.mid(total);
return total;
}
qint64 AudioBuffer::writeData(const char* data, qint64 len)
{
buffer.append(data, len);
return 0;
}
qint64 AudioBuffer::bytesAvailable() const
{
return buffer.size() + QIODevice::bytesAvailable();
}
qint64 AudioBuffer::bufferSize() const
{
return buffer.size();
}

23
audiobuffer.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef AUDIOBUFFER_H
#define AUDIOBUFFER_H
#include <QIODevice>
#include <QByteArray>
class AudioBuffer : public QIODevice
{
Q_OBJECT
public:
explicit AudioBuffer();
~AudioBuffer();
qint64 readData(char *data, qint64 maxlen);
qint64 writeData(const char *data, qint64 len);
qint64 bytesAvailable() const;
qint64 bufferSize() const;
private:
QByteArray buffer;
};
#endif // AUDIOBUFFER_H

View File

@ -17,6 +17,7 @@
#include "core.h"
#include "cdata.h"
#include "cstring.h"
#include "settings.h"
#include <QDebug>
#include <QDir>
@ -27,8 +28,6 @@
#include <QThread>
#include <QtConcurrent/QtConcurrent>
#include "settings.h"
const QString Core::CONFIG_FILE_NAME = "tox_save";
QList<ToxFile> Core::fileSendQueue;
QList<ToxFile> Core::fileRecvQueue;
@ -623,7 +622,9 @@ void Core::process()
fflush(stdout);
#endif
checkConnection();
toxTimer->start(tox_do_interval(tox));
int toxInterval = tox_do_interval(tox);
//qDebug() << QString("Tox interval %1").arg(toxInterval);
toxTimer->start(50);
}
void Core::checkConnection()
@ -1027,7 +1028,6 @@ 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;
@ -1047,11 +1047,16 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav)
calls[callId].audioOutput = new QAudioOutput(format);
calls[callId].active = true;
QtConcurrent::run(playCallAudio, callId, toxav);
calls[callId].audioOutput->setBufferSize(24000);
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";
}
else
qDebug() << QString("Core: Audio started, buffer size %1").arg(calls[callId].audioOutput->bufferSize());
QtConcurrent::run(playCallAudio, callId, toxav);
}
void Core::cleanupCall(int callId)
@ -1062,7 +1067,6 @@ void Core::cleanupCall(int callId)
{
delete calls[callId].audioOutput;
}
calls[callId].audioBuffer.close();
}
void Core::playCallAudio(int callId, ToxAv* toxav)
@ -1070,25 +1074,34 @@ 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);
uint8_t buf[framesize*2];
int len = toxav_recv_audio(toxav, callId, framesize, (int16_t*)buf);
qDebug() << QString("Core: Received %1 audio bytes").arg(len);
if (len < 0)
{
qDebug() << "Core::playCallAudio: Error receiving audio";
QThread::msleep(calls[callId].codecSettings.audio_frame_duration / 2);
qDebug() << QString("Core::playCallAudio: Error receiving audio: %1").arg(len);
QThread::msleep(5);
continue;
}
if (len == 0)
{
qApp->processEvents();
QThread::msleep(5);
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();
}
//qDebug() << QString("Core: Received %1 bytes, %2 audio bytes free, %3 core buffer size")
//.arg(len*2).arg(calls[callId].audioOutput->bytesFree()).arg(calls[callId].audioBuffer.bufferSize());
calls[callId].audioBuffer.writeData((char*)buf, len*2);
int state = calls[callId].audioOutput->state();
if (state != QAudio::ActiveState)
{
qDebug() << QString("Core: Audio state is %1").arg(state);
}
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);
QThread::msleep(5);
}
}

5
core.h
View File

@ -18,6 +18,7 @@
#define CORE_HPP
#include "status.h"
#include "audiobuffer.h"
#include <tox/tox.h>
#include <tox/toxav.h>
@ -33,7 +34,7 @@
#include <QBuffer>
#include <QAudioOutput>
#define TOXAV_MAX_CALLS 32
#define TOXAV_MAX_CALLS 16
#define GROUPCHAT_MAX_SIZE 32
#define TOX_SAVE_INTERVAL 30*1000
#define TOX_FILE_INTERVAL 20
@ -82,7 +83,7 @@ struct ToxFile
struct ToxCall
{
public:
QBuffer audioBuffer;
AudioBuffer audioBuffer;
QAudioOutput* audioOutput;
ToxAvCodecSettings codecSettings;
int callId;

View File

@ -33,7 +33,8 @@ HEADERS += widget/form/addfriendform.h \
core.h \
friendlist.h \
cdata.h \
cstring.h
cstring.h \
audiobuffer.h
FORMS += widget.ui
@ -68,4 +69,5 @@ SOURCES += \
settings.cpp \
status.cpp \
cdata.cpp \
cstring.cpp
cstring.cpp \
audiobuffer.cpp