1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-05-29 13:32:26 -04:00

SSB over TCP.

This commit is contained in:
hexameron 2014-12-03 18:41:38 +00:00
parent acdc87ccc5
commit 4ef7857aa5
11 changed files with 54 additions and 56 deletions

View File

@ -6,11 +6,11 @@
const PluginDescriptor SSBPlugin::m_pluginDescriptor = { const PluginDescriptor SSBPlugin::m_pluginDescriptor = {
QString("SSB Demodulator"), QString("SSB Demodulator"),
QString("---"), QString("1.0"),
QString("(c) maintech GmbH (rewritten by John Greb)"), QString("(c) 2014 John Greb"),
QString("http://www.maintech.de"), QString("http://www.maintech.de"),
true, true,
QString("http://www.maintech.de") QString("github.com/hexameron/rtl-sdrangelove")
}; };
SSBPlugin::SSBPlugin(QObject* parent) : SSBPlugin::SSBPlugin(QObject* parent) :

View File

@ -11,10 +11,10 @@ MESSAGE_CLASS_DEFINITION(TCPSrc::MsgTCPSrcSpectrum, Message)
TCPSrc::TCPSrc(MessageQueue* uiMessageQueue, TCPSrcGUI* tcpSrcGUI, SampleSink* spectrum) TCPSrc::TCPSrc(MessageQueue* uiMessageQueue, TCPSrcGUI* tcpSrcGUI, SampleSink* spectrum)
{ {
m_inputSampleRate = 100000; m_inputSampleRate = 96000;
m_sampleFormat = FormatS8; m_sampleFormat = FormatSSB;
m_outputSampleRate = 48000; m_outputSampleRate = 48000;
m_rfBandwidth = 40000; m_rfBandwidth = 32000;
m_tcpPort = 9999; m_tcpPort = 9999;
m_nco.setFreq(0, m_inputSampleRate); m_nco.setFreq(0, m_inputSampleRate);
m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.1); m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.1);
@ -23,7 +23,7 @@ TCPSrc::TCPSrc(MessageQueue* uiMessageQueue, TCPSrcGUI* tcpSrcGUI, SampleSink* s
m_tcpSrcGUI = tcpSrcGUI; m_tcpSrcGUI = tcpSrcGUI;
m_spectrum = spectrum; m_spectrum = spectrum;
m_spectrumEnabled = false; m_spectrumEnabled = false;
m_nextS8Id = 0; m_nextSSBId = 0;
m_nextS16leId = 0; m_nextS16leId = 0;
} }
@ -51,7 +51,7 @@ void TCPSrc::feed(SampleVector::const_iterator begin, SampleVector::const_iterat
c *= m_nco.nextIQ(); c *= m_nco.nextIQ();
if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) { if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) {
m_sampleBuffer.push_back(Sample(ci.real() * 32768.0, ci.imag() * 32768.0)); m_sampleBuffer.push_back(Sample(ci.real() * 20000.0, ci.imag() * 20000.0));
m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate; m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate;
} }
} }
@ -62,17 +62,17 @@ void TCPSrc::feed(SampleVector::const_iterator begin, SampleVector::const_iterat
for(int i = 0; i < m_s16leSockets.count(); i++) for(int i = 0; i < m_s16leSockets.count(); i++)
m_s16leSockets[i].socket->write((const char*)&m_sampleBuffer[0], m_sampleBuffer.size() * 4); m_s16leSockets[i].socket->write((const char*)&m_sampleBuffer[0], m_sampleBuffer.size() * 4);
if(m_s8Sockets.count() > 0) { if(m_ssbSockets.count() > 0) {
for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it) { for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it) {
m_sampleBufferS8.push_back(it->real() >> 8); // TODO: fft filter
m_sampleBufferS8.push_back(it->imag() >> 8); m_sampleBufferSSB.push_back(it->real() + it->imag());
} }
for(int i = 0; i < m_s8Sockets.count(); i++) for(int i = 0; i < m_ssbSockets.count(); i++)
m_s8Sockets[i].socket->write((const char*)&m_sampleBufferS8[0], m_sampleBufferS8.size()); m_ssbSockets[i].socket->write((const char*)&m_sampleBufferSSB[0], m_sampleBufferSSB.size());
} }
m_sampleBuffer.clear(); m_sampleBuffer.clear();
m_sampleBufferS8.clear(); m_sampleBufferSSB.clear();
} }
void TCPSrc::start() void TCPSrc::start()
@ -84,7 +84,7 @@ void TCPSrc::start()
void TCPSrc::stop() void TCPSrc::stop()
{ {
closeAllSockets(&m_s8Sockets); closeAllSockets(&m_ssbSockets);
closeAllSockets(&m_s16leSockets); closeAllSockets(&m_s16leSockets);
if(m_tcpServer->isListening()) if(m_tcpServer->isListening())
@ -146,11 +146,11 @@ void TCPSrc::onNewConnection()
connect(connection, SIGNAL(disconnected()), this, SLOT(onDisconnected())); connect(connection, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
switch(m_sampleFormat) { switch(m_sampleFormat) {
case FormatS8: { case FormatSSB: {
quint32 id = (FormatS8 << 24) | m_nextS8Id; quint32 id = (FormatSSB << 24) | m_nextSSBId;
MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(true, id, connection->peerAddress(), connection->peerPort()); MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(true, id, connection->peerAddress(), connection->peerPort());
m_nextS8Id = (m_nextS8Id + 1) & 0xffffff; m_nextSSBId = (m_nextSSBId + 1) & 0xffffff;
m_s8Sockets.push_back(Socket(id, connection)); m_ssbSockets.push_back(Socket(id, connection));
msg->submit(m_uiMessageQueue, (PluginGUI*)m_tcpSrcGUI); msg->submit(m_uiMessageQueue, (PluginGUI*)m_tcpSrcGUI);
break; break;
} }
@ -176,11 +176,11 @@ void TCPSrc::onDisconnected()
quint32 id; quint32 id;
QTcpSocket* socket = NULL; QTcpSocket* socket = NULL;
for(int i = 0; i < m_s8Sockets.count(); i++) { for(int i = 0; i < m_ssbSockets.count(); i++) {
if(m_s8Sockets[i].socket == sender()) { if(m_ssbSockets[i].socket == sender()) {
id = m_s8Sockets[i].id; id = m_ssbSockets[i].id;
socket = m_s8Sockets[i].socket; socket = m_ssbSockets[i].socket;
m_s8Sockets.removeAt(i); m_ssbSockets.removeAt(i);
break; break;
} }
} }

View File

@ -16,7 +16,7 @@ class TCPSrc : public SampleSink {
public: public:
enum SampleFormat { enum SampleFormat {
FormatS8, FormatSSB,
FormatS16LE FormatS16LE
}; };
@ -124,7 +124,7 @@ protected:
Real m_sampleDistanceRemain; Real m_sampleDistanceRemain;
SampleVector m_sampleBuffer; SampleVector m_sampleBuffer;
std::vector<qint8> m_sampleBufferS8; std::vector<qint16> m_sampleBufferSSB;
SampleSink* m_spectrum; SampleSink* m_spectrum;
bool m_spectrumEnabled; bool m_spectrumEnabled;
@ -138,9 +138,9 @@ protected:
{ } { }
}; };
typedef QList<Socket> Sockets; typedef QList<Socket> Sockets;
Sockets m_s8Sockets; Sockets m_ssbSockets;
Sockets m_s16leSockets; Sockets m_s16leSockets;
quint32 m_nextS8Id; quint32 m_nextSSBId;
quint32 m_nextS16leId; quint32 m_nextS16leId;
void closeAllSockets(Sockets* sockets); void closeAllSockets(Sockets* sockets);

View File

@ -28,10 +28,11 @@ void TCPSrcGUI::resetToDefaults()
{ {
ui->sampleFormat->setCurrentIndex(0); ui->sampleFormat->setCurrentIndex(0);
ui->sampleRate->setText("48000"); ui->sampleRate->setText("48000");
ui->rfBandwidth->setText("40000"); ui->rfBandwidth->setText("32000");
ui->tcpPort->setText("9999"); ui->tcpPort->setText("9999");
ui->spectrumGUI->resetToDefaults(); ui->spectrumGUI->resetToDefaults();
applySettings(); applySettings();
} }
QByteArray TCPSrcGUI::serialize() const QByteArray TCPSrcGUI::serialize() const
@ -44,7 +45,6 @@ QByteArray TCPSrcGUI::serialize() const
s.writeReal(5, m_rfBandwidth); s.writeReal(5, m_rfBandwidth);
s.writeS32(6, m_tcpPort); s.writeS32(6, m_tcpPort);
s.writeBlob(7, ui->spectrumGUI->serialize()); s.writeBlob(7, ui->spectrumGUI->serialize());
s.writeU32(8, m_channelMarker->getColor().rgb());
return s.final(); return s.final();
} }
@ -60,15 +60,14 @@ bool TCPSrcGUI::deserialize(const QByteArray& data)
if(d.getVersion() == 1) { if(d.getVersion() == 1) {
QByteArray bytetmp; QByteArray bytetmp;
qint32 s32tmp; qint32 s32tmp;
quint32 u32tmp;
Real realtmp; Real realtmp;
d.readBlob(1, &bytetmp); d.readBlob(1, &bytetmp);
restoreState(bytetmp); restoreState(bytetmp);
d.readS32(2, &s32tmp, 0); d.readS32(2, &s32tmp, 0);
m_channelMarker->setCenterFrequency(s32tmp); m_channelMarker->setCenterFrequency(s32tmp);
d.readS32(3, &s32tmp, TCPSrc::FormatS8); d.readS32(3, &s32tmp, TCPSrc::FormatSSB);
switch(s32tmp) { switch(s32tmp) {
case TCPSrc::FormatS8: case TCPSrc::FormatSSB:
ui->sampleFormat->setCurrentIndex(0); ui->sampleFormat->setCurrentIndex(0);
break; break;
case TCPSrc::FormatS16LE: case TCPSrc::FormatS16LE:
@ -80,14 +79,12 @@ bool TCPSrcGUI::deserialize(const QByteArray& data)
} }
d.readReal(4, &realtmp, 48000); d.readReal(4, &realtmp, 48000);
ui->sampleRate->setText(QString("%1").arg(realtmp, 0)); ui->sampleRate->setText(QString("%1").arg(realtmp, 0));
d.readReal(5, &realtmp, 40000); d.readReal(5, &realtmp, 32000);
ui->rfBandwidth->setText(QString("%1").arg(realtmp, 0)); ui->rfBandwidth->setText(QString("%1").arg(realtmp, 0));
d.readS32(6, &s32tmp, 9999); d.readS32(6, &s32tmp, 9999);
ui->tcpPort->setText(QString("%1").arg(s32tmp)); ui->tcpPort->setText(QString("%1").arg(s32tmp));
d.readBlob(7, &bytetmp); d.readBlob(7, &bytetmp);
ui->spectrumGUI->deserialize(bytetmp); ui->spectrumGUI->deserialize(bytetmp);
if(d.readU32(8, &u32tmp))
m_channelMarker->setColor(u32tmp);
applySettings(); applySettings();
return true; return true;
} else { } else {
@ -141,8 +138,9 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent) :
m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
m_channelMarker = new ChannelMarker(this); m_channelMarker = new ChannelMarker(this);
m_channelMarker->setBandwidth(40000); m_channelMarker->setBandwidth(16000);
m_channelMarker->setCenterFrequency(0); m_channelMarker->setCenterFrequency(0);
m_channelMarker->setColor(Qt::green);
m_channelMarker->setVisible(true); m_channelMarker->setVisible(true);
connect(m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged())); connect(m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
m_pluginAPI->addChannelMarker(m_channelMarker); m_pluginAPI->addChannelMarker(m_channelMarker);
@ -194,13 +192,13 @@ void TCPSrcGUI::applySettings()
TCPSrc::SampleFormat sampleFormat; TCPSrc::SampleFormat sampleFormat;
switch(ui->sampleFormat->currentIndex()) { switch(ui->sampleFormat->currentIndex()) {
case 0: case 0:
sampleFormat = TCPSrc::FormatS8; sampleFormat = TCPSrc::FormatSSB;
break; break;
case 1: case 1:
sampleFormat = TCPSrc::FormatS16LE; sampleFormat = TCPSrc::FormatS16LE;
break; break;
default: default:
sampleFormat = TCPSrc::FormatS8; sampleFormat = TCPSrc::FormatSSB;
break; break;
} }

View File

@ -43,7 +43,7 @@
<widget class="QComboBox" name="sampleFormat"> <widget class="QComboBox" name="sampleFormat">
<item> <item>
<property name="text"> <property name="text">
<string>S8 I/Q</string> <string>S16LE SSB</string>
</property> </property>
</item> </item>
<item> <item>
@ -56,7 +56,7 @@
<item row="3" column="1"> <item row="3" column="1">
<widget class="QLineEdit" name="rfBandwidth"> <widget class="QLineEdit" name="rfBandwidth">
<property name="text"> <property name="text">
<string>40000</string> <string>32000</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -6,11 +6,11 @@
const PluginDescriptor TCPSrcPlugin::m_pluginDescriptor = { const PluginDescriptor TCPSrcPlugin::m_pluginDescriptor = {
QString("TCP Channel Source"), QString("TCP Channel Source"),
QString("---"), QString("ssb"),
QString("(c) maintech GmbH (written by Christian Daniel)"), QString("(c) maintech GmbH (written by Christian Daniel)"),
QString("http://www.maintech.de"), QString("http://www.maintech.de"),
true, true,
QString("http://www.maintech.de") QString("github.com/hexameron/rtl-sdrangelove")
}; };
TCPSrcPlugin::TCPSrcPlugin(QObject* parent) : TCPSrcPlugin::TCPSrcPlugin(QObject* parent) :

View File

@ -6,11 +6,11 @@
const PluginDescriptor USBPlugin::m_pluginDescriptor = { const PluginDescriptor USBPlugin::m_pluginDescriptor = {
QString("USB Demodulator"), QString("USB Demodulator"),
QString("---"), QString("0.1"),
QString("(c) maintech GmbH (rewritten by John Greb)"), QString("(c) 2014 John Greb"),
QString("http://www.maintech.de"), QString("http://www.maintech.de"),
true, true,
QString("http://www.maintech.de") QString("github.com/hexameron/rtl-sdrangelove")
}; };
USBPlugin::USBPlugin(QObject* parent) : USBPlugin::USBPlugin(QObject* parent) :

View File

@ -6,11 +6,11 @@
const PluginDescriptor WFMPlugin::m_pluginDescriptor = { const PluginDescriptor WFMPlugin::m_pluginDescriptor = {
QString("WFM Demodulator"), QString("WFM Demodulator"),
QString("---"), QString("1.0"),
QString("(c) maintech GmbH (written by Christian Daniel)"), QString("(c) 2014 JohnGreb"),
QString("http://www.maintech.de"), QString("http://www.maintech.de"),
true, true,
QString("http://www.maintech.de") QString("github.com/hexameron/rtl-sdrangelove")
}; };
WFMPlugin::WFMPlugin(QObject* parent) : WFMPlugin::WFMPlugin(QObject* parent) :

View File

@ -11,7 +11,7 @@ const PluginDescriptor FCDPlugin::m_pluginDescriptor = {
QString("(c) John Greb"), QString("(c) John Greb"),
QString("http://funcubedongle.com"), QString("http://funcubedongle.com"),
true, true,
QString("http://www.oz9aec.net/index.php/funcube-dongle") QString("github.com/hexameron/rtl-sdrangelove")
}; };
FCDPlugin::FCDPlugin(QObject* parent) : FCDPlugin::FCDPlugin(QObject* parent) :

View File

@ -8,11 +8,11 @@
const PluginDescriptor RTLSDRPlugin::m_pluginDescriptor = { const PluginDescriptor RTLSDRPlugin::m_pluginDescriptor = {
QString("RTL-SDR Input"), QString("RTL-SDR Input"),
QString("---"), QString("1.0"),
QString("(c) librtlsdr Authors (see source URL)"), QString("(c) librtlsdr Authors (see source URL)"),
QString("http://sdr.osmocom.org/trac/wiki/rtl-sdr"), QString("http://sdr.osmocom.org/trac/wiki/rtl-sdr"),
true, true,
QString("http://cgit.osmocom.org/cgit/rtl-sdr") QString("github.com/hexameron/rtl-sdrangelove")
}; };
RTLSDRPlugin::RTLSDRPlugin(QObject* parent) : RTLSDRPlugin::RTLSDRPlugin(QObject* parent) :

View File

@ -8,11 +8,11 @@
const PluginDescriptor V4LPlugin::m_pluginDescriptor = { const PluginDescriptor V4LPlugin::m_pluginDescriptor = {
QString("V4L Input"), QString("V4L Input"),
QString("---"), QString("3.18"),
QString("(c) librtlsdr authors"), QString("(c) 2014 John Greb"),
QString("http://sdr.osmocom.org/trac/wiki/rtl-sdr"), QString("http://palosaari.fi/linux/"),
true, true,
QString("http://cgit.osmocom.org/cgit/rtl-sdr") QString("github.com/hexameron/rtl-sdrangelove")
}; };
V4LPlugin::V4LPlugin(QObject* parent) : V4LPlugin::V4LPlugin(QObject* parent) :