1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-15 12:51:49 -05:00

UDPsrc utility: fixed buffer wrap around code. UDPSunk plugin: set a fixed UDP block size of 2048 (512 samples * 4 byte samples) thanks to UDPsrc utility

This commit is contained in:
f4exb 2016-04-03 11:29:11 +02:00
parent f245dc8206
commit 4debb8eb41
3 changed files with 70 additions and 81 deletions

View File

@ -30,6 +30,7 @@ MESSAGE_CLASS_DEFINITION(UDPSrc::MsgUDPSrcSpectrum, Message)
UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, SampleSink* spectrum) :
m_settingsMutex(QMutex::Recursive),
m_udpPort(9999),
m_audioFifo(4, 24000),
m_audioActive(false),
m_audioStereo(false),
@ -37,7 +38,7 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, SampleSink* s
{
setObjectName("UDPSrc");
m_socket = new QUdpSocket(this);
m_udpBuffer = new UDPSink<Sample>(this, udpBLockSampleSize, m_udpPort);
m_audioSocket = new QUdpSocket(this);
m_audioBuffer.resize(1<<9);
@ -47,7 +48,6 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, SampleSink* s
m_sampleFormat = FormatSSB;
m_outputSampleRate = 48000;
m_rfBandwidth = 32000;
m_udpPort = 9999;
m_audioPort = m_udpPort - 1;
m_nco.setFreq(0, m_inputSampleRate);
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0);
@ -64,8 +64,7 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, SampleSink* s
m_scale = 0;
m_boost = 0;
m_magsq = 0;
m_sampleBufferSSB.resize(udpFftLen);
UDPFilter = new fftfilt(0.3 / 48.0, 16.0 / 48.0, udpFftLen);
UDPFilter = new fftfilt(0.3 / 48.0, 16.0 / 48.0, udpBLockSampleSize * sizeof(Sample));
if (m_audioSocket->bind(QHostAddress::LocalHost, m_audioPort))
{
@ -83,7 +82,7 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, SampleSink* s
UDPSrc::~UDPSrc()
{
delete m_audioSocket;
delete m_socket;
delete m_udpBuffer;
if (UDPFilter) delete UDPFilter;
if (m_audioActive) DSPEngine::instance()->removeAudioSink(&m_audioFifo);
}
@ -132,62 +131,38 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
Real l, r;
m_sampleBuffer.clear();
m_settingsMutex.lock();
// Rtl-Sdr uses full 16-bit scale; FCDPP does not
//int rescale = 32768 * (1 << m_boost);
int rescale = (1 << m_boost);
for(SampleVector::const_iterator it = begin; it < end; ++it) {
//Complex c(it->real() / 32768.0f, it->imag() / 32768.0f);
for(SampleVector::const_iterator it = begin; it < end; ++it)
{
Complex c(it->real(), it->imag());
c *= m_nco.nextIQ();
if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci))
{
m_magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())*rescale*rescale) / (1<<30);
m_sampleBuffer.push_back(Sample(ci.real() * rescale, ci.imag() * rescale));
Sample s(ci.real() * rescale, ci.imag() * rescale);
m_sampleBuffer.push_back(s);
m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate;
}
}
if((m_spectrum != 0) && (m_spectrumEnabled))
{
m_spectrum->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), positiveOnly);
}
if (m_sampleFormat == FormatSSB)
{
for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it)
{
//Complex cj(it->real() / 30000.0, it->imag() / 30000.0);
Complex cj(it->real(), it->imag());
int n_out = UDPFilter->runSSB(cj, &sideband, true);
int n_out = UDPFilter->runSSB(ci, &sideband, true);
if (n_out)
{
for (int i = 0; i < n_out; i+=2)
{
//l = (sideband[i].real() + sideband[i].imag()) * 0.7 * 32000.0;
//r = (sideband[i+1].real() + sideband[i+1].imag()) * 0.7 * 32000.0;
l = (sideband[i].real() + sideband[i].imag()) * 0.7;
r = (sideband[i+1].real() + sideband[i+1].imag()) * 0.7;
m_sampleBufferSSB.push_back(Sample(l, r));
}
m_socket->writeDatagram((const char*)&m_sampleBufferSSB[0], (qint64 ) (n_out * 2), m_udpAddress, m_udpPort);
m_sampleBufferSSB.clear();
m_udpBuffer->write(Sample(l, r));
}
}
}
else if (m_sampleFormat == FormatNFM)
{
for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it)
{
Complex cj(it->real() / 32768.0f, it->imag() / 32768.0f);
// An FFT filter here is overkill, but was already set up for SSB
int n_out = UDPFilter->runFilt(cj, &sideband);
int n_out = UDPFilter->runFilt(ci, &sideband);
if (n_out)
{
@ -200,19 +175,25 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
r = m_last.real() * (m_this.imag() - sideband[i+1].imag())
- m_last.imag() * (m_this.real() - sideband[i+1].real());
m_this = sideband[i+1];
m_sampleBufferSSB.push_back(Sample(l * m_scale, r * m_scale));
m_udpBuffer->write(Sample(l*m_scale, r*m_scale));
sum += m_this.real() * m_this.real() + m_this.imag() * m_this.imag();
}
// TODO: correct levels
m_scale = 24000 * udpFftLen / sum;
m_socket->writeDatagram((const char*)&m_sampleBufferSSB[0], (qint64 ) (n_out * 2), m_udpAddress, m_udpPort);
m_sampleBufferSSB.clear();
m_scale = (24000 * udpBLockSampleSize * sizeof(Sample)) / sum; // TODO: correct levels
}
}
}
else
else // Raw I/Q samples
{
m_socket->writeDatagram((const char*)&m_sampleBuffer[0], (qint64 ) (m_sampleBuffer.size() * 4), m_udpAddress, m_udpPort);
m_udpBuffer->write(s);
}
}
}
qDebug() << "UDPSrc::feed: " << m_sampleBuffer.size() * 4;
if((m_spectrum != 0) && (m_spectrumEnabled))
{
m_spectrum->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), positiveOnly);
}
m_settingsMutex.unlock();
@ -305,14 +286,16 @@ bool UDPSrc::handleMessage(const Message& cmd)
m_outputSampleRate = cfg.getOutputSampleRate();
m_rfBandwidth = cfg.getRFBandwidth();
if (cfg.getUDPAddress() != m_udpAddress.toString())
if (cfg.getUDPAddress() != m_udpAddressStr)
{
m_udpAddress.setAddress(cfg.getUDPAddress());
m_udpAddressStr = cfg.getUDPAddress();
m_udpBuffer->setAddress(m_udpAddressStr);
}
if (cfg.getUDPPort() != m_udpPort)
{
m_udpPort = cfg.getUDPPort();
m_udpBuffer->setPort(m_udpPort);
}
if (cfg.getAudioPort() != m_audioPort)
@ -351,7 +334,7 @@ bool UDPSrc::handleMessage(const Message& cmd)
<< " m_outputSampleRate: " << m_outputSampleRate
<< " m_rfBandwidth: " << m_rfBandwidth
<< " m_boost: " << m_boost
<< " m_udpAddress: " << cfg.getUDPAddress()
<< " m_udpAddressStr: " << m_udpAddressStr
<< " m_udpPort: " << m_udpPort
<< " m_audioPort: " << m_audioPort;

View File

@ -24,12 +24,11 @@
#include "dsp/nco.h"
#include "dsp/fftfilt.h"
#include "dsp/interpolator.h"
#include "util/udpsink.h"
#include "util/message.h"
#include "audio/audiofifo.h"
#define udpFftLen 2048
class QUdpSocket;
class UDPSrcGUI;
@ -74,6 +73,8 @@ public:
virtual void stop();
virtual bool handleMessage(const Message& cmd);
static const int udpBLockSampleSize = 512; // UDP block size in number of samples
public slots:
void audioReadyRead();
@ -192,7 +193,6 @@ protected:
MessageQueue* m_uiMessageQueue;
UDPSrcGUI* m_udpSrcGUI;
QUdpSocket *m_socket;
QUdpSocket *m_audioSocket;
int m_inputSampleRate;
@ -200,7 +200,7 @@ protected:
int m_sampleFormat;
Real m_outputSampleRate;
Real m_rfBandwidth;
QHostAddress m_udpAddress;
QString m_udpAddressStr;
quint16 m_udpPort;
quint16 m_audioPort;
int m_boost;
@ -218,7 +218,7 @@ protected:
fftfilt* UDPFilter;
SampleVector m_sampleBuffer;
SampleVector m_sampleBufferSSB;
UDPSink<Sample> *m_udpBuffer;
AudioVector m_audioBuffer;
uint m_audioBufferFill;

View File

@ -22,6 +22,8 @@
#include <QUdpSocket>
#include <QHostAddress>
#include <cassert>
template<typename T>
class UDPSink
{
@ -42,6 +44,7 @@ public:
m_port(port),
m_sampleBufferIndex(0)
{
assert(m_udpSize > 2);
m_sampleBuffer = new T[m_udpSize];
m_socket = new QUdpSocket(parent);
}
@ -52,18 +55,21 @@ public:
delete m_socket;
}
void setAddress(QString& address) { m_address.setAddress(address); }
void setPort(unsigned int port) { m_port = port; }
void write(T sample)
{
m_sampleBuffer[m_sampleBufferIndex] = sample;
if (m_sampleBufferIndex < m_udpSize)
{
m_sampleBuffer[m_sampleBufferIndex] = sample;
m_sampleBufferIndex++;
}
else
{
m_socket->writeDatagram((const char*)&m_sampleBuffer[0], (qint64 ) (m_udpSize * sizeof(T)), m_address, m_port);
m_sampleBufferIndex = 0;
m_sampleBuffer[0] = sample;
m_sampleBufferIndex = 1;
}
}