kopia lustrzana https://gitlab.com/eliggett/wfview
Audio metering initial. Very messy but you can select TxRxAudio as the
meter type and wfview will show you TX or RX audio depending upon if you are transmitting or not. You can also select only TxAudio or RxAudio. This is nice for looking at Tx audio levels prior to transmitting, for example, or metering the radio's "monitor" audio while transmitting.monitor
rodzic
105675a128
commit
9fb74ed6e1
|
@ -157,7 +157,9 @@ bool audioConverter::convert(audioPacket audio)
|
|||
if (samplesF.size() > 0)
|
||||
|
||||
{
|
||||
audio.amplitude = samplesF.array().abs().maxCoeff();
|
||||
audio.amplitudePeak = samplesF.array().abs().maxCoeff();
|
||||
audio.amplitudeRMS = samplesF.squaredNorm();
|
||||
|
||||
// Set the volume
|
||||
samplesF *= audio.volume;
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ struct audioPacket {
|
|||
quint16 sent;
|
||||
QByteArray data;
|
||||
quint8 guid[GUIDLEN];
|
||||
float amplitude;
|
||||
float amplitudePeak;
|
||||
float amplitudeRMS;
|
||||
qreal volume = 1.0;
|
||||
};
|
||||
|
||||
|
|
|
@ -270,12 +270,18 @@ void audioHandler::convertedOutput(audioPacket packet) {
|
|||
}
|
||||
*/
|
||||
lastSentSeq = packet.seq;
|
||||
amplitude = packet.amplitudePeak;
|
||||
computeLevels();
|
||||
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun);
|
||||
|
||||
amplitude = packet.amplitude;
|
||||
}
|
||||
}
|
||||
|
||||
void audioHandler::computeLevels()
|
||||
{
|
||||
if(levelMean)
|
||||
levelMean[(levelPosition++)%levelSize] = amplitude * 255;
|
||||
}
|
||||
|
||||
void audioHandler::getNextAudioChunk()
|
||||
{
|
||||
if (audioDevice) {
|
||||
|
@ -312,7 +318,7 @@ void audioHandler::convertedInput(audioPacket audio)
|
|||
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize ;
|
||||
}
|
||||
lastReceived = QTime::currentTime();
|
||||
amplitude = audio.amplitude;
|
||||
amplitude = audio.amplitudePeak;
|
||||
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,12 @@ private:
|
|||
float amplitude=0.0;
|
||||
qreal volume = 1.0;
|
||||
|
||||
unsigned char *levelMean = Q_NULLPTR;
|
||||
unsigned char *levelPeak = Q_NULLPTR;
|
||||
unsigned char levelSize = 50;
|
||||
unsigned char levelPosition = 0;
|
||||
void computeLevels();
|
||||
|
||||
audioSetup setup;
|
||||
|
||||
OpusEncoder* encoder = Q_NULLPTR;
|
||||
|
|
|
@ -278,7 +278,7 @@ void paHandler::convertedOutput(audioPacket packet) {
|
|||
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (info->outputLatency * 1000);
|
||||
}
|
||||
|
||||
amplitude = packet.amplitude;
|
||||
amplitude = packet.amplitudePeak;
|
||||
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun);
|
||||
}
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ void paHandler::convertedInput(audioPacket packet)
|
|||
{
|
||||
if (packet.data.size() > 0) {
|
||||
emit haveAudioData(packet);
|
||||
amplitude = packet.amplitude;
|
||||
amplitude = packet.amplitudePeak;
|
||||
const PaStreamInfo* info = Pa_GetStreamInfo(audio);
|
||||
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (info->inputLatency * 1000);
|
||||
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun);
|
||||
|
|
|
@ -166,6 +166,8 @@ void rigCommander::commSetup(unsigned char rigCivAddr, udpPreferences prefs, aud
|
|||
// Connect for errors/alerts
|
||||
connect(udp, SIGNAL(haveNetworkError(QString, QString)), this, SLOT(handleSerialPortError(QString, QString)));
|
||||
connect(udp, SIGNAL(haveNetworkStatus(networkStatus)), this, SLOT(handleStatusUpdate(networkStatus)));
|
||||
connect(udp, SIGNAL(haveNetworkAudioLevels(networkAudioLevels)), this, SLOT(handleNetworkAudioLevels(networkAudioLevels)));
|
||||
|
||||
|
||||
connect(ptty, SIGNAL(haveSerialPortError(QString, QString)), this, SLOT(handleSerialPortError(QString, QString)));
|
||||
connect(this, SIGNAL(getMoreDebug()), ptty, SLOT(debugThis()));
|
||||
|
@ -245,6 +247,11 @@ void rigCommander::handleStatusUpdate(const networkStatus status)
|
|||
emit haveStatusUpdate(status);
|
||||
}
|
||||
|
||||
void rigCommander::handleNetworkAudioLevels(networkAudioLevels l)
|
||||
{
|
||||
emit haveNetworkAudioLevels(l);
|
||||
}
|
||||
|
||||
bool rigCommander::usingLAN()
|
||||
{
|
||||
return usingNativeLAN;
|
||||
|
|
|
@ -36,6 +36,7 @@ enum meterKind {
|
|||
meterRxdB,
|
||||
meterTxMod,
|
||||
meterRxAudio,
|
||||
meterAudio,
|
||||
meterLatency
|
||||
};
|
||||
|
||||
|
@ -277,6 +278,7 @@ public slots:
|
|||
|
||||
// Housekeeping:
|
||||
void handleStatusUpdate(const networkStatus status);
|
||||
void handleNetworkAudioLevels(networkAudioLevels);
|
||||
void radioSelection(QList<radio_cap_packet> radios);
|
||||
void radioUsage(quint8 radio, quint8 busy, QString name, QString ip);
|
||||
void setCurrentRadio(quint8 radio);
|
||||
|
@ -288,6 +290,7 @@ signals:
|
|||
void commReady();
|
||||
void haveSerialPortError(const QString port, const QString errorText);
|
||||
void haveStatusUpdate(const networkStatus status);
|
||||
void haveNetworkAudioLevels(const networkAudioLevels l);
|
||||
void dataForComm(const QByteArray &outData);
|
||||
void toggleRTS(bool rtsOn);
|
||||
|
||||
|
@ -397,6 +400,11 @@ private:
|
|||
quint16 decodeTone(QByteArray eTone);
|
||||
quint16 decodeTone(QByteArray eTone, bool &tinv, bool &rinv);
|
||||
|
||||
unsigned char audioLevelRxMean[50];
|
||||
unsigned char audioLevelRxPeak[50];
|
||||
unsigned char audioLevelTxMean[50];
|
||||
unsigned char audioLevelTxPeak[50];
|
||||
|
||||
void parseMode();
|
||||
void parseSpectrum();
|
||||
void parseWFData();
|
||||
|
|
|
@ -331,7 +331,7 @@ void rtHandler::convertedOutput(audioPacket packet)
|
|||
audioMutex.lock();
|
||||
arrayBuffer.append(packet.data);
|
||||
audioMutex.unlock();
|
||||
amplitude = packet.amplitude;
|
||||
amplitude = packet.amplitudePeak;
|
||||
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (outFormat.durationForBytes(audio->getStreamLatency() * (outFormat.sampleSize() / 8) * outFormat.channelCount())/1000);
|
||||
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun);
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ void rtHandler::convertedInput(audioPacket packet)
|
|||
{
|
||||
if (packet.data.size() > 0) {
|
||||
emit haveAudioData(packet);
|
||||
amplitude = packet.amplitude;
|
||||
amplitude = packet.amplitudePeak;
|
||||
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (outFormat.durationForBytes(audio->getStreamLatency() * (outFormat.sampleSize() / 8) * outFormat.channelCount())/1000);
|
||||
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,15 @@ struct udpPreferences {
|
|||
quint8 waterfallFormat;
|
||||
};
|
||||
|
||||
struct networkAudioLevels {
|
||||
bool haveTxLevels = false;
|
||||
bool haveRxLevels = false;
|
||||
quint8 rxAudioRMS = 0;
|
||||
quint8 txAudioRMS = 0;
|
||||
quint8 rxAudioPeak = 0;
|
||||
quint8 txAudioPeak = 0;
|
||||
};
|
||||
|
||||
struct networkStatus {
|
||||
quint8 rxAudioBufferPercent;
|
||||
quint8 txAudioBufferPercent;
|
||||
|
|
|
@ -149,6 +149,17 @@ void udpHandler::getRxLevels(quint16 amplitude,quint16 latency,quint16 current,
|
|||
status.rxCurrentLatency = current;
|
||||
status.rxUnderrun = under;
|
||||
status.rxOverrun = over;
|
||||
audioLevelsRxPeak[(audioLevelsRxPeakPosition++)%audioLevelBufferSize] = amplitude;
|
||||
if((audioLevelsRxPeakPosition++)%3 == 0)
|
||||
{
|
||||
// calculate mean and emit signal
|
||||
unsigned char mean = findMean(audioLevelsRxPeak);
|
||||
networkAudioLevels l;
|
||||
l.haveRxLevels = true;
|
||||
l.rxAudioPeak = mean;
|
||||
//qDebug(logSystem()) << "audio level meter being emitted from udpHandler";
|
||||
emit haveNetworkAudioLevels(l);
|
||||
}
|
||||
}
|
||||
|
||||
void udpHandler::getTxLevels(quint16 amplitude,quint16 latency, quint16 current, bool under, bool over) {
|
||||
|
@ -157,6 +168,26 @@ void udpHandler::getTxLevels(quint16 amplitude,quint16 latency, quint16 current,
|
|||
status.txCurrentLatency = current;
|
||||
status.txUnderrun = under;
|
||||
status.txOverrun = over;
|
||||
audioLevelsTxPeak[(audioLevelsTxPeakPosition++)%audioLevelBufferSize] = amplitude;
|
||||
if((audioLevelsTxPeakPosition++)%3 == 0)
|
||||
{
|
||||
// calculate mean and emit signal
|
||||
unsigned char mean = findMean(audioLevelsTxPeak);
|
||||
networkAudioLevels l;
|
||||
l.haveTxLevels = true;
|
||||
l.txAudioPeak = mean;
|
||||
emit haveNetworkAudioLevels(l);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char udpHandler::findMean(unsigned char *data)
|
||||
{
|
||||
unsigned int sum=0;
|
||||
for(int p=0; p < audioLevelBufferSize; p++)
|
||||
{
|
||||
sum += data[p];
|
||||
}
|
||||
return sum / audioLevelBufferSize;
|
||||
}
|
||||
|
||||
void udpHandler::dataReceived()
|
||||
|
|
14
udphandler.h
14
udphandler.h
|
@ -29,7 +29,7 @@
|
|||
#include "udpcivdata.h"
|
||||
#include "udpaudio.h"
|
||||
|
||||
|
||||
#define audioLevelBufferSize (3)
|
||||
|
||||
// Class to handle the connection/disconnection of the radio.
|
||||
class udpHandler: public udpBase
|
||||
|
@ -58,7 +58,8 @@ public slots:
|
|||
void setCurrentRadio(quint8 radio);
|
||||
void getRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over);
|
||||
void getTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over);
|
||||
|
||||
//void handleRxLevels(networkAudioLevels);
|
||||
//void handleTxLevels(networkAudioLevels);
|
||||
|
||||
signals:
|
||||
void haveDataFromPort(QByteArray data); // emit this when we have data, connect to rigcommander
|
||||
|
@ -67,6 +68,7 @@ signals:
|
|||
void haveChangeLatency(quint16 value);
|
||||
void haveSetVolume(unsigned char value);
|
||||
void haveNetworkStatus(networkStatus);
|
||||
void haveNetworkAudioLevels(networkAudioLevels);
|
||||
void haveBaudRate(quint32 baudrate);
|
||||
void requestRadioSelection(QList<radio_cap_packet> radios);
|
||||
void setRadioUsage(quint8, quint8 busy, QString name, QString mac);
|
||||
|
@ -122,6 +124,14 @@ private:
|
|||
quint16 txSampleRates = 0;
|
||||
networkStatus status;
|
||||
bool splitWf = false;
|
||||
|
||||
unsigned char audioLevelsTxPeak[audioLevelBufferSize];
|
||||
unsigned char audioLevelsRxPeak[audioLevelBufferSize];
|
||||
unsigned char audioLevelsTxPeakPosition = 0;
|
||||
unsigned char audioLevelsRxPeakPosition = 0;
|
||||
unsigned char findMean(unsigned char *d);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
29
wfmain.cpp
29
wfmain.cpp
|
@ -47,6 +47,7 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, const QString s
|
|||
qRegisterMetaType<rigstate*>();
|
||||
qRegisterMetaType<QList<radio_cap_packet>>();
|
||||
qRegisterMetaType<networkStatus>();
|
||||
qRegisterMetaType<networkAudioLevels>();
|
||||
|
||||
haveRigCaps = false;
|
||||
|
||||
|
@ -424,6 +425,7 @@ void wfmain::makeRig()
|
|||
// Rig status and Errors:
|
||||
connect(rig, SIGNAL(haveSerialPortError(QString, QString)), this, SLOT(receiveSerialPortError(QString, QString)));
|
||||
connect(rig, SIGNAL(haveStatusUpdate(networkStatus)), this, SLOT(receiveStatusUpdate(networkStatus)));
|
||||
connect(rig, SIGNAL(haveNetworkAudioLevels(networkAudioLevels)), this, SLOT(receiveNetworkAudioLevels(networkAudioLevels)));
|
||||
connect(rig, SIGNAL(requestRadioSelection(QList<radio_cap_packet>)), this, SLOT(radioSelection(QList<radio_cap_packet>)));
|
||||
connect(rig, SIGNAL(setRadioUsage(quint8, quint8, QString, QString)), selRad, SLOT(setInUse(quint8, quint8, QString, QString)));
|
||||
connect(selRad, SIGNAL(selectedRadio(quint8)), rig, SLOT(setCurrentRadio(quint8)));
|
||||
|
@ -615,6 +617,22 @@ void wfmain::receiveStatusUpdate(networkStatus status)
|
|||
//qInfo(logSystem()) << "Got Status Update" << status.rxAudioLevel;
|
||||
}
|
||||
|
||||
void wfmain::receiveNetworkAudioLevels(networkAudioLevels l)
|
||||
{
|
||||
qInfo(logSystem()) << "audio level meter received.";
|
||||
meterKind m = meterNone;
|
||||
if(l.haveRxLevels)
|
||||
{
|
||||
m = meterRxAudio;
|
||||
receiveMeter(m, l.rxAudioPeak);
|
||||
}
|
||||
if(l.haveTxLevels)
|
||||
{
|
||||
m = meterTxMod;
|
||||
receiveMeter(m, l.txAudioPeak);
|
||||
}
|
||||
}
|
||||
|
||||
void wfmain::setupPlots()
|
||||
{
|
||||
spectrumDrawLock = true;
|
||||
|
@ -746,6 +764,10 @@ void wfmain::setupMainUI()
|
|||
ui->meter2selectionCombo->addItem("Voltage", meterVoltage);
|
||||
ui->meter2selectionCombo->addItem("Current", meterCurrent);
|
||||
ui->meter2selectionCombo->addItem("Center", meterCenter);
|
||||
ui->meter2selectionCombo->addItem("TxRxAudio", meterAudio);
|
||||
ui->meter2selectionCombo->addItem("RxAudio", meterRxAudio);
|
||||
ui->meter2selectionCombo->addItem("TxAudio", meterTxMod);
|
||||
|
||||
ui->meter2Widget->hide();
|
||||
|
||||
ui->meter2selectionCombo->show();
|
||||
|
@ -5096,6 +5118,12 @@ void wfmain::receiveMeter(meterKind inMeter, unsigned char level)
|
|||
if(ui->meter2Widget->getMeterType() == inMeter)
|
||||
{
|
||||
ui->meter2Widget->setLevel(level);
|
||||
} else if ( (ui->meter2Widget->getMeterType() == meterAudio) &&
|
||||
(inMeter == meterTxMod) && amTransmitting) {
|
||||
ui->meter2Widget->setLevel(level);
|
||||
} else if ( (ui->meter2Widget->getMeterType() == meterAudio) &&
|
||||
(inMeter == meterRxAudio) && !amTransmitting) {
|
||||
ui->meter2Widget->setLevel(level);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -5765,6 +5793,7 @@ void wfmain::on_meter2selectionCombo_activated(int index)
|
|||
} else {
|
||||
ui->meter2Widget->show();
|
||||
ui->meter2Widget->setMeterType(newMeterType);
|
||||
if((newMeterType!=meterRxAudio) && (newMeterType!=meterTxMod) && (newMeterType!=meterAudio))
|
||||
insertPeriodicCommandUnique(newCmd);
|
||||
}
|
||||
prefs.meter2Type = newMeterType;
|
||||
|
|
2
wfmain.h
2
wfmain.h
|
@ -275,6 +275,7 @@ private slots:
|
|||
void receiveFoundRigID(rigCapabilities rigCaps);
|
||||
void receiveSerialPortError(QString port, QString errorText);
|
||||
void receiveStatusUpdate(networkStatus status);
|
||||
void receiveNetworkAudioLevels(networkAudioLevels l);
|
||||
void handlePlotClick(QMouseEvent *);
|
||||
void handlePlotDoubleClick(QMouseEvent *);
|
||||
void handleWFClick(QMouseEvent *);
|
||||
|
@ -943,6 +944,7 @@ Q_DECLARE_METATYPE(struct SERVERCONFIG)
|
|||
Q_DECLARE_METATYPE(struct timekind)
|
||||
Q_DECLARE_METATYPE(struct datekind)
|
||||
Q_DECLARE_METATYPE(struct networkStatus)
|
||||
Q_DECLARE_METATYPE(struct networkAudioLevels)
|
||||
Q_DECLARE_METATYPE(enum rigInput)
|
||||
Q_DECLARE_METATYPE(enum meterKind)
|
||||
Q_DECLARE_METATYPE(enum spectrumMode)
|
||||
|
|
Ładowanie…
Reference in New Issue