diff --git a/CMakeLists.txt b/CMakeLists.txt index e2df1d1..8a2e20f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ list(APPEND inspectrum_sources spectrogramplot.cpp traceplot.cpp tuner.cpp + tunertransform.cpp ) INCLUDE(FindPkgConfig) diff --git a/spectrogramplot.cpp b/spectrogramplot.cpp index f1011d3..fd8ce88 100644 --- a/spectrogramplot.cpp +++ b/spectrogramplot.cpp @@ -43,20 +43,9 @@ SpectrogramPlot::SpectrogramPlot(std::shared_ptrconnect(memSource, 0, tunerRotator, 0); - tunerFlowGraph->connect(tunerRotator, 0, tunerFilter, 0); - tunerFlowGraph->connect(tunerFilter, 0, memSink, 0); - - tunerOutput = std::make_shared, std::complex>>( - inputSource.get(), tunerFlowGraph, memSource, memSink - ); + tunerTransform = std::make_shared(src.get()); connect(&tuner, &Tuner::tunerMoved, this, &SpectrogramPlot::tunerMoved); + tunerMoved(); } void SpectrogramPlot::paintFront(QPainter &painter, QRect &rect, range_t sampleRange) @@ -165,7 +154,7 @@ int SpectrogramPlot::getStride() float SpectrogramPlot::getTunerPhaseInc() { auto freq = 0.5f - tuner.centre() / (float)fftSize; - return -freq * Tau; + return freq * Tau; } std::vector SpectrogramPlot::getTunerTaps() @@ -196,7 +185,7 @@ bool SpectrogramPlot::mouseEvent(QEvent::Type type, QMouseEvent event) std::shared_ptr SpectrogramPlot::output() { - return tunerOutput; + return tunerTransform; } void SpectrogramPlot::setFFTSize(int size) @@ -232,13 +221,13 @@ void SpectrogramPlot::setZoomLevel(int zoom) bool SpectrogramPlot::tunerEnabled() { - return (tunerOutput->subscriberCount() > 0); + return (tunerTransform->subscriberCount() > 0); } void SpectrogramPlot::tunerMoved() { - tunerRotator->set_phase_inc(getTunerPhaseInc()); - tunerFilter->set_taps(getTunerTaps()); + tunerTransform->setFrequency(getTunerPhaseInc()); + tunerTransform->setTaps(getTunerTaps()); // TODO: for invalidating traceplot cache, this shouldn't really go here QPixmapCache::clear(); diff --git a/spectrogramplot.h b/spectrogramplot.h index 9c862d2..4d8f47c 100644 --- a/spectrogramplot.h +++ b/spectrogramplot.h @@ -19,8 +19,6 @@ #pragma once -#include "rotator_ex_cc.h" -#include #include #include #include "fft.h" @@ -28,12 +26,11 @@ #include "inputsource.h" #include "plot.h" #include "tuner.h" +#include "tunertransform.h" #include #include -static const double Tau = M_PI * 2.0; - class TileCacheKey; class SpectrogramPlot : public Plot @@ -71,9 +68,7 @@ private: float powerMin; Tuner tuner; - std::shared_ptr, std::complex>> tunerOutput; - gr::blocks::rotator_ex_cc::sptr tunerRotator; - gr::filter::fir_filter_ccf::sptr tunerFilter; + std::shared_ptr tunerTransform; QPixmap* getPixmapTile(off_t tile); float* getFFTTile(off_t tile); diff --git a/tunertransform.cpp b/tunertransform.cpp new file mode 100644 index 0000000..e5f9842 --- /dev/null +++ b/tunertransform.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 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 "tunertransform.h" +#include +#include "util.h" + +TunerTransform::TunerTransform(SampleSource> *src) : SampleBuffer(src), taps{1.0f} +{ + +} + +void TunerTransform::work(void *input, void *output, int count, off_t sampleid) +{ + auto in = static_cast*>(input); + auto out = static_cast*>(output); + std::unique_ptr[]> temp(new std::complex[count]); + + // Mix down + nco_crcf mix = nco_crcf_create(LIQUID_NCO); + nco_crcf_set_phase(mix, fmodf(frequency * sampleid, Tau)); + nco_crcf_set_frequency(mix, frequency); + nco_crcf_mix_block_down(mix, + static_cast*>(input), + temp.get(), + count); + nco_crcf_destroy(mix); + + // Filter + firfilt_crcf filter = firfilt_crcf_create(taps.data(), taps.size()); + for (int i = 0; i < count; i++) + { + firfilt_crcf_push(filter, temp[i]); + firfilt_crcf_execute(filter, &out[i]); + } + firfilt_crcf_destroy(filter); +} + +void TunerTransform::setFrequency(float frequency) +{ + this->frequency = frequency; +} + +void TunerTransform::setTaps(std::vector taps) +{ + this->taps = taps; +} diff --git a/tunertransform.h b/tunertransform.h new file mode 100644 index 0000000..52d0195 --- /dev/null +++ b/tunertransform.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 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 . + */ + +#pragma once + +#include "samplebuffer.h" + +class TunerTransform : public SampleBuffer, std::complex> +{ +private: + float frequency; + std::vector taps; + +public: + TunerTransform(SampleSource> *src); + void work(void *input, void *output, int count, off_t sampleid) override; + void setFrequency(float frequency); + void setTaps(std::vector taps); +}; diff --git a/util.h b/util.h index 13f6f62..fec87ac 100644 --- a/util.h +++ b/util.h @@ -21,6 +21,8 @@ #pragma once #include +static const double Tau = M_PI * 2.0; + template const T& clamp (const T& value, const T& min, const T& max) { return std::min(max, std::max(min, value));