From cbaa2e0ec6ff4087b57bb60c7c95d7a21f1d73f2 Mon Sep 17 00:00:00 2001 From: Hannes Matuschek Date: Fri, 2 Jan 2015 18:16:49 +0100 Subject: [PATCH 1/2] Comments. --- src/baseband.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/baseband.hh b/src/baseband.hh index 4304fe4..11b6842 100644 --- a/src/baseband.hh +++ b/src/baseband.hh @@ -84,9 +84,9 @@ public: _Fc = Fc; this->setFrequencyShift(_Fc); } - /** Returns the center frequency. */ + /** Returns the filter frequency. */ inline double filterFrequency() const { return _Ff; } - /** (Re-) Sets the center frequency. */ + /** (Re-) Sets the filter frequency. */ void setFilterFrequency(double Ff) { _Ff = Ff; _update_filter_kernel(); } From f1d9b0325430f29ce3015cd8d21bb0973e722588 Mon Sep 17 00:00:00 2001 From: Hannes Matuschek Date: Mon, 12 Jan 2015 13:09:40 +0100 Subject: [PATCH 2/2] Cleanup. --- CMakeLists.txt | 13 +- doc/Doxyfile | 96 +++++++++----- examples/CMakeLists.txt | 13 -- src/CMakeLists.txt | 19 --- src/config.hh.in | 1 - src/gui/gui.hh | 7 - src/gui/spectrum.cc | 271 --------------------------------------- src/gui/spectrum.hh | 114 ---------------- src/gui/spectrumview.cc | 192 --------------------------- src/gui/spectrumview.hh | 74 ----------- src/gui/waterfallview.cc | 212 ------------------------------ src/gui/waterfallview.hh | 119 ----------------- src/psk31.hh | 43 +++++-- src/sdr.hh | 2 + 14 files changed, 98 insertions(+), 1078 deletions(-) delete mode 100644 src/gui/gui.hh delete mode 100644 src/gui/spectrum.cc delete mode 100644 src/gui/spectrum.hh delete mode 100644 src/gui/spectrumview.cc delete mode 100644 src/gui/spectrumview.hh delete mode 100644 src/gui/waterfallview.cc delete mode 100644 src/gui/waterfallview.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index da0906f..3bf1aa3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,27 +11,16 @@ SET(libsdr_VERSION_MAJOR "0") SET(libsdr_VERSION_MINOR "1") SET(libsdr_VERSION_PATCH "0") -find_package(Qt5Core) -find_package(Qt5Widgets) - find_package(FFTW) find_package(FFTWSingle) find_package(PortAudio) find_package(RTLSDR) -ADD_DEFINITIONS(${Qt5Widgets_DEFINITIONS}) - -INCLUDE_DIRECTORIES(${Qt5Core_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src) INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}/src) INCLUDE_DIRECTORIES(${PORTAUDIO_INCLUDE_DIRS}) # Set some variables for the configuration file -IF(Qt5Core_FOUND AND Qt5Widgets_FOUND) - set(SDR_WITH_QT5 ON) -ENDIF(Qt5Core_FOUND AND Qt5Widgets_FOUND) - IF(FFTW_FOUND) set(SDR_WITH_FFTW ON) ELSE(FFTW_FOUND) @@ -55,7 +44,7 @@ ENDIF(RTLSDR_FOUND) set(LIBS ${FFTW_LIBRARIES} ${FFTWSingle_LIBRARIES} ${PORTAUDIO_LIBRARIES} ${RTLSDR_LIBRARIES} "pthread") # Set compiler flags -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} -Wall -fPIC") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -ggdb") diff --git a/doc/Doxyfile b/doc/Doxyfile index 4c4b30e..188bb58 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.5 +# Doxyfile 1.8.7 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -70,15 +70,25 @@ OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- -# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, -# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, -# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, -# Turkish, Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -259,9 +269,12 @@ OPTIMIZE_OUTPUT_VHDL = NO # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # @@ -500,6 +513,13 @@ HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. @@ -521,7 +541,8 @@ SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. +# name. If set to NO the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO @@ -1220,7 +1241,8 @@ GENERATE_CHI = NO CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1460,11 +1482,11 @@ SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There -# are two flavours of web server based searching depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. See -# the section "External Indexing and Searching" for details. +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. @@ -1752,6 +1774,13 @@ MAN_OUTPUT = man MAN_EXTENSION = .3 +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without @@ -1779,18 +1808,6 @@ GENERATE_XML = NO XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size @@ -1937,9 +1954,9 @@ PREDEFINED = EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an -# all uppercase name, and do not end with a semicolon. Such function macros are -# typically used for boiler-plate code, and will confuse the parser if not +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not # removed. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1959,7 +1976,7 @@ SKIP_FUNCTION_MACROS = YES # where loc1 and loc2 can be relative or absolute paths or URLs. See the # section "Linking to external documentation" for more information about the use # of tag files. -# Note: Each tag file must have an unique name (where the name does NOT include +# Note: Each tag file must have a unique name (where the name does NOT include # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. @@ -2019,6 +2036,13 @@ CLASS_DIAGRAMS = YES MSCGEN_PATH = +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + # If set to YES, the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2219,6 +2243,12 @@ DOTFILE_DIRS = MSCFILE_DIRS = +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7e405f8..09f9589 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,8 +1,3 @@ -IF(SDR_WITH_QT5 AND SDR_WITH_FFTW AND SDR_WITH_PORTAUDIO) - add_executable(sdr_spec sdr_spec.cc) - target_link_libraries(sdr_spec ${LIBS} ${QT_LIBRARIES} libsdr libsdr-gui ) -ENDIF(SDR_WITH_QT5 AND SDR_WITH_FFTW AND SDR_WITH_PORTAUDIO) - IF(SDR_WITH_PORTAUDIO) add_executable(sdr_wavplay sdr_wavplay.cc) target_link_libraries(sdr_wavplay ${LIBS} libsdr) @@ -17,12 +12,4 @@ IF(SDR_WITH_PORTAUDIO) target_link_libraries(sdr_afsk1200 ${LIBS} libsdr) ENDIF(SDR_WITH_PORTAUDIO) -IF(SDR_WITH_QT5 AND SDR_WITH_FFTW AND SDR_WITH_PORTAUDIO) - add_executable(sdr_rds sdr_rds.cc) - target_link_libraries(sdr_rds ${LIBS} ${QT_LIBRARIES} libsdr libsdr-gui) -ENDIF(SDR_WITH_QT5 AND SDR_WITH_FFTW AND SDR_WITH_PORTAUDIO) - -add_executable(sdr_psk31 sdr_psk31.cc) -target_link_libraries(sdr_psk31 ${LIBS} ${QT_LIBRARIES} libsdr libsdr-gui) - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0f75de..503f01f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,22 +41,3 @@ INSTALL_HEADERS_WITH_DIRECTORY("${LIBSDR_HEADERS}" "${CMAKE_INSTALL_INCLUDEDIR}/ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/config.hh" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/libsdr") -if(SDR_WITH_FFTW AND SDR_WITH_QT5) - set(libsdr_gui_SOURCES gui/spectrum.cc gui/spectrumview.cc gui/waterfallview.cc) - set(libsdr_gui_MOC_HEADERS gui/spectrum.hh gui/spectrumview.hh gui/waterfallview.hh) - set(libsdr_gui_HEADERS ${libsdr_gui_MOC_HEADERS} gui/gui.hh) - qt5_wrap_cpp(libsdr_gui_MOC_SOURCES ${libsdr_gui_MOC_HEADERS}) - - add_library(libsdr-gui SHARED ${libsdr_gui_SOURCES} ${libsdr_gui_MOC_SOURCES}) - set_target_properties(libsdr-gui PROPERTIES OUTPUT_NAME sdr-gui) - set_target_properties(libsdr-gui PROPERTIES VERSION - "${libsdr_VERSION_MAJOR}.${libsdr_VERSION_MINOR}.${libsdr_VERSION_PATCH}") - set_target_properties(libsdr-gui PROPERTIES SOVERION "${libsdr_VERSION_MAJOR}") - set_target_properties(libsdr-gui PROPERTIES INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR}) - set_target_properties(libsdr-gui PROPERTIES MACOSX_RPATH "${CMAKE_INSTALL_RPATH}") - target_link_libraries(libsdr-gui libsdr ${Qt5Core_LIBRARIES} ${Qt5Widgets_LIBRARIES}) - - install(TARGETS libsdr-gui DESTINATION ${CMAKE_INSTALL_LIBDIR}) - INSTALL_HEADERS_WITH_DIRECTORY("${libsdr_gui_HEADERS}" "${CMAKE_INSTALL_INCLUDEDIR}/libsdr") -endif(SDR_WITH_FFTW AND SDR_WITH_QT5) - diff --git a/src/config.hh.in b/src/config.hh.in index f625c8f..49cdd2c 100644 --- a/src/config.hh.in +++ b/src/config.hh.in @@ -1,6 +1,5 @@ #cmakedefine SDR_DEBUG 1 -#cmakedefine SDR_WITH_QT5 1 #cmakedefine SDR_WITH_FFTW 1 #cmakedefine SDR_WITH_PORTAUDIO 1 #cmakedefine SDR_WITH_RTLSDR 1 diff --git a/src/gui/gui.hh b/src/gui/gui.hh deleted file mode 100644 index 63036f9..0000000 --- a/src/gui/gui.hh +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SDR_GUI_GUI_HH__ -#define __SDR_GUI_GUI_HH__ - -#include "spectrumview.hh" -#include "waterfallview.hh" - -#endif diff --git a/src/gui/spectrum.cc b/src/gui/spectrum.cc deleted file mode 100644 index 811b5c4..0000000 --- a/src/gui/spectrum.cc +++ /dev/null @@ -1,271 +0,0 @@ -#include "spectrum.hh" -#include "config.hh" - -using namespace sdr; -using namespace sdr::gui; - - -/* ********************************************************************************************* * - * SpectrumProvider - * ********************************************************************************************* */ -SpectrumProvider::SpectrumProvider(QObject *parent) - : QObject(parent) -{ - // pass... -} - -SpectrumProvider::~SpectrumProvider() { - // pass... -} - - -/* ********************************************************************************************* * - * Spectrum - * ********************************************************************************************* */ -Spectrum::Spectrum(double rrate, size_t fftsize, size_t max_avg, QObject *parent) : - SpectrumProvider(parent), _rrate(rrate), _fft_size(fftsize), _fft_buffer(fftsize), - _compute(fftsize), _spectrum(fftsize), _sample_count(0), _N_samples(0), - _trafo_count(0), _Ntrafo(max_avg), - _samples_left(0), _input_type(Config::Type_UNDEFINED), _sample_rate(0) -{ - // Construct FFT plan - _plan = fftw_plan_dft_1d( - fftsize, (fftw_complex *)_fft_buffer.ptr(), (fftw_complex *)_fft_buffer.ptr(), - FFTW_FORWARD, FFTW_ESTIMATE); - - // Set spectrum to 0: - for (size_t i=0; i<_fft_size; i++) { _spectrum[i] = 0; _compute[i] = 0; } -} - -Spectrum::~Spectrum() { - fftw_destroy_plan(_plan); -} - - -void -Spectrum::config(const Config &src_cfg) { - // Requires at least sample rate and type - if (!src_cfg.hasType() || !src_cfg.hasSampleRate()) { return; } - - // Store sample rate - _sample_rate = src_cfg.sampleRate(); - _samples_left = 0; - _trafo_count = 0; _sample_count=0; - _input_type = src_cfg.type(); - // Compute number of averages to compute to meet rrate approximately - _N_samples = _sample_rate/(_Ntrafo*_rrate); - - LogMessage msg(LOG_DEBUG); - msg << "Configured SpectrumView: " << std::endl - << " Data type: " << _input_type << std::endl - << " sample-rate: " << _sample_rate << std::endl - << " FFT size: " << _fft_size << std::endl - << " # sample drops: " << _N_samples-1 << std::endl - << " # averages: " << _Ntrafo << std::endl - << " refresh rate: " << _sample_rate/(_N_samples*_Ntrafo) << "Hz"; - Logger::get().log(msg); - - // Signal spectrum reconfiguration - emit spectrumConfigured(); -} - - -bool -Spectrum::isInputReal() const { - switch (_input_type) { - case Config::Type_u8: - case Config::Type_s8: - case Config::Type_u16: - case Config::Type_s16: - case Config::Type_f32: - case Config::Type_f64: - return true; - default: - break; - } - return false; -} - -double -Spectrum::sampleRate() const { - return _sample_rate; -} - -size_t -Spectrum::fftSize() const { - return _fft_size; -} - -const Buffer & -Spectrum::spectrum() const { - return _spectrum; -} - -void -Spectrum::handleBuffer(const RawBuffer &buffer, bool allow_overwrite) -{ - double scale=1, offset=0; - switch (_input_type) { - case Config::Type_u8: scale = 1<<8; offset=-128; break; - case Config::Type_cu8: scale = 1<<8; offset=-128; break; - case Config::Type_s8: scale = 1<<8; offset=0; break; - case Config::Type_cs8: scale = 1<<8; offset=0; break; - case Config::Type_u16: scale = 1<<16; offset=-32768; break; - case Config::Type_cu16: scale = 1<<16; offset=-32768; break; - case Config::Type_s16: scale = 1<<16; offset=0; break; - case Config::Type_cs16: scale = 1<<16; offset=0; break; - default: break; - } - - // Dispatch by input type: - if (Config::Type_u8 == _input_type) { - Buffer input(buffer); - for (size_t i=0; i transform - if (_samples_left == _fft_size) { _updateFFT(); _samples_left=0; _sample_count=0; } - } - } else if (Config::Type_s8 == _input_type) { - Buffer input(buffer); - for (size_t i=0; i transform - if (_samples_left == _fft_size) { _updateFFT(); _samples_left=0; _sample_count=0; } - } - } else if (Config::Type_u16 == _input_type) { - Buffer input(buffer); - for (size_t i=0; i input(buffer); - for (size_t i=0; i input(buffer); - for (size_t i=0; i input(buffer); - for (size_t i=0; i > input(buffer); - for (size_t i=0; i( - double(input[i].real())+offset, - double(input[i].imag())+offset)/scale; - _samples_left++; - if (_samples_left == _fft_size) { _updateFFT(); _samples_left=0; _sample_count=0; } - } - } else if (Config::Type_cs8 == _input_type) { - Buffer< std::complex > input(buffer); - for (size_t i=0; i( - double(input[i].real())+offset, - double(input[i].imag())+offset)/scale; - _samples_left++; - if (_samples_left == _fft_size) { _updateFFT(); _samples_left=0; _sample_count=0; } - } - } else if (Config::Type_cu16 == _input_type) { - Buffer< std::complex > input(buffer); - for (size_t i=0; i( - double(input[i].real())+offset,double(input[i].imag())+offset)/scale; - _samples_left++; - if (_samples_left == _fft_size) { _updateFFT(); _samples_left=0; _sample_count=0; } - } - } else if (Config::Type_cs16 == _input_type) { - Buffer< std::complex > input(buffer); - for (size_t i=0; i( - double(input[i].real())+offset,double(input[i].imag())+offset)/scale; - _samples_left++; - if (_samples_left == _fft_size) { _updateFFT(); _samples_left=0; _sample_count=0; } - } - } else if (Config::Type_cf32 == _input_type) { - Buffer< std::complex > input(buffer); - for (size_t i=0; i > input(buffer); - for (size_t i=0; i -#include -#include "sdr.hh" - - -namespace sdr { -namespace gui { - - -class SpectrumProvider: public QObject -{ - Q_OBJECT - -public: - SpectrumProvider(QObject *parent=0); - - virtual ~SpectrumProvider(); - - /** Returns true if the input is real. */ - virtual bool isInputReal() const = 0; - - /** Retunrs the sample rate. */ - virtual double sampleRate() const = 0; - - /** Returns the FFT size. */ - virtual size_t fftSize() const = 0; - - /** Returns the current spectrum. */ - virtual const Buffer &spectrum() const = 0; - -signals: - /** Gets emitted once the spectrum was updated. */ - void spectrumUpdated(); - /** Gets emitted once the spectrum was reconfigured. */ - void spectrumConfigured(); -}; - - -/** Calculates the power spectrum of a singnal. The spectrum gets updated with a specified - * rate (if possible). */ -class Spectrum : public SpectrumProvider, public SinkBase -{ - Q_OBJECT - -public: - /** Constructs a new spectrum recorder (sink). - * @param rrate Specifies the desired refresh-rate of the spectrum. - * @param fftsize Specifies the size (bins) of the spectrum. - * @param max_avg Specifies the max. number of averages to take. - * @param parent Specifies the parent of the @c Spectrum instance. */ - explicit Spectrum(double rrate=2, size_t fftsize=1024, size_t max_avg=1, QObject *parent = 0); - - /** Destructor. */ - virtual ~Spectrum(); - - /** Configures the Sink. */ - virtual void config(const Config &src_cfg); - - /** Receives the data stream and updates the _fft_buffer. */ - virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite); - - /** Returns true if the input is real. */ - bool isInputReal() const; - - /** Retunrs the sample rate. */ - double sampleRate() const; - - /** Returns the FFT size. */ - size_t fftSize() const; - - /** Returns the current spectrum. */ - const Buffer &spectrum() const; - -protected: - /** Updates the FFT in the _compute buffer. */ - void _updateFFT(); - -protected: - /** The desired refresh rate for the spectrum plot. */ - double _rrate; - /** Size of the FFT (resolution). */ - size_t _fft_size; - /** Input and compute buffer for the FFT. */ - Buffer< std::complex > _fft_buffer; - /** Summation buffer of the spectrum. */ - Buffer< double > _compute; - /** The current spectrum. */ - Buffer< double > _spectrum; - /** Specifies the number of received samples since last FFT. */ - size_t _sample_count; - /** Specifies the number of samples to drop before performing a FFT. */ - size_t _N_samples; - /** Number of transforms in the _compute buffer. */ - size_t _trafo_count; - /** Max. number of transforms. */ - size_t _Ntrafo; - /** Number of samples, left in the buffer by the previous input. */ - size_t _samples_left; - /** The input type. */ - Config::Type _input_type; - /** The sample-rate of the input. */ - double _sample_rate; - /** The FFTW plan. */ - fftw_plan _plan; -}; - - -} -} - -#endif // SPECTRUM_HH diff --git a/src/gui/spectrumview.cc b/src/gui/spectrumview.cc deleted file mode 100644 index dc98ed0..0000000 --- a/src/gui/spectrumview.cc +++ /dev/null @@ -1,192 +0,0 @@ -#include "spectrumview.hh" -#include -#include -#include -#include -#include - -using namespace sdr; -using namespace sdr::gui; - -SpectrumView::SpectrumView(SpectrumProvider *spectrum, QWidget *parent) - : QWidget(parent), _spectrum(spectrum), _numXTicks(11), _numYTicks(6), - _maxF(std::numeric_limits::infinity()), _mindB(-60) -{ - // Assemble pens - _axisPen = QPen(Qt::black); - _axisPen.setWidth(3); - _axisPen.setStyle(Qt::SolidLine); - _graphPen = QPen(Qt::blue); - _axisPen.setWidth(2); - _axisPen.setStyle(Qt::SolidLine); - - // Connect to update signal - QObject::connect(_spectrum, SIGNAL(spectrumUpdated()), this, SLOT(update())); - QObject::connect(_spectrum, SIGNAL(spectrumConfigured()), this, SLOT(update())); -} - -SpectrumView::~SpectrumView() { - // pass... -} - - -void -SpectrumView::mouseReleaseEvent(QMouseEvent *evt) { - // If event is accepted -> determine frequency - if ((evt->pos().x() < _plotArea.left()) || (evt->pos().x() > _plotArea.right())) { return; } - double f=0; - - if (_spectrum->isInputReal()) { - double dfdx = _spectrum->sampleRate()/(2*_plotArea.width()); - f = dfdx * (evt->pos().x()-_plotArea.left()); - } else { - double dfdx = _spectrum->sampleRate()/_plotArea.width(); - f = -_spectrum->sampleRate()/2 + dfdx * (evt->pos().x()-_plotArea.left()); - } - - emit click(f); - - // Forward to default impl: - QWidget::mouseReleaseEvent(evt); - // redraw - update(); -} - - -void -SpectrumView::resizeEvent(QResizeEvent *evt) { - // First, forward to default impl. - QWidget::resizeEvent(evt); - - // If resize event was accepted, recalc plot area - if (evt->isAccepted()) { - QSize ws = evt->size(); - QFontMetrics fm(_axisFont); - int leftMargin = 15 + 6*fm.width("x"); - int topMargin = 10; - int rightMargin = 3*fm.width("x"); - int bottomMargin = 15 + 2*fm.xHeight(); - _plotArea = QRect( - leftMargin, topMargin, - ws.width()-leftMargin-rightMargin, - ws.height()-bottomMargin-topMargin); - } -} - -void -SpectrumView::paintEvent(QPaintEvent *evt) { - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.save(); - - // Clip region to update - painter.setClipRect(evt->rect()); - - // Draw background - painter.fillRect(QRect(0,0, this->width(), this->height()), QColor(Qt::white)); - - _drawAxis(painter); - - _drawGraph(painter); - - painter.restore(); -} - - -void -SpectrumView::_drawGraph(QPainter &painter) { - // Draw spectrum - painter.save(); - painter.setClipRect(_plotArea); - painter.setPen(_graphPen); - double height = _plotArea.height(); - double width = _plotArea.width(); - - if (_spectrum->isInputReal()) { - double df = double(2*width)/_spectrum->fftSize(); - double dh = double(height)/_mindB; - int xoff = _plotArea.x(); - int yoff = _plotArea.y(); - for (size_t i=1; i<_spectrum->fftSize()/2; i++) { - int x1 = xoff+df*(i-1), x2 = xoff+df*(i); - int y1 = yoff+dh*(10*log10(_spectrum->spectrum()[i-1])-10*log10(_spectrum->fftSize())); - int y2 = yoff+dh*(10*log10(_spectrum->spectrum()[i])-10*log10(_spectrum->fftSize())); - painter.drawLine(x1, y1, x2, y2); - } - } else { - double df = double(width)/_spectrum->fftSize(); - double dh = double(height)/_mindB; - int xoff = _plotArea.x(); - int yoff = _plotArea.y(); - for (size_t i=1; i<_spectrum->fftSize(); i++) { - int idx1 = (_spectrum->fftSize()/2+i-1) % _spectrum->fftSize(); - int idx2 = (_spectrum->fftSize()/2+i) % _spectrum->fftSize(); - int x1 = xoff+df*(i-1), x2 = xoff+df*(i); - int y1 = yoff+dh*(10*log10(_spectrum->spectrum()[idx1])-10*log10(_spectrum->fftSize())); - int y2 = yoff+dh*(10*log10(_spectrum->spectrum()[idx2])-10*log10(_spectrum->fftSize())); - painter.drawLine(x1,y1, x2,y2); - } - } - painter.restore(); -} - - -void -SpectrumView::_drawAxis(QPainter &painter) { - painter.save(); - // Get some sizes - double height = _plotArea.height(); - double width = _plotArea.width(); - - painter.setPen(_axisPen); - - // Axes - painter.drawLine(_plotArea.topLeft(), _plotArea.bottomLeft()); - painter.drawLine(_plotArea.bottomLeft(), _plotArea.bottomRight()); - - // draw y-ticks & labels - double dh = double(height)/_mindB; - double x = _plotArea.topLeft().x(); - double y = _plotArea.topLeft().y(); - double ddB = _mindB/(_numYTicks-1); - QFontMetrics fm(_axisFont); QRect bb; double db=0; - for (size_t i=0; i<_numYTicks; i++, db+=ddB) { - QString label = QString("%1").arg(db); - bb = fm.boundingRect(label); - y = _plotArea.topLeft().y() + db*dh; - bb.translate(x-8-bb.width(),y+fm.strikeOutPos()); - painter.drawLine(x-5,y, x,y); - painter.drawText(bb, label); - } - - // Draw x ticks & labels (real spectrum) - if (_spectrum->isInputReal()) { - double dx = double(width)/(_numXTicks-1); - double maxF = std::min(_maxF, _spectrum->sampleRate()/2); - double df = maxF/(_numXTicks-1); - double x = _plotArea.bottomLeft().x(); - double y = _plotArea.bottomLeft().y(); - double f = 0; - for (size_t i=0; i<11; i++, f +=df, x += dx) { - QString label = QString("%1").arg(f); - bb = fm.boundingRect(label); - bb.translate(x-bb.width()/2,y+8+fm.overlinePos()); - painter.drawLine(x,y, x,y+5); - painter.drawText(bb, label); - } - } else { - double dx = double(width)/(_numXTicks-1); - double df = _spectrum->sampleRate()/(_numXTicks-1); - double x = _plotArea.bottomLeft().x(); - double y = _plotArea.bottomLeft().y(); - double f = -_spectrum->sampleRate()/2; - for (size_t i=0; i<_numXTicks; i++, f +=df, x += dx) { - QString label = QString("%1").arg(f); - bb = fm.boundingRect(label); - bb.translate(x-bb.width()/2,y+8+fm.overlinePos()); - painter.drawLine(x,y, x,y+5); - painter.drawText(bb, label); - } - } - painter.restore(); -} diff --git a/src/gui/spectrumview.hh b/src/gui/spectrumview.hh deleted file mode 100644 index b61205d..0000000 --- a/src/gui/spectrumview.hh +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef __SDR_GUI_SPECTRUMVIEW_HH__ -#define __SDR_GUI_SPECTRUMVIEW_HH__ - -#include -#include - -#include "sdr.hh" -#include "spectrum.hh" - - -namespace sdr { -namespace gui { - -/** A simple widget to display a PSD with live update. */ -class SpectrumView: public QWidget -{ -Q_OBJECT - -public: - /** @param rrate Specifies the (approx) refreshrate of the FFT plot. */ - explicit SpectrumView(SpectrumProvider *spectrum, QWidget *parent=0); - - inline size_t numXTicks() const { return _numXTicks; } - inline void setNumXTicks(size_t N) { _numXTicks=N; update(); } - - inline size_t numYTicks() const { return _numYTicks; } - inline void setNumYTicks(size_t N) { _numYTicks = N; } - - inline double mindB() const { return _mindB; } - inline void setMindB(double mindB) { _mindB = mindB; } - - /// Destructor. - virtual ~SpectrumView(); - -signals: - void click(double f); - -protected: - /** Handles mouse clicks. */ - virtual void mouseReleaseEvent(QMouseEvent *evt); - - /** Updates _plotArea on resize events. */ - virtual void resizeEvent(QResizeEvent *evt); - /** Draws the spectrum. */ - virtual void paintEvent(QPaintEvent *evt); - /** Draws the spectrum graph */ - void _drawGraph(QPainter &painter); - /** Draw the axes, ticks and labels. */ - void _drawAxis(QPainter &painter); - - -protected: - /** Holds a weak reference to the spectrum recorder object. */ - SpectrumProvider *_spectrum; - /// The font being used for axis labels - QFont _axisFont; - /// The plot area - QRect _plotArea; - /// Axis pen. - QPen _axisPen; - /// The pen used to draw the graph. - QPen _graphPen; - - size_t _numXTicks; - size_t _numYTicks; - double _maxF; - /** Lower bound of the PSD plot. */ - double _mindB; -}; - -} -} - -#endif // __SDR_GUI_SPECTRUMVIEW_HH__ diff --git a/src/gui/waterfallview.cc b/src/gui/waterfallview.cc deleted file mode 100644 index add8edd..0000000 --- a/src/gui/waterfallview.cc +++ /dev/null @@ -1,212 +0,0 @@ -#include "waterfallview.hh" -#include -#include -#include - -using namespace sdr; -using namespace sdr::gui; - - - -/* ****************************************************************************************** * - * Implementation of ColorMap - * ****************************************************************************************** */ -ColorMap::ColorMap(double min, double max) - : _min(min), _max(max) -{ - // pass... -} - -ColorMap::~ColorMap() { - // pass... -} - -/* ****************************************************************************************** * - * Implementation of GrayScaleColorMap - * ****************************************************************************************** */ -GrayScaleColorMap::GrayScaleColorMap(double min, double max) - : ColorMap(min, max) -{ - // pass... -} - -GrayScaleColorMap::~GrayScaleColorMap() { - // pass... -} - -QColor -GrayScaleColorMap::map(const double &value) { - int h = 255*value; - return QColor(h,h,h); -} - - -/* ****************************************************************************************** * - * Implementation of LinearColorMap - * ****************************************************************************************** */ -LinearColorMap::LinearColorMap(const QVector &colors, double min, double max) - : ColorMap(min, max), _colors(colors) -{ - // pass... -} - -LinearColorMap::~LinearColorMap() { - // pass... -} - -QColor -LinearColorMap::map(const double &value) { - // Calc indices - double upper = ceil(value*(_colors.size()-1)); - double lower = floor(value*(_colors.size()-1)); - int idx = int(lower); - if (lower == upper) { return _colors[idx]; } - double dv = upper-(value*(_colors.size()-1)); - double dr = dv * (_colors[idx].red() - _colors[idx+1].red()); - double dg = dv * (_colors[idx].green() - _colors[idx+1].green()); - double db = dv * (_colors[idx].blue() - _colors[idx+1].blue()); - return QColor(int(_colors[idx+1].red()+dr), - int(_colors[idx+1].green()+dg), - int(_colors[idx+1].blue()+db)); -} - - -/* ****************************************************************************************** * - * Implementation of WaterFallView - * ****************************************************************************************** */ -WaterFallView::WaterFallView(SpectrumProvider *spectrum, size_t hist, Direction dir, QWidget *parent) - : QWidget(parent), _spectrum(spectrum), _N(_spectrum->fftSize()), _M(hist), _dir(dir), - _waterfall(_N,_M) -{ - switch (dir) { - case BOTTOM_UP: - case TOP_DOWN: - setMinimumHeight(hist); - break; - case LEFT_RIGHT: - case RIGHT_LEFT: - setMinimumWidth(hist); - break; - } - - // Fill waterfall pixmap - _waterfall.fill(Qt::black); - // Create color map - //_colorMap = new GrayScaleColorMap(-120, 0); - QVector colors; colors.reserve(4); - colors << Qt::black << Qt::red << Qt::yellow << Qt::white; - _colorMap = new LinearColorMap(colors, -60, 0); - - // Get notified once a new spectrum is available: - QObject::connect(_spectrum, SIGNAL(spectrumUpdated()), this, SLOT(_onSpectrumUpdated())); - QObject::connect(_spectrum, SIGNAL(spectrumConfigured()), this, SLOT(_onSpectrumConfigure())); -} - -void -WaterFallView::_onSpectrumUpdated() { - if (_waterfall.isNull() || (_M==0) || (_N==0)) { return; } - - QPainter painter(&_waterfall); - // scroll pixmap one pixel up - QRect target(0,0, _N, _M-1), source(0,1,_N,_M-1); - painter.drawPixmap(target, _waterfall, source); - - // Draw new spectrum - for (size_t i=0; i<_N; i++) { - int idx = (_spectrum->fftSize()/2+i) % _spectrum->fftSize(); - double value; - if ((TOP_DOWN == _dir) || (LEFT_RIGHT == _dir)) { - value = 10*log10(_spectrum->spectrum()[_spectrum->fftSize()-1-idx])-10*log10(_N); - } else { - value = 10*log10(_spectrum->spectrum()[idx])-10*log10(_N); - } - // Reset NaNs - if (value != value) { value = std::numeric_limits::min(); } - painter.setPen((*_colorMap)(value)); - painter.drawPoint(i, _M-1); - } - - // Trigger update - this->update(); -} - -void -WaterFallView::_onSpectrumConfigure() { - // Update spectrum width - _N = _spectrum->fftSize(); - // Replace WaterFall pixmap - _waterfall = QPixmap(_N, _M); - // Fill waterfall pixmap - _waterfall.fill(Qt::black); - - // Trigger update - this->update(); -} - -void -WaterFallView::mouseReleaseEvent(QMouseEvent *evt) { - // If event is accepted -> determine frequency - if ((evt->pos().x() < 0) || (evt->pos().x() > this->width())) { return; } - double f=0; - - if ((BOTTOM_UP == _dir) || (TOP_DOWN == _dir)) { - double dfdx = _spectrum->sampleRate()/this->width(); - f = -_spectrum->sampleRate()/2 + dfdx*evt->pos().x(); - emit click(f); - } else { - double dfdx = _spectrum->sampleRate()/this->height(); - f = -_spectrum->sampleRate()/2 + dfdx*evt->pos().y(); - emit click(f); - } - - // Forward to default impl: - QWidget::mouseReleaseEvent(evt); - - // redraw - this->update(); -} - -void -WaterFallView::paintEvent(QPaintEvent *evt) -{ - QWidget::paintEvent(evt); - - QPainter painter(this); - - painter.save(); - painter.setRenderHints(QPainter::SmoothPixmapTransform|QPainter::Antialiasing); - // Assemble trafo - QTransform trafo; - switch (_dir) { - case BOTTOM_UP: - trafo.scale(this->width()/qreal(_N), this->height()/qreal(_M)); - break; - case LEFT_RIGHT: - trafo.scale(this->width()/qreal(_M), this->height()/qreal(_N)); - trafo.translate(_M,0); - trafo.rotate(90); - break; - case TOP_DOWN: - trafo.scale(this->width()/qreal(_N), this->height()/qreal(_M)); - trafo.translate(_N,_M); - trafo.rotate(180); - break; - case RIGHT_LEFT: - trafo.scale(this->width()/qreal(_M), this->height()/qreal(_N)); - trafo.translate(0,_N); - trafo.rotate(270); - break; - } - painter.setTransform(trafo); - QRect exposedRect = painter.matrix().inverted() - .mapRect(evt->rect()) - .adjusted(-1, -1, 1, 1); - // the adjust is to account for half pixels along edges - painter.drawPixmap(exposedRect, _waterfall, exposedRect); - //painter.drawPixmap(0,0, _waterfall); - painter.restore(); -} - - - - diff --git a/src/gui/waterfallview.hh b/src/gui/waterfallview.hh deleted file mode 100644 index c33072f..0000000 --- a/src/gui/waterfallview.hh +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef __SDR_GUI_WATERFALLVIEW_HH__ -#define __SDR_GUI_WATERFALLVIEW_HH__ - -#include -#include -#include "spectrum.hh" - - -namespace sdr { -namespace gui { - -/** Interface for all color maps. */ -class ColorMap -{ -protected: - /** Hidden constructor. */ - ColorMap(double min, double max); - -public: - /** Destructor. */ - virtual ~ColorMap(); - - /** Maps a value to a color. */ - inline QColor operator()(const double &value) { - if (value > _max) { return this->map(1); } - if (value < _min) { return this->map(0); } - return this->map((value-_min)/(_max-_min)); - } - - /** Maps a value on the interval [0,1] to a color. - * Needs to be implemented by all sub-classes. */ - virtual QColor map(const double &value) = 0; - -protected: - /** Minimum value. */ - double _min; - /** Maximum value. */ - double _max; -}; - -/** A simple gray-scale color map. */ -class GrayScaleColorMap: public ColorMap -{ -public: - /** Constructor. - * @param mindB Specifices the minimum value in dB of the color-scale. Mapping values [min, max] - * to a gray-scale. */ - GrayScaleColorMap(double min, double max); - /** Destructor. */ - virtual ~GrayScaleColorMap(); - /** Implements the color mapping. */ - virtual QColor map(const double &value); -}; - -/** A linear interpolating color map. */ -class LinearColorMap: public ColorMap { -public: - LinearColorMap(const QVector &colors, double min, double max); - /** Destructor. */ - virtual ~LinearColorMap(); - virtual QColor map(const double &value); - -protected: - QVector _colors; -}; - - -/** A simple waterfall display of the spectrogram. */ -class WaterFallView : public QWidget -{ - Q_OBJECT - -public: - typedef enum { - BOTTOM_UP, TOP_DOWN, LEFT_RIGHT, RIGHT_LEFT - } Direction; - -public: - /** Constructor. - * @param spectrum Specifies the spectrum sink. - * @param hist Specifies the number of PSDs to display. - * @param parent The parent widget. */ - explicit WaterFallView(SpectrumProvider *spectrum, size_t hist=100, Direction dir=BOTTOM_UP, QWidget *parent = 0); - -signals: - void click(double f); - -protected: - /** Handles mouse clicks. */ - virtual void mouseReleaseEvent(QMouseEvent *evt); - - /** Draws the scaled waterfall spectrogram. */ - virtual void paintEvent(QPaintEvent *evt); - -protected slots: - /** Gets called once a new PSD is available. */ - void _onSpectrumUpdated(); - /** Gets called once the spectrum provider gets reconfigured. */ - void _onSpectrumConfigure(); - -protected: - /** The spectrum sink. */ - SpectrumProvider *_spectrum; - /** The size of the spectrum. */ - size_t _N; - /** "Height of the spectrum. */ - size_t _M; - /** Specifies the direction of the waterfall. */ - Direction _dir; - /** The waterfall spectrogram. */ - QPixmap _waterfall; - /** The color map to be used. */ - ColorMap *_colorMap; -}; - -} -} - -#endif // WATERFALLVIEW_HH diff --git a/src/psk31.hh b/src/psk31.hh index 150338e..b9f0fe2 100644 --- a/src/psk31.hh +++ b/src/psk31.hh @@ -10,7 +10,7 @@ namespace sdr { /** A simple BPSK31 "demodulator". This node consumes a complex input stream with a sample-rate of * at least 2000Hz and produces a bitstream with 31.25 Hz "sample-rate". Use the @c Varicode node - * to decode this bitstream to ASCII chars. The BPSK31 signal should be centered around 0Hz, this + * to decode this bitstream to ASCII chars. The BPSK31 signal should be centered around 0Hz. This * node uses a simple PLL to adjust for small detunings. */ template class BPSK31: public Sink< std::complex >, public Source @@ -60,6 +60,7 @@ public: _superSample = 64; } + /** Destructor. */ virtual ~BPSK31() { // pass... } @@ -155,17 +156,20 @@ public: protected: + /** Returns @c true if there is a phase transition at the current sample. */ inline bool _hasTransition() const { return ((_hist[_hist_idx-1]>=0) && (_hist[_hist_idx]<=0)) || ((_hist[_hist_idx-1]<=0) && (_hist[_hist_idx]>=0)); } + /** Returns the current constellation. */ inline int _currentContellation() const { float value = 0; for (size_t i=0; i<=_hist_idx; i++) { value += _hist[i]; } return (value > 0) ? 1 : -1; } + /** Computes the phase error. */ inline float _phaseError(const std::complex &value) const { float r2 = value.real()*value.real(); float i2 = value.imag()*value.imag(); @@ -174,6 +178,7 @@ protected: return -value.real()*value.imag()/nrm2; } + /** Updates the PLL (@c _F and @c _P). */ inline void _updatePLL(const std::complex &sample) { float phi = _phaseError(sample); _F += _beta*phi; @@ -184,6 +189,7 @@ protected: //std::cerr << "Update PLL: P=" << _P << "; F=" << _F << ", err= " << phi << std::endl; } + /** Updates the sub-sampler. */ inline void _updateSampler(const std::complex &value) { // decrease fractional sub-sample counter _mu-=1; @@ -202,6 +208,7 @@ protected: _dl_idx = (_dl_idx + 1) % 8; } + /** Updates the PPL state (@c _mu and @c _omega). */ inline void _errorTracking(const std::complex &sample) { // Update last 2 constellation and phases _p_2T = _p_1T; _p_1T = _p_0T; _p_0T = sample; @@ -229,10 +236,14 @@ protected: float _P; /** Frequency of the carrier PLL. */ float _F; - /** Upper and lower frequency limit of the carrier PLL. */ - float _Fmin, _Fmax; - /** Gain factors of the carrier PLL. */ - float _alpha, _beta; + /** Lower frequency limit of the carrier PLL. */ + float _Fmin; + /** Upper frequency limit of the carrier PLL. */ + float _Fmax; + /** Gain factor of the carrier PLL. */ + float _alpha; + /** Gain factor of the carrier PLL. */ + float _beta; /** The delay line for the interpolating sub-sampler. */ Buffer< std::complex > _dl; /** The current index of the delay line. */ @@ -247,14 +258,24 @@ protected: float _omega; /** Relative error of the subsample rate. */ float _omega_rel; - /** Limits of the sub-sample rate. */ - float _min_omega, _max_omega; + /** Minimum of the sub-sample rate. */ + float _min_omega; + /** Maximum of the sub-sample rate. */ + float _max_omega; /** Gain of the sub-sample rate correction. */ float _gain_omega; - /** Last 3 phases. */ - std::complex _p_0T, _p_1T, _p_2T; - /** Last 3 constellations. */ - std::complex _c_0T, _c_1T, _c_2T; + /** Phase at T = 0 (samples). */ + std::complex _p_0T; + /** Phase at T=-1 (samples). */ + std::complex _p_1T; + /** Phase at T=-2 (samples). */ + std::complex _p_2T; + /** Constellation at T=0 (samples). */ + std::complex _c_0T; + /** Constellation at T=-1 (samples). */ + std::complex _c_1T; + /** Constellation at T=-2 (samples). */ + std::complex _c_2T; /** The last @c _superSample phases. */ Buffer _hist; /** Current phase history index. */ diff --git a/src/sdr.hh b/src/sdr.hh index 4f110d9..d3b9710 100644 --- a/src/sdr.hh +++ b/src/sdr.hh @@ -291,6 +291,8 @@ #include "demod.hh" #include "psk31.hh" +#include "fftplan.hh" + #ifdef SDR_WITH_FFTW #include "filternode.hh" #endif