kopia lustrzana https://gitlab.com/eliggett/wfview
Working (in Windows) audio output
rodzic
8ec62fec8d
commit
389f661c79
262
audiohandler.cpp
262
audiohandler.cpp
|
@ -73,28 +73,30 @@ bool audioHandler::init(audioSetup setupIn)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setup = setupIn;
|
setup = setupIn;
|
||||||
setup.radioChan = 1;
|
setup.format.setChannelCount(1);
|
||||||
setup.bits = 8;
|
setup.format.setSampleSize(8);
|
||||||
|
setup.format.setSampleType(QAudioFormat::UnSignedInt);
|
||||||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "audio handler starting:" << setup.name;
|
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "audio handler starting:" << setup.name;
|
||||||
|
|
||||||
if (setup.codec == 0x01 || setup.codec == 0x20) {
|
if (setup.codec == 0x01 || setup.codec == 0x20) {
|
||||||
setup.ulaw = true;
|
setup.ulaw = true;
|
||||||
}
|
}
|
||||||
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) {
|
||||||
setup.radioChan = 2;
|
setup.format.setChannelCount(2);
|
||||||
}
|
}
|
||||||
if (setup.codec == 0x04 || setup.codec == 0x10 || setup.codec == 0x40 || setup.codec == 0x80) {
|
if (setup.codec == 0x04 || setup.codec == 0x10 || setup.codec == 0x40 || setup.codec == 0x80) {
|
||||||
setup.bits = 16;
|
setup.format.setSampleSize(16);
|
||||||
|
setup.format.setSampleType(QAudioFormat::SignedInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug(logAudio()) << "Creating" << (setup.isinput ? "Input" : "Output") << "audio device:" << setup.name <<
|
qDebug(logAudio()) << "Creating" << (setup.isinput ? "Input" : "Output") << "audio device:" << setup.name <<
|
||||||
", bits" << setup.bits <<
|
", bits" << setup.format.sampleSize() <<
|
||||||
", codec" << setup.codec <<
|
", codec" << setup.codec <<
|
||||||
", latency" << setup.latency <<
|
", latency" << setup.latency <<
|
||||||
", localAFGain" << setup.localAFgain <<
|
", localAFGain" << setup.localAFgain <<
|
||||||
", radioChan" << setup.radioChan <<
|
", radioChan" << setup.format.channelCount() <<
|
||||||
", resampleQuality" << setup.resampleQuality <<
|
", resampleQuality" << setup.resampleQuality <<
|
||||||
", samplerate" << setup.samplerate <<
|
", samplerate" << setup.format.sampleRate() <<
|
||||||
", uLaw" << setup.ulaw;
|
", uLaw" << setup.ulaw;
|
||||||
|
|
||||||
|
|
||||||
|
@ -325,11 +327,9 @@ bool audioHandler::init(audioSetup setupIn)
|
||||||
else {
|
else {
|
||||||
audioOutput = new QAudioOutput(setup.port, format, this);
|
audioOutput = new QAudioOutput(setup.port, format, this);
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
audioOutput->setBufferSize(getAudioSize(setup.latency, format));
|
||||||
audioOutput->setBufferSize(chunkSize*4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
connect(audioOutput, SIGNAL(notify()), SLOT(notified()));
|
//connect(audioOutput, SIGNAL(notify()), SLOT(notified()));
|
||||||
connect(audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
connect(audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
}
|
}
|
||||||
|
@ -339,10 +339,10 @@ bool audioHandler::init(audioSetup setupIn)
|
||||||
int resample_error = 0;
|
int resample_error = 0;
|
||||||
int opus_err = 0;
|
int opus_err = 0;
|
||||||
if (setup.isinput) {
|
if (setup.isinput) {
|
||||||
resampler = wf_resampler_init(devChannels, nativeSampleRate, setup.samplerate, setup.resampleQuality, &resample_error);
|
resampler = wf_resampler_init(devChannels, nativeSampleRate, setup.format.sampleRate(), setup.resampleQuality, &resample_error);
|
||||||
if (setup.codec == 0x40 || setup.codec == 0x80) {
|
if (setup.codec == 0x40 || setup.codec == 0x80) {
|
||||||
// Opus codec
|
// Opus codec
|
||||||
encoder = opus_encoder_create(setup.samplerate, setup.radioChan, OPUS_APPLICATION_AUDIO, &opus_err);
|
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_LSB_DEPTH(16));
|
||||||
opus_encoder_ctl(encoder, OPUS_SET_INBAND_FEC(1));
|
opus_encoder_ctl(encoder, OPUS_SET_INBAND_FEC(1));
|
||||||
opus_encoder_ctl(encoder, OPUS_SET_DTX(1));
|
opus_encoder_ctl(encoder, OPUS_SET_DTX(1));
|
||||||
|
@ -351,10 +351,13 @@ bool audioHandler::init(audioSetup setupIn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
resampler = wf_resampler_init(devChannels, setup.samplerate, this->nativeSampleRate, setup.resampleQuality, &resample_error);
|
|
||||||
|
//resampBufs = new r8b::CFixedBuffer<double>[format.channelCount()];
|
||||||
|
//resamps = new r8b::CPtrKeeper<r8b::CDSPResampler24*>[format.channelCount()];
|
||||||
|
resampler = wf_resampler_init(devChannels, setup.format.sampleRate(), this->nativeSampleRate, setup.resampleQuality, &resample_error);
|
||||||
if (setup.codec == 0x40 || setup.codec == 0x80) {
|
if (setup.codec == 0x40 || setup.codec == 0x80) {
|
||||||
// Opus codec
|
// Opus codec
|
||||||
decoder = opus_decoder_create(setup.samplerate, setup.radioChan, &opus_err);
|
decoder = opus_decoder_create(setup.format.sampleRate(), setup.format.sampleRate(), &opus_err);
|
||||||
qInfo(logAudio()) << "Creating opus decoder: " << opus_strerror(opus_err);
|
qInfo(logAudio()) << "Creating opus decoder: " << opus_strerror(opus_err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,9 +403,18 @@ void audioHandler::start()
|
||||||
this->open(QIODevice::ReadOnly);
|
this->open(QIODevice::ReadOnly);
|
||||||
#else
|
#else
|
||||||
//this->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
//this->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||||
this->open(QIODevice::ReadOnly);
|
//this->open(QIODevice::ReadOnly);
|
||||||
#endif
|
#endif
|
||||||
audioOutput->start(this);
|
audioDevice = audioOutput->start();
|
||||||
|
if (!audioDevice)
|
||||||
|
{
|
||||||
|
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio device failed to start()";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connect(audioOutput, &QAudioOutput::destroyed, audioDevice, &QIODevice::deleteLater, Qt::UniqueConnection);
|
||||||
|
connect(audioDevice, &QIODevice::destroyed, this, &QAudioOutput::deleteLater, Qt::UniqueConnection);
|
||||||
|
audioBuffered = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -612,45 +624,30 @@ void audioHandler::incomingAudio(audioPacket inPacket)
|
||||||
// Regardless of the radio stream format, the buffered audio will ALWAYS be
|
// Regardless of the radio stream format, the buffered audio will ALWAYS be
|
||||||
// 16bit sample interleaved stereo 48K (or whatever the native sample rate is)
|
// 16bit sample interleaved stereo 48K (or whatever the native sample rate is)
|
||||||
|
|
||||||
if (inPacket.time.msecsTo(QTime::currentTime()) > 20)
|
|
||||||
{
|
|
||||||
qInfo(logUdp()) << "Audio took" << inPacket.time.msecsTo(QTime::currentTime()) << "ms to arrive!";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isInitialized && !isReady)
|
|
||||||
{
|
|
||||||
qDebug(logAudio()) << "Packet received when stream was not ready";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!audioBuffered && ringBuf->size() > ringBuf->capacity() / 2)
|
|
||||||
{
|
|
||||||
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio buffering complete, capacity:" << ringBuf->capacity() << ", used:" << ringBuf->size();
|
|
||||||
audioBuffered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
audioPacket livePacket = inPacket;
|
audioPacket livePacket = inPacket;
|
||||||
|
|
||||||
if (setup.codec == 0x40 || setup.codec == 0x80) {
|
if (setup.codec == 0x40 || setup.codec == 0x80) {
|
||||||
|
/* Opus data */
|
||||||
unsigned char* in = (unsigned char*)inPacket.data.data();
|
unsigned char* in = (unsigned char*)inPacket.data.data();
|
||||||
|
|
||||||
/* Decode the frame. */
|
/* Decode the frame. */
|
||||||
QByteArray outPacket((setup.samplerate / 50) * sizeof(qint16) * setup.radioChan, (char)0xff); // Preset the output buffer size.
|
QByteArray outPacket((setup.format.sampleRate() / 50) * sizeof(qint16) * setup.format.channelCount(), (char)0xff); // Preset the output buffer size.
|
||||||
qint16* out = (qint16*)outPacket.data();
|
qint16* out = (qint16*)outPacket.data();
|
||||||
int nSamples = opus_packet_get_nb_samples(in, livePacket.data.size(),setup.samplerate);
|
int nSamples = opus_packet_get_nb_samples(in, livePacket.data.size(),setup.format.sampleRate());
|
||||||
if (nSamples == -1) {
|
if (nSamples == -1) {
|
||||||
// No opus data yet?
|
// No opus data yet?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (nSamples != setup.samplerate / 50)
|
else if (nSamples != setup.format.sampleRate() / 50)
|
||||||
{
|
{
|
||||||
qInfo(logAudio()) << "Opus nSamples=" << nSamples << " expected:" << (setup.samplerate / 50);
|
qInfo(logAudio()) << "Opus nSamples=" << nSamples << " expected:" << (setup.format.sampleRate() / 50);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (livePacket.seq > lastSentSeq + 1) {
|
if (livePacket.seq > lastSentSeq + 1) {
|
||||||
nSamples = opus_decode(decoder, in, livePacket.data.size(), out, (setup.samplerate / 50), 1);
|
nSamples = opus_decode(decoder, in, livePacket.data.size(), out, (setup.format.sampleRate() / 50), 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nSamples = opus_decode(decoder, in, livePacket.data.size(), out, (setup.samplerate / 50), 0);
|
nSamples = opus_decode(decoder, in, livePacket.data.size(), out, (setup.format.sampleRate() / 50), 0);
|
||||||
}
|
}
|
||||||
if (nSamples < 0)
|
if (nSamples < 0)
|
||||||
{
|
{
|
||||||
|
@ -658,10 +655,10 @@ void audioHandler::incomingAudio(audioPacket inPacket)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (int(nSamples * sizeof(qint16) * setup.radioChan) != outPacket.size())
|
if (int(nSamples * sizeof(qint16) * setup.format.channelCount()) != outPacket.size())
|
||||||
{
|
{
|
||||||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus decoder mismatch: nBytes:" << nSamples * sizeof(qint16) * setup.radioChan << "outPacket:" << outPacket.size();
|
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus decoder mismatch: nBytes:" << nSamples * sizeof(qint16) * setup.format.channelCount() << "outPacket:" << outPacket.size();
|
||||||
outPacket.resize(nSamples * sizeof(qint16) * setup.radioChan);
|
outPacket.resize(nSamples * sizeof(qint16) * setup.format.channelCount());
|
||||||
}
|
}
|
||||||
//qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus decoded" << livePacket.data.size() << "bytes, into" << outPacket.length() << "bytes";
|
//qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus decoded" << livePacket.data.size() << "bytes, into" << outPacket.length() << "bytes";
|
||||||
livePacket.data.clear();
|
livePacket.data.clear();
|
||||||
|
@ -669,105 +666,100 @@ void audioHandler::incomingAudio(audioPacket inPacket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//qDebug(logAudio()) << "Got" << setup.bits << "bits, length" << livePacket.data.length();
|
// Process uLaw
|
||||||
// Incoming data is 8bits?
|
if (setup.ulaw)
|
||||||
int tempAmplitude=0;
|
|
||||||
if (setup.bits == 8)
|
|
||||||
{
|
{
|
||||||
// Current packet is 8bit so need to create a new buffer that is 16bit
|
// Current packet is 8bit so need to create a new buffer that is 16bit
|
||||||
QByteArray outPacket((int)livePacket.data.length() * 2 * (devChannels / setup.radioChan), (char)0xff);
|
QByteArray outPacket((int)livePacket.data.length() * 2, (char)0xff);
|
||||||
qint16* out = (qint16*)outPacket.data();
|
qint16* out = (qint16*)outPacket.data();
|
||||||
for (int f = 0; f < livePacket.data.length(); f++)
|
for (int f = 0; f < livePacket.data.length(); f++)
|
||||||
{
|
{
|
||||||
int samp = (quint8)livePacket.data[f];
|
*out++ = ulaw_decode[(quint8)livePacket.data[f]];
|
||||||
tempAmplitude = qMax(tempAmplitude, abs(samp));
|
|
||||||
for (int g = setup.radioChan; g <= devChannels; g++)
|
|
||||||
{
|
|
||||||
if (setup.ulaw) {
|
|
||||||
*out++ = ulaw_decode[samp] * this->volume;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*out++ = (qint16)((samp - 128) << 8) * this->volume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
livePacket.data.clear();
|
livePacket.data.clear();
|
||||||
livePacket.data = outPacket; // Replace incoming data with converted.
|
livePacket.data = outPacket; // Replace incoming data with converted.
|
||||||
|
setup.format.setSampleSize(16);
|
||||||
|
setup.format.setSampleType(QAudioFormat::SignedInt);
|
||||||
|
// Buffer now contains 16bit signed samples.
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// This is already a 16bit stream, do we need to convert to stereo?
|
|
||||||
if (setup.radioChan == 1 && devChannels > 1) {
|
if (!livePacket.data.isEmpty()) {
|
||||||
// Yes
|
|
||||||
QByteArray outPacket(livePacket.data.length() * 2, (char)0xff); // Preset the output buffer size.
|
Eigen::VectorXf samplesF;
|
||||||
qint16* in = (qint16*)livePacket.data.data();
|
if (setup.format.sampleSize() == 16)
|
||||||
|
{
|
||||||
|
VectorXint16 samplesI = Eigen::Map<VectorXint16>(reinterpret_cast<qint16*>(livePacket.data.data()), livePacket.data.size() / int(sizeof(qint16)));
|
||||||
|
samplesF = samplesI.cast<float>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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());;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the max amplitude found in the vector
|
||||||
|
amplitude = samplesF.array().abs().maxCoeff();
|
||||||
|
|
||||||
|
// Set the volume
|
||||||
|
samplesF *= volume;
|
||||||
|
|
||||||
|
// Convert mono to stereo
|
||||||
|
if (setup.format.channelCount() == 1) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (format.sampleType() == QAudioFormat::SignedInt)
|
||||||
|
{
|
||||||
|
VectorXint16 samplesI = samplesF.cast<qint16>();
|
||||||
|
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesI.data()), int(samplesI.size()) * int(sizeof(qint16)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
livePacket.data = QByteArray(reinterpret_cast<char*>(samplesF.data()), int(samplesF.size()) * int(sizeof(float)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (resampleRatio != 1.0) {
|
||||||
|
|
||||||
|
// We need to resample
|
||||||
|
// We have a stereo 16bit stream.
|
||||||
|
quint32 outFrames = ((livePacket.data.length() / 2 / devChannels) * resampleRatio);
|
||||||
|
quint32 inFrames = (livePacket.data.length() / 2 / devChannels);
|
||||||
|
QByteArray outPacket(outFrames * 4, (char)0xff); // Preset the output buffer size.
|
||||||
|
|
||||||
|
const qint16* in = (qint16*)livePacket.data.constData();
|
||||||
qint16* out = (qint16*)outPacket.data();
|
qint16* out = (qint16*)outPacket.data();
|
||||||
for (int f = 0; f < livePacket.data.length() / 2; f++)
|
|
||||||
{
|
int err = 0;
|
||||||
tempAmplitude = qMax(tempAmplitude, (int)(abs(*in) / 256));
|
err = wf_resampler_process_interleaved_int(resampler, in, &inFrames, out, &outFrames);
|
||||||
*out++ = (qint16)*in * this->volume;
|
if (err) {
|
||||||
*out++ = (qint16)*in++ * this->volume;
|
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Resampler error " << err << " inFrames:" << inFrames << " outFrames:" << outFrames;
|
||||||
}
|
}
|
||||||
livePacket.data.clear();
|
livePacket.data.clear();
|
||||||
livePacket.data = outPacket; // Replace incoming data with converted.
|
livePacket.data = outPacket; // Replace incoming data with converted.
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// We already have the same number of channels so just update volume.
|
//qDebug(logAudio()) << "Adding packet to buffer:" << livePacket.seq << ": " << livePacket.data.length();
|
||||||
qint16* in = (qint16*)livePacket.data.data();
|
|
||||||
for (int f = 0; f < livePacket.data.length() / 2; f++)
|
currentLatency = livePacket.time.msecsTo(QTime::currentTime());
|
||||||
{
|
|
||||||
tempAmplitude = qMax(tempAmplitude, (int)(abs(*in) / 256));
|
audioDevice->write(livePacket.data);
|
||||||
*in = *in * this->volume;
|
|
||||||
in++;
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
amplitude = tempAmplitude;
|
|
||||||
/* We now have an array of 16bit samples in the NATIVE samplerate of the radio
|
|
||||||
If the radio sample rate is below 48000, we need to resample.
|
|
||||||
*/
|
|
||||||
//qDebug(logAudio()) << "Now 16 bit stereo, length" << livePacket.data.length();
|
|
||||||
|
|
||||||
if (resampleRatio != 1.0) {
|
|
||||||
|
|
||||||
// We need to resample
|
|
||||||
// We have a stereo 16bit stream.
|
|
||||||
quint32 outFrames = ((livePacket.data.length() / 2 / devChannels) * resampleRatio);
|
|
||||||
quint32 inFrames = (livePacket.data.length() / 2 / devChannels);
|
|
||||||
QByteArray outPacket(outFrames * 4, (char)0xff); // Preset the output buffer size.
|
|
||||||
|
|
||||||
const qint16* in = (qint16*)livePacket.data.constData();
|
|
||||||
qint16* out = (qint16*)outPacket.data();
|
|
||||||
|
|
||||||
int err = 0;
|
|
||||||
err = wf_resampler_process_interleaved_int(resampler, in, &inFrames, out, &outFrames);
|
|
||||||
if (err) {
|
|
||||||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Resampler error " << err << " inFrames:" << inFrames << " outFrames:" << outFrames;
|
|
||||||
}
|
|
||||||
livePacket.data.clear();
|
|
||||||
livePacket.data = outPacket; // Replace incoming data with converted.
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug(logAudio()) << "Adding packet to buffer:" << livePacket.seq << ": " << livePacket.data.length();
|
|
||||||
|
|
||||||
if (!ringBuf->try_write(livePacket))
|
|
||||||
{
|
|
||||||
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Buffer full! capacity:" << ringBuf->capacity() << "length" << ringBuf->size();
|
|
||||||
while (ringBuf->try_read(inPacket)); // Empty buffer
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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;
|
lastSentSeq = inPacket.seq;
|
||||||
incomingAudio(inPacket); // Call myself again to run the packet a second time (FEC)
|
|
||||||
}
|
}
|
||||||
lastSentSeq = inPacket.seq;
|
|
||||||
//if (inPacket.time.msecsTo(QTime::currentTime()) > 20)
|
|
||||||
//{
|
|
||||||
//qDebug(logAudio()) << "After processing, audio took" << inPacket.time.msecsTo(QTime::currentTime()) << "ms to arrive!";
|
|
||||||
//}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -776,9 +768,18 @@ void audioHandler::changeLatency(const quint16 newSize)
|
||||||
{
|
{
|
||||||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Changing latency to: " << newSize << " from " << setup.latency;
|
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Changing latency to: " << newSize << " from " << setup.latency;
|
||||||
setup.latency = newSize;
|
setup.latency = newSize;
|
||||||
delete ringBuf;
|
//delete ringBuf;
|
||||||
audioBuffered = false;
|
//audioBuffered = false;
|
||||||
ringBuf = new wilt::Ring<audioPacket>(setup.latency + 1); // Should be customizable.
|
//ringBuf = new wilt::Ring<audioPacket>(setup.latency + 1); // Should be customizable.
|
||||||
|
if (!setup.isinput) {
|
||||||
|
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Current buffer size is" << audioOutput->bufferSize() << " " << getAudioDuration(audioOutput->bufferSize(), format) << "ms)";
|
||||||
|
audioOutput->stop();
|
||||||
|
audioOutput->setBufferSize(getAudioSize(setup.latency, format));
|
||||||
|
audioDevice = audioOutput->start();
|
||||||
|
connect(audioOutput, &QAudioOutput::destroyed, audioDevice, &QIODevice::deleteLater, Qt::UniqueConnection);
|
||||||
|
connect(audioDevice, &QIODevice::destroyed, this, &QAudioOutput::deleteLater, Qt::UniqueConnection);
|
||||||
|
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "New buffer size is" << audioOutput->bufferSize() << " " << getAudioDuration(audioOutput->bufferSize(), format) << "ms)";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int audioHandler::getLatency()
|
int audioHandler::getLatency()
|
||||||
|
@ -830,7 +831,7 @@ void audioHandler::getNextAudioChunk(QByteArray& ret)
|
||||||
|
|
||||||
int tempAmplitude = 0;
|
int tempAmplitude = 0;
|
||||||
// Do we need to convert mono to stereo?
|
// Do we need to convert mono to stereo?
|
||||||
if (setup.radioChan == 1 && devChannels > 1)
|
if (setup.format.channelCount() == 1 && devChannels > 1)
|
||||||
{
|
{
|
||||||
// Strip out right channel?
|
// Strip out right channel?
|
||||||
QByteArray outPacket(packet.data.length()/2, (char)0xff);
|
QByteArray outPacket(packet.data.length()/2, (char)0xff);
|
||||||
|
@ -857,7 +858,7 @@ void audioHandler::getNextAudioChunk(QByteArray& ret)
|
||||||
QByteArray outPacket(1275, (char)0xff); // Preset the output buffer size to MAXIMUM possible Opus frame size
|
QByteArray outPacket(1275, (char)0xff); // Preset the output buffer size to MAXIMUM possible Opus frame size
|
||||||
unsigned char* out = (unsigned char*)outPacket.data();
|
unsigned char* out = (unsigned char*)outPacket.data();
|
||||||
|
|
||||||
int nbBytes = opus_encode(encoder, in, (setup.samplerate / 50), out, outPacket.length());
|
int nbBytes = opus_encode(encoder, in, (setup.format.sampleRate() / 50), out, outPacket.length());
|
||||||
if (nbBytes < 0)
|
if (nbBytes < 0)
|
||||||
{
|
{
|
||||||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus encode failed:" << opus_strerror(nbBytes);
|
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Opus encode failed:" << opus_strerror(nbBytes);
|
||||||
|
@ -870,7 +871,7 @@ void audioHandler::getNextAudioChunk(QByteArray& ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (setup.bits == 8)
|
else if (setup.format.sampleSize() == 8)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Do we need to convert 16-bit to 8-bit?
|
// Do we need to convert 16-bit to 8-bit?
|
||||||
|
@ -908,7 +909,6 @@ void audioHandler::getNextAudioChunk(QByteArray& ret)
|
||||||
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Too many delayed packets, flushing buffer";
|
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Too many delayed packets, flushing buffer";
|
||||||
while (ringBuf->try_read(packet)); // Empty buffer
|
while (ringBuf->try_read(packet)); // Empty buffer
|
||||||
delayedPackets = 0;
|
delayedPackets = 0;
|
||||||
audioBuffered = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -997,6 +997,6 @@ void audioHandler::stop()
|
||||||
|
|
||||||
quint16 audioHandler::getAmplitude()
|
quint16 audioHandler::getAmplitude()
|
||||||
{
|
{
|
||||||
return amplitude;
|
return *reinterpret_cast<quint16*>(&litude);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
226
audiohandler.h
226
audiohandler.h
|
@ -25,20 +25,10 @@
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Eigen>
|
|
||||||
|
|
||||||
#include "packettypes.h"
|
#include "packettypes.h"
|
||||||
|
|
||||||
typedef signed short MY_TYPE;
|
typedef signed short MY_TYPE;
|
||||||
#define FORMAT RTAUDIO_SINT16
|
#define FORMAT RTAUDIO_SINT16
|
||||||
#define SCALE 32767.0
|
|
||||||
|
|
||||||
#define LOG100 4.60517018599
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
@ -55,6 +45,10 @@ typedef Eigen::Matrix<qint32, Eigen::Dynamic, 1> VectorXint32;
|
||||||
#endif
|
#endif
|
||||||
#include "audiotaper.h"
|
#include "audiotaper.h"
|
||||||
|
|
||||||
|
#include <Eigen/Eigen>
|
||||||
|
|
||||||
|
//#include <r8bbase.h>
|
||||||
|
//#include <CDSPResampler.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
@ -75,13 +69,14 @@ struct audioPacket {
|
||||||
|
|
||||||
struct audioSetup {
|
struct audioSetup {
|
||||||
QString name;
|
QString name;
|
||||||
quint8 bits;
|
// quint8 bits;
|
||||||
quint8 radioChan;
|
// quint8 radioChan;
|
||||||
quint16 samplerate;
|
// quint16 samplerate;
|
||||||
quint16 latency;
|
quint16 latency;
|
||||||
quint8 codec;
|
quint8 codec;
|
||||||
bool ulaw;
|
bool ulaw = false;
|
||||||
bool isinput;
|
bool isinput;
|
||||||
|
QAudioFormat format; // Use this for all audio APIs
|
||||||
#if defined(RTAUDIO) || defined(PORTAUDIO)
|
#if defined(RTAUDIO) || defined(PORTAUDIO)
|
||||||
int port;
|
int port;
|
||||||
#else
|
#else
|
||||||
|
@ -190,17 +185,22 @@ private:
|
||||||
#else
|
#else
|
||||||
QAudioOutput* audioOutput=Q_NULLPTR;
|
QAudioOutput* audioOutput=Q_NULLPTR;
|
||||||
QAudioInput* audioInput=Q_NULLPTR;
|
QAudioInput* audioInput=Q_NULLPTR;
|
||||||
|
QIODevice* audioDevice=Q_NULLPTR;
|
||||||
QAudioFormat format;
|
QAudioFormat format;
|
||||||
QAudioDeviceInfo deviceInfo;
|
QAudioDeviceInfo deviceInfo;
|
||||||
#endif
|
#endif
|
||||||
SpeexResamplerState* resampler = Q_NULLPTR;
|
SpeexResamplerState* resampler = Q_NULLPTR;
|
||||||
|
|
||||||
|
//r8b::CFixedBuffer<double>* resampBufs;
|
||||||
|
//r8b::CPtrKeeper<r8b::CDSPResampler24*>* resamps;
|
||||||
|
|
||||||
quint16 audioLatency;
|
quint16 audioLatency;
|
||||||
unsigned int chunkSize;
|
unsigned int chunkSize;
|
||||||
bool chunkAvailable;
|
bool chunkAvailable;
|
||||||
|
|
||||||
quint32 lastSeq;
|
quint32 lastSeq;
|
||||||
quint32 lastSentSeq=0;
|
quint32 lastSentSeq=0;
|
||||||
|
qint64 elapsedMs = 0;
|
||||||
|
|
||||||
quint16 nativeSampleRate=0;
|
quint16 nativeSampleRate=0;
|
||||||
quint8 radioSampleBits;
|
quint8 radioSampleBits;
|
||||||
|
@ -217,7 +217,7 @@ private:
|
||||||
volatile bool ready = false;
|
volatile bool ready = false;
|
||||||
audioPacket tempBuf;
|
audioPacket tempBuf;
|
||||||
quint16 currentLatency;
|
quint16 currentLatency;
|
||||||
quint16 amplitude = 0;
|
float amplitude;
|
||||||
qreal volume=1.0;
|
qreal volume=1.0;
|
||||||
int devChannels;
|
int devChannels;
|
||||||
audioSetup setup;
|
audioSetup setup;
|
||||||
|
@ -225,4 +225,200 @@ private:
|
||||||
OpusDecoder* decoder=Q_NULLPTR;
|
OpusDecoder* decoder=Q_NULLPTR;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Various audio handling functions declared inline
|
||||||
|
|
||||||
|
static inline qint64 getAudioSize(qint64 timeInMs, const QAudioFormat& format)
|
||||||
|
{
|
||||||
|
qint64 value = qint64(qCeil(format.channelCount() * (format.sampleSize() / 8) * format.sampleRate() / qreal(10000) * timeInMs));
|
||||||
|
|
||||||
|
if (value % (format.channelCount() * (format.sampleSize() / 8)) != 0)
|
||||||
|
value += (format.channelCount() * (format.sampleSize() / 8) - value % (format.channelCount() * (format.sampleSize() / 8)));
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline qint64 getAudioDuration(qint64 bytes, const QAudioFormat& format)
|
||||||
|
{
|
||||||
|
return qint64(qFloor(bytes / (format.channelCount() * (format.sampleSize() / 8) * format.sampleRate() / qreal(1000))));
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
static inline QByteArray samplesToInt(const QByteArray& data, const QAudioFormat& supported_format)
|
||||||
|
{
|
||||||
|
QByteArray input = data;
|
||||||
|
|
||||||
|
switch (supported_format.sampleSize())
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
switch (supported_format.sampleType())
|
||||||
|
{
|
||||||
|
case QAudioFormat::UnSignedInt:
|
||||||
|
{
|
||||||
|
Eigen::Ref<Eigen::VectorXf> samples_float = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(input.data()), input.size() / int(sizeof(float)));
|
||||||
|
|
||||||
|
Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits<quint8>::max());
|
||||||
|
|
||||||
|
VectorXuint8 samples_int = samples_int_tmp.cast<quint8>();
|
||||||
|
|
||||||
|
QByteArray raw = QByteArray(reinterpret_cast<char*>(samples_int.data()), int(samples_int.size()) * int(sizeof(quint8)));
|
||||||
|
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
case QAudioFormat::SignedInt:
|
||||||
|
{
|
||||||
|
Eigen::Ref<Eigen::VectorXf> samples_float = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(input.data()), input.size() / int(sizeof(float)));
|
||||||
|
|
||||||
|
Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits<qint8>::max());
|
||||||
|
|
||||||
|
VectorXint8 samples_int = samples_int_tmp.cast<qint8>();
|
||||||
|
|
||||||
|
QByteArray raw = QByteArray(reinterpret_cast<char*>(samples_int.data()), int(samples_int.size()) * int(sizeof(qint8)));
|
||||||
|
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
switch (supported_format.sampleType())
|
||||||
|
{
|
||||||
|
case QAudioFormat::SignedInt:
|
||||||
|
{
|
||||||
|
Eigen::Ref<Eigen::VectorXf> samples_float = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(input.data()), input.size() / int(sizeof(float)));
|
||||||
|
|
||||||
|
Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits<qint16>::max());
|
||||||
|
|
||||||
|
VectorXint16 samples_int = samples_int_tmp.cast<qint16>();
|
||||||
|
|
||||||
|
QByteArray raw = QByteArray(reinterpret_cast<char*>(samples_int.data()), int(samples_int.size()) * int(sizeof(qint16)));
|
||||||
|
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 32:
|
||||||
|
{
|
||||||
|
switch (supported_format.sampleType())
|
||||||
|
{
|
||||||
|
case QAudioFormat::SignedInt:
|
||||||
|
{
|
||||||
|
Eigen::Ref<Eigen::VectorXf> samples_float = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(input.data()), input.size() / int(sizeof(float)));
|
||||||
|
|
||||||
|
Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits<qint32>::max());
|
||||||
|
|
||||||
|
VectorXint32 samples_int = samples_int_tmp.cast<qint32>();
|
||||||
|
|
||||||
|
QByteArray raw = QByteArray(reinterpret_cast<char*>(samples_int.data()), int(samples_int.size()) * int(sizeof(qint32)));
|
||||||
|
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QByteArray samplesToFloat(const QByteArray& data, const QAudioFormat& supported_format)
|
||||||
|
{
|
||||||
|
QByteArray input = data;
|
||||||
|
|
||||||
|
switch (supported_format.sampleSize())
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
switch (supported_format.sampleType())
|
||||||
|
{
|
||||||
|
case QAudioFormat::UnSignedInt:
|
||||||
|
{
|
||||||
|
QByteArray raw = input;
|
||||||
|
|
||||||
|
Eigen::Ref<VectorXuint8> samples_int = Eigen::Map<VectorXuint8>(reinterpret_cast<quint8*>(raw.data()), raw.size() / int(sizeof(quint8)));
|
||||||
|
|
||||||
|
Eigen::VectorXf samples_float = samples_int.cast<float>() / float(std::numeric_limits<quint8>::max());
|
||||||
|
|
||||||
|
return QByteArray(reinterpret_cast<char*>(samples_float.data()), int(samples_float.size()) * int(sizeof(float)));
|
||||||
|
}
|
||||||
|
case QAudioFormat::SignedInt:
|
||||||
|
{
|
||||||
|
QByteArray raw = input;
|
||||||
|
|
||||||
|
Eigen::Ref<VectorXint8> samples_int = Eigen::Map<VectorXint8>(reinterpret_cast<qint8*>(raw.data()), raw.size() / int(sizeof(qint8)));
|
||||||
|
|
||||||
|
Eigen::VectorXf samples_float = samples_int.cast<float>() / float(std::numeric_limits<qint8>::max());
|
||||||
|
|
||||||
|
return QByteArray(reinterpret_cast<char*>(samples_float.data()), int(samples_float.size()) * int(sizeof(float)));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
switch (supported_format.sampleType())
|
||||||
|
{
|
||||||
|
case QAudioFormat::SignedInt:
|
||||||
|
{
|
||||||
|
QByteArray raw = input;
|
||||||
|
|
||||||
|
Eigen::Ref<VectorXint16> samples_int = Eigen::Map<VectorXint16>(reinterpret_cast<qint16*>(raw.data()), raw.size() / int(sizeof(qint16)));
|
||||||
|
|
||||||
|
Eigen::VectorXf samples_float = samples_int.cast<float>() / float(std::numeric_limits<qint16>::max());
|
||||||
|
|
||||||
|
return QByteArray(reinterpret_cast<char*>(samples_float.data()), int(samples_float.size()) * int(sizeof(float)));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 32:
|
||||||
|
{
|
||||||
|
switch (supported_format.sampleType())
|
||||||
|
{
|
||||||
|
case QAudioFormat::SignedInt:
|
||||||
|
{
|
||||||
|
QByteArray raw = input;
|
||||||
|
|
||||||
|
Eigen::Ref<VectorXint32> samples_int = Eigen::Map<VectorXint32>(reinterpret_cast<qint32*>(raw.data()), raw.size() / int(sizeof(qint32)));
|
||||||
|
|
||||||
|
Eigen::VectorXf samples_float = samples_int.cast<float>() / float(std::numeric_limits<qint32>::max());
|
||||||
|
|
||||||
|
return QByteArray(reinterpret_cast<char*>(samples_float.data()), int(samples_float.size()) * int(sizeof(float)));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
#endif // AUDIOHANDLER_H
|
#endif // AUDIOHANDLER_H
|
||||||
|
|
|
@ -151,7 +151,7 @@ void rigCommander::commSetup(unsigned char rigCivAddr, udpPreferences prefs, aud
|
||||||
connect(ptty, SIGNAL(haveDataFromPort(QByteArray)), udp, SLOT(receiveDataFromUserToRig(QByteArray)));
|
connect(ptty, SIGNAL(haveDataFromPort(QByteArray)), udp, SLOT(receiveDataFromUserToRig(QByteArray)));
|
||||||
|
|
||||||
// data from the tcp port to the Rig:
|
// data from the tcp port to the Rig:
|
||||||
connect(tcp, SIGNAL(haveData(QByteArray)), udp, SLOT(receiveDataFromUserToRig(QByteArray)));
|
connect(tcp, SIGNAL(receiveData(QByteArray)), udp, SLOT(receiveDataFromUserToRig(QByteArray)));
|
||||||
|
|
||||||
connect(this, SIGNAL(haveChangeLatency(quint16)), udp, SLOT(changeLatency(quint16)));
|
connect(this, SIGNAL(haveChangeLatency(quint16)), udp, SLOT(changeLatency(quint16)));
|
||||||
connect(this, SIGNAL(haveSetVolume(unsigned char)), udp, SLOT(setVolume(unsigned char)));
|
connect(this, SIGNAL(haveSetVolume(unsigned char)), udp, SLOT(setVolume(unsigned char)));
|
||||||
|
|
|
@ -28,6 +28,7 @@ int tcpServer::startServer(qint16 port) {
|
||||||
void tcpServer::incomingConnection(qintptr socket) {
|
void tcpServer::incomingConnection(qintptr socket) {
|
||||||
tcpServerClient* client = new tcpServerClient(socket, this);
|
tcpServerClient* client = new tcpServerClient(socket, this);
|
||||||
connect(this, SIGNAL(onStopped()), client, SLOT(closeSocket()));
|
connect(this, SIGNAL(onStopped()), client, SLOT(closeSocket()));
|
||||||
|
emit newClient(socket); // Signal par
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcpServer::stopServer()
|
void tcpServer::stopServer()
|
||||||
|
@ -39,7 +40,7 @@ void tcpServer::stopServer()
|
||||||
|
|
||||||
void tcpServer::receiveDataFromClient(QByteArray data)
|
void tcpServer::receiveDataFromClient(QByteArray data)
|
||||||
{
|
{
|
||||||
emit haveData(data);
|
emit receiveData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcpServer::sendData(QByteArray data) {
|
void tcpServer::sendData(QByteArray data) {
|
||||||
|
|
|
@ -29,8 +29,9 @@ public slots:
|
||||||
signals:
|
signals:
|
||||||
void onStarted();
|
void onStarted();
|
||||||
void onStopped();
|
void onStopped();
|
||||||
void haveData(QByteArray data); // emit this when we have data from tcp client, connect to rigcommander
|
void receiveData(QByteArray data); // emit this when we have data from tcp client, connect to rigcommander
|
||||||
void sendDataToClient(QByteArray data);
|
void sendDataToClient(QByteArray data);
|
||||||
|
void newClient(int socketId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTcpServer* server;
|
QTcpServer* server;
|
||||||
|
|
|
@ -20,8 +20,8 @@ udpHandler::udpHandler(udpPreferences prefs, audioSetup rx, audioSetup tx) :
|
||||||
this->password = prefs.password;
|
this->password = prefs.password;
|
||||||
this->compName = prefs.clientName.mid(0,8) + "-wfview";
|
this->compName = prefs.clientName.mid(0,8) + "-wfview";
|
||||||
|
|
||||||
qInfo(logUdp()) << "Starting udpHandler user:" << username << " rx latency:" << rxSetup.latency << " tx latency:" << txSetup.latency << " rx sample rate: " << rxSetup.samplerate <<
|
qInfo(logUdp()) << "Starting udpHandler user:" << username << " rx latency:" << rxSetup.latency << " tx latency:" << txSetup.latency << " rx sample rate: " << rxSetup.format.sampleRate() <<
|
||||||
" rx codec: " << rxSetup.codec << " tx sample rate: " << txSetup.samplerate << " tx codec: " << txSetup.codec;
|
" rx codec: " << rxSetup.codec << " tx sample rate: " << txSetup.format.sampleRate() << " tx codec: " << txSetup.codec;
|
||||||
|
|
||||||
// Try to set the IP address, if it is a hostname then perform a DNS lookup.
|
// Try to set the IP address, if it is a hostname then perform a DNS lookup.
|
||||||
if (!radioIP.setAddress(prefs.ipAddress))
|
if (!radioIP.setAddress(prefs.ipAddress))
|
||||||
|
@ -280,7 +280,7 @@ void udpHandler::dataReceived()
|
||||||
|
|
||||||
// TX is not supported
|
// TX is not supported
|
||||||
if (txSampleRates < 2) {
|
if (txSampleRates < 2) {
|
||||||
txSetup.samplerate = 0;
|
txSetup.format.setSampleRate(0);
|
||||||
txSetup.codec = 0;
|
txSetup.codec = 0;
|
||||||
}
|
}
|
||||||
audio = new udpAudio(localIP, radioIP, audioPort, audioLocalPort, rxSetup, txSetup);
|
audio = new udpAudio(localIP, radioIP, audioPort, audioLocalPort, rxSetup, txSetup);
|
||||||
|
@ -512,8 +512,8 @@ void udpHandler::sendRequestStream()
|
||||||
}
|
}
|
||||||
p.rxcodec = rxSetup.codec;
|
p.rxcodec = rxSetup.codec;
|
||||||
memcpy(&p.username, usernameEncoded.constData(), usernameEncoded.length());
|
memcpy(&p.username, usernameEncoded.constData(), usernameEncoded.length());
|
||||||
p.rxsample = qToBigEndian((quint32)rxSetup.samplerate);
|
p.rxsample = qToBigEndian((quint32)rxSetup.format.sampleRate());
|
||||||
p.txsample = qToBigEndian((quint32)txSetup.samplerate);
|
p.txsample = qToBigEndian((quint32)txSetup.format.sampleRate());
|
||||||
p.civport = qToBigEndian((quint32)civLocalPort);
|
p.civport = qToBigEndian((quint32)civLocalPort);
|
||||||
p.audioport = qToBigEndian((quint32)audioLocalPort);
|
p.audioport = qToBigEndian((quint32)audioLocalPort);
|
||||||
p.txbuffer = qToBigEndian((quint32)txSetup.latency);
|
p.txbuffer = qToBigEndian((quint32)txSetup.latency);
|
||||||
|
@ -789,7 +789,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
|
||||||
this->port = audioPort;
|
this->port = audioPort;
|
||||||
this->radioIP = ip;
|
this->radioIP = ip;
|
||||||
|
|
||||||
if (txSetup.samplerate == 0) {
|
if (txSetup.format.sampleRate() == 0) {
|
||||||
enableTx = false;
|
enableTx = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,7 +812,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
|
||||||
connect(this, SIGNAL(haveSetVolume(unsigned char)), rxaudio, SLOT(setVolume(unsigned char)));
|
connect(this, SIGNAL(haveSetVolume(unsigned char)), rxaudio, SLOT(setVolume(unsigned char)));
|
||||||
connect(rxAudioThread, SIGNAL(finished()), rxaudio, SLOT(deleteLater()));
|
connect(rxAudioThread, SIGNAL(finished()), rxaudio, SLOT(deleteLater()));
|
||||||
|
|
||||||
txSetup.radioChan = 1;
|
txSetup.format.setChannelCount(1); // TX Audio is always single channel.
|
||||||
|
|
||||||
txaudio = new audioHandler();
|
txaudio = new audioHandler();
|
||||||
txAudioThread = new QThread(this);
|
txAudioThread = new QThread(this);
|
||||||
|
|
|
@ -350,7 +350,7 @@ void udpServer::controlReceived()
|
||||||
if (!memcmp(radio->guid, current->guid, GUIDLEN) && radio->txaudio == Q_NULLPTR)
|
if (!memcmp(radio->guid, current->guid, GUIDLEN) && radio->txaudio == Q_NULLPTR)
|
||||||
{
|
{
|
||||||
radio->txAudioSetup.codec = current->txCodec;
|
radio->txAudioSetup.codec = current->txCodec;
|
||||||
radio->txAudioSetup.samplerate = current->txSampleRate;
|
radio->txAudioSetup.format.setSampleRate(current->txSampleRate);
|
||||||
radio->txAudioSetup.isinput = false;
|
radio->txAudioSetup.isinput = false;
|
||||||
radio->txAudioSetup.latency = current->txBufferLen;
|
radio->txAudioSetup.latency = current->txBufferLen;
|
||||||
outAudio.isinput = false;
|
outAudio.isinput = false;
|
||||||
|
@ -390,7 +390,7 @@ void udpServer::controlReceived()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
radio->rxAudioSetup.codec = current->rxCodec;
|
radio->rxAudioSetup.codec = current->rxCodec;
|
||||||
radio->rxAudioSetup.samplerate = current->rxSampleRate;
|
radio->rxAudioSetup.format.setSampleRate(current->rxSampleRate);
|
||||||
radio->rxAudioSetup.latency = current->txBufferLen;
|
radio->rxAudioSetup.latency = current->txBufferLen;
|
||||||
radio->rxAudioSetup.isinput = true;
|
radio->rxAudioSetup.isinput = true;
|
||||||
|
|
||||||
|
|
15
wfmain.cpp
15
wfmain.cpp
|
@ -1552,10 +1552,11 @@ void wfmain::loadSettings()
|
||||||
ui->txLatencySlider->setTracking(false); // Stop it sending value on every change.
|
ui->txLatencySlider->setTracking(false); // Stop it sending value on every change.
|
||||||
|
|
||||||
ui->audioSampleRateCombo->blockSignals(true);
|
ui->audioSampleRateCombo->blockSignals(true);
|
||||||
rxSetup.samplerate = settings->value("AudioRXSampleRate", "48000").toInt();
|
rxSetup.format.setSampleRate(settings->value("AudioRXSampleRate", "48000").toInt());
|
||||||
txSetup.samplerate = rxSetup.samplerate;
|
txSetup.format.setSampleRate(rxSetup.format.sampleRate());
|
||||||
|
|
||||||
ui->audioSampleRateCombo->setEnabled(ui->lanEnableBtn->isChecked());
|
ui->audioSampleRateCombo->setEnabled(ui->lanEnableBtn->isChecked());
|
||||||
int audioSampleRateIndex = ui->audioSampleRateCombo->findText(QString::number(rxSetup.samplerate));
|
int audioSampleRateIndex = ui->audioSampleRateCombo->findText(QString::number(rxSetup.format.sampleRate()));
|
||||||
if (audioSampleRateIndex != -1) {
|
if (audioSampleRateIndex != -1) {
|
||||||
ui->audioSampleRateCombo->setCurrentIndex(audioSampleRateIndex);
|
ui->audioSampleRateCombo->setCurrentIndex(audioSampleRateIndex);
|
||||||
}
|
}
|
||||||
|
@ -1974,9 +1975,9 @@ void wfmain::saveSettings()
|
||||||
settings->setValue("Password", udpPrefs.password);
|
settings->setValue("Password", udpPrefs.password);
|
||||||
settings->setValue("AudioRXLatency", rxSetup.latency);
|
settings->setValue("AudioRXLatency", rxSetup.latency);
|
||||||
settings->setValue("AudioTXLatency", txSetup.latency);
|
settings->setValue("AudioTXLatency", txSetup.latency);
|
||||||
settings->setValue("AudioRXSampleRate", rxSetup.samplerate);
|
settings->setValue("AudioRXSampleRate", rxSetup.format.sampleRate());
|
||||||
settings->setValue("AudioRXCodec", rxSetup.codec);
|
settings->setValue("AudioRXCodec", rxSetup.codec);
|
||||||
settings->setValue("AudioTXSampleRate", txSetup.samplerate);
|
settings->setValue("AudioTXSampleRate", txSetup.format.sampleRate());
|
||||||
settings->setValue("AudioTXCodec", txSetup.codec);
|
settings->setValue("AudioTXCodec", txSetup.codec);
|
||||||
settings->setValue("AudioOutput", rxSetup.name);
|
settings->setValue("AudioOutput", rxSetup.name);
|
||||||
settings->setValue("AudioInput", txSetup.name);
|
settings->setValue("AudioInput", txSetup.name);
|
||||||
|
@ -4721,8 +4722,8 @@ void wfmain::on_audioSampleRateCombo_currentIndexChanged(QString text)
|
||||||
{
|
{
|
||||||
//udpPrefs.audioRXSampleRate = text.toInt();
|
//udpPrefs.audioRXSampleRate = text.toInt();
|
||||||
//udpPrefs.audioTXSampleRate = text.toInt();
|
//udpPrefs.audioTXSampleRate = text.toInt();
|
||||||
rxSetup.samplerate = text.toInt();
|
rxSetup.format.setSampleRate(text.toInt());
|
||||||
txSetup.samplerate = text.toInt();
|
txSetup.format.setSampleRate(text.toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
void wfmain::on_audioRXCodecCombo_currentIndexChanged(int value)
|
void wfmain::on_audioRXCodecCombo_currentIndexChanged(int value)
|
||||||
|
|
10
wfview.pro
10
wfview.pro
|
@ -150,7 +150,8 @@ macx:LIBS += -framework CoreAudio -framework CoreFoundation -lpthread -lopus
|
||||||
|
|
||||||
!linux:INCLUDEPATH += ../opus/include
|
!linux:INCLUDEPATH += ../opus/include
|
||||||
|
|
||||||
!linux:INCLUDEPATH += ../eigen/Eigen
|
!linux:INCLUDEPATH += ../eigen
|
||||||
|
!linux:INCLUDEPATH += ../r8brain-free-src
|
||||||
|
|
||||||
INCLUDEPATH += resampler
|
INCLUDEPATH += resampler
|
||||||
|
|
||||||
|
@ -175,8 +176,8 @@ SOURCES += main.cpp\
|
||||||
ring/ring.cpp \
|
ring/ring.cpp \
|
||||||
transceiveradjustments.cpp \
|
transceiveradjustments.cpp \
|
||||||
selectradio.cpp \
|
selectradio.cpp \
|
||||||
tcpserver.cpp \
|
tcpserver.cpp \
|
||||||
aboutbox.cpp
|
aboutbox.cpp
|
||||||
|
|
||||||
HEADERS += wfmain.h \
|
HEADERS += wfmain.h \
|
||||||
commhandler.h \
|
commhandler.h \
|
||||||
|
@ -204,7 +205,8 @@ HEADERS += wfmain.h \
|
||||||
transceiveradjustments.h \
|
transceiveradjustments.h \
|
||||||
audiotaper.h \
|
audiotaper.h \
|
||||||
selectradio.h \
|
selectradio.h \
|
||||||
tcpserver.h \
|
tcpserver.h \
|
||||||
|
audiocommon.h \
|
||||||
aboutbox.h
|
aboutbox.h
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>.;..\qcustomplot;..\opus\include;..\eigen\Eigen;resampler;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>.;..\qcustomplot;..\opus\include;..\eigen;..\r8brain-free-src;resampler;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
||||||
<AssemblerListingLocation>release\</AssemblerListingLocation>
|
<AssemblerListingLocation>release\</AssemblerListingLocation>
|
||||||
<BrowseInformation>false</BrowseInformation>
|
<BrowseInformation>false</BrowseInformation>
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
<ObjectFileName>release\</ObjectFileName>
|
<ObjectFileName>release\</ObjectFileName>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION="1.2d";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="c5cf0fd";HOST="wfview.org";UNAME="build";NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION="1.2d";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="8ec62fe";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>
|
||||||
|
@ -85,12 +85,12 @@
|
||||||
<WarningLevel>0</WarningLevel>
|
<WarningLevel>0</WarningLevel>
|
||||||
</Midl>
|
</Midl>
|
||||||
<ResourceCompile>
|
<ResourceCompile>
|
||||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION=\"1.2d\";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=\"c5cf0fd\";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.2d\";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=\"8ec62fe\";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\Eigen;resampler;debug;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>.;..\qcustomplot;..\opus\include;..\eigen;..\r8brain-free-src;resampler;debug;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
||||||
<AssemblerListingLocation>debug\</AssemblerListingLocation>
|
<AssemblerListingLocation>debug\</AssemblerListingLocation>
|
||||||
<BrowseInformation>false</BrowseInformation>
|
<BrowseInformation>false</BrowseInformation>
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
<ObjectFileName>debug\</ObjectFileName>
|
<ObjectFileName>debug\</ObjectFileName>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION="1.2d";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="c5cf0fd";HOST="wfview.org";UNAME="build";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION="1.2d";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="8ec62fe";HOST="wfview.org";UNAME="build";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessToFile>false</PreprocessToFile>
|
<PreprocessToFile>false</PreprocessToFile>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
<WarningLevel>0</WarningLevel>
|
<WarningLevel>0</WarningLevel>
|
||||||
</Midl>
|
</Midl>
|
||||||
<ResourceCompile>
|
<ResourceCompile>
|
||||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WFVIEW_VERSION=\"1.2d\";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=\"c5cf0fd\";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.2d\";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=\"8ec62fe\";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>
|
||||||
|
@ -165,6 +165,7 @@
|
||||||
|
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
<ClInclude Include="resampler\arch.h" />
|
<ClInclude Include="resampler\arch.h" />
|
||||||
|
<ClInclude Include="audiocommon.h" />
|
||||||
<QtMoc Include="audiohandler.h">
|
<QtMoc Include="audiohandler.h">
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,9 @@
|
||||||
<ClInclude Include="resampler\arch.h">
|
<ClInclude Include="resampler\arch.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="audiocommon.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<QtMoc Include="audiohandler.h">
|
<QtMoc Include="audiohandler.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
|
|
Ładowanie…
Reference in New Issue