mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 01:18:38 -05:00
Compare commits
6 Commits
8e79cd7ff2
...
113aff6e57
Author | SHA1 | Date | |
---|---|---|---|
|
113aff6e57 | ||
|
adfaac1545 | ||
|
c678b40988 | ||
|
4c2ca8fa20 | ||
|
22604244a3 | ||
|
308ffcad54 |
17
CHANGELOG
17
CHANGELOG
@ -1,3 +1,20 @@
|
||||
sdrangel (6.19.1-1) unstable; urgency=medium
|
||||
|
||||
* Fix stereo sound in DAB demod. PR #1150.
|
||||
* Make Channel API inherit from QObject. Issue #1147
|
||||
* Channel Analyzer: fixed reverse API handling and a few other things. Fixes #1144
|
||||
* Metis MISO: set spectrum sink input back in GUI. Fixes #1145
|
||||
* DATV Demod - Increase max RF bandwidth in GUI to 50MHz. PR #1142. Issue #1136.
|
||||
* DATV Mod - Increase RF bandwidth slider to 50M. PR #1137. Issue #1136
|
||||
* Spectrum markers update. PR #1141
|
||||
* Pager demod: fixed typo in POCSAG. Fixes #1138
|
||||
* Metis MISO: save stream and spectrum stream indices in settings. Fixes #1126
|
||||
* Map feature, ADSB and AIS demods updates. PR #1135
|
||||
* Do not write tail audio samples and write to sample buffer only if necessary. Issue #1132
|
||||
* ValueDialZ: fixed compilation warning, Fixes #1155
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Feb 2022 21:31:55 +0100
|
||||
|
||||
sdrangel (6.19.0-1) unstable; urgency=medium
|
||||
|
||||
* Map: added 3D to map feature. PR #1127
|
||||
|
@ -16,7 +16,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# configure version
|
||||
set(sdrangel_VERSION_MAJOR "6")
|
||||
set(sdrangel_VERSION_MINOR "19")
|
||||
set(sdrangel_VERSION_PATCH "0")
|
||||
set(sdrangel_VERSION_PATCH "1")
|
||||
set(sdrangel_VERSION_SUFFIX "")
|
||||
|
||||
# SDRAngel cmake options
|
||||
|
17
debian/changelog
vendored
17
debian/changelog
vendored
@ -1,3 +1,20 @@
|
||||
sdrangel (6.19.1-1) unstable; urgency=medium
|
||||
|
||||
* Fix stereo sound in DAB demod. PR #1150.
|
||||
* Make Channel API inherit from QObject. Issue #1147
|
||||
* Channel Analyzer: fixed reverse API handling and a few other things. Fixes #1144
|
||||
* Metis MISO: set spectrum sink input back in GUI. Fixes #1145
|
||||
* DATV Demod - Increase max RF bandwidth in GUI to 50MHz. PR #1142. Issue #1136.
|
||||
* DATV Mod - Increase RF bandwidth slider to 50M. PR #1137. Issue #1136
|
||||
* Spectrum markers update. PR #1141
|
||||
* Pager demod: fixed typo in POCSAG. Fixes #1138
|
||||
* Metis MISO: save stream and spectrum stream indices in settings. Fixes #1126
|
||||
* Map feature, ADSB and AIS demods updates. PR #1135
|
||||
* Do not write tail audio samples and write to sample buffer only if necessary. Issue #1132
|
||||
* ValueDialZ: fixed compilation warning, Fixes #1155
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Feb 2022 21:31:55 +0100
|
||||
|
||||
sdrangel (6.19.0-1) unstable; urgency=medium
|
||||
|
||||
* Map: added 3D to map feature. PR #1127
|
||||
|
@ -26,7 +26,7 @@
|
||||
const PluginDescriptor ChannelAnalyzerPlugin::m_pluginDescriptor = {
|
||||
ChannelAnalyzer::m_channelId,
|
||||
QStringLiteral("Channel Analyzer"),
|
||||
QStringLiteral("6.18.0"),
|
||||
QStringLiteral("6.19.1"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -30,7 +30,7 @@
|
||||
const PluginDescriptor ADSBPlugin::m_pluginDescriptor = {
|
||||
ADSBDemod::m_channelId,
|
||||
QStringLiteral("ADS-B Demodulator"),
|
||||
QStringLiteral("6.19.0"),
|
||||
QStringLiteral("6.19.1"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -29,7 +29,7 @@
|
||||
const PluginDescriptor AISDemodPlugin::m_pluginDescriptor = {
|
||||
AISDemod::m_channelId,
|
||||
QStringLiteral("AIS Demodulator"),
|
||||
QStringLiteral("6.19.0"),
|
||||
QStringLiteral("6.19.1"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -383,14 +383,20 @@ void AISDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,14 +219,20 @@ void AMDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
const PluginDescriptor DABDemodPlugin::m_pluginDescriptor = {
|
||||
DABDemod::m_channelId,
|
||||
QStringLiteral("DAB Demodulator"),
|
||||
QStringLiteral("6.18.0"),
|
||||
QStringLiteral("6.19.1"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE. DAB library by Jvan Katwijk"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -447,14 +447,20 @@ void DABDemodSink::processOneAudioSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeCI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeCI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ const PluginDescriptor DATVDemodPlugin::m_ptrPluginDescriptor =
|
||||
{
|
||||
DATVDemod::m_channelId,
|
||||
QString("DATV Demodulator"),
|
||||
QString("6.19.0"),
|
||||
QString("6.19.1"),
|
||||
QString("(c) F4HKW for SDRAngel using LeanSDR framework (c) F4DAV"),
|
||||
QString("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -180,14 +180,20 @@ void DSDDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,14 +256,20 @@ void NFMDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,14 +249,20 @@ void PacketDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
const PluginDescriptor PagerDemodPlugin::m_pluginDescriptor = {
|
||||
PagerDemod::m_channelId,
|
||||
QStringLiteral("Pager Demodulator"),
|
||||
QStringLiteral("6.18.0"),
|
||||
QStringLiteral("6.19.1"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -594,14 +594,20 @@ void PagerDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,19 +207,25 @@ void SSBDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it)
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
(*it)->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_audioBinaual ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
fifo->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_audioBinaual ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,14 +141,20 @@ void WFMDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,14 +272,20 @@ void AISModSource::modulateSample()
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,14 +112,20 @@ void AMModSource::pullOne(Sample& sample)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
const PluginDescriptor DATVModPlugin::m_pluginDescriptor = {
|
||||
DATVMod::m_channelId,
|
||||
QStringLiteral("DATV Modulator"),
|
||||
QStringLiteral("6.18.0"),
|
||||
QStringLiteral("6.19.1"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE, Edouard Griffiths, F4EXB. DVB-S2 by G4GUO"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -173,14 +173,20 @@ void NFMModSource::modulateSample()
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,14 +280,20 @@ void PacketModSource::modulateSample()
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,19 +184,25 @@ void SSBModSource::modulateSample()
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it)
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
(*it)->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_settings.m_audioBinaural ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
fifo->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_settings.m_audioBinaural ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,14 +152,20 @@ void WFMModSource::pullOne(Sample& sample)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ DemodAnalyzer::DemodAnalyzer(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||
m_spectrumVis(SDR_RX_SCALEF),
|
||||
m_selectedChannel(nullptr),
|
||||
m_dataFifo(nullptr)
|
||||
m_dataPipe(nullptr)
|
||||
{
|
||||
qDebug("DemodAnalyzer::DemodAnalyzer: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||
setObjectName(m_featureId);
|
||||
@ -88,10 +88,15 @@ void DemodAnalyzer::start()
|
||||
= DemodAnalyzerWorker::MsgConfigureDemodAnalyzerWorker::create(m_settings, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
|
||||
if (m_dataFifo)
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(m_dataFifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(fifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,10 +104,15 @@ void DemodAnalyzer::stop()
|
||||
{
|
||||
qDebug("DemodAnalyzer::stop");
|
||||
|
||||
if (m_dataFifo)
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(m_dataFifo, false);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(fifo, false);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
m_worker->stopWork();
|
||||
@ -169,8 +179,13 @@ bool DemodAnalyzer::handleMessage(const Message& cmd)
|
||||
DSPSignalNotification *msg = new DSPSignalNotification(0, m_sampleRate);
|
||||
m_spectrumVis.getInputMessageQueue()->push(msg);
|
||||
|
||||
if (m_dataFifo) {
|
||||
m_dataFifo->setSize(2*m_sampleRate);
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->setSize(2*m_sampleRate);
|
||||
}
|
||||
}
|
||||
|
||||
if (getMessageQueueToGUI())
|
||||
@ -319,7 +334,8 @@ void DemodAnalyzer::setChannel(ChannelAPI *selectedChannel)
|
||||
|
||||
if (m_selectedChannel)
|
||||
{
|
||||
DataFifo *fifo = mainCore->getDataPipes().unregisterChannelToFeature(m_selectedChannel, this, "demod");
|
||||
ObjectPipe *pipe = mainCore->getDataPipes().unregisterProducerToConsumer(m_selectedChannel, this, "demod");
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(pipe->m_element);
|
||||
|
||||
if ((fifo) && m_worker->isRunning())
|
||||
{
|
||||
@ -331,13 +347,19 @@ void DemodAnalyzer::setChannel(ChannelAPI *selectedChannel)
|
||||
disconnect(messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessageQueue(MessageQueue*)));
|
||||
}
|
||||
|
||||
m_dataFifo = mainCore->getDataPipes().registerChannelToFeature(selectedChannel, this, "demod");
|
||||
m_dataFifo->setSize(96000);
|
||||
m_dataPipe = mainCore->getDataPipes().registerProducerToConsumer(selectedChannel, this, "demod");
|
||||
connect(m_dataPipe, SIGNAL(toBeDeleted(int, QObject*)), this, SLOT(handleDataPipeToBeDeleted(int, QObject*)));
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (m_worker->isRunning())
|
||||
if (fifo)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(m_dataFifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
fifo->setSize(96000);
|
||||
|
||||
if (m_worker->isRunning())
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(fifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueue *messageQueue = mainCore->getMessagePipes().registerChannelToFeature(selectedChannel, this, "reportdemod");
|
||||
@ -580,3 +602,22 @@ void DemodAnalyzer::handleChannelMessageQueue(MessageQueue* messageQueue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DemodAnalyzer::handleDataPipeToBeDeleted(int reason, QObject *object)
|
||||
{
|
||||
qDebug("DemodAnalyzer::handleDataPipeToBeDeleted: %d %p", reason, object);
|
||||
|
||||
if ((reason == 0) && (m_selectedChannel == object))
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo && m_worker->isRunning())
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(fifo, false);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
updateChannels();
|
||||
m_selectedChannel = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class WebAPIAdapterInterface;
|
||||
class DemodAnalyzerWorker;
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class DataFifo;
|
||||
class ObjectPipe;
|
||||
|
||||
namespace SWGSDRangel {
|
||||
class SWGDeviceState;
|
||||
@ -201,7 +201,7 @@ private:
|
||||
ScopeVis m_scopeVis;
|
||||
QHash<ChannelAPI*, DemodAnalyzerSettings::AvailableChannel> m_availableChannels;
|
||||
ChannelAPI *m_selectedChannel;
|
||||
DataFifo *m_dataFifo;
|
||||
ObjectPipe *m_dataPipe;
|
||||
int m_sampleRate;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
@ -217,6 +217,7 @@ private:
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleChannelMessageQueue(MessageQueue *messageQueues);
|
||||
void handleDataPipeToBeDeleted(int reason, QObject *object);
|
||||
};
|
||||
|
||||
#endif // INCLUDE_FEATURE_DEMODANALYZER_H_
|
||||
|
@ -156,11 +156,11 @@ bool DemodAnalyzerWorker::handleMessage(const Message& cmd)
|
||||
}
|
||||
else if (MsgConnectFifo::match(cmd))
|
||||
{
|
||||
qDebug("DemodAnalyzerWorker::handleMessage: MsgConnectFifo");
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
MsgConnectFifo& msg = (MsgConnectFifo&) cmd;
|
||||
m_dataFifo = msg.getFifo();
|
||||
bool doConnect = msg.getConnect();
|
||||
qDebug("DemodAnalyzerWorker::handleMessage: MsgConnectFifo: %s", (doConnect ? "connect" : "disconnect"));
|
||||
|
||||
if (doConnect) {
|
||||
QObject::connect(
|
||||
@ -170,7 +170,9 @@ bool DemodAnalyzerWorker::handleMessage(const Message& cmd)
|
||||
&DemodAnalyzerWorker::handleData,
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
QObject::disconnect(
|
||||
m_dataFifo,
|
||||
&DataFifo::dataReady,
|
||||
|
@ -30,7 +30,7 @@
|
||||
const PluginDescriptor MapPlugin::m_pluginDescriptor = {
|
||||
Map::m_featureId,
|
||||
QStringLiteral("Map"),
|
||||
QStringLiteral("6.19.0"),
|
||||
QStringLiteral("6.19.1"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -32,7 +32,7 @@
|
||||
const PluginDescriptor MetisMISOPlugin::m_pluginDescriptor = {
|
||||
QStringLiteral("MetisMISO"),
|
||||
QStringLiteral("Metis MISO"),
|
||||
QStringLiteral("6.18.1"),
|
||||
QStringLiteral("6.19.1"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -167,13 +167,15 @@ set(sdrbase_SOURCES
|
||||
|
||||
limerfe/limerfeusbcalib.cpp
|
||||
|
||||
pipes/datafifostore.cpp
|
||||
pipes/datapipes.cpp
|
||||
pipes/datapipescommon.cpp
|
||||
pipes/datapipesgcworker.cpp
|
||||
pipes/messagepipes.cpp
|
||||
pipes/messagepipescommon.cpp
|
||||
pipes/messagepipesgcworker.cpp
|
||||
pipes/pipeendpoint.cpp
|
||||
pipes/objectpipe.cpp
|
||||
pipes/objectpipesregistrations.cpp
|
||||
|
||||
settings/featuresetpreset.cpp
|
||||
settings/preferences.cpp
|
||||
@ -371,8 +373,8 @@ set(sdrbase_HEADERS
|
||||
|
||||
limerfe/limerfeusbcalib.h
|
||||
|
||||
pipes/datafifostore.h
|
||||
pipes/datapipes.h
|
||||
pipes/datapipescommon.h
|
||||
pipes/datapipesgcworker.h
|
||||
pipes/elementpipescommon.h
|
||||
pipes/elementpipesgc.h
|
||||
@ -380,6 +382,8 @@ set(sdrbase_HEADERS
|
||||
pipes/messagepipescommon.h
|
||||
pipes/messagepipesgcworker.h
|
||||
pipes/pipeendpoint.h
|
||||
pipes/objectpipe.h
|
||||
pipes/objectpipesregistrations.h
|
||||
|
||||
plugin/plugininterface.h
|
||||
plugin/pluginapi.h
|
||||
|
@ -46,8 +46,8 @@ NCOF::NCOF()
|
||||
|
||||
void NCOF::setFreq(Real freq, Real sampleRate)
|
||||
{
|
||||
m_phaseIncrement = (freq * TableSize) / sampleRate;
|
||||
qDebug("NCOF::setFreq: freq: %f m_phaseIncrement: %f", freq, m_phaseIncrement);
|
||||
m_phaseIncrement = sampleRate == 0 ? 0 : (freq * TableSize) / sampleRate;
|
||||
qDebug("NCOF::setFreq: freq: %f sr: %f m_phaseIncrement: %f", freq, sampleRate, m_phaseIncrement);
|
||||
}
|
||||
|
||||
float NCOF::next()
|
||||
|
56
sdrbase/pipes/datafifostore.cpp
Normal file
56
sdrbase/pipes/datafifostore.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dsp/datafifo.h"
|
||||
#include "datafifostore.h"
|
||||
|
||||
DataFifoStore::DataFifoStore()
|
||||
{}
|
||||
|
||||
DataFifoStore::~DataFifoStore()
|
||||
{
|
||||
deleteAllElements();
|
||||
}
|
||||
|
||||
QObject *DataFifoStore::createElement()
|
||||
{
|
||||
DataFifo *fifo = new DataFifo();
|
||||
m_dataFifos.push_back(fifo);
|
||||
qDebug("DataFifoStore::createElement: %d added", m_dataFifos.size() - 1);
|
||||
return fifo;
|
||||
}
|
||||
|
||||
void DataFifoStore::deleteElement(QObject *element)
|
||||
{
|
||||
int i = m_dataFifos.indexOf((DataFifo*) element);
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
qDebug("DataFifoStore::deleteElement: delte element at %d", i);
|
||||
delete m_dataFifos[i];
|
||||
m_dataFifos.removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
void DataFifoStore::deleteAllElements()
|
||||
{
|
||||
for (auto& fifo : m_dataFifos) {
|
||||
delete fifo;
|
||||
}
|
||||
|
||||
m_dataFifos.clear();
|
||||
}
|
42
sdrbase/pipes/datafifostore.h
Normal file
42
sdrbase/pipes/datafifostore.h
Normal file
@ -0,0 +1,42 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRBASE_PIPES_DATAFIFOSTORE_H_
|
||||
#define SDRBASE_PIPES_DATAFIFOSTORE_H_
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "export.h"
|
||||
#include "objectpipeelementsstore.h"
|
||||
|
||||
class DataFifo;
|
||||
|
||||
class SDRBASE_API DataFifoStore : public ObjectPipeElementsStore
|
||||
{
|
||||
public:
|
||||
DataFifoStore();
|
||||
virtual ~DataFifoStore();
|
||||
|
||||
virtual QObject *createElement();
|
||||
virtual void deleteElement(QObject*);
|
||||
|
||||
private:
|
||||
void deleteAllElements();
|
||||
QList<DataFifo*> m_dataFifos;
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_DATAFIFOSTORE_H_
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -16,18 +16,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dsp/datafifo.h"
|
||||
|
||||
#include "datapipesgcworker.h"
|
||||
#include "datapipes.h"
|
||||
#include "datapipesgcworker.h"
|
||||
|
||||
DataPipes::DataPipes()
|
||||
DataPipes::DataPipes() :
|
||||
m_registrations(&m_dataFifoStore)
|
||||
{
|
||||
m_gcWorker = new DataPipesGCWorker();
|
||||
m_gcWorker->setC2FRegistrations(
|
||||
m_registrations.getMutex(),
|
||||
m_registrations.getElements(),
|
||||
m_registrations.getConsumers()
|
||||
);
|
||||
m_gcWorker = new DataPipesGCWorker(m_registrations);
|
||||
m_gcWorker->moveToThread(&m_gcThread);
|
||||
startGC();
|
||||
}
|
||||
@ -37,23 +32,23 @@ DataPipes::~DataPipes()
|
||||
if (m_gcWorker->isRunning()) {
|
||||
stopGC();
|
||||
}
|
||||
|
||||
m_gcWorker->deleteLater();
|
||||
}
|
||||
|
||||
DataFifo *DataPipes::registerChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type)
|
||||
ObjectPipe *DataPipes::registerProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type)
|
||||
{
|
||||
return m_registrations.registerProducerToConsumer(source, feature, type);
|
||||
return m_registrations.registerProducerToConsumer(producer, consumer, type);
|
||||
}
|
||||
|
||||
DataFifo *DataPipes::unregisterChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type)
|
||||
ObjectPipe *DataPipes::unregisterProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type)
|
||||
{
|
||||
DataFifo *dataFifo = m_registrations.unregisterProducerToConsumer(source, feature, type);
|
||||
m_gcWorker->addDataFifoToDelete(dataFifo);
|
||||
return dataFifo;
|
||||
return m_registrations.unregisterProducerToConsumer(producer, consumer, type);
|
||||
}
|
||||
|
||||
QList<DataFifo*>* DataPipes::getFifos(const ChannelAPI *source, const QString& type)
|
||||
void DataPipes::getDataPipes(const QObject *producer, const QString& type, QList<ObjectPipe*>& pipes)
|
||||
{
|
||||
return m_registrations.getElements(source, type);
|
||||
return m_registrations.getPipes(producer, type, pipes);
|
||||
}
|
||||
|
||||
void DataPipes::startGC()
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -15,24 +15,18 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRBASE_PIPES_DATAPIPES_H_
|
||||
#define SDRBASE_PIPES_DATAPIPES_H_
|
||||
#ifndef SDRBASE_PIPES_DATAPIPES2_H_
|
||||
#define SDRBASE_PIPES_DATAPIPES2_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include <QThread>
|
||||
|
||||
#include "export.h"
|
||||
#include "objectpipesregistrations.h"
|
||||
#include "datafifostore.h"
|
||||
|
||||
#include "datapipescommon.h"
|
||||
#include "elementpipesregistrations.h"
|
||||
|
||||
class ChannelAPI;
|
||||
class Feature;
|
||||
class DataPipesGCWorker;
|
||||
class DataFifo;
|
||||
class DataPipesGCWorker;
|
||||
|
||||
class SDRBASE_API DataPipes : public QObject
|
||||
{
|
||||
@ -43,12 +37,13 @@ public:
|
||||
DataPipes& operator=(const DataPipes&) = delete;
|
||||
~DataPipes();
|
||||
|
||||
DataFifo *registerChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type);
|
||||
DataFifo *unregisterChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type);
|
||||
QList<DataFifo*>* getFifos(const ChannelAPI *source, const QString& type);
|
||||
ObjectPipe *registerProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type);
|
||||
ObjectPipe *unregisterProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type);
|
||||
void getDataPipes(const QObject *producer, const QString& type, QList<ObjectPipe*>& pipes);
|
||||
|
||||
private:
|
||||
ElementPipesRegistrations<ChannelAPI, Feature, DataFifo> m_registrations;
|
||||
DataFifoStore m_dataFifoStore;
|
||||
ObjectPipesRegistrations m_registrations;
|
||||
QThread m_gcThread; //!< Garbage collector thread
|
||||
DataPipesGCWorker *m_gcWorker; //!< Garbage collector
|
||||
|
||||
@ -56,4 +51,5 @@ private:
|
||||
void stopGC(); //!< Stop garbage collector
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_DATAPIPES_H_
|
||||
|
||||
#endif // SDRBASE_PIPES_DATAPIPES2_H_
|
||||
|
@ -1,63 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRBASE_PIPES_DATAPIPESCOMON_H_
|
||||
#define SDRBASE_PIPES_DATAPIPESCOMON_H_
|
||||
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
|
||||
#include "export.h"
|
||||
#include "util/message.h"
|
||||
|
||||
#include "elementpipescommon.h"
|
||||
|
||||
class ChannelAPI;
|
||||
class Feature;
|
||||
class DataFifo;
|
||||
|
||||
class SDRBASE_API DataPipesCommon
|
||||
{
|
||||
public:
|
||||
typedef ElementPipesCommon::RegistrationKey<ChannelAPI> ChannelRegistrationKey;
|
||||
|
||||
/** Send this message to stakeholders when the garbage collector finds that a channel was deleted */
|
||||
class SDRBASE_API MsgReportChannelDeleted : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const DataFifo *getFifo() const { return m_fifo; }
|
||||
const ChannelRegistrationKey& getChannelRegistrationKey() const { return m_channelRegistrationKey; }
|
||||
|
||||
static MsgReportChannelDeleted* create(const DataFifo *fifo, const ChannelRegistrationKey& channelRegistrationKey) {
|
||||
return new MsgReportChannelDeleted(fifo, channelRegistrationKey);
|
||||
}
|
||||
|
||||
private:
|
||||
const DataFifo *m_fifo;
|
||||
ChannelRegistrationKey m_channelRegistrationKey;
|
||||
|
||||
MsgReportChannelDeleted(const DataFifo *fifo, const ChannelRegistrationKey& channelRegistrationKey) :
|
||||
Message(),
|
||||
m_fifo(fifo),
|
||||
m_channelRegistrationKey(channelRegistrationKey)
|
||||
{ }
|
||||
};
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_DATAPIPESCOMON_H_
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -15,31 +15,12 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "feature/feature.h"
|
||||
#include "dsp/datafifo.h"
|
||||
#include "maincore.h"
|
||||
#include "datapipescommon.h"
|
||||
#include "datapipesgcworker.h"
|
||||
|
||||
bool DataPipesGCWorker::DataPipesGC::existsProducer(const ChannelAPI *channel)
|
||||
{
|
||||
return MainCore::instance()->existsChannel(channel);
|
||||
}
|
||||
|
||||
bool DataPipesGCWorker::DataPipesGC::existsConsumer(const Feature *feature)
|
||||
{
|
||||
return MainCore::instance()->existsFeature(feature);
|
||||
}
|
||||
|
||||
void DataPipesGCWorker::DataPipesGC::sendMessageToConsumer(const DataFifo *fifo, DataPipesCommon::ChannelRegistrationKey channelKey, Feature *feature)
|
||||
{
|
||||
DataPipesCommon::MsgReportChannelDeleted *msg = DataPipesCommon::MsgReportChannelDeleted::create(
|
||||
fifo, channelKey);
|
||||
feature->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
DataPipesGCWorker::DataPipesGCWorker() :
|
||||
m_running(false)
|
||||
DataPipesGCWorker::DataPipesGCWorker(ObjectPipesRegistrations& objectPipesRegistrations) :
|
||||
m_running(false),
|
||||
m_objectPipesRegistrations(objectPipesRegistrations)
|
||||
{}
|
||||
|
||||
DataPipesGCWorker::~DataPipesGCWorker()
|
||||
@ -59,17 +40,7 @@ void DataPipesGCWorker::stopWork()
|
||||
disconnect(&m_gcTimer, SIGNAL(timeout()), this, SLOT(processGC()));
|
||||
}
|
||||
|
||||
void DataPipesGCWorker::addDataFifoToDelete(DataFifo *dataFifo)
|
||||
{
|
||||
if (dataFifo)
|
||||
{
|
||||
m_gcTimer.start(10000); // restart GC to make sure deletion is postponed
|
||||
m_dataPipesGC.addElementToDelete(dataFifo);
|
||||
}
|
||||
}
|
||||
|
||||
void DataPipesGCWorker::processGC()
|
||||
{
|
||||
// qDebug("MessagePipesGCWorker::processGC");
|
||||
m_dataPipesGC.processGC();
|
||||
m_objectPipesRegistrations.processGC();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -15,56 +15,35 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRBASE_PIPES_DATAPIPESGCWORKER_H_
|
||||
#define SDRBASE_PIPES_DATAPIPESGCWORKER_H_
|
||||
#ifndef SDRBASE_PIPES_DATAPIPES2GCWORKER_H_
|
||||
#define SDRBASE_PIPES_DATAPIPES2GCWORKER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
#include "export.h"
|
||||
#include "objectpipesregistrations.h"
|
||||
|
||||
#include "elementpipesgc.h"
|
||||
#include "datapipescommon.h"
|
||||
|
||||
class QMutex;
|
||||
class DataFifo;
|
||||
|
||||
class SDRBASE_API DataPipesGCWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataPipesGCWorker();
|
||||
DataPipesGCWorker(ObjectPipesRegistrations& objectPipesRegistrations);
|
||||
~DataPipesGCWorker();
|
||||
|
||||
void setC2FRegistrations(
|
||||
QMutex *c2fMutex,
|
||||
QMap<DataPipesCommon::ChannelRegistrationKey, QList<DataFifo*>> *c2fFifos,
|
||||
QMap<DataPipesCommon::ChannelRegistrationKey, QList<Feature*>> *c2fFeatures
|
||||
)
|
||||
{
|
||||
m_dataPipesGC.setRegistrations(c2fMutex, c2fFifos, c2fFeatures);
|
||||
}
|
||||
|
||||
void startWork();
|
||||
void stopWork();
|
||||
void addDataFifoToDelete(DataFifo *dataFifo);
|
||||
bool isRunning() const { return m_running; }
|
||||
|
||||
private:
|
||||
class DataPipesGC : public ElementPipesGC<ChannelAPI, Feature, DataFifo>
|
||||
{
|
||||
private:
|
||||
virtual bool existsProducer(const ChannelAPI *channelAPI);
|
||||
virtual bool existsConsumer(const Feature *feature);
|
||||
virtual void sendMessageToConsumer(const DataFifo *fifo, DataPipesCommon::ChannelRegistrationKey key, Feature *feature);
|
||||
};
|
||||
|
||||
DataPipesGC m_dataPipesGC;
|
||||
bool m_running;
|
||||
QTimer m_gcTimer;
|
||||
ObjectPipesRegistrations& m_objectPipesRegistrations;
|
||||
|
||||
private slots:
|
||||
void processGC(); //!< Collect garbage
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_DATAPIPESGCWORKER_H_
|
||||
#endif // SDRBASE_PIPES_DATAPIPES2GCWORKER_H_
|
||||
|
47
sdrbase/pipes/objectpipe.cpp
Normal file
47
sdrbase/pipes/objectpipe.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "objectpipe.h"
|
||||
|
||||
ObjectPipe::ObjectPipe() :
|
||||
m_pipeId(0),
|
||||
m_typeId(0),
|
||||
m_producer(nullptr),
|
||||
m_consumer(nullptr),
|
||||
m_element(nullptr),
|
||||
m_gcCount(0)
|
||||
{}
|
||||
|
||||
void ObjectPipe::setToBeDeleted(int reason, QObject *object)
|
||||
{
|
||||
m_gcCount = 2; // will defer actual deletion by one GC pass
|
||||
emit toBeDeleted(reason, object);
|
||||
}
|
||||
|
||||
int ObjectPipe::getGCCount() const {
|
||||
return m_gcCount;
|
||||
}
|
||||
|
||||
int ObjectPipe::decreaseGCCount()
|
||||
{
|
||||
if (m_gcCount > 0) {
|
||||
return m_gcCount--;
|
||||
} else {
|
||||
return m_gcCount;
|
||||
}
|
||||
}
|
||||
|
51
sdrbase/pipes/objectpipe.h
Normal file
51
sdrbase/pipes/objectpipe.h
Normal file
@ -0,0 +1,51 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRBASE_PIPES_OBJECTPIPE_H_
|
||||
#define SDRBASE_PIPES_OBJECTPIPE_H_
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
class SDRBASE_API ObjectPipe : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ObjectPipe();
|
||||
ObjectPipe(const ObjectPipe&) = default;
|
||||
ObjectPipe& operator=(const ObjectPipe&) = default;
|
||||
|
||||
void setToBeDeleted(int reason, QObject *object);
|
||||
int getGCCount() const;
|
||||
int decreaseGCCount();
|
||||
|
||||
unsigned int m_pipeId;
|
||||
int m_typeId;
|
||||
const QObject *m_producer;
|
||||
const QObject *m_consumer;
|
||||
QObject *m_element;
|
||||
|
||||
signals:
|
||||
void toBeDeleted(int reason, QObject *object);
|
||||
|
||||
private:
|
||||
int m_gcCount;
|
||||
};
|
||||
|
||||
|
||||
#endif // SDRBASE_PIPES_OBJECTPIPE_H_
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -15,6 +15,16 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "datapipescommon.h"
|
||||
#ifndef SDRBASE_PIPES_OBJECTPIPESELEMENT_H_
|
||||
#define SDRBASE_PIPES_OBJECTPIPESELEMENT_H_
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(DataPipesCommon::MsgReportChannelDeleted, Message)
|
||||
class QObject;
|
||||
|
||||
class ObjectPipeElementsStore
|
||||
{
|
||||
public:
|
||||
virtual QObject *createElement() = 0;
|
||||
virtual void deleteElement(QObject*) = 0;
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_OBJECTPIPESELEMENT_H_
|
241
sdrbase/pipes/objectpipesregistrations.cpp
Normal file
241
sdrbase/pipes/objectpipesregistrations.cpp
Normal file
@ -0,0 +1,241 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "objectpipesregistrations.h"
|
||||
|
||||
ObjectPipesRegistrations::ObjectPipesRegistrations(ObjectPipeElementsStore *objectPipeElementsStore) :
|
||||
m_typeCount(0),
|
||||
m_pipeId(0),
|
||||
m_objectPipeElementsStore(objectPipeElementsStore),
|
||||
m_mutex(QMutex::Recursive)
|
||||
{}
|
||||
|
||||
ObjectPipesRegistrations::~ObjectPipesRegistrations()
|
||||
{}
|
||||
|
||||
ObjectPipe *ObjectPipesRegistrations::registerProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type)
|
||||
{
|
||||
qDebug("ObjectPipesRegistrations::registerProducerToConsumer: %p %p %s", producer, consumer, qPrintable("type"));
|
||||
int typeId;
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
if (m_typeIds.contains(type))
|
||||
{
|
||||
typeId = m_typeIds.value(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeId = m_typeCount++;
|
||||
m_typeIds.insert(type, typeId);
|
||||
m_types.insert(typeId, type);
|
||||
}
|
||||
|
||||
for (auto& pipe : m_pipes) // check if pipe exists already - there is a unique pipe per producer, consumer and type
|
||||
{
|
||||
if ((producer == pipe->m_producer) && (consumer == pipe->m_consumer) && (typeId == pipe->m_typeId)) {
|
||||
return pipe;
|
||||
}
|
||||
}
|
||||
|
||||
QObject *element = m_objectPipeElementsStore->createElement();
|
||||
m_pipes.push_back(new ObjectPipe());
|
||||
m_pipes.back()->m_pipeId = ++m_pipeId;
|
||||
m_pipes.back()->m_typeId = typeId;
|
||||
m_pipes.back()->m_producer = producer;
|
||||
m_pipes.back()->m_consumer = consumer;
|
||||
m_pipes.back()->m_element = element;
|
||||
|
||||
m_producerPipes[producer].push_back(m_pipes.back());
|
||||
m_consumerPipes[consumer].push_back(m_pipes.back());
|
||||
m_typeIdPipes[typeId].push_back(m_pipes.back());
|
||||
m_producerAndTypeIdPipes[std::make_tuple(producer, typeId)].push_back(m_pipes.back());
|
||||
m_pipeMap[std::make_tuple(producer, consumer, typeId)] = m_pipes.back();
|
||||
|
||||
connect(producer, SIGNAL(destroyed(QObject*)), this, SLOT(removeProducer(QObject*)));
|
||||
connect(consumer, SIGNAL(destroyed(QObject*)), this, SLOT(removeConsumer(QObject*)));
|
||||
|
||||
return m_pipes.back();
|
||||
}
|
||||
|
||||
ObjectPipe *ObjectPipesRegistrations::unregisterProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type)
|
||||
{
|
||||
qDebug("ObjectPipesRegistrations::unregisterProducerToConsumer: %p %p %s", producer, consumer, qPrintable("type"));
|
||||
ObjectPipe *pipe = nullptr;
|
||||
|
||||
if (m_typeIds.contains(type))
|
||||
{
|
||||
int typeId = m_typeIds.value(type);
|
||||
|
||||
if (m_pipeMap.contains(std::make_tuple(producer, consumer, typeId)))
|
||||
{
|
||||
pipe = m_pipeMap[std::make_tuple(producer, consumer, typeId)];
|
||||
m_producerPipes[producer].removeAll(pipe);
|
||||
m_consumerPipes[consumer].removeAll(pipe);
|
||||
m_typeIdPipes[typeId].removeAll(pipe);
|
||||
m_producerAndTypeIdPipes[std::make_tuple(producer, typeId)].removeAll(pipe);
|
||||
|
||||
if (m_producerPipes[producer].size() == 0) {
|
||||
m_producerPipes.remove(producer);
|
||||
}
|
||||
|
||||
if (m_consumerPipes[consumer].size() == 0) {
|
||||
m_consumerPipes.remove(consumer);
|
||||
}
|
||||
|
||||
if (m_typeIdPipes[typeId].size() == 0) {
|
||||
m_typeIdPipes.remove(typeId);
|
||||
}
|
||||
|
||||
if (m_producerAndTypeIdPipes[std::make_tuple(producer, typeId)].size() == 0) {
|
||||
m_producerAndTypeIdPipes.remove(std::make_tuple(producer, typeId));
|
||||
}
|
||||
|
||||
pipe->setToBeDeleted(PipeDeletionReason::PipeDeleted, pipe);
|
||||
}
|
||||
}
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
void ObjectPipesRegistrations::getPipes(const QObject *producer, const QString& type, QList<ObjectPipe*>& pipes)
|
||||
{
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
if (m_typeIds.contains(type))
|
||||
{
|
||||
if (m_producerAndTypeIdPipes.contains(std::make_tuple(producer, m_typeIds[type]))) {
|
||||
pipes = m_producerAndTypeIdPipes[std::make_tuple(producer, m_typeIds[type])];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPipesRegistrations::processGC()
|
||||
{
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
typename QList<ObjectPipe*>::iterator itPipe = m_pipes.begin();
|
||||
|
||||
while (itPipe != m_pipes.end())
|
||||
{
|
||||
if ((*itPipe)->getGCCount() > 0) // scheduled for deletion
|
||||
{
|
||||
if ((*itPipe)->decreaseGCCount() == 0) // delete on this pass
|
||||
{
|
||||
m_objectPipeElementsStore->deleteElement((*itPipe)->m_element);
|
||||
delete *itPipe;
|
||||
itPipe = m_pipes.erase(itPipe);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itPipe;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++itPipe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPipesRegistrations::removeProducer(QObject *producer)
|
||||
{
|
||||
qDebug("ObjectPipesRegistrations::removeProducer: %p", producer);
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
if (m_producerPipes.contains(producer) && (m_producerPipes[producer].size() != 0))
|
||||
{
|
||||
const QList<ObjectPipe*>& pipeList = m_producerPipes[producer];
|
||||
|
||||
for (auto& pipe : pipeList)
|
||||
{
|
||||
for (const auto& consumer : m_consumerPipes.keys()) {
|
||||
m_consumerPipes[consumer].removeAll(pipe);
|
||||
}
|
||||
|
||||
for (const auto& typeId : m_typeIdPipes.keys()) {
|
||||
m_typeIdPipes[typeId].removeAll(pipe);
|
||||
}
|
||||
|
||||
pipe->setToBeDeleted(PipeDeletionReason::PipeProducerDeleted, producer);
|
||||
}
|
||||
|
||||
m_producerPipes.remove(producer);
|
||||
}
|
||||
|
||||
typename QMap<std::tuple<const QObject*, const QObject*, int>, ObjectPipe*>::iterator itP = m_pipeMap.begin();
|
||||
|
||||
while (itP != m_pipeMap.end())
|
||||
{
|
||||
if (std::get<0>(itP.key())) {
|
||||
itP = m_pipeMap.erase(itP);
|
||||
} else {
|
||||
++itP;
|
||||
}
|
||||
}
|
||||
|
||||
typename QMap<std::tuple<const QObject*, int>, QList<ObjectPipe*>>::iterator itPT = m_producerAndTypeIdPipes.begin();
|
||||
|
||||
while (itPT != m_producerAndTypeIdPipes.end())
|
||||
{
|
||||
if (std::get<0>(itPT.key()) == producer) {
|
||||
itPT = m_producerAndTypeIdPipes.erase(itPT);
|
||||
} else {
|
||||
++itPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPipesRegistrations::removeConsumer(QObject *consumer)
|
||||
{
|
||||
qDebug("ObjectPipesRegistrations::removeConsumer: %p", consumer);
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
if (m_consumerPipes.contains(consumer) && (m_consumerPipes[consumer].size() != 0))
|
||||
{
|
||||
QList<ObjectPipe*>& pipeList = m_consumerPipes[consumer];
|
||||
|
||||
for (auto& pipe : pipeList)
|
||||
{
|
||||
for (const auto& producer : m_producerPipes.keys()) {
|
||||
m_producerPipes[producer].removeAll(pipe);
|
||||
}
|
||||
|
||||
for (const auto& typeId : m_typeIdPipes.keys()) {
|
||||
m_typeIdPipes[typeId].removeAll(pipe);
|
||||
}
|
||||
|
||||
for (const auto& producerAndTypeId : m_producerAndTypeIdPipes.keys()) {
|
||||
m_producerAndTypeIdPipes[producerAndTypeId].removeAll(pipe);
|
||||
}
|
||||
|
||||
pipe->setToBeDeleted(PipeDeletionReason::PipeConsumerDeleted, consumer);
|
||||
}
|
||||
|
||||
m_consumerPipes.remove(consumer);
|
||||
}
|
||||
|
||||
typename QMap<std::tuple<const QObject*, const QObject*, int>, ObjectPipe*>::iterator it = m_pipeMap.begin();
|
||||
|
||||
while (it != m_pipeMap.end())
|
||||
{
|
||||
if (std::get<1>(it.key()) == consumer) {
|
||||
it = m_pipeMap.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
75
sdrbase/pipes/objectpipesregistrations.h
Normal file
75
sdrbase/pipes/objectpipesregistrations.h
Normal file
@ -0,0 +1,75 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRBASE_PIPES_OBJECTPIPESREGISTRATION_H_
|
||||
#define SDRBASE_PIPES_OBJECTPIPESREGISTRATION_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QMutex>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "export.h"
|
||||
#include "objectpipe.h"
|
||||
#include "objectpipeelementsstore.h"
|
||||
|
||||
class SDRBASE_API ObjectPipesRegistrations : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum PipeDeletionReason
|
||||
{
|
||||
PipeProducerDeleted,
|
||||
PipeConsumerDeleted,
|
||||
PipeDeleted
|
||||
};
|
||||
|
||||
ObjectPipesRegistrations(ObjectPipeElementsStore *objectPipeElementsStore);
|
||||
~ObjectPipesRegistrations();
|
||||
|
||||
ObjectPipe *registerProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type);
|
||||
ObjectPipe *unregisterProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type);
|
||||
void getPipes(const QObject *producer, const QString& type, QList<ObjectPipe*>& pipes);
|
||||
void processGC();
|
||||
|
||||
private slots:
|
||||
void removeProducer(QObject *producer);
|
||||
void removeConsumer(QObject *consumer);
|
||||
|
||||
private:
|
||||
QHash<QString, int> m_typeIds;
|
||||
QMap<int, QString> m_types;
|
||||
int m_typeCount;
|
||||
unsigned int m_pipeId;
|
||||
ObjectPipeElementsStore *m_objectPipeElementsStore;
|
||||
QList<ObjectPipe*> m_pipes;
|
||||
|
||||
QMap<const QObject*, QList<ObjectPipe*>> m_producerPipes;
|
||||
QMap<const QObject*, QList<ObjectPipe*>> m_consumerPipes;
|
||||
QMap<int, QList<ObjectPipe*>> m_typeIdPipes;
|
||||
QMap<std::tuple<const QObject*, int>, QList<ObjectPipe*>> m_producerAndTypeIdPipes;
|
||||
QMap<std::tuple<const QObject*, const QObject*, int>, ObjectPipe*> m_pipeMap;
|
||||
|
||||
QMutex m_mutex;
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_OBJECTPIPESREGISTRATION_H_
|
@ -136,7 +136,7 @@ void ValueDialZ::setValue(qint64 value)
|
||||
void ValueDialZ::setValueRange(bool positiveOnly, uint numDigits, qint64 min, qint64 max, int decimalPos)
|
||||
{
|
||||
m_positiveOnly = positiveOnly;
|
||||
m_decimalPos = decimalPos < 0 ? 0 : decimalPos > numDigits ? numDigits : decimalPos;
|
||||
m_decimalPos = decimalPos < 0 ? 0 : decimalPos > (int) numDigits ? numDigits : decimalPos;
|
||||
m_numDigits = numDigits;
|
||||
m_numThousandPoints = m_numDigits < 3 ? 0 : (m_numDigits%3) == 0 ? (m_numDigits/3)-1 : m_numDigits/3;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user