diff --git a/plugins/channelrx/demodapt/aptdemod.cpp b/plugins/channelrx/demodapt/aptdemod.cpp index 101d31536..11c99bb1b 100644 --- a/plugins/channelrx/demodapt/aptdemod.cpp +++ b/plugins/channelrx/demodapt/aptdemod.cpp @@ -45,6 +45,7 @@ MESSAGE_CLASS_DEFINITION(APTDemod::MsgConfigureAPTDemod, Message) MESSAGE_CLASS_DEFINITION(APTDemod::MsgPixels, Message) MESSAGE_CLASS_DEFINITION(APTDemod::MsgImage, Message) +MESSAGE_CLASS_DEFINITION(APTDemod::MsgLine, Message) MESSAGE_CLASS_DEFINITION(APTDemod::MsgResetDecoder, Message) const char * const APTDemod::m_channelIdURI = "sdrangel.channel.aptdemod"; diff --git a/plugins/channelrx/demodapt/aptdemod.h b/plugins/channelrx/demodapt/aptdemod.h index 58ff596e5..d30dad511 100644 --- a/plugins/channelrx/demodapt/aptdemod.h +++ b/plugins/channelrx/demodapt/aptdemod.h @@ -120,6 +120,32 @@ public: } }; + // Unprocessed line to be sent to GUI + class MsgLine : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const uchar* getLine() const { return m_line; } + int getSize() const { return m_size; } + void setSize(int size) { m_size = size;} + + static MsgLine* create(uchar **line) + { + MsgLine *msg = new MsgLine(); + *line = msg->m_line; + return msg; + } + + private: + uchar m_line[APT_PROW_WIDTH]; + int m_size; + + MsgLine() : + Message(), + m_size(APT_PROW_WIDTH) + {} + }; + // Sent from GUI to reset decoder class MsgResetDecoder : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/channelrx/demodapt/aptdemodgui.cpp b/plugins/channelrx/demodapt/aptdemodgui.cpp index 06e724482..7a8b3ac3d 100644 --- a/plugins/channelrx/demodapt/aptdemodgui.cpp +++ b/plugins/channelrx/demodapt/aptdemodgui.cpp @@ -126,6 +126,37 @@ bool APTDemodGUI::handleMessage(const Message& message) ui->imageContainer->setWindowTitle("Received image"); return true; } + else if (APTDemod::MsgLine::match(message)) + { + const APTDemod::MsgLine& lineMsg = (APTDemod::MsgLine&) message; + + if (m_image.width() == 0) + { + m_image = QImage(lineMsg.getSize(), 1, QImage::Format_Grayscale8); + } + else + { + m_image = m_image.copy(0, 0, m_image.width(), m_image.height()+1); // Add a line at tne bottom + + if (m_settings.m_flip) + { + m_pixmap.convertFromImage(m_image); + m_pixmap.scroll(0, 1, 0, 0, m_image.width(), m_image.height()-1); // scroll down 1 line + m_image = m_pixmap.toImage(); + } + } + + int len = std::min(m_image.width(), lineMsg.getSize()); + std::copy( + lineMsg.getLine(), + lineMsg.getLine() + len, + m_image.scanLine(m_settings.m_flip ? 0 : m_image.height()-1) + ); + m_pixmap.convertFromImage(m_image); + ui->image->setPixmap(m_pixmap); + + return true; + } else if (DSPSignalNotification::match(message)) { DSPSignalNotification& notif = (DSPSignalNotification&) message; diff --git a/plugins/channelrx/demodapt/aptdemodimageworker.cpp b/plugins/channelrx/demodapt/aptdemodimageworker.cpp index 125dcdcb9..00b398dd3 100644 --- a/plugins/channelrx/demodapt/aptdemodimageworker.cpp +++ b/plugins/channelrx/demodapt/aptdemodimageworker.cpp @@ -157,8 +157,14 @@ void APTDemodImageWorker::resetDecoder() void APTDemodImageWorker::processPixels(const float *pixels) { std::copy(pixels, pixels + APT_PROW_WIDTH, m_image.prow[m_image.nrow]); + + if (m_image.nrow % 20 == 0) { // send full image only every 20 lines + sendImageToGUI(); + } else { // else send unprocessed line just to show stg is moving + sendLineToGUI(); + } + m_image.nrow++; - sendImageToGUI(); } void APTDemodImageWorker::sendImageToGUI() @@ -172,6 +178,40 @@ void APTDemodImageWorker::sendImageToGUI() } } +void APTDemodImageWorker::sendLineToGUI() +{ + if (m_messageQueueToGUI) + { + float *pixels = m_image.prow[m_image.nrow]; + uchar *line; + APTDemod::MsgLine *msg = APTDemod::MsgLine::create(&line); + + if (m_settings.m_channels == APTDemodSettings::BOTH_CHANNELS) + { + for (int i = 0; i < APT_IMG_WIDTH; i++) { + line[i] = roundAndClip(pixels[i]); + } + msg->setSize(APT_IMG_WIDTH); + } + else if (m_settings.m_channels == APTDemodSettings::CHANNEL_A) + { + for (int i = 0; i < APT_CH_WIDTH; i++) { + line[i] = roundAndClip(pixels[i + APT_CHA_OFFSET]); + } + msg->setSize(APT_CH_WIDTH); + } + else + { + for (int i = 0; i < APT_CH_WIDTH; i++) { + line[i] = roundAndClip(pixels[i + APT_CHB_OFFSET]); + } + msg->setSize(APT_CH_WIDTH); + } + + m_messageQueueToGUI->push(msg); + } +} + QImage APTDemodImageWorker::processImage(QStringList& imageTypes) { copyImage(&m_tempImage, &m_image); diff --git a/plugins/channelrx/demodapt/aptdemodimageworker.h b/plugins/channelrx/demodapt/aptdemodimageworker.h index a4b47a9dc..9dcfd49ac 100644 --- a/plugins/channelrx/demodapt/aptdemodimageworker.h +++ b/plugins/channelrx/demodapt/aptdemodimageworker.h @@ -104,6 +104,7 @@ private: void resetDecoder(); void processPixels(const float *pixels); void sendImageToGUI(); + void sendLineToGUI(); void saveImageToDisk(); QImage processImage(QStringList& imageTypes); QImage extractImage(QImage image);