/* * Copyright (C) 2015-2016, Mike Walters * * This file is part of inspectrum. * * 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, either 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "plotview.h" #include #include #include #include #include #include #include #include "grsamplebuffer.h" #include "memory_sink.h" #include "memory_source.h" #include "spectrogramplot.h" #include "traceplot.h" PlotView::PlotView() { } void PlotView::refreshSources() { plots.clear(); auto sp = new SpectrogramPlot(mainSampleSource); plots.emplace_back(sp); gr::top_block_sptr iq_tb = gr::make_top_block("multiply"); auto iq_mem_source = gr::blocks::memory_source::make(8); auto iq_mem_sink = gr::blocks::memory_sink::make(8); auto multiply = gr::blocks::multiply_const_cc::make(20); if (selection) { float centre = (selectionFreq.first + selectionFreq.second) / 2; float cutoff = std::abs(selectionFreq.first - centre); auto lp_taps = gr::filter::firdes::low_pass(1.0, 1.0, cutoff, cutoff / 2); auto filter = gr::filter::freq_xlating_fir_filter_ccf::make(1, lp_taps, centre, 1.0); iq_tb->connect(iq_mem_source, 0, filter, 0); iq_tb->connect(filter, 0, multiply, 0); iq_tb->connect(multiply, 0, iq_mem_sink, 0); } else { iq_tb->connect(iq_mem_source, 0, multiply, 0); iq_tb->connect(multiply, 0, iq_mem_sink, 0); } gr::top_block_sptr quad_demod_tb = gr::make_top_block("quad_demod"); auto quad_demod_mem_source = gr::blocks::memory_source::make(8); auto quad_demod_mem_sink = gr::blocks::memory_sink::make(4); auto quad_demod = gr::analog::quadrature_demod_cf::make(5); quad_demod_tb->connect(quad_demod_mem_source, 0, quad_demod, 0); quad_demod_tb->connect(quad_demod, 0, quad_demod_mem_sink, 0); auto iq_src = std::make_shared, std::complex>>(mainSampleSource, iq_tb, iq_mem_source, iq_mem_sink); plots.emplace_back(new TracePlot(iq_src)); plots.emplace_back( new TracePlot( std::make_shared, float>>( dynamic_cast>*>(iq_src.get()), quad_demod_tb, quad_demod_mem_source, quad_demod_mem_sink ) ) ); update(); } void PlotView::inputSourceChanged(AbstractSampleSource *src) { auto derived = dynamic_cast>*>(src); if (derived == nullptr) throw new std::runtime_error("SampleSource doesn't provide correct type for GRSampleBuffer"); mainSampleSource = derived; refreshSources(); } void PlotView::viewChanged(off_t firstSample, off_t lastSample) { this->firstSample = firstSample; this->lastSample = lastSample; update(); } void PlotView::selectionChanged(std::pair selectionTime, std::pair selectionFreq) { this->selectionTime = selectionTime; this->selectionFreq = selectionFreq; selection = true; refreshSources(); } void PlotView::selectionCleared() { selection = false; refreshSources(); } void PlotView::paintEvent(QPaintEvent *event) { if (lastSample - firstSample <= 0) return; QRect rect = QRect(0, 0, width(), height()); QPainter painter(this); painter.fillRect(rect, Qt::black); #define PLOT_LAYER(paintFunc) \ { \ int y = 0; \ for (auto&& plot : plots) { \ QRect rect = QRect(0, y, width(), plot->height()); \ plot->paintFunc(painter, rect, {firstSample, lastSample}); \ y += plot->height(); \ } \ } PLOT_LAYER(paintBack); PLOT_LAYER(paintMid); PLOT_LAYER(paintFront); #undef PLOT_LAYER }