kopia lustrzana https://gitlab.com/eliggett/wfview
Use signal/slot for audio signal reporting
rodzic
cfc22dcb30
commit
f00051ecd4
|
@ -124,9 +124,11 @@ bool audioHandler::init(audioSetup setupIn)
|
||||||
|
|
||||||
if (setup.isinput) {
|
if (setup.isinput) {
|
||||||
audioInput = new QAudioInput(setup.port, format, this);
|
audioInput = new QAudioInput(setup.port, format, this);
|
||||||
|
connect(audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
audioOutput = new QAudioOutput(setup.port, format, this);
|
audioOutput = new QAudioOutput(setup.port, format, this);
|
||||||
|
connect(audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup resampler and opus if they are needed.
|
// Setup resampler and opus if they are needed.
|
||||||
|
@ -357,7 +359,6 @@ void audioHandler::incomingAudio(audioPacket inPacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
currentLatency = livePacket.time.msecsTo(QTime::currentTime()) + getAudioDuration(audioOutput->bufferSize()-audioOutput->bytesFree(),format);
|
currentLatency = livePacket.time.msecsTo(QTime::currentTime()) + getAudioDuration(audioOutput->bufferSize()-audioOutput->bytesFree(),format);
|
||||||
|
|
||||||
if (audioDevice != Q_NULLPTR) {
|
if (audioDevice != Q_NULLPTR) {
|
||||||
audioDevice->write(livePacket.data);
|
audioDevice->write(livePacket.data);
|
||||||
}
|
}
|
||||||
|
@ -370,6 +371,8 @@ void audioHandler::incomingAudio(audioPacket inPacket)
|
||||||
lastSentSeq = inPacket.seq;
|
lastSentSeq = inPacket.seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit haveLevels(getAmplitude(), setup.latency, currentLatency,isUnderrun);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,6 +528,9 @@ void audioHandler::getNextAudioChunk(QByteArray& ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -555,3 +561,46 @@ quint16 audioHandler::getAmplitude()
|
||||||
return static_cast<quint16>(amplitude * 255.0);
|
return static_cast<quint16>(amplitude * 255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void audioHandler::stateChanged(QAudio::State state)
|
||||||
|
{
|
||||||
|
// Process the state
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case QAudio::IdleState:
|
||||||
|
{
|
||||||
|
isUnderrun = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QAudio::ActiveState:
|
||||||
|
{
|
||||||
|
//qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio started!";
|
||||||
|
if (underTimer == Q_NULLPTR) {
|
||||||
|
underTimer = new QTimer();
|
||||||
|
underTimer->setSingleShot(true);
|
||||||
|
connect(underTimer, &QTimer::timeout, this, &audioHandler::clearUnderrun);
|
||||||
|
underTimer->start(500);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QAudio::SuspendedState:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QAudio::StoppedState:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void audioHandler::clearUnderrun()
|
||||||
|
{
|
||||||
|
isUnderrun = false;
|
||||||
|
delete underTimer;
|
||||||
|
underTimer = Q_NULLPTR;
|
||||||
|
}
|
|
@ -95,16 +95,18 @@ public slots:
|
||||||
void incomingAudio(const audioPacket data);
|
void incomingAudio(const audioPacket data);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void stateChanged(QAudio::State state);
|
||||||
|
void clearUnderrun();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void audioMessage(QString message);
|
void audioMessage(QString message);
|
||||||
void sendLatency(quint16 newSize);
|
void sendLatency(quint16 newSize);
|
||||||
void haveAudioData(const QByteArray& data);
|
void haveAudioData(const QByteArray& data);
|
||||||
|
void haveLevels(quint16 amplitude,quint16 latency,quint16 current,bool under);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool isUnderrun = false;
|
||||||
bool isInitialized=false;
|
bool isInitialized=false;
|
||||||
bool isReady = false;
|
bool isReady = false;
|
||||||
bool audioBuffered = false;
|
bool audioBuffered = false;
|
||||||
|
@ -140,6 +142,7 @@ private:
|
||||||
|
|
||||||
OpusEncoder* encoder=Q_NULLPTR;
|
OpusEncoder* encoder=Q_NULLPTR;
|
||||||
OpusDecoder* decoder=Q_NULLPTR;
|
OpusDecoder* decoder=Q_NULLPTR;
|
||||||
|
QTimer * underTimer=Q_NULLPTR;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,20 @@ void udpHandler::receiveDataFromUserToRig(QByteArray data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void udpHandler::getRxLevels(quint16 amplitude,quint16 latency,quint16 current, bool under) {
|
||||||
|
status.rxAudioLevel = amplitude;
|
||||||
|
status.rxLatency = latency;
|
||||||
|
status.rxCurrentLatency = current;
|
||||||
|
status.rxUnderrun = under;
|
||||||
|
}
|
||||||
|
|
||||||
|
void udpHandler::getTxLevels(quint16 amplitude,quint16 latency, quint16 current, bool under) {
|
||||||
|
status.txAudioLevel = amplitude;
|
||||||
|
status.txLatency = latency;
|
||||||
|
status.txCurrentLatency = current;
|
||||||
|
status.txUnderrun = under;
|
||||||
|
}
|
||||||
|
|
||||||
void udpHandler::dataReceived()
|
void udpHandler::dataReceived()
|
||||||
{
|
{
|
||||||
while (udp->hasPendingDatagrams()) {
|
while (udp->hasPendingDatagrams()) {
|
||||||
|
@ -186,13 +200,12 @@ void udpHandler::dataReceived()
|
||||||
}
|
}
|
||||||
|
|
||||||
QString tempLatency;
|
QString tempLatency;
|
||||||
status.rxLatency = audio->audioLatency;
|
if (status.rxLatency > status.rxCurrentLatency && !status.rxUnderrun)
|
||||||
if (rxSetup.latency > audio->audioLatency)
|
|
||||||
{
|
{
|
||||||
tempLatency = QString("%1 ms").arg(audio->audioLatency,3);
|
tempLatency = QString("%1 ms").arg(status.rxCurrentLatency,3);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tempLatency = QString("<span style = \"color:red\">%1 ms</span>").arg(audio->audioLatency,3);
|
tempLatency = QString("<span style = \"color:red\">%1 ms</span>").arg(status.rxCurrentLatency,3);
|
||||||
}
|
}
|
||||||
QString txString="";
|
QString txString="";
|
||||||
if (txSetup.codec == 0) {
|
if (txSetup.codec == 0) {
|
||||||
|
@ -200,10 +213,6 @@ void udpHandler::dataReceived()
|
||||||
}
|
}
|
||||||
status.message = QString("<pre>%1 rx latency: %2 / rtt: %3 ms / loss: %4/%5</pre>").arg(txString).arg(tempLatency).arg(status.networkLatency, 3).arg(status.packetsLost, 3).arg(status.packetsSent, 3);
|
status.message = QString("<pre>%1 rx latency: %2 / rtt: %3 ms / loss: %4/%5</pre>").arg(txString).arg(tempLatency).arg(status.networkLatency, 3).arg(status.packetsLost, 3).arg(status.packetsSent, 3);
|
||||||
|
|
||||||
if (audio != Q_NULLPTR) {
|
|
||||||
status.rxAudioLevel = audio->getRxAmplitude();
|
|
||||||
status.txAudioLevel = audio->getTxAmplitude();
|
|
||||||
}
|
|
||||||
emit haveNetworkStatus(status);
|
emit haveNetworkStatus(status);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -289,6 +298,8 @@ void udpHandler::dataReceived()
|
||||||
QObject::connect(audio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket)));
|
QObject::connect(audio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket)));
|
||||||
QObject::connect(this, SIGNAL(haveChangeLatency(quint16)), audio, SLOT(changeLatency(quint16)));
|
QObject::connect(this, SIGNAL(haveChangeLatency(quint16)), audio, SLOT(changeLatency(quint16)));
|
||||||
QObject::connect(this, SIGNAL(haveSetVolume(unsigned char)), audio, SLOT(setVolume(unsigned char)));
|
QObject::connect(this, SIGNAL(haveSetVolume(unsigned char)), audio, SLOT(setVolume(unsigned char)));
|
||||||
|
QObject::connect(audio, SIGNAL(haveRxLevels(quint16, quint16, quint16,bool)), this, SLOT(getRxLevels(quint16, quint16,quint16,bool)));
|
||||||
|
QObject::connect(audio, SIGNAL(haveTxLevels(quint16, quint16,quint16,bool)), this, SLOT(getTxLevels(quint16, quint16,quint16,bool)));
|
||||||
|
|
||||||
streamOpened = true;
|
streamOpened = true;
|
||||||
}
|
}
|
||||||
|
@ -810,6 +821,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
|
||||||
connect(this, SIGNAL(haveAudioData(audioPacket)), rxaudio, SLOT(incomingAudio(audioPacket)));
|
connect(this, SIGNAL(haveAudioData(audioPacket)), rxaudio, SLOT(incomingAudio(audioPacket)));
|
||||||
connect(this, SIGNAL(haveChangeLatency(quint16)), rxaudio, SLOT(changeLatency(quint16)));
|
connect(this, SIGNAL(haveChangeLatency(quint16)), rxaudio, SLOT(changeLatency(quint16)));
|
||||||
connect(this, SIGNAL(haveSetVolume(unsigned char)), rxaudio, SLOT(setVolume(unsigned char)));
|
connect(this, SIGNAL(haveSetVolume(unsigned char)), rxaudio, SLOT(setVolume(unsigned char)));
|
||||||
|
connect(rxaudio, SIGNAL(haveLevels(quint16, quint16, quint16,bool)), this, SLOT(getRxLevels(quint16, quint16, quint16,bool)));
|
||||||
connect(rxAudioThread, SIGNAL(finished()), rxaudio, SLOT(deleteLater()));
|
connect(rxAudioThread, SIGNAL(finished()), rxaudio, SLOT(deleteLater()));
|
||||||
|
|
||||||
txSetup.format.setChannelCount(1); // TX Audio is always single channel.
|
txSetup.format.setChannelCount(1); // TX Audio is always single channel.
|
||||||
|
@ -822,6 +834,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
|
||||||
txAudioThread->start(QThread::TimeCriticalPriority);
|
txAudioThread->start(QThread::TimeCriticalPriority);
|
||||||
|
|
||||||
connect(this, SIGNAL(setupTxAudio(audioSetup)), txaudio, SLOT(init(audioSetup)));
|
connect(this, SIGNAL(setupTxAudio(audioSetup)), txaudio, SLOT(init(audioSetup)));
|
||||||
|
connect(txaudio, SIGNAL(haveLevels(quint16, quint16, quint16, bool)), this, SLOT(getTxLevels(quint16, quint16, quint16, bool)));
|
||||||
|
|
||||||
connect(txAudioThread, SIGNAL(finished()), txaudio, SLOT(deleteLater()));
|
connect(txAudioThread, SIGNAL(finished()), txaudio, SLOT(deleteLater()));
|
||||||
|
|
||||||
|
@ -973,22 +986,13 @@ void udpAudio::setVolume(unsigned char value)
|
||||||
emit haveSetVolume(value);
|
emit haveSetVolume(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
quint16 udpAudio::getRxAmplitude() {
|
void udpAudio::getRxLevels(quint16 amplitude,quint16 latency, quint16 current, bool under) {
|
||||||
if (rxaudio != Q_NULLPTR) {
|
|
||||||
return rxaudio->getAmplitude();
|
emit haveRxLevels(amplitude,latency, current, under);
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
quint16 udpAudio::getTxAmplitude() {
|
void udpAudio::getTxLevels(quint16 amplitude,quint16 latency, quint16 current, bool under) {
|
||||||
if (txaudio != Q_NULLPTR) {
|
emit haveTxLevels(amplitude,latency, current, under);
|
||||||
return txaudio->getAmplitude();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void udpAudio::dataReceived()
|
void udpAudio::dataReceived()
|
||||||
|
@ -1040,7 +1044,6 @@ void udpAudio::dataReceived()
|
||||||
// Need to do more testing but latency appears fine.
|
// Need to do more testing but latency appears fine.
|
||||||
//rxaudio->incomingAudio(tempAudio);
|
//rxaudio->incomingAudio(tempAudio);
|
||||||
emit haveAudioData(tempAudio);
|
emit haveAudioData(tempAudio);
|
||||||
audioLatency = rxaudio->getLatency();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
12
udphandler.h
12
udphandler.h
|
@ -43,6 +43,10 @@ struct networkStatus {
|
||||||
quint8 txAudioLevel;
|
quint8 txAudioLevel;
|
||||||
quint16 rxLatency;
|
quint16 rxLatency;
|
||||||
quint16 txLatency;
|
quint16 txLatency;
|
||||||
|
bool rxUnderrun;
|
||||||
|
bool txUnderrun;
|
||||||
|
quint16 rxCurrentLatency;
|
||||||
|
quint16 txCurrentLatency;
|
||||||
quint32 packetsSent=0;
|
quint32 packetsSent=0;
|
||||||
quint32 packetsLost=0;
|
quint32 packetsLost=0;
|
||||||
quint16 rtt=0;
|
quint16 rtt=0;
|
||||||
|
@ -175,8 +179,6 @@ public:
|
||||||
~udpAudio();
|
~udpAudio();
|
||||||
|
|
||||||
int audioLatency = 0;
|
int audioLatency = 0;
|
||||||
quint16 getRxAmplitude();
|
|
||||||
quint16 getTxAmplitude();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void haveAudioData(audioPacket data);
|
void haveAudioData(audioPacket data);
|
||||||
|
@ -186,10 +188,14 @@ signals:
|
||||||
|
|
||||||
void haveChangeLatency(quint16 value);
|
void haveChangeLatency(quint16 value);
|
||||||
void haveSetVolume(unsigned char value);
|
void haveSetVolume(unsigned char value);
|
||||||
|
void haveRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
||||||
|
void haveTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void changeLatency(quint16 value);
|
void changeLatency(quint16 value);
|
||||||
void setVolume(unsigned char value);
|
void setVolume(unsigned char value);
|
||||||
|
void getRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
||||||
|
void getTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -239,6 +245,8 @@ public slots:
|
||||||
void setVolume(unsigned char value);
|
void setVolume(unsigned char value);
|
||||||
void init();
|
void init();
|
||||||
void setCurrentRadio(quint8 radio);
|
void setCurrentRadio(quint8 radio);
|
||||||
|
void getRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
||||||
|
void getTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
Ładowanie…
Reference in New Issue