Add experimental audio converter

monitor
Phil Taylor 2022-05-06 23:10:46 +01:00
rodzic 5bd29096e5
commit 78f16b7cff
8 zmienionych plików z 584 dodań i 756 usunięć

293
audioconverter.cpp 100644
Wyświetl plik

@ -0,0 +1,293 @@
#include "audioconverter.h"
#include "logcategories.h"
#include "ulaw.h"
audioConverter::audioConverter(){
}
bool audioConverter::init(QAudioFormat inFormat, QAudioFormat outFormat, quint8 opusComplexity, quint8 resampleQuality)
{
this->inFormat = inFormat;
this->outFormat = outFormat;
this->opusComplexity = opusComplexity;
this->resampleQuality = resampleQuality;
qInfo(logAudioConverter) << "Starting audioConverter() Input:" << inFormat.channelCount() << "Channels of" << inFormat.codec() << inFormat.sampleRate() << inFormat.sampleType() << inFormat.sampleSize() <<
"Output:" << outFormat.channelCount() << "Channels of" << outFormat.codec() << outFormat.sampleRate() << outFormat.sampleType() << outFormat.sampleSize();
if (inFormat.codec() == "audio/opus")
{
// Create instance of opus decoder
int opus_err = 0;
opusDecoder = opus_decoder_create(inFormat.sampleRate(), inFormat.channelCount(), &opus_err);
qInfo(logAudioConverter()) << "Creating opus decoder: " << opus_strerror(opus_err);
}
if (outFormat.codec() == "audio/opus")
{
// Create instance of opus encoder
int opus_err = 0;
opusEncoder = opus_encoder_create(outFormat.sampleRate(), outFormat.channelCount(), OPUS_APPLICATION_AUDIO, &opus_err);
opus_encoder_ctl(opusEncoder, OPUS_SET_LSB_DEPTH(16));
opus_encoder_ctl(opusEncoder, OPUS_SET_INBAND_FEC(1));
opus_encoder_ctl(opusEncoder, OPUS_SET_DTX(1));
opus_encoder_ctl(opusEncoder, OPUS_SET_PACKET_LOSS_PERC(5));
opus_encoder_ctl(opusEncoder, OPUS_SET_COMPLEXITY(opusComplexity)); // Reduce complexity to maybe lower CPU?
qInfo(logAudioConverter()) << "Creating opus encoder: " << opus_strerror(opus_err);
}
if (inFormat.sampleRate() != outFormat.sampleRate())
{
int resampleError = 0;
unsigned int ratioNum;
unsigned int ratioDen;
// Sample rate conversion required.
resampler = wf_resampler_init(outFormat.channelCount(), inFormat.sampleRate(), outFormat.sampleRate(), resampleQuality, &resampleError);
wf_resampler_get_ratio(resampler, &ratioNum, &ratioDen);
resampleRatio = static_cast<double>(ratioDen) / ratioNum;
qInfo(logAudioConverter()) << "wf_resampler_init() returned: " << resampleError << " resampleRatio: " << resampleRatio;
}
return true;
}
audioConverter::~audioConverter()
{
qInfo(logAudioConverter) << "Closing audioConverter() Input:" << inFormat.channelCount() << "Channels of" << inFormat.codec() << inFormat.sampleRate() << inFormat.sampleType() << inFormat.sampleSize() <<
"Output:" << outFormat.channelCount() << "Channels of" << outFormat.codec() << outFormat.sampleRate() << outFormat.sampleType() << outFormat.sampleSize();
if (opusEncoder != Q_NULLPTR) {
qInfo(logAudioConverter()) << "Destroying opus encoder";
opus_encoder_destroy(opusEncoder);
}
if (opusDecoder != Q_NULLPTR) {
qInfo(logAudioConverter()) << "Destroying opus decoder";
opus_decoder_destroy(opusDecoder);
}
if (resampler != Q_NULLPTR) {
speex_resampler_destroy(resampler);
qDebug(logAudioConverter()) << "Resampler closed";
}
}
bool audioConverter::convert(audioPacket audio)
{
if (inFormat.codec() == "audio/opus")
{
unsigned char* in = (unsigned char*)audio.data.data();
//Decode the frame.
int nSamples = opus_packet_get_nb_samples(in, audio.data.size(), inFormat.sampleRate());
if (nSamples == -1) {
// No opus data yet?
return false;
}
QByteArray outPacket(nSamples * sizeof(float) * inFormat.channelCount(), (char)0xff); // Preset the output buffer size.
float* out = (float*)outPacket.data();
if (audio.seq > lastAudioSequence + 1) {
nSamples = opus_decode_float(opusDecoder, Q_NULLPTR, 0, out, nSamples, 1);
}
else {
nSamples = opus_decode_float(opusDecoder, in, audio.data.size(), out, nSamples, 0);
}
audio.data.clear();
audio.data = outPacket; // Replace incoming data with converted.
}
else if (inFormat.codec() == "audio/PCMU")
{
// Current packet is "technically" 8bit so need to create a new buffer that is 16bit
QByteArray outPacket((int)audio.data.length() * 2, (char)0xff);
qint16* out = (qint16*)outPacket.data();
for (int f = 0; f < audio.data.length(); f++)
{
*out++ = ulaw_decode[(quint8)audio.data[f]];
}
audio.data.clear();
audio.data = outPacket; // Replace incoming data with converted.
// Make sure that sample size/type is set correctly
}
Eigen::VectorXf samplesF;
if (inFormat.sampleType() == QAudioFormat::SignedInt && inFormat.sampleSize() == 32)
{
Eigen::Ref<VectorXint32> samplesI = Eigen::Map<VectorXint32>(reinterpret_cast<qint32*>(audio.data.data()), audio.data.size() / int(sizeof(qint32)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint32>::max());
}
else if (inFormat.sampleType() == QAudioFormat::SignedInt && inFormat.sampleSize() == 16)
{
Eigen::Ref<VectorXint16> samplesI = Eigen::Map<VectorXint16>(reinterpret_cast<qint16*>(audio.data.data()), audio.data.size() / int(sizeof(qint16)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint16>::max());
}
else if (inFormat.sampleType() == QAudioFormat::SignedInt && inFormat.sampleSize() == 8)
{
Eigen::Ref<VectorXint8> samplesI = Eigen::Map<VectorXint8>(reinterpret_cast<qint8*>(audio.data.data()), audio.data.size() / int(sizeof(qint8)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint8>::max());;
}
else if (inFormat.sampleType() == QAudioFormat::UnSignedInt && inFormat.sampleSize() == 8)
{
Eigen::Ref<VectorXuint8> samplesI = Eigen::Map<VectorXuint8>(reinterpret_cast<quint8*>(audio.data.data()), audio.data.size() / int(sizeof(quint8)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<quint8>::max());;
}
else if (inFormat.sampleType() == QAudioFormat::Float) {
samplesF = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(audio.data.data()), audio.data.size() / int(sizeof(float)));
}
else
{
qInfo(logAudio()) << "Unsupported Sample Type:" << inFormat.sampleType() << "Size:" << inFormat.sampleSize();
}
audio.amplitude = samplesF.array().abs().maxCoeff();
// Set the volume
samplesF *= audio.volume;
/*
samplesF is now an Eigen Vector of the current samples in float format
The next step is to convert to the correct number of channels in outFormat.channelCount()
*/
if (inFormat.channelCount() == 2 && outFormat.channelCount() == 1) {
// If we need to drop one of the audio channels, do it now
Eigen::VectorXf samplesTemp(samplesF.size() / 2);
samplesTemp = Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesF.data(), samplesF.size() / 2);
samplesF = samplesTemp;
}
else if (inFormat.channelCount() == 1 && outFormat.channelCount() == 2) {
// Convert mono to stereo if required
Eigen::VectorXf samplesTemp(samplesF.size() * 2);
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data(), samplesF.size()) = samplesF;
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data() + 1, samplesF.size()) = samplesF;
samplesF = samplesTemp;
}
/*
Next step is to resample (if needed)
*/
if (resampler != Q_NULLPTR && resampleRatio != 1.0)
{
quint32 outFrames = ((samplesF.size() / outFormat.channelCount()) * resampleRatio);
quint32 inFrames = (samplesF.size() / outFormat.channelCount());
QByteArray outPacket(outFrames * outFormat.channelCount() * sizeof(float), (char)0xff); // Preset the output buffer size.
const float* in = (float*)samplesF.data();
float* out = (float*)outPacket.data();
int err = 0;
if (outFormat.channelCount() == 1) {
err = wf_resampler_process_float(resampler, 0, in, &inFrames, out, &outFrames);
}
else {
err = wf_resampler_process_interleaved_float(resampler, in, &inFrames, out, &outFrames);
}
if (err) {
qInfo(logAudioConverter()) << "Resampler error " << err << " inFrames:" << inFrames << " outFrames:" << outFrames;
}
samplesF = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(outPacket.data()), outPacket.size() / int(sizeof(float)));
}
/*
Output is Opus so encode it now
*/
if (outFormat.codec() == "audio/opus")
{
float* in = (float*)samplesF.data();
QByteArray outPacket(1275, (char)0xff); // Preset the output buffer size to MAXIMUM possible Opus frame size
unsigned char* out = (unsigned char*)outPacket.data();
int nbBytes = opus_encode_float(opusEncoder, in, (samplesF.size() / outFormat.channelCount()), out, outPacket.length());
if (nbBytes < 0)
{
qInfo(logAudioConverter()) << "Opus encode failed:" << opus_strerror(nbBytes) << "Num Samples:" << samplesF.size();
return false;
}
else {
outPacket.resize(nbBytes);
samplesF = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(outPacket.data()), outPacket.size() / int(sizeof(float)));
}
}
/*
Now convert back into the output format required
*/
audio.data.clear();
if (outFormat.sampleType() == QAudioFormat::UnSignedInt && outFormat.sampleSize() == 8)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<quint8>::max());
VectorXuint8 samplesI = samplesITemp.cast<quint8>();
audio.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(quint8)));
}
if (outFormat.sampleType() == QAudioFormat::SignedInt && outFormat.sampleSize() == 8)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint8>::max());
VectorXint8 samplesI = samplesITemp.cast<qint8>();
audio.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint8)));
}
if (outFormat.sampleType() == QAudioFormat::SignedInt && outFormat.sampleSize() == 16)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint16>::max());
VectorXint16 samplesI = samplesITemp.cast<qint16>();
audio.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint16)));
}
else if (outFormat.sampleType() == QAudioFormat::SignedInt && outFormat.sampleSize() == 32)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint32>::max());
VectorXint32 samplesI = samplesITemp.cast<qint32>();
audio.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint32)));
}
else if (outFormat.sampleType() == QAudioFormat::Float)
{
audio.data = QByteArray(reinterpret_cast<char*>(samplesF.data()), int(samplesF.size()) * int(sizeof(float)));
}
else {
qInfo(logAudio()) << "Unsupported Sample Type:" << outFormat.sampleType();
}
/*
As we currently don't have a float based uLaw encoder, this must be done
after all other conversion has taken place.
*/
if (outFormat.codec() == "audio/PCMU")
{
QByteArray outPacket((int)audio.data.length() / 2, (char)0xff);
qint16* in = (qint16*)audio.data.data();
for (int f = 0; f < outPacket.length(); f++)
{
qint16 sample = *in++;
int sign = (sample >> 8) & 0x80;
if (sign)
sample = (short)-sample;
if (sample > cClip)
sample = cClip;
sample = (short)(sample + cBias);
int exponent = (int)MuLawCompressTable[(sample >> 7) & 0xFF];
int mantissa = (sample >> (exponent + 3)) & 0x0F;
int compressedByte = ~(sign | (exponent << 4) | mantissa);
outPacket[f] = (quint8)compressedByte;
}
audio.data.clear();
audio.data = outPacket; // Copy output packet back to input buffer.
}
emit converted(audio);
return true;
}

68
audioconverter.h 100644
Wyświetl plik

@ -0,0 +1,68 @@
#ifndef AUDIOCONVERTER_H
#define AUDIOCONVERTER_H
#include <QObject>
#include <QByteArray>
#include <QTime>
#include <QMap>
#include <QDebug>
#include <QAudioFormat>
/* Opus and Eigen */
#ifdef Q_OS_WIN
#include "opus.h"
#include <Eigen/Eigen>
#else
#include "opus/opus.h"
#include <eigen3/Eigen/Eigen>
#endif
#include "resampler/speex_resampler.h"
#include "packettypes.h"
struct audioPacket {
quint32 seq;
QTime time;
quint16 sent;
QByteArray data;
quint8 guid[GUIDLEN];
float amplitude;
qreal volume = 1.0;
};
class audioConverter : public QObject
{
Q_OBJECT
public:
audioConverter();
~audioConverter();
public slots:
bool init(QAudioFormat inFormat, QAudioFormat outFormat, quint8 opusComplexity, quint8 resampleQuality);
bool convert(audioPacket audio);
signals:
void converted(audioPacket audio);
protected:
QAudioFormat inFormat;
QAudioFormat outFormat;
OpusEncoder* opusEncoder = Q_NULLPTR;
OpusDecoder* opusDecoder = Q_NULLPTR;
SpeexResamplerState* resampler = Q_NULLPTR;
quint8 opusComplexity;
quint8 resampleQuality = 4;
double resampleRatio=1.0; // Default resample ratio is 1:1
quint32 lastAudioSequence;
};
// Various audio handling functions declared inline
typedef Eigen::Matrix<quint8, Eigen::Dynamic, 1> VectorXuint8;
typedef Eigen::Matrix<qint8, Eigen::Dynamic, 1> VectorXint8;
typedef Eigen::Matrix<qint16, Eigen::Dynamic, 1> VectorXint16;
typedef Eigen::Matrix<qint32, Eigen::Dynamic, 1> VectorXint32;
#endif

Wyświetl plik

@ -31,18 +31,9 @@ audioHandler::~audioHandler()
audioOutput = Q_NULLPTR; audioOutput = Q_NULLPTR;
} }
if (converterThread != Q_NULLPTR) {
if (resampler != Q_NULLPTR) { converterThread->quit();
speex_resampler_destroy(resampler); converterThread->wait();
qDebug(logAudio()) << "Resampler closed";
}
if (encoder != Q_NULLPTR) {
qInfo(logAudio()) << "Destroying opus encoder";
opus_encoder_destroy(encoder);
}
if (decoder != Q_NULLPTR) {
qInfo(logAudio()) << "Destroying opus decoder";
opus_decoder_destroy(decoder);
} }
} }
@ -58,12 +49,15 @@ bool audioHandler::init(audioSetup setupIn)
0x08 PCM 2ch 8bit 0x08 PCM 2ch 8bit
0x10 PCM 2ch 16bit 0x10 PCM 2ch 16bit
0x20 uLaw 2ch 8bit 0x20 uLaw 2ch 8bit
0x40 Opus 1ch
0x80 Opus 2ch
*/ */
setup = setupIn; setup = setupIn;
setup.format.setChannelCount(1); setup.format.setChannelCount(1);
setup.format.setSampleSize(8); setup.format.setSampleSize(8);
setup.format.setSampleType(QAudioFormat::UnSignedInt); setup.format.setSampleType(QAudioFormat::UnSignedInt);
setup.format.setCodec("audio/pcm");
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "audio handler starting:" << setup.name; qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "audio handler starting:" << setup.name;
if (setup.port.isNull()) if (setup.port.isNull())
@ -76,6 +70,7 @@ bool audioHandler::init(audioSetup setupIn)
setup.ulaw = true; setup.ulaw = true;
setup.format.setSampleSize(16); setup.format.setSampleSize(16);
setup.format.setSampleType(QAudioFormat::SignedInt); setup.format.setSampleType(QAudioFormat::SignedInt);
setup.format.setCodec("audio/PCMU");
} }
if (setup.codec == 0x08 || setup.codec == 0x10 || setup.codec == 0x20 || setup.codec == 0x80) { if (setup.codec == 0x08 || setup.codec == 0x10 || setup.codec == 0x20 || setup.codec == 0x80) {
@ -88,7 +83,9 @@ bool audioHandler::init(audioSetup setupIn)
} }
if (setup.codec == 0x40 || setup.codec == 0x80) { if (setup.codec == 0x40 || setup.codec == 0x80) {
setup.format.setSampleSize(32);
setup.format.setSampleType(QAudioFormat::Float); setup.format.setSampleType(QAudioFormat::Float);
setup.format.setCodec("audio/opus");
} }
qDebug(logAudio()) << "Creating" << (setup.isinput ? "Input" : "Output") << "audio device:" << setup.name << qDebug(logAudio()) << "Creating" << (setup.isinput ? "Input" : "Output") << "audio device:" << setup.name <<
@ -151,51 +148,32 @@ bool audioHandler::init(audioSetup setupIn)
// We "hopefully" now have a valid format that is supported so try connecting // We "hopefully" now have a valid format that is supported so try connecting
converter = new audioConverter();
converterThread = new QThread(this);
converterThread->setObjectName("audioConverter()");
converter->moveToThread(converterThread);
connect(this, SIGNAL(setupConverter(QAudioFormat,QAudioFormat,quint8,quint8)), converter, SLOT(init(QAudioFormat,QAudioFormat,quint8,quint8)));
connect(converterThread, SIGNAL(finished()), converter, SLOT(deleteLater()));
connect(this, SIGNAL(sendToConverter(audioPacket)), converter, SLOT(convert(audioPacket)));
converterThread->start(QThread::TimeCriticalPriority);
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))); connect(audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
emit setupConverter(format, setup.format, 7, setup.resampleQuality);
connect(converter, SIGNAL(converted(audioPacket)), this, SLOT(convertedInput(audioPacket)));
} }
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))); connect(audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
emit setupConverter(setup.format, format, 7, setup.resampleQuality);
connect(converter, SIGNAL(converted(audioPacket)), this, SLOT(convertedOutput(audioPacket)));
} }
// Setup resampler and opus if they are needed.
int resample_error = 0;
int opus_err = 0;
if (setup.isinput) {
resampler = wf_resampler_init(format.channelCount(), format.sampleRate(), setup.format.sampleRate(), setup.resampleQuality, &resample_error);
if (setup.codec == 0x40 || setup.codec == 0x80) {
// Opus codec
encoder = opus_encoder_create(setup.format.sampleRate(), setup.format.channelCount(), OPUS_APPLICATION_AUDIO, &opus_err);
opus_encoder_ctl(encoder, OPUS_SET_LSB_DEPTH(16));
opus_encoder_ctl(encoder, OPUS_SET_INBAND_FEC(1));
opus_encoder_ctl(encoder, OPUS_SET_DTX(1));
opus_encoder_ctl(encoder, OPUS_SET_PACKET_LOSS_PERC(5));
opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(7)); // Reduce complexity to maybe lower CPU?
qInfo(logAudio()) << "Creating opus encoder: " << opus_strerror(opus_err);
}
}
else {
//resampBufs = new r8b::CFixedBuffer<double>[format.channelCount()];
//resamps = new r8b::CPtrKeeper<r8b::CDSPResampler24*>[format.channelCount()];
resampler = wf_resampler_init(format.channelCount(), setup.format.sampleRate(), format.sampleRate(), setup.resampleQuality, &resample_error);
if (setup.codec == 0x40 || setup.codec == 0x80) {
// Opus codec
decoder = opus_decoder_create(setup.format.sampleRate(), setup.format.channelCount(), &opus_err);
qInfo(logAudio()) << "Creating opus decoder: " << opus_strerror(opus_err);
}
}
unsigned int ratioNum;
unsigned int ratioDen;
wf_resampler_get_ratio(resampler, &ratioNum, &ratioDen); qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "thread id" << QThread::currentThreadId();
resampleRatio = static_cast<double>(ratioDen) / ratioNum;
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "wf_resampler_init() returned: " << resample_error << " resampleRatio: " << resampleRatio;
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "thread id" << QThread::currentThreadId();
underTimer = new QTimer(); underTimer = new QTimer();
underTimer->setSingleShot(true); underTimer->setSingleShot(true);
@ -211,9 +189,10 @@ void audioHandler::start()
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "start() running"; qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "start() running";
if (setup.isinput) { if (setup.isinput) {
audioDevice = audioInput->start(); this->open(QIODevice::WriteOnly);
audioInput->start(this);
connect(audioInput, SIGNAL(destroyed()), audioDevice, SLOT(deleteLater()), Qt::UniqueConnection); connect(audioInput, SIGNAL(destroyed()), audioDevice, SLOT(deleteLater()), Qt::UniqueConnection);
connect(audioDevice, SIGNAL(readyRead()), this, SLOT(getNextAudioChunk()), Qt::UniqueConnection); //connect(audioDevice, SIGNAL(readyRead()), this, SLOT(getNextAudioChunk()), Qt::UniqueConnection);
} }
else { else {
// Buffer size must be set before audio is started. // Buffer size must be set before audio is started.
@ -249,6 +228,31 @@ void audioHandler::stop()
audioDevice = Q_NULLPTR; audioDevice = Q_NULLPTR;
} }
qint64 audioHandler::readData(char* data, qint64 nBytes) {
return nBytes;
}
qint64 audioHandler::writeData(const char* data, qint64 nBytes) {
tempBuf.data.append(data,nBytes);
while (tempBuf.data.length() >= format.bytesForDuration(setup.blockSize * 1000)) {
audioPacket packet;
packet.time = QTime::currentTime();
packet.sent = 0;
packet.volume = volume;
memcpy(&packet.guid, setup.guid, GUIDLEN);
QTime startProcessing = QTime::currentTime();
packet.data.clear();
packet.data = tempBuf.data.mid(0, format.bytesForDuration(setup.blockSize * 1000));
tempBuf.data.remove(0, format.bytesForDuration(setup.blockSize * 1000));
emit sendToConverter(packet);
}
return nBytes;
}
void audioHandler::setVolume(unsigned char volume) void audioHandler::setVolume(unsigned char volume)
{ {
this->volume = audiopot[volume]; this->volume = audiopot[volume];
@ -256,386 +260,77 @@ void audioHandler::setVolume(unsigned char volume)
} }
void audioHandler::incomingAudio(audioPacket inPacket) void audioHandler::incomingAudio(audioPacket packet)
{ {
QTime startProcessing = QTime::currentTime(); QTime startProcessing = QTime::currentTime();
audioPacket livePacket = inPacket; packet.volume = volume;
// Process uLaw.
if (setup.ulaw)
{
// Current packet is 8bit so need to create a new buffer that is 16bit
QByteArray outPacket((int)livePacket.data.length() * 2, (char)0xff);
qint16* out = (qint16*)outPacket.data();
for (int f = 0; f < livePacket.data.length(); f++)
{
*out++ = ulaw_decode[(quint8)livePacket.data[f]];
}
livePacket.data.clear();
livePacket.data = outPacket; // Replace incoming data with converted.
}
emit sendToConverter(packet);
/* Opus data */
if (setup.codec == 0x40 || setup.codec == 0x80) {
unsigned char* in = (unsigned char*)inPacket.data.data();
//Decode the frame.
int nSamples = opus_packet_get_nb_samples(in, livePacket.data.size(),setup.format.sampleRate());
if (nSamples == -1) {
// No opus data yet?
return;
}
QByteArray outPacket(nSamples*sizeof(float)*setup.format.channelCount(), (char)0xff); // Preset the output buffer size.
float* out = (float*)outPacket.data();
if (livePacket.seq > lastSentSeq + 1) {
nSamples = opus_decode_float(decoder, Q_NULLPTR,0, out, nSamples, 1);
}
else {
nSamples = opus_decode_float(decoder, in, livePacket.data.size(), out, nSamples, 0);
}
if (nSamples < 0)
{
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus decode failed:" << opus_strerror(nSamples) << "packet size" << livePacket.data.length();
return;
}
else {
if (int(nSamples * sizeof(float) * setup.format.channelCount()) != outPacket.size())
{
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus decoder mismatch: nBytes:" << nSamples * sizeof(float) * setup.format.channelCount() << "outPacket:" << outPacket.size();
outPacket.resize(nSamples * sizeof(float) * setup.format.channelCount());
}
//qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus decoded" << livePacket.data.size() << "bytes, into" << outPacket.length() << "bytes";
livePacket.data.clear();
livePacket.data = outPacket; // Replace incoming data with converted.
}
}
if (!livePacket.data.isEmpty()) {
Eigen::VectorXf samplesF;
if (setup.format.sampleType() == QAudioFormat::SignedInt && setup.format.sampleSize() == 32)
{
Eigen::Ref<VectorXint32> samplesI = Eigen::Map<VectorXint32>(reinterpret_cast<qint32*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(qint32)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint32>::max());
}
else if (setup.format.sampleType() == QAudioFormat::SignedInt && setup.format.sampleSize() == 16)
{
Eigen::Ref<VectorXint16> samplesI = Eigen::Map<VectorXint16>(reinterpret_cast<qint16*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(qint16)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint16>::max());
}
else if (setup.format.sampleType() == QAudioFormat::SignedInt && setup.format.sampleSize() == 8)
{
Eigen::Ref<VectorXint8> samplesI = Eigen::Map<VectorXint8>(reinterpret_cast<qint8*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(qint8)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint8>::max());;
}
else if (setup.format.sampleType() == QAudioFormat::UnSignedInt && setup.format.sampleSize() == 8)
{
Eigen::Ref<VectorXuint8> samplesI = Eigen::Map<VectorXuint8>(reinterpret_cast<quint8*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(quint8)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<quint8>::max());;
}
else if (setup.format.sampleType() == QAudioFormat::Float) {
samplesF = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(float)));
}
else
{
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Unsupported Sample Type:" << format.sampleType();
}
/* samplesF is now an Eigen Vector of the current samples in float format */
// Set the max amplitude found in the vector
// Should it be before or after volume is applied?
amplitude = samplesF.array().abs().maxCoeff();
// Set the volume
samplesF *= volume;
if (setup.format.channelCount() == 2 && format.channelCount() == 1) {
// If we need to drop one of the audio channels, do it now
Eigen::VectorXf samplesTemp(samplesF.size() / 2);
samplesTemp = Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesF.data(), samplesF.size() / 2);
samplesF = samplesTemp;
}
else if (setup.format.channelCount() == 1 && format.channelCount() == 2) {
// Convert mono to stereo if required
Eigen::VectorXf samplesTemp(samplesF.size() * 2);
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data(), samplesF.size()) = samplesF;
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data() + 1, samplesF.size()) = samplesF;
samplesF = samplesTemp;
}
// We now have format.channelCount() (native) channels of audio.
if (resampleRatio != 1.0) {
// We need to resample
// We have a stereo 16bit stream.
quint32 outFrames = ((samplesF.size() / format.channelCount()) * resampleRatio);
quint32 inFrames = (samplesF.size() / format.channelCount());
QByteArray outPacket(outFrames * format.channelCount() * sizeof(float), (char)0xff); // Preset the output buffer size.
const float* in = (float*)samplesF.data();
float* out = (float*)outPacket.data();
int err = 0;
if (format.channelCount() == 1) {
err = wf_resampler_process_float(resampler, 0, in, &inFrames, out, &outFrames);
}
else {
err = wf_resampler_process_interleaved_float(resampler, in, &inFrames, out, &outFrames);
}
if (err) {
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Resampler error " << err << " inFrames:" << inFrames << " outFrames:" << outFrames;
}
samplesF = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(outPacket.data()), outPacket.size() / int(sizeof(float)));
}
if (format.sampleType() == QAudioFormat::UnSignedInt && format.sampleSize() == 8)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<quint8>::max());
VectorXuint8 samplesI = samplesITemp.cast<quint8>();
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(quint8)));
}
if (format.sampleType() == QAudioFormat::SignedInt && format.sampleSize() == 8)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint8>::max());
VectorXint8 samplesI = samplesITemp.cast<qint8>();
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint8)));
}
if (format.sampleType() == QAudioFormat::SignedInt && format.sampleSize() == 16)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint16>::max());
VectorXint16 samplesI = samplesITemp.cast<qint16>();
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint16)));
}
else if (format.sampleType() == QAudioFormat::SignedInt && format.sampleSize() == 32)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint32>::max());
VectorXint32 samplesI = samplesITemp.cast<qint32>();
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint32)));
}
else if (format.sampleType() == QAudioFormat::Float)
{
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesF.data()), int(samplesF.size()) * int(sizeof(float)));
}
else {
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Unsupported Sample Type:" << format.sampleType();
}
currentLatency = livePacket.time.msecsTo(QTime::currentTime()) + (format.durationForBytes(audioOutput->bufferSize()-audioOutput->bytesFree())/1000);
if (audioDevice != Q_NULLPTR) {
audioDevice->write(livePacket.data);
if (lastReceived.msecsTo(QTime::currentTime()) > 100) {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize << "Processing time" << startProcessing.msecsTo(QTime::currentTime());
}
lastReceived = QTime::currentTime();
}
if ((inPacket.seq > lastSentSeq + 1) && (setup.codec == 0x40 || setup.codec == 0x80)) {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Attempting FEC on packet" << inPacket.seq << "as last is" << lastSentSeq;
lastSentSeq = inPacket.seq;
incomingAudio(inPacket); // Call myself again to run the packet a second time (FEC)
}
lastSentSeq = inPacket.seq;
}
emit haveLevels(getAmplitude(), setup.latency, currentLatency,isUnderrun);
return; return;
} }
void audioHandler::convertedOutput(audioPacket packet) {
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (format.durationForBytes(audioOutput->bufferSize() - audioOutput->bytesFree()) / 1000);
if (audioDevice != Q_NULLPTR) {
audioDevice->write(packet.data);
if (lastReceived.msecsTo(QTime::currentTime()) > 100) {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize;
}
lastReceived = QTime::currentTime();
}
/*
if ((packet.seq > lastSentSeq + 1) && (setup.codec == 0x40 || setup.codec == 0x80)) {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Attempting FEC on packet" << packet.seq << "as last is" << lastSentSeq;
lastSentSeq = packet.seq;
incomingAudio(packet); // Call myself again to run the packet a second time (FEC)
}
*/
lastSentSeq = packet.seq;
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun);
amplitude = packet.amplitude;
}
void audioHandler::getNextAudioChunk() void audioHandler::getNextAudioChunk()
{ {
tempBuf.data.append(audioDevice->readAll()); tempBuf.data.append(audioDevice->readAll());
while (tempBuf.data.length() >= format.bytesForDuration(setup.blockSize * 1000)) { while (tempBuf.data.length() >= format.bytesForDuration(setup.blockSize * 1000)) {
audioPacket livePacket; audioPacket packet;
livePacket.time = QTime::currentTime(); packet.time = QTime::currentTime();
livePacket.sent = 0; packet.sent = 0;
memcpy(&livePacket.guid, setup.guid, GUIDLEN); packet.volume = volume;
memcpy(&packet.guid, setup.guid, GUIDLEN);
QTime startProcessing = QTime::currentTime(); QTime startProcessing = QTime::currentTime();
livePacket.data.clear(); packet.data.clear();
livePacket.data = tempBuf.data.mid(0, format.bytesForDuration(setup.blockSize * 1000)); packet.data = tempBuf.data.mid(0, format.bytesForDuration(setup.blockSize * 1000));
tempBuf.data.remove(0, format.bytesForDuration(setup.blockSize * 1000)); tempBuf.data.remove(0, format.bytesForDuration(setup.blockSize * 1000));
if (livePacket.data.length() > 0)
{
Eigen::VectorXf samplesF;
if (format.sampleType() == QAudioFormat::SignedInt && format.sampleSize() == 32)
{
Eigen::Ref<VectorXint32> samplesI = Eigen::Map<VectorXint32>(reinterpret_cast<qint32*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(qint32)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint32>::max());
}
else if (format.sampleType() == QAudioFormat::SignedInt && format.sampleSize() == 16)
{
Eigen::Ref<VectorXint16> samplesI = Eigen::Map<VectorXint16>(reinterpret_cast<qint16*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(qint16)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint16>::max());
}
else if (format.sampleType() == QAudioFormat::UnSignedInt && format.sampleSize() == 8)
{
Eigen::Ref<VectorXuint8> samplesI = Eigen::Map<VectorXuint8>(reinterpret_cast<quint8*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(quint8)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<quint8>::max());;
}
else if (format.sampleType() == QAudioFormat::SignedInt && format.sampleSize() == 8)
{
Eigen::Ref<VectorXint8> samplesI = Eigen::Map<VectorXint8>(reinterpret_cast<qint8*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(qint8)));
samplesF = samplesI.cast<float>() / float(std::numeric_limits<qint8>::max());;
}
else if (format.sampleType() == QAudioFormat::Float)
{
samplesF = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(float)));
}
else {
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Unsupported Sample Type:" << format.sampleType() << format.sampleSize();
}
/* samplesF is now an Eigen Vector of the current samples in float format */ emit sendToConverter(packet);
// Set the max amplitude found in the vector
if (samplesF.size() > 0) {
amplitude = samplesF.array().abs().maxCoeff();
if (resampleRatio != 1.0) {
// We need to resample
// We have a stereo 16bit stream.
quint32 outFrames = ((samplesF.size() / format.channelCount()) * resampleRatio);
quint32 inFrames = (samplesF.size() / format.channelCount());
QByteArray outPacket(outFrames * format.channelCount() * sizeof(float), (char)0xff); // Preset the output buffer size.
const float* in = (float*)samplesF.data();
float* out = (float*)outPacket.data();
int err = 0;
if (format.channelCount() == 1) {
err = wf_resampler_process_float(resampler, 0, in, &inFrames, out, &outFrames);
}
else {
err = wf_resampler_process_interleaved_float(resampler, in, &inFrames, out, &outFrames);
}
if (err) {
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Resampler error " << err << " inFrames:" << inFrames << " outFrames:" << outFrames;
}
samplesF = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(outPacket.data()), outPacket.size() / int(sizeof(float)));
}
// If we need to drop one of the audio channels, do it now
if (format.channelCount() == 2 && setup.format.channelCount() == 1) {
Eigen::VectorXf samplesTemp(samplesF.size() / 2);
samplesTemp = Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesF.data(), samplesF.size() / 2);
samplesF = samplesTemp;
}
else if (format.channelCount() == 1 && setup.format.channelCount() == 2) {
// Convert mono to stereo if required
Eigen::VectorXf samplesTemp(samplesF.size() * 2);
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data(), samplesF.size()) = samplesF;
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data() + 1, samplesF.size()) = samplesF;
samplesF = samplesTemp;
}
//qInfo(logAudio()) << "Sending audio len" << livePacket.data.length() << "remaining" << tempBuf.data.length() << "resampled" << samplesF.size();
if (setup.codec == 0x40 || setup.codec == 0x80)
{
//Are we using the opus codec?
float* in = (float*)samplesF.data();
/* Encode the frame. */
QByteArray outPacket(1275, (char)0xff); // Preset the output buffer size to MAXIMUM possible Opus frame size
unsigned char* out = (unsigned char*)outPacket.data();
int nbBytes = opus_encode_float(encoder, in, (samplesF.size() / setup.format.channelCount()), out, outPacket.length());
if (nbBytes < 0)
{
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus encode failed:" << opus_strerror(nbBytes) << "Num Samples:" << samplesF.size();
return;
}
else {
outPacket.resize(nbBytes);
samplesF = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(outPacket.data()), outPacket.size() / int(sizeof(float)));
}
}
if (setup.format.sampleType() == QAudioFormat::SignedInt && setup.format.sampleSize() == 8)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint8>::max());
VectorXint8 samplesI = samplesITemp.cast<qint8>();
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint8)));
}
else if (setup.format.sampleType() == QAudioFormat::UnSignedInt && setup.format.sampleSize() == 8)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<quint8>::max());
VectorXuint8 samplesI = samplesITemp.cast<quint8>();
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(quint8)));
}
else if (setup.format.sampleType() == QAudioFormat::SignedInt && setup.format.sampleSize() == 16)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint16>::max());
VectorXint16 samplesI = samplesITemp.cast<qint16>();
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint16)));
}
else if (setup.format.sampleType() == QAudioFormat::SignedInt && setup.format.sampleSize() == 32)
{
Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits<qint32>::max());
VectorXint32 samplesI = samplesITemp.cast<qint32>();
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint32)));
}
else if (setup.format.sampleType() == QAudioFormat::Float)
{
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesF.data()), int(samplesF.size()) * int(sizeof(float)));
}
else {
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Unsupported Sample Type:" << format.sampleType();
}
/* Need to find a floating point uLaw encoder!*/
if (setup.ulaw)
{
QByteArray outPacket((int)livePacket.data.length() / 2, (char)0xff);
qint16* in = (qint16*)livePacket.data.data();
for (int f = 0; f < outPacket.length(); f++)
{
qint16 sample = *in++;
if (setup.ulaw) {
int sign = (sample >> 8) & 0x80;
if (sign)
sample = (short)-sample;
if (sample > cClip)
sample = cClip;
sample = (short)(sample + cBias);
int exponent = (int)MuLawCompressTable[(sample >> 7) & 0xFF];
int mantissa = (sample >> (exponent + 3)) & 0x0F;
int compressedByte = ~(sign | (exponent << 4) | mantissa);
outPacket[f] = (quint8)compressedByte;
}
}
livePacket.data.clear();
livePacket.data = outPacket; // Copy output packet back to input buffer.
}
emit haveAudioData(livePacket);
if (lastReceived.msecsTo(QTime::currentTime()) > 100) {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize << "Processing time" << startProcessing.msecsTo(QTime::currentTime());
}
lastReceived = QTime::currentTime();
//ret = livePacket.data;
}
}
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun);
} }
return; return;
} }
void audioHandler::convertedInput(audioPacket audio)
{
emit haveAudioData(audio);
if (lastReceived.msecsTo(QTime::currentTime()) > 100) {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize ;
}
lastReceived = QTime::currentTime();
//ret = livePacket.data;
amplitude = audio.amplitude;
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun);
}
void audioHandler::changeLatency(const quint16 newSize) void audioHandler::changeLatency(const quint16 newSize)
{ {

Wyświetl plik

@ -48,16 +48,14 @@
/* Logarithmic taper for volume control */ /* Logarithmic taper for volume control */
#include "audiotaper.h" #include "audiotaper.h"
/* Audio converter class*/
#include "audioconverter.h"
#define MULAW_BIAS 33 #define MULAW_BIAS 33
#define MULAW_MAX 0x1fff #define MULAW_MAX 0x1fff
struct audioPacket {
quint32 seq;
QTime time;
quint16 sent;
QByteArray data;
quint8 guid[GUIDLEN];
};
struct audioSetup { struct audioSetup {
QString name; QString name;
@ -74,7 +72,7 @@ struct audioSetup {
}; };
// For QtMultimedia, use a native QIODevice // For QtMultimedia, use a native QIODevice
class audioHandler : public QObject class audioHandler : public QIODevice
{ {
Q_OBJECT Q_OBJECT
@ -94,6 +92,8 @@ public slots:
void changeLatency(const quint16 newSize); void changeLatency(const quint16 newSize);
void setVolume(unsigned char volume); void setVolume(unsigned char volume);
void incomingAudio(const audioPacket data); void incomingAudio(const audioPacket data);
void convertedInput(audioPacket audio);
void convertedOutput(audioPacket audio);
private slots: private slots:
void stateChanged(QAudio::State state); void stateChanged(QAudio::State state);
@ -105,8 +105,16 @@ signals:
void sendLatency(quint16 newSize); void sendLatency(quint16 newSize);
void haveAudioData(const audioPacket& data); void haveAudioData(const audioPacket& data);
void haveLevels(quint16 amplitude,quint16 latency,quint16 current,bool under); void haveLevels(quint16 amplitude,quint16 latency,quint16 current,bool under);
void setupConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp);
void sendToConverter(audioPacket audio);
private: private:
qint64 readData(char* data, qint64 nBytes);
qint64 writeData(const char* data, qint64 nBytes);
bool isUnderrun = false; bool isUnderrun = false;
bool isInitialized=false; bool isInitialized=false;
bool isReady = false; bool isReady = false;
@ -117,7 +125,9 @@ private:
QIODevice* audioDevice=Q_NULLPTR; QIODevice* audioDevice=Q_NULLPTR;
QAudioFormat format; QAudioFormat format;
QAudioDeviceInfo deviceInfo; QAudioDeviceInfo deviceInfo;
SpeexResamplerState* resampler = Q_NULLPTR;
audioConverter* converter=Q_NULLPTR;
QThread* converterThread = Q_NULLPTR;
QTime lastReceived; QTime lastReceived;
//r8b::CFixedBuffer<double>* resampBufs; //r8b::CFixedBuffer<double>* resampBufs;
//r8b::CPtrKeeper<r8b::CDSPResampler24*>* resamps; //r8b::CPtrKeeper<r8b::CDSPResampler24*>* resamps;
@ -136,21 +146,14 @@ private:
audioPacket tempBuf; audioPacket tempBuf;
quint16 currentLatency; quint16 currentLatency;
float amplitude; float amplitude;
qreal volume=1.0; qreal volume = 1.0;
audioSetup setup; audioSetup setup;
OpusEncoder* encoder=Q_NULLPTR; OpusEncoder* encoder = Q_NULLPTR;
OpusDecoder* decoder=Q_NULLPTR; OpusDecoder* decoder = Q_NULLPTR;
QTimer* underTimer; QTimer* underTimer;
}; };
// Various audio handling functions declared inline
typedef Eigen::Matrix<quint8, Eigen::Dynamic, 1> VectorXuint8;
typedef Eigen::Matrix<qint8, Eigen::Dynamic, 1> VectorXint8;
typedef Eigen::Matrix<qint16, Eigen::Dynamic, 1> VectorXint16;
typedef Eigen::Matrix<qint32, Eigen::Dynamic, 1> VectorXint32;
#endif // AUDIOHANDLER_H #endif // AUDIOHANDLER_H

Wyświetl plik

@ -9,3 +9,4 @@ Q_LOGGING_CATEGORY(logUdp, "udp")
Q_LOGGING_CATEGORY(logUdpServer, "udp.server") Q_LOGGING_CATEGORY(logUdpServer, "udp.server")
Q_LOGGING_CATEGORY(logRigCtlD, "rigctld") Q_LOGGING_CATEGORY(logRigCtlD, "rigctld")
Q_LOGGING_CATEGORY(logTcpServer, "tcpserver") Q_LOGGING_CATEGORY(logTcpServer, "tcpserver")
Q_LOGGING_CATEGORY(logAudioConverter, "audioconverter")

Wyświetl plik

@ -12,6 +12,7 @@ Q_DECLARE_LOGGING_CATEGORY(logUdp)
Q_DECLARE_LOGGING_CATEGORY(logUdpServer) Q_DECLARE_LOGGING_CATEGORY(logUdpServer)
Q_DECLARE_LOGGING_CATEGORY(logRigCtlD) Q_DECLARE_LOGGING_CATEGORY(logRigCtlD)
Q_DECLARE_LOGGING_CATEGORY(logTcpServer) Q_DECLARE_LOGGING_CATEGORY(logTcpServer)
Q_DECLARE_LOGGING_CATEGORY(logAudioConverter)
#if defined(Q_OS_WIN) && !defined(__PRETTY_FUNCTION__) #if defined(Q_OS_WIN) && !defined(__PRETTY_FUNCTION__)

Wyświetl plik

@ -16,7 +16,8 @@
<Keyword>QtVS_v304</Keyword> <Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion> <WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild></PropertyGroup> <QtMsBuild Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
@ -36,7 +37,10 @@
<IntermediateDirectory>debug\</IntermediateDirectory> <IntermediateDirectory>debug\</IntermediateDirectory>
<PrimaryOutput>wfview</PrimaryOutput> <PrimaryOutput>wfview</PrimaryOutput>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /><Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')"><Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." /></Target> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Label="ExtensionSettings" /> <ImportGroup Label="ExtensionSettings" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
@ -44,8 +48,34 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /><ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')"><Import Project="$(QtMsBuild)\qt_defaults.props" /></ImportGroup><PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"><OutDir>debug\</OutDir><IntDir>debug\</IntDir><TargetName>wfview</TargetName><IgnoreImportLibrary>true</IgnoreImportLibrary></PropertyGroup><PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"><OutDir>release\</OutDir><IntDir>release\</IntDir><TargetName>wfview</TargetName><IgnoreImportLibrary>true</IgnoreImportLibrary><LinkIncremental>false</LinkIncremental></PropertyGroup><PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"><QtInstall>msvc2019</QtInstall><QtModules>core;network;gui;multimedia;widgets;serialport;printsupport</QtModules></PropertyGroup><PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"><QtInstall>msvc2019</QtInstall><QtModules>core;network;gui;multimedia;widgets;serialport;printsupport</QtModules></PropertyGroup><ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')"><Import Project="$(QtMsBuild)\qt.props" /></ImportGroup> <PropertyGroup Label="UserMacros" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>debug\</OutDir>
<IntDir>debug\</IntDir>
<TargetName>wfview</TargetName>
<IgnoreImportLibrary>true</IgnoreImportLibrary>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>release\</OutDir>
<IntDir>release\</IntDir>
<TargetName>wfview</TargetName>
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<QtInstall>msvc2019</QtInstall>
<QtModules>core;network;gui;multimedia;widgets;serialport;printsupport</QtModules>
</PropertyGroup>
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<QtInstall>msvc2019</QtInstall>
<QtModules>core;network;gui;multimedia;widgets;serialport;printsupport</QtModules>
</PropertyGroup>
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
<Import Project="$(QtMsBuild)\qt.props" />
</ImportGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>.;..\qcustomplot;..\opus\include;..\eigen;..\r8brain-free-src;resampler;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;..\qcustomplot;..\opus\include;..\eigen;..\r8brain-free-src;resampler;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@ -59,12 +89,14 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION="1.2e";BUILD_WFVIEW;QT_DEPRECATED_WARNINGS;QCUSTOMPLOT_COMPILE_LIBRARY;USE_SSE;USE_SSE2;OUTSIDE_SPEEX;RANDOM_PREFIX=wf;EIGEN_MPL2_ONLY;EIGEN_DONT_VECTORIZE;EIGEN_VECTORIZE_SSE3;PREFIX="/usr/local";GITSHORT="b510b70";HOST="wfview.org";UNAME="build";NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION="1.2e";BUILD_WFVIEW;QT_DEPRECATED_WARNINGS;QCUSTOMPLOT_COMPILE_LIBRARY;USE_SSE;USE_SSE2;OUTSIDE_SPEEX;RANDOM_PREFIX=wf;EIGEN_MPL2_ONLY;EIGEN_DONT_VECTORIZE;EIGEN_VECTORIZE_SSE3;PREFIX="/usr/local";GITSHORT="b510b70";HOST="wfview.org";UNAME="build";NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile> <PreprocessToFile>false</PreprocessToFile>
<ProgramDataBaseFileName></ProgramDataBaseFileName> <ProgramDataBaseFileName>
</ProgramDataBaseFileName>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<MultiProcessorCompilation>true</MultiProcessorCompilation></ClCompile> <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link> <Link>
<AdditionalDependencies>..\opus\win32\VS2015\Win32\Release\opus.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>..\opus\win32\VS2015\Win32\Release\opus.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\opus\win32\VS2015\Win32\Release;C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\opus\win32\VS2015\Win32\Release;C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -87,7 +119,26 @@
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION=\"1.2e\";BUILD_WFVIEW;QT_DEPRECATED_WARNINGS;QCUSTOMPLOT_COMPILE_LIBRARY;USE_SSE;USE_SSE2;OUTSIDE_SPEEX;RANDOM_PREFIX=wf;EIGEN_MPL2_ONLY;EIGEN_DONT_VECTORIZE;EIGEN_VECTORIZE_SSE3;PREFIX=\"/usr/local\";GITSHORT=\"b510b70\";HOST=\"wfview.org\";UNAME=\"build\";NDEBUG;QT_NO_DEBUG;QT_MULTIMEDIA_LIB;QT_PRINTSUPPORT_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_SERIALPORT_LIB;QT_NETWORK_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION=\"1.2e\";BUILD_WFVIEW;QT_DEPRECATED_WARNINGS;QCUSTOMPLOT_COMPILE_LIBRARY;USE_SSE;USE_SSE2;OUTSIDE_SPEEX;RANDOM_PREFIX=wf;EIGEN_MPL2_ONLY;EIGEN_DONT_VECTORIZE;EIGEN_VECTORIZE_SSE3;PREFIX=\"/usr/local\";GITSHORT=\"b510b70\";HOST=\"wfview.org\";UNAME=\"build\";NDEBUG;QT_NO_DEBUG;QT_MULTIMEDIA_LIB;QT_PRINTSUPPORT_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_SERIALPORT_LIB;QT_NETWORK_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile> </ResourceCompile>
<QtMoc><CompilerFlavor>msvc</CompilerFlavor><Include>./$(Configuration)/moc_predefs.h</Include><ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription><DynamicSource>output</DynamicSource><QtMocDir>$(Configuration)</QtMocDir><QtMocFileName>moc_%(Filename).cpp</QtMocFileName></QtMoc><QtRcc><Compression>default</Compression><ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription><QtRccDir>$(Configuration)</QtRccDir><QtRccFileName>qrc_%(Filename).cpp</QtRccFileName></QtRcc><QtUic><ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription><QtUicDir>$(ProjectDir)</QtUicDir><QtUicFileName>ui_%(Filename).h</QtUicFileName></QtUic></ItemDefinitionGroup> <QtMoc>
<CompilerFlavor>msvc</CompilerFlavor>
<Include>./$(Configuration)/moc_predefs.h</Include>
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
<DynamicSource>output</DynamicSource>
<QtMocDir>$(Configuration)</QtMocDir>
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
</QtMoc>
<QtRcc>
<Compression>default</Compression>
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
<QtRccDir>$(Configuration)</QtRccDir>
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
</QtRcc>
<QtUic>
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
<QtUicDir>$(ProjectDir)</QtUicDir>
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
</QtUic>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>.;..\qcustomplot;..\opus\include;..\eigen;..\r8brain-free-src;resampler;debug;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;..\qcustomplot;..\opus\include;..\eigen;..\r8brain-free-src;resampler;debug;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@ -105,7 +156,8 @@
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<MultiProcessorCompilation>true</MultiProcessorCompilation></ClCompile> <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link> <Link>
<AdditionalDependencies>..\opus\win32\VS2015\Win32\Debug\opus.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>..\opus\win32\VS2015\Win32\Debug\opus.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\opus\win32\VS2015\Win32\Debug;C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\opus\win32\VS2015\Win32\Debug;C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -126,9 +178,29 @@
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION=\"1.2e\";BUILD_WFVIEW;QT_DEPRECATED_WARNINGS;QCUSTOMPLOT_COMPILE_LIBRARY;USE_SSE;USE_SSE2;OUTSIDE_SPEEX;RANDOM_PREFIX=wf;EIGEN_MPL2_ONLY;EIGEN_DONT_VECTORIZE;EIGEN_VECTORIZE_SSE3;PREFIX=\"/usr/local\";GITSHORT=\"b510b70\";HOST=\"wfview.org\";UNAME=\"build\";QT_MULTIMEDIA_LIB;QT_PRINTSUPPORT_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_SERIALPORT_LIB;QT_NETWORK_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION=\"1.2e\";BUILD_WFVIEW;QT_DEPRECATED_WARNINGS;QCUSTOMPLOT_COMPILE_LIBRARY;USE_SSE;USE_SSE2;OUTSIDE_SPEEX;RANDOM_PREFIX=wf;EIGEN_MPL2_ONLY;EIGEN_DONT_VECTORIZE;EIGEN_VECTORIZE_SSE3;PREFIX=\"/usr/local\";GITSHORT=\"b510b70\";HOST=\"wfview.org\";UNAME=\"build\";QT_MULTIMEDIA_LIB;QT_PRINTSUPPORT_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_SERIALPORT_LIB;QT_NETWORK_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile> </ResourceCompile>
<QtMoc><CompilerFlavor>msvc</CompilerFlavor><Include>./$(Configuration)/moc_predefs.h</Include><ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription><DynamicSource>output</DynamicSource><QtMocDir>$(Configuration)</QtMocDir><QtMocFileName>moc_%(Filename).cpp</QtMocFileName></QtMoc><QtRcc><Compression>default</Compression><ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription><QtRccDir>$(Configuration)</QtRccDir><QtRccFileName>qrc_%(Filename).cpp</QtRccFileName></QtRcc><QtUic><ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription><QtUicDir>$(ProjectDir)</QtUicDir><QtUicFileName>ui_%(Filename).h</QtUicFileName></QtUic></ItemDefinitionGroup> <QtMoc>
<CompilerFlavor>msvc</CompilerFlavor>
<Include>./$(Configuration)/moc_predefs.h</Include>
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
<DynamicSource>output</DynamicSource>
<QtMocDir>$(Configuration)</QtMocDir>
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
</QtMoc>
<QtRcc>
<Compression>default</Compression>
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
<QtRccDir>$(Configuration)</QtRccDir>
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
</QtRcc>
<QtUic>
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
<QtUicDir>$(ProjectDir)</QtUicDir>
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
</QtUic>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="aboutbox.cpp" /> <ClCompile Include="aboutbox.cpp" />
<ClCompile Include="audioconverter.cpp" />
<ClCompile Include="audiohandler.cpp" /> <ClCompile Include="audiohandler.cpp" />
<ClCompile Include="calibrationwindow.cpp" /> <ClCompile Include="calibrationwindow.cpp" />
<ClCompile Include="commhandler.cpp" /> <ClCompile Include="commhandler.cpp" />
@ -154,207 +226,54 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="aboutbox.h"> <QtMoc Include="aboutbox.h">
</QtMoc> </QtMoc>
<QtMoc Include="audioconverter.h" />
<ClInclude Include="resampler\arch.h" /> <ClInclude Include="resampler\arch.h" />
<QtMoc Include="audiohandler.h"> <QtMoc Include="audiohandler.h">
</QtMoc> </QtMoc>
<ClInclude Include="audiotaper.h" /> <ClInclude Include="audiotaper.h" />
<QtMoc Include="calibrationwindow.h"> <QtMoc Include="calibrationwindow.h">
</QtMoc> </QtMoc>
<QtMoc Include="commhandler.h"> <QtMoc Include="commhandler.h">
</QtMoc> </QtMoc>
<ClInclude Include="freqmemory.h" /> <ClInclude Include="freqmemory.h" />
<ClInclude Include="logcategories.h" /> <ClInclude Include="logcategories.h" />
<QtMoc Include="meter.h"> <QtMoc Include="meter.h">
</QtMoc> </QtMoc>
<ClInclude Include="packettypes.h" /> <ClInclude Include="packettypes.h" />
<QtMoc Include="pttyhandler.h"> <QtMoc Include="pttyhandler.h">
</QtMoc> </QtMoc>
<QtMoc Include="..\qcustomplot\qcustomplot.h"> <QtMoc Include="..\qcustomplot\qcustomplot.h">
</QtMoc> </QtMoc>
<QtMoc Include="qledlabel.h"> <QtMoc Include="qledlabel.h">
</QtMoc> </QtMoc>
<ClInclude Include="repeaterattributes.h" /> <ClInclude Include="repeaterattributes.h" />
<QtMoc Include="repeatersetup.h"> <QtMoc Include="repeatersetup.h">
</QtMoc> </QtMoc>
<ClInclude Include="resampler\resample_sse.h" /> <ClInclude Include="resampler\resample_sse.h" />
<QtMoc Include="rigcommander.h"> <QtMoc Include="rigcommander.h">
</QtMoc> </QtMoc>
<QtMoc Include="rigctld.h"> <QtMoc Include="rigctld.h">
</QtMoc> </QtMoc>
<ClInclude Include="rigidentities.h" /> <ClInclude Include="rigidentities.h" />
<QtMoc Include="satellitesetup.h"> <QtMoc Include="satellitesetup.h">
</QtMoc> </QtMoc>
<QtMoc Include="selectradio.h"> <QtMoc Include="selectradio.h">
</QtMoc> </QtMoc>
<ClInclude Include="resampler\speex_resampler.h" /> <ClInclude Include="resampler\speex_resampler.h" />
<QtMoc Include="tcpserver.h"> <QtMoc Include="tcpserver.h">
</QtMoc> </QtMoc>
<QtMoc Include="transceiveradjustments.h"> <QtMoc Include="transceiveradjustments.h">
</QtMoc> </QtMoc>
<QtMoc Include="udphandler.h"> <QtMoc Include="udphandler.h">
</QtMoc> </QtMoc>
<QtMoc Include="udpserver.h"> <QtMoc Include="udpserver.h">
</QtMoc> </QtMoc>
<ClInclude Include="ulaw.h" /> <ClInclude Include="ulaw.h" />
<QtMoc Include="wfmain.h"> <QtMoc Include="wfmain.h">
</QtMoc> </QtMoc>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt"> <CustomBuild Include="debug\moc_predefs.h.cbt">
<FileType>Document</FileType> <FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -371,121 +290,21 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">release\moc_predefs.h;%(Outputs)</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">release\moc_predefs.h;%(Outputs)</Outputs>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</CustomBuild> </CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtUic Include="aboutbox.ui"> <QtUic Include="aboutbox.ui">
</QtUic> </QtUic>
<QtUic Include="calibrationwindow.ui"> <QtUic Include="calibrationwindow.ui">
</QtUic> </QtUic>
<QtUic Include="repeatersetup.ui"> <QtUic Include="repeatersetup.ui">
</QtUic> </QtUic>
<QtUic Include="satellitesetup.ui"> <QtUic Include="satellitesetup.ui">
</QtUic> </QtUic>
<QtUic Include="selectradio.ui"> <QtUic Include="selectradio.ui">
</QtUic> </QtUic>
<QtUic Include="transceiveradjustments.ui"> <QtUic Include="transceiveradjustments.ui">
</QtUic> </QtUic>
<QtUic Include="wfmain.ui"> <QtUic Include="wfmain.ui">
</QtUic> </QtUic>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -519,30 +338,16 @@
<None Include="qdarkstyle\rc\radio_unchecked_disabled.png" /> <None Include="qdarkstyle\rc\radio_unchecked_disabled.png" />
<None Include="qdarkstyle\rc\radio_unchecked_focus.png" /> <None Include="qdarkstyle\rc\radio_unchecked_focus.png" />
<QtRcc Include="resources\resources.qrc"> <QtRcc Include="resources\resources.qrc">
<InitFuncName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">resources</InitFuncName>
<InitFuncName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">resources</InitFuncName>
</QtRcc>
<InitFuncName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">resources</InitFuncName><InitFuncName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">resources</InitFuncName></QtRcc>
<None Include="qdarkstyle\rc\right_arrow.png" /> <None Include="qdarkstyle\rc\right_arrow.png" />
<None Include="qdarkstyle\rc\right_arrow_disabled.png" /> <None Include="qdarkstyle\rc\right_arrow_disabled.png" />
<None Include="qdarkstyle\rc\sizegrip.png" /> <None Include="qdarkstyle\rc\sizegrip.png" />
<QtRcc Include="qdarkstyle\style.qrc"> <QtRcc Include="qdarkstyle\style.qrc">
<InitFuncName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">style</InitFuncName>
<InitFuncName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">style</InitFuncName>
</QtRcc>
<InitFuncName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">style</InitFuncName><InitFuncName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">style</InitFuncName></QtRcc>
<None Include="qdarkstyle\style.qss" /> <None Include="qdarkstyle\style.qss" />
<None Include="qdarkstyle\rc\stylesheet-branch-end.png" /> <None Include="qdarkstyle\rc\stylesheet-branch-end.png" />
<None Include="qdarkstyle\rc\stylesheet-branch-more.png" /> <None Include="qdarkstyle\rc\stylesheet-branch-more.png" />
@ -556,6 +361,9 @@
<ItemGroup> <ItemGroup>
<ResourceCompile Include=".\wfview_resource.rc" /> <ResourceCompile Include=".\wfview_resource.rc" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /><ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')"><Import Project="$(QtMsBuild)\qt.targets" /></ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets" /> <ImportGroup Label="ExtensionTargets" />
</Project> </Project>

Wyświetl plik

@ -116,6 +116,9 @@
<ClCompile Include="wfmain.cpp"> <ClCompile Include="wfmain.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="audioconverter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="aboutbox.h"> <QtMoc Include="aboutbox.h">
@ -202,61 +205,17 @@
<QtMoc Include="wfmain.h"> <QtMoc Include="wfmain.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="audioconverter.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt"> <CustomBuild Include="debug\moc_predefs.h.cbt">
<Filter>Generated Files</Filter> <Filter>Generated Files</Filter>
</CustomBuild> </CustomBuild>
<CustomBuild Include="release\moc_predefs.h.cbt"> <CustomBuild Include="release\moc_predefs.h.cbt">
<Filter>Generated Files</Filter> <Filter>Generated Files</Filter>
</CustomBuild> </CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtUic Include="aboutbox.ui"> <QtUic Include="aboutbox.ui">
@ -413,6 +372,6 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="C:\Users\Phil\source\repos\wfview\wfview_resource.rc" /> <ResourceCompile Include=".\wfview_resource.rc" />
</ItemGroup> </ItemGroup>
</Project> </Project>