kopia lustrzana https://gitlab.com/eliggett/wfview
Add audio resampler
rodzic
998381ac00
commit
a0f4a4deeb
223
audiohandler.cpp
223
audiohandler.cpp
|
@ -750,9 +750,13 @@ audioHandler::~audioHandler()
|
|||
if (audioInput != Q_NULLPTR) {
|
||||
delete audioInput;
|
||||
}
|
||||
|
||||
if (resampler) {
|
||||
speex_resampler_destroy(resampler);
|
||||
}
|
||||
}
|
||||
|
||||
bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16 samplerate, const quint16 latency, const bool ulaw, const bool isinput, QString port)
|
||||
bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16 samplerate, const quint16 latency, const bool ulaw, const bool isinput, QString port, quint8 resampleQuality)
|
||||
{
|
||||
if (isInitialized) {
|
||||
return false;
|
||||
|
@ -760,7 +764,7 @@ bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16
|
|||
/* Always use 16 bit 48K samples internally*/
|
||||
format.setSampleSize(16);
|
||||
format.setChannelCount(channels);
|
||||
format.setSampleRate(48000);
|
||||
format.setSampleRate(INTERNAL_SAMPLE_RATE);
|
||||
format.setCodec("audio/pcm");
|
||||
format.setByteOrder(QAudioFormat::LittleEndian);
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
|
@ -770,7 +774,27 @@ bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16
|
|||
this->isInput = isinput;
|
||||
this->radioSampleBits = bits;
|
||||
this->radioSampleRate = samplerate;
|
||||
this->chunkSize = this->radioSampleBits * 120;
|
||||
this->radioChannels = channels;
|
||||
|
||||
//this->chunkSize = (INTERNAL_SAMPLE_RATE / 25) * (radioSampleBits / 8)/2;
|
||||
|
||||
this->chunkSize = 1920*radioChannels;
|
||||
|
||||
qDebug(logAudio()) << "Audio chunkSize: " << this->chunkSize;
|
||||
|
||||
int resample_error=0;
|
||||
if (isinput) {
|
||||
resampler = wf_resampler_init(radioChannels, INTERNAL_SAMPLE_RATE, samplerate, resampleQuality, &resample_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
resampler = wf_resampler_init(radioChannels, samplerate, INTERNAL_SAMPLE_RATE, resampleQuality, &resample_error);
|
||||
}
|
||||
|
||||
|
||||
wf_resampler_get_ratio(resampler, &ratioNum, &ratioDen);
|
||||
|
||||
qDebug(logAudio()) << "wf_resampler_init() returned: " << resample_error << " ratioNum" << ratioNum << " ratioDen" << ratioDen << " input " << isinput;
|
||||
|
||||
qDebug(logAudio()) << "Got audio port name: " << port;
|
||||
|
||||
|
@ -869,8 +893,8 @@ void audioHandler::reinit()
|
|||
delete audioOutput;
|
||||
audioOutput = Q_NULLPTR;
|
||||
audioOutput = new QAudioOutput(deviceInfo, format, this);
|
||||
audioOutput->setBufferSize((radioSampleRate/25)*(radioSampleBits/8)*2);
|
||||
connect(audioOutput, SIGNAL(notify()), SLOT(notified()));
|
||||
audioOutput->setBufferSize((radioSampleRate / 25) * (radioSampleBits / 8) * 2);
|
||||
connect(audioOutput, SIGNAL(notify()), SLOT(notified()));
|
||||
connect(audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||
}
|
||||
|
||||
|
@ -929,11 +953,18 @@ void audioHandler::stop()
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function processes the incoming audio FROM the radio and pushes it into the playback buffer *data
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="maxlen"></param>
|
||||
/// <returns></returns>
|
||||
qint64 audioHandler::readData(char* data, qint64 maxlen)
|
||||
{
|
||||
// Calculate output length, always full samples
|
||||
int sentlen = 0;
|
||||
|
||||
|
||||
//qDebug(logAudio()) << "Looking for: " << maxlen << " bytes";
|
||||
|
||||
// We must lock the mutex for the entire time that the buffer may be modified.
|
||||
|
@ -941,11 +972,8 @@ qint64 audioHandler::readData(char* data, qint64 maxlen)
|
|||
// Get next packet from buffer.
|
||||
if (!audioBuffer.isEmpty())
|
||||
{
|
||||
|
||||
|
||||
// Output buffer is ALWAYS 16 bit.
|
||||
int divisor = 16 / radioSampleBits;
|
||||
|
||||
auto packet = audioBuffer.begin();
|
||||
while (packet != audioBuffer.end() && sentlen < maxlen)
|
||||
{
|
||||
|
@ -956,44 +984,18 @@ qint64 audioHandler::readData(char* data, qint64 maxlen)
|
|||
}
|
||||
else if (packet->seq == lastSeq+1 || packet->seq <= lastSeq)
|
||||
{
|
||||
int send = qMin((int)maxlen-sentlen, packet->dataout.length() - packet->sent);
|
||||
lastSeq = packet->seq;
|
||||
//qDebug(logAudio()) << "Packet " << hex << packet->seq << " arrived on time " << dec << packet->time.msecsTo(QTime::currentTime()) << "ms";
|
||||
// Will this packet fit in the current buffer?
|
||||
int send = qMin((int)((maxlen/divisor) - (sentlen/divisor)), packet->data.length() - packet->sent);
|
||||
|
||||
if (divisor == 2)
|
||||
{
|
||||
// Input buffer is 8bit and output buffer is 16bit
|
||||
for (int f = 0; f < send; f++)
|
||||
{
|
||||
if (isUlaw)
|
||||
qToLittleEndian<qint16>(ulaw_decode[(quint8)packet->data[f+packet->sent]], data + (f * 2 + sentlen));
|
||||
else
|
||||
qToLittleEndian<qint16>((qint16)(packet->data[f+packet->sent] << 8) - 32640, data + (f * 2 + sentlen));
|
||||
}
|
||||
}
|
||||
else if (divisor == 1)
|
||||
{
|
||||
// 16 bit audio so just copy it in place.
|
||||
//qDebug(logAudio()) << "Adding packet to buffer:" << (*packet).seq << ": " << (*packet).data.length()-(*packet).sent;
|
||||
memcpy(data+sentlen, packet->data.constData()+packet->sent, send);
|
||||
}
|
||||
else
|
||||
{
|
||||
//qDebug(logAudio()) << "Invalid number of bits in audio " << radioSampleBits;
|
||||
break;
|
||||
}
|
||||
memcpy(data + sentlen, packet->dataout.constData() + packet->sent, send);
|
||||
|
||||
sentlen = sentlen + (send * divisor);
|
||||
sentlen = sentlen + send;
|
||||
|
||||
if (send == packet->data.length())
|
||||
if (send == packet->dataout.length())
|
||||
{
|
||||
lastSeq = packet->seq;
|
||||
//qDebug(logAudio()) << "Get next packet";
|
||||
packet = audioBuffer.erase(packet); // returns next packet
|
||||
if (maxlen - sentlen == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (send == 0)
|
||||
{
|
||||
|
@ -1019,9 +1021,7 @@ qint64 audioHandler::readData(char* data, qint64 maxlen)
|
|||
|
||||
qint64 audioHandler::writeData(const char* data, qint64 len)
|
||||
{
|
||||
int multiplier = (int)16 / radioSampleBits;
|
||||
qint64 sentlen = 0;
|
||||
int tosend = 0;
|
||||
QMutexLocker locker(&mutex);
|
||||
audioPacket *current;
|
||||
|
||||
|
@ -1041,36 +1041,15 @@ qint64 audioHandler::writeData(const char* data, qint64 len)
|
|||
}
|
||||
current = &audioBuffer.last();
|
||||
|
||||
tosend = qMin((int)((len - sentlen)/multiplier), (int)chunkSize-current->sent);
|
||||
int send = qMin((int)(len - sentlen), (int)chunkSize-current->sent);
|
||||
|
||||
if (radioSampleBits == 8) {
|
||||
int f = 0;
|
||||
while (f < tosend)
|
||||
{
|
||||
quint8 outdata=0;
|
||||
if (isUlaw) {
|
||||
qint16 enc = qFromLittleEndian<quint16>(data + ((f * multiplier) + sentlen));
|
||||
if (enc >= 0)
|
||||
outdata=ulaw_encode[enc];
|
||||
else
|
||||
outdata=0x7f & ulaw_encode[-enc];
|
||||
}
|
||||
else {
|
||||
outdata = (quint8)(((qFromLittleEndian<qint16>((data + ((f * multiplier) + sentlen))) >> 8) ^ 0x80) & 0xff);
|
||||
}
|
||||
current->data.append((char)outdata);
|
||||
f++;
|
||||
}
|
||||
}
|
||||
else if (radioSampleBits == 16)
|
||||
{
|
||||
current->data.append(QByteArray::fromRawData(data + sentlen, tosend ));
|
||||
}
|
||||
current->datain.append(QByteArray::fromRawData(data + sentlen, send ));
|
||||
|
||||
sentlen = sentlen + send;
|
||||
|
||||
sentlen = sentlen + (tosend * multiplier);
|
||||
current->seq = 0; // Not used in TX
|
||||
current->time = QTime::currentTime();
|
||||
current->sent = current->data.length();
|
||||
current->sent = current->datain.length();
|
||||
|
||||
if (current->sent == chunkSize)
|
||||
{
|
||||
|
@ -1082,7 +1061,6 @@ qint64 audioHandler::writeData(const char* data, qint64 len)
|
|||
|
||||
}
|
||||
|
||||
|
||||
return (sentlen); // Always return the same number as we received
|
||||
}
|
||||
|
||||
|
@ -1139,10 +1117,59 @@ void audioHandler::stateChanged(QAudio::State state)
|
|||
|
||||
|
||||
|
||||
void audioHandler::incomingAudio(const audioPacket data)
|
||||
void audioHandler::incomingAudio(audioPacket data)
|
||||
{
|
||||
if (audioOutput != Q_NULLPTR && audioOutput->state() != QAudio::StoppedState) {
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
// Incoming data is 8bits?
|
||||
if (radioSampleBits == 8)
|
||||
{
|
||||
QByteArray inPacket((int)data.datain.length() * 2, (char)0xff);
|
||||
qint16* in = (qint16*)inPacket.data();
|
||||
for (int f = 0; f < data.datain.length(); f++)
|
||||
{
|
||||
if (isUlaw)
|
||||
{
|
||||
in[f] = ulaw_decode[(quint8)data.datain[f]];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert 8-bit sample to 16-bit
|
||||
in[f] = (qint16)(((quint8)data.datain[f] << 8) - 32640);
|
||||
}
|
||||
}
|
||||
data.datain = inPacket; // Replace incoming data with converted.
|
||||
}
|
||||
|
||||
//qDebug(logAudio()) << "Adding packet to buffer:" << (*packet).seq << ": " << inPacket.length();
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
if (ratioDen != 1) {
|
||||
|
||||
// We need to resample
|
||||
quint32 outFrames = ((data.datain.length() / 2) * ratioDen) / radioChannels;
|
||||
quint32 inFrames = (data.datain.length() / 2) / radioChannels;
|
||||
data.dataout.resize(outFrames * 2 * radioChannels); // Preset the output buffer size.
|
||||
|
||||
int err = 0;
|
||||
if (this->radioChannels == 1) {
|
||||
err = wf_resampler_process_int(resampler, 0, (const qint16*)data.datain.constData(), &inFrames, (qint16*)data.dataout.data(), &outFrames);
|
||||
}
|
||||
else {
|
||||
err = wf_resampler_process_interleaved_int(resampler, (const qint16*)data.datain.constData(), &inFrames, (qint16*)data.dataout.data(), &outFrames);
|
||||
}
|
||||
if (err) {
|
||||
qDebug(logAudio()) << "Resampler error " << err << " inFrames:" << inFrames << " outFrames:" << outFrames;
|
||||
}
|
||||
}
|
||||
else {
|
||||
data.dataout = data.datain;
|
||||
}
|
||||
|
||||
audioBuffer.push_back(data);
|
||||
|
||||
// Sort the buffer by seq number. This is important and audio packets may have arrived out-of-order
|
||||
|
@ -1193,9 +1220,63 @@ void audioHandler::getNextAudioChunk(QByteArray& ret)
|
|||
packet = audioBuffer.erase(packet); // returns next packet
|
||||
}
|
||||
else {
|
||||
if (packet->data.length() == chunkSize && ret.length() == 0)
|
||||
if (packet->datain.length() == chunkSize && ret.length() == 0)
|
||||
{
|
||||
ret.append(packet->data);
|
||||
/* We now have an array of samples in the computer native format (48000)
|
||||
If the radio sample rate is below 48000, we need to resample.
|
||||
*/
|
||||
|
||||
if (ratioNum != 1)
|
||||
{
|
||||
// We need to resample (we are STILL 16 bit!)
|
||||
quint32 outFrames = ((packet->datain.length() / 2) / ratioNum) / radioChannels;
|
||||
quint32 inFrames = (packet->datain.length() / 2) / radioChannels;
|
||||
packet->dataout.resize(outFrames * 2 * radioChannels); // Preset the output buffer size.
|
||||
|
||||
int err = 0;
|
||||
if (this->radioChannels == 1) {
|
||||
err = wf_resampler_process_int(resampler, 0, (const qint16*)packet->datain.constData(), &inFrames, (qint16*)packet->dataout.data(), &outFrames);
|
||||
}
|
||||
else {
|
||||
err = wf_resampler_process_interleaved_int(resampler, (const qint16*)packet->datain.constData(), &inFrames, (qint16*)packet->dataout.data(), &outFrames);
|
||||
}
|
||||
if (err) {
|
||||
qDebug(logAudio()) << "Resampler error " << err << " inFrames:" << inFrames << " outFrames:" << outFrames;
|
||||
}
|
||||
//qDebug(logAudio()) << "Resampler run " << err << " inFrames:" << inFrames << " outFrames:" << outFrames;
|
||||
//qDebug(logAudio()) << "Resampler run inLen:" << packet->datain.length() << " outLen:" << packet->dataout.length();
|
||||
if (radioSampleBits == 8)
|
||||
{
|
||||
packet->datain = packet->dataout; // Copy packet back to input buffer.
|
||||
}
|
||||
}
|
||||
else if (radioSampleBits == 16 ){
|
||||
// Only copy buffer if radioSampleBits is 16, as it will be handled below otherwise.
|
||||
packet->dataout = packet->datain;
|
||||
}
|
||||
|
||||
// Do we need to convert 16-bit to 8-bit?
|
||||
if (radioSampleBits == 8) {
|
||||
packet->dataout.resize(packet->datain.length() / 2);
|
||||
qint16* in = (qint16*)packet->datain.data();
|
||||
for (int f = 0; f < packet->dataout.length(); f++)
|
||||
{
|
||||
quint8 outdata = 0;
|
||||
if (isUlaw) {
|
||||
qint16 enc = qFromLittleEndian<quint16>(in + f);
|
||||
if (enc >= 0)
|
||||
outdata = ulaw_encode[enc];
|
||||
else
|
||||
outdata = 0x7f & ulaw_encode[-enc];
|
||||
}
|
||||
else {
|
||||
outdata = (quint8)(((qFromLittleEndian<qint16>(in + f) >> 8) ^ 0x80) & 0xff);
|
||||
}
|
||||
packet->dataout[f] = (char)outdata;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
ret.append(packet->dataout);
|
||||
packet = audioBuffer.erase(packet); // returns next packet
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -15,17 +15,20 @@
|
|||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QTime>
|
||||
#include "resampler/speex_resampler.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
//#define BUFFER_SIZE (32*1024)
|
||||
|
||||
#define INTERNAL_SAMPLE_RATE 48000
|
||||
|
||||
struct audioPacket {
|
||||
quint16 seq;
|
||||
QTime time;
|
||||
quint16 sent;
|
||||
QByteArray data;
|
||||
QByteArray datain;
|
||||
QByteArray dataout;
|
||||
};
|
||||
|
||||
|
||||
|
@ -54,7 +57,7 @@ public:
|
|||
void getNextAudioChunk(QByteArray &data);
|
||||
bool isChunkAvailable();
|
||||
public slots:
|
||||
bool init(const quint8 bits, const quint8 channels, const quint16 samplerate, const quint16 latency, const bool isulaw, const bool isinput, QString port);
|
||||
bool init(const quint8 bits, const quint8 channels, const quint16 samplerate, const quint16 latency, const bool isulaw, const bool isinput, QString port, quint8 resampleQuality);
|
||||
void incomingAudio(const audioPacket data);
|
||||
void changeLatency(const quint16 newSize);
|
||||
|
||||
|
@ -88,7 +91,12 @@ private:
|
|||
QAudioDeviceInfo deviceInfo;
|
||||
quint16 radioSampleRate;
|
||||
quint8 radioSampleBits;
|
||||
quint8 radioChannels;
|
||||
QVector<audioPacket> audioBuffer;
|
||||
|
||||
SpeexResamplerState* resampler;
|
||||
unsigned int ratioNum;
|
||||
unsigned int ratioDen;
|
||||
};
|
||||
|
||||
#endif // AUDIOHANDLER_H
|
||||
|
|
|
@ -294,7 +294,8 @@ typedef union conninfo_packet {
|
|||
quint32 civport; // 0x7c
|
||||
quint32 audioport; // 0x80
|
||||
quint32 txbuffer; // 0x84
|
||||
char unusedl[8]; // 0x88
|
||||
quint8 convert; // 0x88
|
||||
char unusedl[7]; // 0x89
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/* Copyright (C) 2003 Jean-Marc Valin */
|
||||
/**
|
||||
@file arch.h
|
||||
@brief Various architecture definitions Speex
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCH_H
|
||||
#define ARCH_H
|
||||
|
||||
/* A couple test to catch stupid option combinations */
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
|
||||
#error Make up your mind. What CPU do you have?
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
|
||||
#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OUTSIDE_SPEEX
|
||||
#include "speex/speexdsp_types.h"
|
||||
#endif
|
||||
|
||||
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
|
||||
#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
|
||||
#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */
|
||||
#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
|
||||
#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */
|
||||
#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */
|
||||
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
typedef spx_int16_t spx_word16_t;
|
||||
typedef spx_int32_t spx_word32_t;
|
||||
typedef spx_word32_t spx_mem_t;
|
||||
typedef spx_word16_t spx_coef_t;
|
||||
typedef spx_word16_t spx_lsp_t;
|
||||
typedef spx_word32_t spx_sig_t;
|
||||
|
||||
#define Q15ONE 32767
|
||||
|
||||
#define LPC_SCALING 8192
|
||||
#define SIG_SCALING 16384
|
||||
#define LSP_SCALING 8192.
|
||||
#define GAMMA_SCALING 32768.
|
||||
#define GAIN_SCALING 64
|
||||
#define GAIN_SCALING_1 0.015625
|
||||
|
||||
#define LPC_SHIFT 13
|
||||
#define LSP_SHIFT 13
|
||||
#define SIG_SHIFT 14
|
||||
#define GAIN_SHIFT 6
|
||||
|
||||
#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))
|
||||
|
||||
#define VERY_SMALL 0
|
||||
#define VERY_LARGE32 ((spx_word32_t)2147483647)
|
||||
#define VERY_LARGE16 ((spx_word16_t)32767)
|
||||
#define Q15_ONE ((spx_word16_t)32767)
|
||||
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
#include "fixed_debug.h"
|
||||
#else
|
||||
|
||||
#include "fixed_generic.h"
|
||||
|
||||
#ifdef ARM5E_ASM
|
||||
#include "fixed_arm5e.h"
|
||||
#elif defined (ARM4_ASM)
|
||||
#include "fixed_arm4.h"
|
||||
#elif defined (BFIN_ASM)
|
||||
#include "fixed_bfin.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
|
||||
typedef float spx_mem_t;
|
||||
typedef float spx_coef_t;
|
||||
typedef float spx_lsp_t;
|
||||
typedef float spx_sig_t;
|
||||
typedef float spx_word16_t;
|
||||
typedef float spx_word32_t;
|
||||
|
||||
#define Q15ONE 1.0f
|
||||
#define LPC_SCALING 1.f
|
||||
#define SIG_SCALING 1.f
|
||||
#define LSP_SCALING 1.f
|
||||
#define GAMMA_SCALING 1.f
|
||||
#define GAIN_SCALING 1.f
|
||||
#define GAIN_SCALING_1 1.f
|
||||
|
||||
|
||||
#define VERY_SMALL 1e-15f
|
||||
#define VERY_LARGE32 1e15f
|
||||
#define VERY_LARGE16 1e15f
|
||||
#define Q15_ONE ((spx_word16_t)1.f)
|
||||
|
||||
#define QCONST16(x,bits) (x)
|
||||
#define QCONST32(x,bits) (x)
|
||||
|
||||
#define NEG16(x) (-(x))
|
||||
#define NEG32(x) (-(x))
|
||||
#define EXTRACT16(x) (x)
|
||||
#define EXTEND32(x) (x)
|
||||
#define SHR16(a,shift) (a)
|
||||
#define SHL16(a,shift) (a)
|
||||
#define SHR32(a,shift) (a)
|
||||
#define SHL32(a,shift) (a)
|
||||
#define PSHR16(a,shift) (a)
|
||||
#define PSHR32(a,shift) (a)
|
||||
#define VSHR32(a,shift) (a)
|
||||
#define SATURATE16(x,a) (x)
|
||||
#define SATURATE32(x,a) (x)
|
||||
#define SATURATE32PSHR(x,shift,a) (x)
|
||||
|
||||
#define PSHR(a,shift) (a)
|
||||
#define SHR(a,shift) (a)
|
||||
#define SHL(a,shift) (a)
|
||||
#define SATURATE(x,a) (x)
|
||||
|
||||
#define ADD16(a,b) ((a)+(b))
|
||||
#define SUB16(a,b) ((a)-(b))
|
||||
#define ADD32(a,b) ((a)+(b))
|
||||
#define SUB32(a,b) ((a)-(b))
|
||||
#define MULT16_16_16(a,b) ((a)*(b))
|
||||
#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b))
|
||||
#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))
|
||||
|
||||
#define MULT16_32_Q11(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q13(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q14(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q15(a,b) ((a)*(b))
|
||||
#define MULT16_32_P15(a,b) ((a)*(b))
|
||||
|
||||
#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
|
||||
|
||||
#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_16_P13(c,a,b) ((c)+(a)*(b))
|
||||
#define MULT16_16_Q11_32(a,b) ((a)*(b))
|
||||
#define MULT16_16_Q13(a,b) ((a)*(b))
|
||||
#define MULT16_16_Q14(a,b) ((a)*(b))
|
||||
#define MULT16_16_Q15(a,b) ((a)*(b))
|
||||
#define MULT16_16_P15(a,b) ((a)*(b))
|
||||
#define MULT16_16_P13(a,b) ((a)*(b))
|
||||
#define MULT16_16_P14(a,b) ((a)*(b))
|
||||
|
||||
#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
|
||||
#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
|
||||
#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
|
||||
#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
|
||||
|
||||
#define WORD2INT(x) ((x) < -32767.5f ? -32768 : \
|
||||
((x) > 32766.5f ? 32767 : (spx_int16_t)floor(.5 + (x))))
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
|
||||
|
||||
/* 2 on TI C5x DSP */
|
||||
#define BYTES_PER_CHAR 2
|
||||
#define BITS_PER_CHAR 16
|
||||
#define LOG2_BITS_PER_CHAR 4
|
||||
|
||||
#else
|
||||
|
||||
#define BYTES_PER_CHAR 1
|
||||
#define BITS_PER_CHAR 8
|
||||
#define LOG2_BITS_PER_CHAR 3
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
extern long long spx_mips;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,128 @@
|
|||
/* Copyright (C) 2007-2008 Jean-Marc Valin
|
||||
* Copyright (C) 2008 Thorvald Natvig
|
||||
*/
|
||||
/**
|
||||
@file resample_sse.h
|
||||
@brief Resampler functions (SSE version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define OVERRIDE_INNER_PRODUCT_SINGLE
|
||||
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
for (i=0;i<len;i+=8)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));
|
||||
}
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
|
||||
static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
for(i=0;i<len;i+=2)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));
|
||||
}
|
||||
sum = _mm_mul_ps(f, sum);
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
#include <emmintrin.h>
|
||||
#define OVERRIDE_INNER_PRODUCT_DOUBLE
|
||||
|
||||
static inline double inner_product_double(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
double ret;
|
||||
__m128d sum = _mm_setzero_pd();
|
||||
__m128 t;
|
||||
for (i=0;i<len;i+=8)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
|
||||
static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
|
||||
int i;
|
||||
double ret;
|
||||
__m128d sum;
|
||||
__m128d sum1 = _mm_setzero_pd();
|
||||
__m128d sum2 = _mm_setzero_pd();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
__m128d f1 = _mm_cvtps_pd(f);
|
||||
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));
|
||||
__m128 t;
|
||||
for(i=0;i<len;i+=2)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
|
||||
t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum1 = _mm_mul_pd(f1, sum1);
|
||||
sum2 = _mm_mul_pd(f2, sum2);
|
||||
sum = _mm_add_pd(sum1, sum2);
|
||||
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,344 @@
|
|||
/* Copyright (C) 2007 Jean-Marc Valin
|
||||
|
||||
File: speex_resampler.h
|
||||
Resampling code
|
||||
|
||||
The design goals of this code are:
|
||||
- Very fast algorithm
|
||||
- Low memory requirement
|
||||
- Good *perceptual* quality (and not best SNR)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SPEEX_RESAMPLER_H
|
||||
#define SPEEX_RESAMPLER_H
|
||||
|
||||
#ifdef OUTSIDE_SPEEX
|
||||
|
||||
/********* WARNING: MENTAL SANITY ENDS HERE *************/
|
||||
|
||||
/* If the resampler is defined outside of Speex, we change the symbol names so that
|
||||
there won't be any clash if linking with Speex later on. */
|
||||
|
||||
/* #define RANDOM_PREFIX your software name here */
|
||||
#ifndef RANDOM_PREFIX
|
||||
#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes"
|
||||
#endif
|
||||
|
||||
#define CAT_PREFIX2(a,b) a ## b
|
||||
#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
|
||||
|
||||
#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
|
||||
#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
|
||||
#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
|
||||
#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)
|
||||
#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)
|
||||
#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)
|
||||
#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)
|
||||
#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)
|
||||
#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)
|
||||
#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)
|
||||
#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)
|
||||
#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)
|
||||
#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
|
||||
#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
|
||||
#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
|
||||
#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
|
||||
#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
|
||||
#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency)
|
||||
#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency)
|
||||
#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
|
||||
#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
|
||||
#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
|
||||
|
||||
#define spx_int16_t short
|
||||
#define spx_int32_t int
|
||||
#define spx_uint16_t unsigned short
|
||||
#define spx_uint32_t unsigned int
|
||||
|
||||
#define speex_assert(cond)
|
||||
|
||||
#else /* OUTSIDE_SPEEX */
|
||||
|
||||
#include "speexdsp_types.h"
|
||||
|
||||
#endif /* OUTSIDE_SPEEX */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SPEEX_RESAMPLER_QUALITY_MAX 10
|
||||
#define SPEEX_RESAMPLER_QUALITY_MIN 0
|
||||
#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
|
||||
#define SPEEX_RESAMPLER_QUALITY_VOIP 3
|
||||
#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
|
||||
|
||||
enum {
|
||||
RESAMPLER_ERR_SUCCESS = 0,
|
||||
RESAMPLER_ERR_ALLOC_FAILED = 1,
|
||||
RESAMPLER_ERR_BAD_STATE = 2,
|
||||
RESAMPLER_ERR_INVALID_ARG = 3,
|
||||
RESAMPLER_ERR_PTR_OVERLAP = 4,
|
||||
RESAMPLER_ERR_OVERFLOW = 5,
|
||||
|
||||
RESAMPLER_ERR_MAX_ERROR
|
||||
};
|
||||
|
||||
struct SpeexResamplerState_;
|
||||
typedef struct SpeexResamplerState_ SpeexResamplerState;
|
||||
|
||||
/** Create a new resampler with integer input and output rates.
|
||||
* @param nb_channels Number of channels to be processed
|
||||
* @param in_rate Input sampling rate (integer number of Hz).
|
||||
* @param out_rate Output sampling rate (integer number of Hz).
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor quality
|
||||
* and 10 has very high quality.
|
||||
* @return Newly created resampler state
|
||||
* @retval NULL Error: not enough memory
|
||||
*/
|
||||
|
||||
SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate,
|
||||
int quality,
|
||||
int *err);
|
||||
|
||||
/** Create a new resampler with fractional input/output rates. The sampling
|
||||
* rate ratio is an arbitrary rational number with both the numerator and
|
||||
* denominator being 32-bit integers.
|
||||
* @param nb_channels Number of channels to be processed
|
||||
* @param ratio_num Numerator of the sampling rate ratio
|
||||
* @param ratio_den Denominator of the sampling rate ratio
|
||||
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor quality
|
||||
* and 10 has very high quality.
|
||||
* @return Newly created resampler state
|
||||
* @retval NULL Error: not enough memory
|
||||
*/
|
||||
SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
|
||||
spx_uint32_t ratio_num,
|
||||
spx_uint32_t ratio_den,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate,
|
||||
int quality,
|
||||
int *err);
|
||||
|
||||
/** Destroy a resampler state.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
void speex_resampler_destroy(SpeexResamplerState *st);
|
||||
|
||||
/** Resample a float array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param channel_index Index of the channel to process for the multi-channel
|
||||
* base (0 otherwise)
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the
|
||||
* number of samples processed
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written
|
||||
*/
|
||||
int speex_resampler_process_float(SpeexResamplerState *st,
|
||||
spx_uint32_t channel_index,
|
||||
const float *in,
|
||||
spx_uint32_t *in_len,
|
||||
float *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an int array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param channel_index Index of the channel to process for the multi-channel
|
||||
* base (0 otherwise)
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written
|
||||
*/
|
||||
int speex_resampler_process_int(SpeexResamplerState *st,
|
||||
spx_uint32_t channel_index,
|
||||
const spx_int16_t *in,
|
||||
spx_uint32_t *in_len,
|
||||
spx_int16_t *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an interleaved float array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed. This is all per-channel.
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written.
|
||||
* This is all per-channel.
|
||||
*/
|
||||
int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
|
||||
const float *in,
|
||||
spx_uint32_t *in_len,
|
||||
float *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an interleaved int array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed. This is all per-channel.
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written.
|
||||
* This is all per-channel.
|
||||
*/
|
||||
int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
|
||||
const spx_int16_t *in,
|
||||
spx_uint32_t *in_len,
|
||||
spx_int16_t *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Set (change) the input/output sampling rates (integer value).
|
||||
* @param st Resampler state
|
||||
* @param in_rate Input sampling rate (integer number of Hz).
|
||||
* @param out_rate Output sampling rate (integer number of Hz).
|
||||
*/
|
||||
int speex_resampler_set_rate(SpeexResamplerState *st,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate);
|
||||
|
||||
/** Get the current input/output sampling rates (integer value).
|
||||
* @param st Resampler state
|
||||
* @param in_rate Input sampling rate (integer number of Hz) copied.
|
||||
* @param out_rate Output sampling rate (integer number of Hz) copied.
|
||||
*/
|
||||
void speex_resampler_get_rate(SpeexResamplerState *st,
|
||||
spx_uint32_t *in_rate,
|
||||
spx_uint32_t *out_rate);
|
||||
|
||||
/** Set (change) the input/output sampling rates and resampling ratio
|
||||
* (fractional values in Hz supported).
|
||||
* @param st Resampler state
|
||||
* @param ratio_num Numerator of the sampling rate ratio
|
||||
* @param ratio_den Denominator of the sampling rate ratio
|
||||
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
|
||||
*/
|
||||
int speex_resampler_set_rate_frac(SpeexResamplerState *st,
|
||||
spx_uint32_t ratio_num,
|
||||
spx_uint32_t ratio_den,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate);
|
||||
|
||||
/** Get the current resampling ratio. This will be reduced to the least
|
||||
* common denominator.
|
||||
* @param st Resampler state
|
||||
* @param ratio_num Numerator of the sampling rate ratio copied
|
||||
* @param ratio_den Denominator of the sampling rate ratio copied
|
||||
*/
|
||||
void speex_resampler_get_ratio(SpeexResamplerState *st,
|
||||
spx_uint32_t *ratio_num,
|
||||
spx_uint32_t *ratio_den);
|
||||
|
||||
/** Set (change) the conversion quality.
|
||||
* @param st Resampler state
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor
|
||||
* quality and 10 has very high quality.
|
||||
*/
|
||||
int speex_resampler_set_quality(SpeexResamplerState *st,
|
||||
int quality);
|
||||
|
||||
/** Get the conversion quality.
|
||||
* @param st Resampler state
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor
|
||||
* quality and 10 has very high quality.
|
||||
*/
|
||||
void speex_resampler_get_quality(SpeexResamplerState *st,
|
||||
int *quality);
|
||||
|
||||
/** Set (change) the input stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Input stride
|
||||
*/
|
||||
void speex_resampler_set_input_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t stride);
|
||||
|
||||
/** Get the input stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Input stride copied
|
||||
*/
|
||||
void speex_resampler_get_input_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t *stride);
|
||||
|
||||
/** Set (change) the output stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Output stride
|
||||
*/
|
||||
void speex_resampler_set_output_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t stride);
|
||||
|
||||
/** Get the output stride.
|
||||
* @param st Resampler state copied
|
||||
* @param stride Output stride
|
||||
*/
|
||||
void speex_resampler_get_output_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t *stride);
|
||||
|
||||
/** Get the latency introduced by the resampler measured in input samples.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_get_input_latency(SpeexResamplerState *st);
|
||||
|
||||
/** Get the latency introduced by the resampler measured in output samples.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_get_output_latency(SpeexResamplerState *st);
|
||||
|
||||
/** Make sure that the first samples to go out of the resamplers don't have
|
||||
* leading zeros. This is only useful before starting to use a newly created
|
||||
* resampler. It is recommended to use that when resampling an audio file, as
|
||||
* it will generate a file with the same length. For real-time processing,
|
||||
* it is probably easier not to use this call (so that the output duration
|
||||
* is the same for the first frame).
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_skip_zeros(SpeexResamplerState *st);
|
||||
|
||||
/** Reset a resampler so a new (unrelated) stream can be processed.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_reset_mem(SpeexResamplerState *st);
|
||||
|
||||
/** Returns the English meaning for an error code
|
||||
* @param err Error code
|
||||
* @return English string
|
||||
*/
|
||||
const char *speex_resampler_strerror(int err);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -15,7 +15,8 @@ udpHandler::udpHandler(udpPreferences prefs) :
|
|||
rxCodec(prefs.audioRXCodec),
|
||||
txCodec(prefs.audioTXCodec),
|
||||
audioInputPort(prefs.audioInput),
|
||||
audioOutputPort(prefs.audioOutput)
|
||||
audioOutputPort(prefs.audioOutput),
|
||||
resampleQuality(prefs.resampleQuality)
|
||||
{
|
||||
|
||||
this->port = this->controlPort;
|
||||
|
@ -150,6 +151,8 @@ void udpHandler::dataReceived()
|
|||
control_packet_t in = (control_packet_t)r.constData();
|
||||
if (in->type == 0x04) {
|
||||
// If timer is active, stop it as they are obviously there!
|
||||
qDebug(logUdp()) << this->metaObject()->className() << ": Received I am here from: " <<datagram.senderAddress();
|
||||
|
||||
if (areYouThereTimer->isActive()) {
|
||||
// send ping packets every second
|
||||
areYouThereTimer->stop();
|
||||
|
@ -305,7 +308,7 @@ void udpHandler::dataReceived()
|
|||
}
|
||||
else {
|
||||
civ = new udpCivData(localIP, radioIP, civPort);
|
||||
audio = new udpAudio(localIP, radioIP, audioPort, rxLatency, txLatency, rxSampleRate, rxCodec, txSampleRate, txCodec, audioOutputPort, audioInputPort);
|
||||
audio = new udpAudio(localIP, radioIP, audioPort, rxLatency, txLatency, rxSampleRate, rxCodec, txSampleRate, txCodec, audioOutputPort, audioInputPort,resampleQuality);
|
||||
|
||||
QObject::connect(civ, SIGNAL(receive(QByteArray)), this, SLOT(receiveFromCivStream(QByteArray)));
|
||||
QObject::connect(audio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket)));
|
||||
|
@ -399,7 +402,7 @@ void udpHandler::sendRequestStream()
|
|||
p.civport = qToBigEndian((quint32)civPort);
|
||||
p.audioport = qToBigEndian((quint32)audioPort);
|
||||
p.txbuffer = qToBigEndian((quint32)txLatency);
|
||||
|
||||
p.convert = 1;
|
||||
sendTrackedPacket(QByteArray::fromRawData((const char*)p.packet, sizeof(p)));
|
||||
return;
|
||||
}
|
||||
|
@ -642,7 +645,7 @@ void udpCivData::dataReceived()
|
|||
|
||||
|
||||
// Audio stream
|
||||
udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint16 rxlatency, quint16 txlatency, quint16 rxsample, quint8 rxcodec, quint16 txsample, quint8 txcodec, QString outputPort, QString inputPort)
|
||||
udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint16 rxlatency, quint16 txlatency, quint16 rxsample, quint8 rxcodec, quint16 txsample, quint8 txcodec, QString outputPort, QString inputPort,quint8 resampleQuality)
|
||||
{
|
||||
qDebug(logUdp()) << "Starting udpAudio";
|
||||
this->localIP = local;
|
||||
|
@ -685,7 +688,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
|
|||
|
||||
rxaudio->moveToThread(rxAudioThread);
|
||||
|
||||
connect(this, SIGNAL(setupRxAudio(quint8, quint8, quint16, quint16, bool, bool, QString)), rxaudio, SLOT(init(quint8, quint8, quint16, quint16, bool, bool,QString)));
|
||||
connect(this, SIGNAL(setupRxAudio(quint8, quint8, quint16, quint16, bool, bool, QString, quint8)), rxaudio, SLOT(init(quint8, quint8, quint16, quint16, bool, bool,QString, quint8)));
|
||||
|
||||
qRegisterMetaType<audioPacket>();
|
||||
connect(this, SIGNAL(haveAudioData(audioPacket)), rxaudio, SLOT(incomingAudio(audioPacket)));
|
||||
|
@ -704,7 +707,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
|
|||
|
||||
txaudio->moveToThread(txAudioThread);
|
||||
|
||||
connect(this, SIGNAL(setupTxAudio(quint8, quint8, quint16, quint16, bool, bool,QString)), txaudio, SLOT(init(quint8, quint8, quint16, quint16, bool, bool,QString)));
|
||||
connect(this, SIGNAL(setupTxAudio(quint8, quint8, quint16, quint16, bool, bool,QString,quint8)), txaudio, SLOT(init(quint8, quint8, quint16, quint16, bool, bool,QString,quint8)));
|
||||
connect(txAudioThread, SIGNAL(finished()), txaudio, SLOT(deleteLater()));
|
||||
|
||||
rxAudioThread->start();
|
||||
|
@ -717,8 +720,8 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
|
|||
connect(pingTimer, &QTimer::timeout, this, &udpBase::sendPing);
|
||||
pingTimer->start(PING_PERIOD); // send ping packets every 100ms
|
||||
|
||||
emit setupTxAudio(txNumSamples, txChannelCount, txSampleRate, txLatency, txIsUlawCodec, true, inputPort);
|
||||
emit setupRxAudio(rxNumSamples, rxChannelCount, rxSampleRate, txLatency, rxIsUlawCodec, false, outputPort);
|
||||
emit setupTxAudio(txNumSamples, txChannelCount, txSampleRate, txLatency, txIsUlawCodec, true, inputPort,resampleQuality);
|
||||
emit setupRxAudio(rxNumSamples, rxChannelCount, rxSampleRate, txLatency, rxIsUlawCodec, false, outputPort,resampleQuality);
|
||||
|
||||
watchdogTimer = new QTimer();
|
||||
connect(watchdogTimer, &QTimer::timeout, this, &udpAudio::watchdog);
|
||||
|
@ -788,7 +791,12 @@ void udpAudio::sendTxAudio()
|
|||
p.len = sizeof(p) + partial.length();
|
||||
p.sentid = myId;
|
||||
p.rcvdid = remoteId;
|
||||
p.ident = 0x0080; // TX audio is always this?
|
||||
if (partial.length() == 0xa0) {
|
||||
p.ident = 0x9781;
|
||||
}
|
||||
else {
|
||||
p.ident = 0x0080; // TX audio is always this?
|
||||
}
|
||||
p.datalen = (quint16)qToBigEndian((quint16)partial.length());
|
||||
p.sendseq = (quint16)qToBigEndian((quint16)sendAudioSeq); // THIS IS BIG ENDIAN!
|
||||
QByteArray tx = QByteArray::fromRawData((const char*)p.packet, sizeof(p));
|
||||
|
@ -838,23 +846,18 @@ void udpAudio::dataReceived()
|
|||
|
||||
*/
|
||||
control_packet_t in = (control_packet_t)r.constData();
|
||||
if (in->type != 0x01) {
|
||||
if (r.mid(0, 2) == QByteArrayLiteral("\x6c\x05") ||
|
||||
r.mid(0, 2) == QByteArrayLiteral("\x44\x02") ||
|
||||
r.mid(0, 2) == QByteArrayLiteral("\xd8\x03") ||
|
||||
r.mid(0, 2) == QByteArrayLiteral("\x70\x04"))
|
||||
{
|
||||
lastReceived = QTime::currentTime();
|
||||
audioPacket tempAudio;
|
||||
tempAudio.seq = in->seq;
|
||||
tempAudio.time = lastReceived;
|
||||
tempAudio.sent = 0;
|
||||
tempAudio.data = r.mid(0x18);
|
||||
// Prefer signal/slot to forward audio as it is thread/safe
|
||||
// Need to do more testing but latency appears fine.
|
||||
emit haveAudioData(tempAudio);
|
||||
//rxaudio->incomingAudio(tempAudio);
|
||||
}
|
||||
if (in->type != 0x01 && in->len >= 0xAC) {
|
||||
// 0xac is the smallest possible audio packet.
|
||||
lastReceived = QTime::currentTime();
|
||||
audioPacket tempAudio;
|
||||
tempAudio.seq = in->seq;
|
||||
tempAudio.time = lastReceived;
|
||||
tempAudio.sent = 0;
|
||||
tempAudio.datain = r.mid(0x18);
|
||||
// Prefer signal/slot to forward audio as it is thread/safe
|
||||
// Need to do more testing but latency appears fine.
|
||||
emit haveAudioData(tempAudio);
|
||||
//rxaudio->incomingAudio(tempAudio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -956,7 +959,7 @@ void udpBase::dataReceived(QByteArray r)
|
|||
}
|
||||
}
|
||||
if (in->type == 0x04) {
|
||||
qDebug(logUdp()) << this->metaObject()->className() << ": Received I am here";
|
||||
qDebug(logUdp()) << this->metaObject()->className() << ": Received I am here ";
|
||||
areYouThereCounter = 0;
|
||||
// I don't think that we will ever receive an "I am here" other than in response to "Are you there?"
|
||||
remoteId = in->sentid;
|
||||
|
|
|
@ -48,6 +48,7 @@ struct udpPreferences {
|
|||
quint8 audioRXCodec;
|
||||
quint16 audioTXSampleRate;
|
||||
quint8 audioTXCodec;
|
||||
quint8 resampleQuality;
|
||||
};
|
||||
|
||||
void passcode(QString in, QByteArray& out);
|
||||
|
@ -166,14 +167,14 @@ class udpAudio : public udpBase
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 rxlatency, quint16 txlatency, quint16 rxsample, quint8 rxcodec, quint16 txsample, quint8 txcodec, QString outputPort, QString inputPort);
|
||||
udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 rxlatency, quint16 txlatency, quint16 rxsample, quint8 rxcodec, quint16 txsample, quint8 txcodec, QString outputPort, QString inputPort,quint8 resampleQuality);
|
||||
~udpAudio();
|
||||
|
||||
signals:
|
||||
void haveAudioData(audioPacket data);
|
||||
|
||||
void setupTxAudio(const quint8 samples, const quint8 channels, const quint16 samplerate, const quint16 latency, const bool isUlaw, const bool isInput, QString port);
|
||||
void setupRxAudio(const quint8 samples, const quint8 channels, const quint16 samplerate, const quint16 latency, const bool isUlaw, const bool isInput, QString port);
|
||||
void setupTxAudio(const quint8 samples, const quint8 channels, const quint16 samplerate, const quint16 latency, const bool isUlaw, const bool isInput, QString port,quint8 resampleQuality);
|
||||
void setupRxAudio(const quint8 samples, const quint8 channels, const quint16 samplerate, const quint16 latency, const bool isUlaw, const bool isInput, QString port,quint8 resampleQuality);
|
||||
|
||||
void haveChangeLatency(quint16 value);
|
||||
|
||||
|
@ -276,6 +277,8 @@ private:
|
|||
|
||||
QString audioInputPort;
|
||||
QString audioOutputPort;
|
||||
|
||||
quint8 resampleQuality;
|
||||
|
||||
quint16 reauthInterval = 60000;
|
||||
QString devName;
|
||||
|
|
|
@ -1062,14 +1062,14 @@ void udpServer::receiveAudioData(const audioPacket &d)
|
|||
if (client != Q_NULLPTR && client->connected) {
|
||||
audio_packet p;
|
||||
memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00!
|
||||
p.len = sizeof(p) + d.data.length();
|
||||
p.len = sizeof(p) + d.datain.length();
|
||||
p.sentid = client->myId;
|
||||
p.rcvdid = client->remoteId;
|
||||
p.ident = 0x0080; // audio is always this?
|
||||
p.datalen = (quint16)qToBigEndian((quint16)d.data.length());
|
||||
p.datalen = (quint16)qToBigEndian((quint16)d.datain.length());
|
||||
p.sendseq = (quint16)qToBigEndian((quint16)client->sendAudioSeq); // THIS IS BIG ENDIAN!
|
||||
QByteArray t = QByteArray::fromRawData((const char*)p.packet, sizeof(p));
|
||||
t.append(d.data);
|
||||
t.append(d.datain);
|
||||
QMutexLocker locker(&mutex);
|
||||
client->txSeqBuf.append(SEQBUFENTRY());
|
||||
client->txSeqBuf.last().seqNum = p.seq;
|
||||
|
|
|
@ -761,8 +761,7 @@ void wfmain::setDefPrefs()
|
|||
udpDefPrefs.audioRXCodec = 4;
|
||||
udpDefPrefs.audioTXSampleRate = 48000;
|
||||
udpDefPrefs.audioTXCodec = 4;
|
||||
|
||||
|
||||
udpDefPrefs.resampleQuality = 4;
|
||||
}
|
||||
|
||||
void wfmain::loadSettings()
|
||||
|
@ -878,6 +877,8 @@ void wfmain::loadSettings()
|
|||
ui->audioInputCombo->setCurrentIndex(audioInputIndex);
|
||||
}
|
||||
|
||||
udpPrefs.resampleQuality = settings.value("ResampleQuality", udpDefPrefs.resampleQuality).toInt();
|
||||
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Server");
|
||||
|
@ -985,6 +986,7 @@ void wfmain::saveSettings()
|
|||
settings.setValue("AudioTXCodec", udpPrefs.audioTXCodec);
|
||||
settings.setValue("AudioOutput", udpPrefs.audioOutput);
|
||||
settings.setValue("AudioInput", udpPrefs.audioInput);
|
||||
settings.setValue("ResampleQuality", udpPrefs.resampleQuality);
|
||||
settings.endGroup();
|
||||
|
||||
// Memory channels
|
||||
|
|
12
wfview.pro
12
wfview.pro
|
@ -31,6 +31,10 @@ QMAKE_LFLAGS += -O2 -march=native -s
|
|||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
DEFINES += QCUSTOMPLOT_COMPILE_LIBRARY
|
||||
|
||||
# These defines are used for the resampler
|
||||
DEFINES += OUTSIDE_SPEEX
|
||||
DEFINES += RANDOM_PREFIX=wf
|
||||
|
||||
linux:DEFINES += HOST=\\\"`hostname`\\\" UNAME=\\\"`whoami`\\\"
|
||||
|
||||
linux:DEFINES += GITSHORT="\\\"$(shell git -C $$PWD rev-parse --short HEAD)\\\""
|
||||
|
@ -88,7 +92,8 @@ SOURCES += main.cpp\
|
|||
udpserver.cpp \
|
||||
meter.cpp \
|
||||
qledlabel.cpp \
|
||||
pttyhandler.cpp
|
||||
pttyhandler.cpp \
|
||||
resampler/resample.cpp
|
||||
|
||||
HEADERS += wfmain.h \
|
||||
commhandler.h \
|
||||
|
@ -105,7 +110,10 @@ HEADERS += wfmain.h \
|
|||
packettypes.h \
|
||||
meter.h \
|
||||
qledlabel.h \
|
||||
pttyhandler.h
|
||||
pttyhandler.h \
|
||||
resampler/speex_resampler.h \
|
||||
resampler/arch.h \
|
||||
resampler/resample_sse.h
|
||||
|
||||
|
||||
FORMS += wfmain.ui \
|
||||
|
|
10
wfview.sln
10
wfview.sln
|
@ -8,13 +8,23 @@ EndProject
|
|||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
Template|x64 = Template|x64
|
||||
Template|x86 = Template|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Debug|x64.Build.0 = Debug|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Release|x64.ActiveCfg = Release|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Release|x64.Build.0 = Release|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Release|x86.ActiveCfg = Release|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Template|x64.ActiveCfg = Release|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Template|x64.Build.0 = Release|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Template|x86.ActiveCfg = Release|x64
|
||||
{326108AD-FA9D-3AAF-8D3E-062C4DDC34E2}.Template|x86.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ObjectFileName>debug\</ObjectFileName>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DEPRECATED_WARNINGS;QCUSTOMPLOT_USE_OPENGL;HOST=1;UNAME=1;GITSHORT=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DEPRECATED_WARNINGS;QCUSTOMPLOT_USE_OPENGL;HOST=1;UNAME=1;GITSHORT=1;OUTSIDE_SPEEX;RANDOM_PREFIX=wf;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
|
@ -210,6 +210,7 @@
|
|||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="c:\qcustomplot\qcustomplot.cpp" />
|
||||
<ClCompile Include="meter.cpp" />
|
||||
<ClCompile Include="resampler\resample.c" />
|
||||
<ClCompile Include="rigcommander.cpp" />
|
||||
<ClCompile Include="rigidentities.cpp" />
|
||||
<ClCompile Include="audiohandler.cpp" />
|
||||
|
@ -237,6 +238,7 @@
|
|||
<QtMoc Include="meter.h" />
|
||||
<ClInclude Include="packettypes.h" />
|
||||
<QtMoc Include="pttyhandler.h" />
|
||||
<ClInclude Include="resampler\speex_resampler.h" />
|
||||
<ClInclude Include="rigidentities.h" />
|
||||
<QtMoc Include="udphandler.h">
|
||||
</QtMoc>
|
||||
|
|
|
@ -108,6 +108,9 @@
|
|||
<ClCompile Include="pttyhandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="resampler\resample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="commhandler.h">
|
||||
|
@ -323,6 +326,10 @@
|
|||
<None Include="resources\wfview.png" />
|
||||
<None Include="resources\wfview.png" />
|
||||
<None Include="resources\wfview.png" />
|
||||
<None Include="resources\wfview.png" />
|
||||
<None Include="resources\wfview.png" />
|
||||
<None Include="resources\wfview.png" />
|
||||
<None Include="resources\wfview.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resources\install.sh">
|
||||
|
@ -339,5 +346,8 @@
|
|||
<ClInclude Include="packettypes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resampler\speex_resampler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Ładowanie…
Reference in New Issue