kopia lustrzana https://gitlab.com/eliggett/wfview
Merge remote-tracking branch 'origin/lan-alpha' into ui-enhance
commit
27815a7994
165
audiohandler.cpp
165
audiohandler.cpp
|
@ -4,14 +4,15 @@
|
|||
*/
|
||||
#include "audiohandler.h"
|
||||
|
||||
static int8_t uLawEncode(int16_t number)
|
||||
#define MULAW_BIAS 33
|
||||
#define MULAW_MAX 0x1fff
|
||||
|
||||
qint8 uLawEncode(qint16 number)
|
||||
{
|
||||
const uint16_t MULAW_MAX = 0x1FFF;
|
||||
const uint16_t MULAW_BIAS = 33;
|
||||
uint16_t mask = 0x1000;
|
||||
uint8_t sign = 0;
|
||||
uint8_t position = 12;
|
||||
uint8_t lsb = 0;
|
||||
quint16 mask = 0x1000;
|
||||
quint8 sign = 0;
|
||||
quint8 position = 12;
|
||||
quint8 lsb = 0;
|
||||
if (number < 0)
|
||||
{
|
||||
number = -number;
|
||||
|
@ -28,8 +29,25 @@ static int8_t uLawEncode(int16_t number)
|
|||
return (~(sign | ((position - 5) << 4) | lsb));
|
||||
}
|
||||
|
||||
/*
|
||||
qint16 uLawDecode(qint8 number)
|
||||
{
|
||||
quint8 sign = 0, position = 0;
|
||||
qint16 decoded = 0;
|
||||
number = ~number;
|
||||
if (number & 0x80)
|
||||
{
|
||||
number &= ~(1 << 7);
|
||||
sign = -1;
|
||||
}
|
||||
position = ((number & 0xF0) >> 4) + 5;
|
||||
decoded = ((1 << position) | ((number & 0x0F) << (position - 4))
|
||||
| (1 << (position - 5))) - MULAW_BIAS;
|
||||
return (sign == 0) ? (decoded) : (-(decoded));
|
||||
}
|
||||
*/
|
||||
|
||||
static qint16 uLawDecode(quint8 in)
|
||||
qint16 uLawDecode(const quint8 in)
|
||||
{
|
||||
static const qint16 ulaw_decode[256] = {
|
||||
-32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
|
||||
|
@ -64,12 +82,9 @@ static qint16 uLawDecode(quint8 in)
|
|||
244, 228, 212, 196, 180, 164, 148, 132,
|
||||
120, 112, 104, 96, 88, 80, 72, 64,
|
||||
56, 48, 40, 32, 24, 16, 8, 0 };
|
||||
if (in == 0x02) // MUZERO
|
||||
in = 0;
|
||||
return ulaw_decode[in];
|
||||
}
|
||||
|
||||
|
||||
audioHandler::audioHandler(QObject* parent) :
|
||||
QIODevice(parent),
|
||||
isInitialized(false),
|
||||
|
@ -80,7 +95,6 @@ audioHandler::audioHandler(QObject* parent) :
|
|||
isInput(0),
|
||||
volume(1.0f)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
audioHandler::~audioHandler()
|
||||
|
@ -167,25 +181,29 @@ void audioHandler::reinit()
|
|||
|
||||
// Calculate the minimum required audio buffer
|
||||
// This may need work depending on how it performs on other platforms.
|
||||
int audioBuffer = format.sampleRate() / 10;
|
||||
audioBuffer = audioBuffer * (format.sampleSize() / 8);
|
||||
//int audioBuffer = format.sampleRate() / 10;
|
||||
//audioBuffer = audioBuffer * (format.sampleSize() / 8);
|
||||
|
||||
if (this->isInput)
|
||||
{
|
||||
// (Re)initialize audio input
|
||||
delete audioInput;
|
||||
audioInput = Q_NULLPTR;
|
||||
if (audioInput != Q_NULLPTR)
|
||||
delete audioInput;
|
||||
audioInput = new QAudioInput(deviceInfo, format, this);
|
||||
audioInput->setBufferSize(audioBuffer);
|
||||
//audioInput->setBufferSize(audioBuffer);
|
||||
//audioInput->setNotifyInterval(20);
|
||||
|
||||
connect(audioInput, SIGNAL(notify()), SLOT(notified()));
|
||||
connect(audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||
|
||||
}
|
||||
else {
|
||||
// (Re)initialize audio output
|
||||
delete audioOutput;
|
||||
if (audioOutput != Q_NULLPTR)
|
||||
delete audioOutput;
|
||||
audioOutput = Q_NULLPTR;
|
||||
audioOutput = new QAudioOutput(deviceInfo, format, this);
|
||||
audioOutput->setBufferSize(audioBuffer);
|
||||
//audioOutput->setBufferSize(audioBuffer);
|
||||
connect(audioOutput, SIGNAL(notify()), SLOT(notified()));
|
||||
connect(audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||
}
|
||||
|
@ -193,8 +211,6 @@ void audioHandler::reinit()
|
|||
if (running) {
|
||||
this->start();
|
||||
}
|
||||
flush();
|
||||
|
||||
}
|
||||
|
||||
void audioHandler::start()
|
||||
|
@ -212,7 +228,6 @@ void audioHandler::start()
|
|||
else {
|
||||
this->open(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
buffer.clear(); // No buffer used on audioinput.
|
||||
|
||||
if (isInput) {
|
||||
|
@ -231,8 +246,6 @@ void audioHandler::setVolume(float volume)
|
|||
|
||||
void audioHandler::flush()
|
||||
{
|
||||
// Flushing buffers is a bit tricky...
|
||||
// Don't modify this unless you're sure
|
||||
qDebug() << this->metaObject()->className() << ": flush() running";
|
||||
this->stop();
|
||||
if (isInput) {
|
||||
|
@ -246,9 +259,12 @@ void audioHandler::flush()
|
|||
|
||||
void audioHandler::stop()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
if (audioOutput && audioOutput->state() != QAudio::StoppedState) {
|
||||
// Stop audio output
|
||||
audioOutput->stop();
|
||||
QByteArray ret;
|
||||
|
||||
buffer.clear();
|
||||
this->close();
|
||||
}
|
||||
|
@ -265,49 +281,51 @@ qint64 audioHandler::readData(char* data, qint64 maxlen)
|
|||
{
|
||||
// Calculate output length, always full samples
|
||||
int outlen = 0;
|
||||
if (isUlaw)
|
||||
if (radioSampleBits == 8)
|
||||
{
|
||||
// Need to process uLaw.
|
||||
// Input buffer is 8bit and output buffer is 16bit
|
||||
outlen = qMin(buffer.length(), (int)maxlen / 2);
|
||||
for (int f = 0; f < outlen; f++)
|
||||
for (quint16 f = 0; f < outlen; f++)
|
||||
{
|
||||
qToLittleEndian<qint16>(uLawDecode(buffer.at(f)), data + f * 2);
|
||||
if (isUlaw)
|
||||
qToLittleEndian<qint16>(uLawDecode(buffer.at(f)), data + (f * 2));
|
||||
else
|
||||
qToLittleEndian<qint16>((qint16)(buffer[f] << 8) - 32640, data + (f * 2));
|
||||
}
|
||||
QMutexLocker locker(&mutex);
|
||||
buffer.remove(0, outlen);
|
||||
outlen = outlen * 2;
|
||||
}
|
||||
else {
|
||||
if (radioSampleBits == 8)
|
||||
{
|
||||
outlen = qMin(buffer.length(), (int)maxlen/2);
|
||||
for (int f = 0; f < outlen; f++)
|
||||
{
|
||||
qToLittleEndian<qint16>((qint16)(buffer[f]<<8) - 32640, data + f * 2);
|
||||
}
|
||||
buffer.remove(0, outlen);
|
||||
outlen = outlen * 2;
|
||||
} else {
|
||||
// Just copy it.
|
||||
outlen = qMin(buffer.length(), (int)maxlen);
|
||||
if (outlen % 2 != 0) {
|
||||
outlen += 1;
|
||||
}
|
||||
memcpy(data, buffer.data(), outlen);
|
||||
else if (radioSampleBits == 16) {
|
||||
// Just copy it
|
||||
outlen = qMin(buffer.length(), (int)maxlen);
|
||||
if (outlen % 2 != 0) {
|
||||
outlen += 1; // Not sure if this is necessary as we should always have an even number!
|
||||
}
|
||||
memcpy(data, buffer.data(), outlen);
|
||||
QMutexLocker locker(&mutex);
|
||||
buffer.remove(0, outlen);
|
||||
}
|
||||
|
||||
else {
|
||||
qDebug() << "Sample bits MUST be 8 or 16 - got: " << radioSampleBits; // Should never happen?
|
||||
}
|
||||
return outlen;
|
||||
}
|
||||
|
||||
qint64 audioHandler::writeData(const char* data, qint64 len)
|
||||
{
|
||||
int chunkSize = 960; // Assume 8bit or uLaw.
|
||||
|
||||
QMutexLocker locker(&mutex);
|
||||
if (buffer.length() > bufferSize * 4)
|
||||
{
|
||||
qWarning() << "writeData() Buffer overflow";
|
||||
buffer.clear(); // Will cause a click!
|
||||
}
|
||||
|
||||
if (isUlaw) {
|
||||
for (int f = 0; f < len / 2; f++)
|
||||
{
|
||||
buffer.append(uLawEncode(qFromLittleEndian<qint16>(data + f * 2)));
|
||||
buffer.append((quint8)uLawEncode(qFromLittleEndian<qint16>(data + f * 2)));
|
||||
}
|
||||
}
|
||||
else if (radioSampleBits == 8) {
|
||||
|
@ -318,16 +336,12 @@ qint64 audioHandler::writeData(const char* data, qint64 len)
|
|||
}
|
||||
else if (radioSampleBits == 16) {
|
||||
buffer.append(QByteArray::fromRawData(data, len));
|
||||
chunkSize = 1920;
|
||||
}
|
||||
else {
|
||||
qWarning() << "Unsupported number of bits! :" << radioSampleBits;
|
||||
}
|
||||
|
||||
while (buffer.length() >= chunkSize)
|
||||
{
|
||||
emit haveAudioData(buffer.mid(0, chunkSize));
|
||||
buffer.remove(0, chunkSize);
|
||||
if (buffer.size() >= radioSampleBits * 120) {
|
||||
chunkAvailable = true;
|
||||
}
|
||||
return (len); // Always return the same number as we received
|
||||
}
|
||||
|
@ -346,15 +360,18 @@ void audioHandler::notified()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioHandler::stateChanged(QAudio::State state)
|
||||
{
|
||||
if (state == QAudio::IdleState && audioOutput->error() == QAudio::UnderrunError) {
|
||||
qDebug() << this->metaObject()->className() << ":Buffer underrun";
|
||||
if (buffer.length() < bufferSize) {
|
||||
audioOutput->suspend();
|
||||
}
|
||||
qDebug() << this->metaObject()->className() << "RX:Buffer underrun";
|
||||
//if (buffer.length() < bufferSize) {
|
||||
// audioOutput->suspend();
|
||||
//}
|
||||
}
|
||||
qDebug() << this->metaObject()->className() << ": state = " << state;
|
||||
//qDebug() << this->metaObject()->className() << ": state = " << state;
|
||||
}
|
||||
|
||||
|
||||
|
@ -362,21 +379,13 @@ void audioHandler::stateChanged(QAudio::State state)
|
|||
void audioHandler::incomingAudio(const QByteArray& data)
|
||||
{
|
||||
//qDebug() << "Got " << data.length() << " samples";
|
||||
QMutexLocker locker(&mutex);
|
||||
if (audioOutput != Q_NULLPTR && audioOutput->state() != QAudio::StoppedState) {
|
||||
// Append input data to the end of buffer
|
||||
QMutexLocker locker(&mutex);
|
||||
buffer.append(data);
|
||||
|
||||
//if (buffer.length() > bufferSize*2) {
|
||||
// this->flush();
|
||||
//}
|
||||
|
||||
// If audio is suspended and buffer is full, resume
|
||||
if (audioOutput->state() == QAudio::SuspendedState) {
|
||||
if (buffer.length() >= bufferSize) {
|
||||
qDebug() << this->metaObject()->className() << ": Resuming...";
|
||||
audioOutput->resume();
|
||||
}
|
||||
qDebug() << "RX Audio Suspended, Resuming...";
|
||||
audioOutput->resume();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -389,7 +398,6 @@ void audioHandler::changeBufferSize(const quint16 newSize)
|
|||
QMutexLocker locker(&mutex);
|
||||
qDebug() << this->metaObject()->className() << ": Changing buffer size to: " << newSize << " from " << bufferSize;
|
||||
bufferSize = newSize;
|
||||
flush();
|
||||
}
|
||||
|
||||
void audioHandler::getBufferSize()
|
||||
|
@ -397,5 +405,20 @@ void audioHandler::getBufferSize()
|
|||
emit sendBufferSize(audioOutput->bufferSize());
|
||||
}
|
||||
|
||||
void audioHandler::getNextAudioChunk(QByteArray& ret)
|
||||
{
|
||||
quint16 numSamples = radioSampleBits * 120;
|
||||
if (buffer.size() >= numSamples) {
|
||||
QMutexLocker locker(&mutex);
|
||||
ret.append(buffer.mid(0, numSamples));
|
||||
buffer.remove(0, numSamples);
|
||||
}
|
||||
if (buffer.size() < numSamples)
|
||||
{
|
||||
chunkAvailable = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <QAudioInput>
|
||||
#include <QIODevice>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
@ -39,10 +40,12 @@ public:
|
|||
qint64 writeData(const char* data, qint64 len);
|
||||
qint64 bytesAvailable() const;
|
||||
bool isSequential() const;
|
||||
volatile bool chunkAvailable;
|
||||
void incomingAudio(const QByteArray& data);
|
||||
void getNextAudioChunk(QByteArray &data);
|
||||
|
||||
public slots:
|
||||
bool init(const quint8 bits, const quint8 channels, const quint16 samplerate, const quint16 bufferSize, const bool isulaw, const bool isinput);
|
||||
void incomingAudio(const QByteArray& data);
|
||||
void changeBufferSize(const quint16 newSize);
|
||||
|
||||
private slots:
|
||||
|
@ -54,6 +57,7 @@ signals:
|
|||
void sendBufferSize(quint16 newSize);
|
||||
void haveAudioData(const QByteArray& data);
|
||||
|
||||
|
||||
private:
|
||||
void reinit();
|
||||
|
||||
|
@ -73,6 +77,7 @@ private:
|
|||
quint16 radioSampleRate;
|
||||
quint8 radioSampleBits;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // AUDIOHANDLER_H
|
||||
|
|
|
@ -498,7 +498,7 @@ void udpSerial::DataReceived()
|
|||
pkt7Timer->start(3000); // send pkt7 idle packets every 3 seconds
|
||||
|
||||
pkt0Timer = new QTimer(this);
|
||||
connect(pkt0Timer, &QTimer::timeout, this, std::bind(&udpBase::SendPkt0Idle,this,true,0));
|
||||
connect(pkt0Timer, &QTimer::timeout, this, std::bind(&udpBase::SendPkt0Idle, this, true, 0));
|
||||
pkt0Timer->start(100);
|
||||
|
||||
periodicRunning = true;
|
||||
|
@ -584,7 +584,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 b
|
|||
rxaudio->moveToThread(rxAudioThread);
|
||||
|
||||
connect(this, SIGNAL(setupRxAudio(quint8, quint8, quint16, quint16, bool, bool)), rxaudio, SLOT(init(quint8, quint8, quint16, quint16, bool, bool)));
|
||||
connect(this, SIGNAL(haveAudioData(QByteArray)), rxaudio, SLOT(incomingAudio(QByteArray)));
|
||||
//connect(this, SIGNAL(haveAudioData(QByteArray)), rxaudio, SLOT(incomingAudio(QByteArray)));
|
||||
connect(this, SIGNAL(haveChangeBufferSize(quint16)), rxaudio, SLOT(changeBufferSize(quint16)));
|
||||
connect(rxAudioThread, SIGNAL(finished()), rxaudio, SLOT(deleteLater()));
|
||||
|
||||
|
@ -601,7 +601,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 b
|
|||
txaudio->moveToThread(txAudioThread);
|
||||
|
||||
connect(this, SIGNAL(setupTxAudio(quint8, quint8, quint16, quint16, bool, bool)), txaudio, SLOT(init(quint8, quint8, quint16, quint16, bool, bool)));
|
||||
connect(txaudio, SIGNAL(haveAudioData(QByteArray)), this, SLOT(sendTxAudio(QByteArray)));
|
||||
//connect(txaudio, SIGNAL(haveAudioData(QByteArray)), this, SLOT(sendTxAudio(QByteArray)));
|
||||
connect(txAudioThread, SIGNAL(finished()), txaudio, SLOT(deleteLater()));
|
||||
|
||||
rxAudioThread->start();
|
||||
|
@ -624,36 +624,46 @@ udpAudio::~udpAudio()
|
|||
txAudioThread->quit();
|
||||
txAudioThread->wait();
|
||||
}
|
||||
if (txAudioTimer != Q_NULLPTR)
|
||||
{
|
||||
txAudioTimer->stop();
|
||||
delete txAudioTimer;
|
||||
}
|
||||
}
|
||||
|
||||
void udpAudio::sendTxAudio(QByteArray audio)
|
||||
|
||||
|
||||
|
||||
void udpAudio::sendTxAudio()
|
||||
{
|
||||
quint8 p[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(localSID >> 24 & 0xff), static_cast<quint8>(localSID >> 16 & 0xff), static_cast<quint8>(localSID >> 8 & 0xff), static_cast<quint8>(localSID & 0xff),
|
||||
static_cast<quint8>(remoteSID >> 24 & 0xff), static_cast<quint8>(remoteSID >> 16 & 0xff), static_cast<quint8>(remoteSID >> 8 & 0xff), static_cast<quint8>(remoteSID & 0xff),
|
||||
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
int counter = 0;
|
||||
if (((txCodec == 0x01 || txCodec == 0x02) && audio.length() != 960) || (txCodec == 0x04 && audio.length() != 1920)) {
|
||||
qDebug() << "Unsupported TX audio length :" << audio.length() << " With codec: " << txCodec;
|
||||
//if (((txCodec == 0x01 || txCodec == 0x02) && audio.length() != 960) || (txCodec == 0x04 && audio.length() != 1920)) {
|
||||
// qDebug() << "Unsupported TX audio length :" << audio.length() << " With codec: " << txCodec;
|
||||
//}
|
||||
if (txaudio->chunkAvailable) {
|
||||
QByteArray audio;
|
||||
txaudio->getNextAudioChunk(audio);
|
||||
int counter = 0;
|
||||
while (counter < audio.length()) {
|
||||
QByteArray tx = QByteArray::fromRawData((const char*)p, sizeof(p));
|
||||
QByteArray partial = audio.mid(counter, 1364);
|
||||
tx.append(partial);
|
||||
tx[0] = static_cast<quint8>(tx.length() & 0xff);
|
||||
tx[1] = static_cast<quint8>(tx.length() >> 8 & 0xff);
|
||||
tx[18] = static_cast<quint8>(sendAudioSeq >> 8 & 0xff);
|
||||
tx[19] = static_cast<quint8>(sendAudioSeq & 0xff);
|
||||
tx[22] = static_cast<quint8>(partial.length() >> 8 & 0xff);
|
||||
tx[23] = static_cast<quint8>(partial.length() & 0xff);
|
||||
counter = counter + partial.length();
|
||||
//qDebug() << "Sending audio packet length: " << tx.length();
|
||||
SendTrackedPacket(tx);
|
||||
sendAudioSeq++;
|
||||
}
|
||||
}
|
||||
while (counter < audio.length())
|
||||
{
|
||||
QByteArray tx = QByteArray::fromRawData((const char*)p, sizeof(p));
|
||||
QByteArray partial = audio.mid(counter, 1364);
|
||||
tx.append(partial);
|
||||
tx[0] = static_cast<quint8>(tx.length() & 0xff);
|
||||
tx[1] = static_cast<quint8>(tx.length() >> 8 & 0xff);
|
||||
tx[18] = static_cast<quint8>(sendAudioSeq >> 8 & 0xff);
|
||||
tx[19] = static_cast<quint8>(sendAudioSeq & 0xff);
|
||||
tx[22] = static_cast<quint8>(partial.length() >> 8 & 0xff);
|
||||
tx[23] = static_cast<quint8>(partial.length() & 0xff);
|
||||
counter = counter + partial.length();
|
||||
//qDebug() << "Sending audio packet length: " << tx.length();
|
||||
SendTrackedPacket(tx);
|
||||
sendAudioSeq++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void udpAudio::changeBufferSize(quint16 value)
|
||||
|
@ -661,6 +671,8 @@ void udpAudio::changeBufferSize(quint16 value)
|
|||
emit haveChangeBufferSize(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void udpAudio::DataReceived()
|
||||
{
|
||||
while (udp->hasPendingDatagrams()) {
|
||||
|
@ -677,9 +689,14 @@ void udpAudio::DataReceived()
|
|||
remoteSID = qFromBigEndian<quint32>(r.mid(8, 4));
|
||||
if (!periodicRunning) {
|
||||
periodicRunning = true;
|
||||
|
||||
pkt7Timer = new QTimer(this);
|
||||
connect(pkt7Timer, &QTimer::timeout, this, &udpBase::SendPkt7Idle);
|
||||
pkt7Timer->start(3000); // send pkt7 idle packets every 3 seconds
|
||||
|
||||
txAudioTimer = new QTimer(this);
|
||||
connect(txAudioTimer, &QTimer::timeout, this, &udpAudio::sendTxAudio);
|
||||
txAudioTimer->start(10); // send pkt7 idle packets every 3 seconds
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -711,7 +728,7 @@ void udpAudio::DataReceived()
|
|||
|
||||
lastReceivedSeq = gotSeq;
|
||||
|
||||
emit haveAudioData(r.mid(24));
|
||||
rxaudio->incomingAudio(r.mid(24));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
14
udphandler.h
14
udphandler.h
|
@ -69,7 +69,7 @@ public:
|
|||
quint16 port=0;
|
||||
QTimer *pkt7Timer=Q_NULLPTR; // Send pkt7 packets every 3 seconds
|
||||
QTimer *pkt0Timer=Q_NULLPTR; // Send pkt0 packets every 1000ms.
|
||||
QTimer *periodic=Q_NULLPTR; // Send pkt0 packets every 1000ms.
|
||||
QTimer* periodic = Q_NULLPTR; // Send pkt0 packets every 1000ms.
|
||||
bool periodicRunning = false;
|
||||
bool sentPacketConnect2 = false;
|
||||
time_t lastReceived = time(0);
|
||||
|
@ -132,10 +132,10 @@ signals:
|
|||
|
||||
public slots:
|
||||
void changeBufferSize(quint16 value);
|
||||
void sendTxAudio(QByteArray d);
|
||||
|
||||
private:
|
||||
|
||||
void sendTxAudio();
|
||||
void DataReceived();
|
||||
QAudioFormat format;
|
||||
quint16 bufferSize;
|
||||
|
@ -153,11 +153,13 @@ private:
|
|||
bool sentPacketConnect2 = false;
|
||||
uint16_t sendAudioSeq = 0;
|
||||
|
||||
audioHandler* rxaudio;
|
||||
QThread* rxAudioThread;
|
||||
audioHandler* rxaudio=Q_NULLPTR;
|
||||
QThread* rxAudioThread=Q_NULLPTR;
|
||||
|
||||
audioHandler* txaudio;
|
||||
QThread* txAudioThread;
|
||||
audioHandler* txaudio=Q_NULLPTR;
|
||||
QThread* txAudioThread=Q_NULLPTR;
|
||||
|
||||
QTimer* txAudioTimer=Q_NULLPTR;
|
||||
|
||||
};
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue