aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/example.ini6
-rw-r--r--src/DabMod.cpp11
-rw-r--r--src/DabModulator.cpp4
-rw-r--r--src/DabModulator.h4
-rw-r--r--src/FIRFilter.cpp87
-rw-r--r--src/FIRFilter.h11
-rw-r--r--src/Utils.cpp1
7 files changed, 75 insertions, 49 deletions
diff --git a/doc/example.ini b/doc/example.ini
index 6a4b0f4..8403e8f 100644
--- a/doc/example.ini
+++ b/doc/example.ini
@@ -114,10 +114,12 @@ dac_clk_rate=0
[firfilter]
; The FIR Filter can be used to create a better spectral quality.
+enabled=1
+
; The filter taps can be calculated with the python script
; doc/fir-filter/generate-filter.py
-enabled=0
-filtertapsfile=simple_taps.txt
+; If filtertapsfile is not given, the default taps are used.
+;filtertapsfile=simple_taps.txt
[output]
; choose output: possible values: uhd, file, zmq
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index 194c441..fc28218 100644
--- a/src/DabMod.cpp
+++ b/src/DabMod.cpp
@@ -423,14 +423,7 @@ int launch_modulator(int argc, char* argv[])
// FIR Filter parameters:
if (pt.get("firfilter.enabled", 0) == 1) {
- try {
- filterTapsFilename = pt.get<std::string>("firfilter.filtertapsfile");
- }
- catch (std::exception &e) {
- std::cerr << "Error: " << e.what() << "\n";
- std::cerr << " Configuration enables firfilter, but does not specify filter taps file\n";
- throw std::runtime_error("Configuration error");
- }
+ filterTapsFilename = pt.get<std::string>("firfilter.filtertapsfile", "default");
}
// Output options
@@ -609,7 +602,7 @@ int launch_modulator(int argc, char* argv[])
// When using the FIRFilter, increase the modulator offset pipelining delay
// by the correct amount
- if (filterTapsFilename != "") {
+ if (not filterTapsFilename.empty()) {
tist_delay_stages += FIRFILTER_PIPELINE_DELAY;
}
diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp
index 927c7bd..6d22f2d 100644
--- a/src/DabModulator.cpp
+++ b/src/DabModulator.cpp
@@ -60,7 +60,7 @@ DabModulator::DabModulator(
unsigned outputRate, unsigned clockRate,
unsigned dabMode, GainMode gainMode,
float& digGain, float normalise,
- std::string& filterTapsFilename
+ const std::string& filterTapsFilename
) :
ModCodec(ModFormat(1), ModFormat(0)),
myOutputRate(outputRate),
@@ -214,7 +214,7 @@ int DabModulator::process(Buffer* const dataIn, Buffer* dataOut)
myNbSymbols, mySpacing, myNullSize, mySymSize);
shared_ptr<FIRFilter> cifFilter;
- if (myFilterTapsFilename != "") {
+ if (not myFilterTapsFilename.empty()) {
cifFilter = make_shared<FIRFilter>(myFilterTapsFilename);
rcs.enrol(cifFilter.get());
}
diff --git a/src/DabModulator.h b/src/DabModulator.h
index fb2d758..41fa42d 100644
--- a/src/DabModulator.h
+++ b/src/DabModulator.h
@@ -55,7 +55,7 @@ public:
unsigned outputRate, unsigned clockRate,
unsigned dabMode, GainMode gainMode,
float& digGain, float normalise,
- std::string& filterTapsFilename);
+ const std::string& filterTapsFilename);
DabModulator(const DabModulator& other) = delete;
DabModulator& operator=(const DabModulator& other) = delete;
virtual ~DabModulator();
@@ -78,7 +78,7 @@ protected:
EtiReader myEtiReader;
Flowgraph* myFlowgraph;
OutputMemory* myOutput;
- std::string& myFilterTapsFilename;
+ std::string myFilterTapsFilename;
tii_config_t& myTiiConfig;
size_t myNbSymbols;
diff --git a/src/FIRFilter.cpp b/src/FIRFilter.cpp
index 86f558b..7e6014c 100644
--- a/src/FIRFilter.cpp
+++ b/src/FIRFilter.cpp
@@ -2,8 +2,10 @@
Copyright (C) 2007, 2008, 2009, 2010, 2011 Her Majesty the Queen in
Right of Canada (Communications Research Center Canada)
- Written by
- 2012, Matthias P. Braendli, matthias.braendli@mpb.li
+ Copyright (C) 2016
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ http://opendigitalradio.org
This block implements a FIR filter. The real filter taps are given
as floats, and the block can take advantage of SSE.
@@ -34,6 +36,7 @@
#include <stdio.h>
#include <stdexcept>
+#include <array>
#include <iostream>
#include <fstream>
#include <memory>
@@ -46,6 +49,29 @@ using namespace std;
#include <sys/time.h>
+/* This is the FIR Filter calculated with the doc/fir-filter/generate-filter.py script
+ * with settings
+ * gain = 1
+ * sampling_freq = 2.048e6
+ * cutoff = 810e3
+ * transition_width = 250e3
+ *
+ * It is a good default filter for the common scenarios.
+ */
+static const std::array<float, 45> default_filter_taps({
+ -0.00110450468492, 0.00120703084394, -0.000840645749122, -0.000187368263141,
+ 0.00184351124335, -0.00355578539893, 0.00419321097434, -0.00254214904271,
+ -0.00183473504148, 0.00781436730176, -0.0125957569107, 0.0126200336963,
+ -0.00537294941023, -0.00866683479398, 0.0249746385962, -0.0356550291181,
+ 0.0319730602205, -0.00795613788068, -0.0363943465054, 0.0938014090061,
+ -0.151176810265, 0.193567320704, 0.791776955128, 0.193567320704,
+ -0.151176810265, 0.0938014090061, -0.0363943465054, -0.00795613788068,
+ 0.0319730602205, -0.0356550291181, 0.0249746385962, -0.00866683479398,
+ -0.00537294941023, 0.0126200336963, -0.0125957569107, 0.00781436730176,
+ -0.00183473504148, -0.00254214904271, 0.00419321097434, -0.00355578539893,
+ 0.00184351124335, -0.000187368263141, -0.000840645749122, 0.00120703084394,
+ -0.00110450468492});
+
void FIRFilterWorker::process(struct FIRFilterWorkerData *fwd)
{
size_t i;
@@ -238,7 +264,7 @@ void FIRFilterWorker::process(struct FIRFilterWorkerData *fwd)
}
-FIRFilter::FIRFilter(std::string& taps_file) :
+FIRFilter::FIRFilter(const std::string& taps_file) :
ModCodec(ModFormat(sizeof(complexf)), ModFormat(sizeof(complexf))),
RemoteControllable("firfilter"),
myTapsFile(taps_file)
@@ -257,37 +283,44 @@ FIRFilter::FIRFilter(std::string& taps_file) :
worker.start(&firwd);
}
-void FIRFilter::load_filter_taps(std::string tapsFile)
+void FIRFilter::load_filter_taps(const std::string &tapsFile)
{
- std::ifstream taps_fstream(tapsFile.c_str());
- if(!taps_fstream) {
- fprintf(stderr, "FIRFilter: file %s could not be opened !\n", tapsFile.c_str());
- throw std::runtime_error("FIRFilter: Could not open file with taps! ");
+ std::vector<float> filter_taps;
+ if (tapsFile == "default") {
+ std::copy(default_filter_taps.begin(), default_filter_taps.end(),
+ std::back_inserter(filter_taps));
}
- int n_taps;
- taps_fstream >> n_taps;
+ else {
+ std::ifstream taps_fstream(tapsFile.c_str());
+ if(!taps_fstream) {
+ fprintf(stderr, "FIRFilter: file %s could not be opened !\n", tapsFile.c_str());
+ throw std::runtime_error("FIRFilter: Could not open file with taps! ");
+ }
+ int n_taps;
+ taps_fstream >> n_taps;
- if (n_taps <= 0) {
- fprintf(stderr, "FIRFilter: warning: taps file has invalid format\n");
- throw std::runtime_error("FIRFilter: taps file has invalid format.");
- }
+ if (n_taps <= 0) {
+ fprintf(stderr, "FIRFilter: warning: taps file has invalid format\n");
+ throw std::runtime_error("FIRFilter: taps file has invalid format.");
+ }
- if (n_taps > 100) {
- fprintf(stderr, "FIRFilter: warning: taps file has more than 100 taps\n");
- }
+ if (n_taps > 100) {
+ fprintf(stderr, "FIRFilter: warning: taps file has more than 100 taps\n");
+ }
- fprintf(stderr, "FIRFilter: Reading %d taps...\n", n_taps);
+ fprintf(stderr, "FIRFilter: Reading %d taps...\n", n_taps);
- std::vector<float> filter_taps(n_taps);
+ filter_taps.resize(n_taps);
- int n;
- for (n = 0; n < n_taps; n++) {
- taps_fstream >> filter_taps[n];
- PDEBUG("FIRFilter: tap: %f\n", filter_taps[n] );
- if (taps_fstream.eof()) {
- fprintf(stderr, "FIRFilter: file %s should contains %d taps, but EOF reached "\
- "after %d taps !\n", tapsFile.c_str(), n_taps, n);
- throw std::runtime_error("FIRFilter: filtertaps file invalid ! ");
+ int n;
+ for (n = 0; n < n_taps; n++) {
+ taps_fstream >> filter_taps[n];
+ PDEBUG("FIRFilter: tap: %f\n", filter_taps[n] );
+ if (taps_fstream.eof()) {
+ fprintf(stderr, "FIRFilter: file %s should contains %d taps, but EOF reached "\
+ "after %d taps !\n", tapsFile.c_str(), n_taps, n);
+ throw std::runtime_error("FIRFilter: filtertaps file invalid ! ");
+ }
}
}
diff --git a/src/FIRFilter.h b/src/FIRFilter.h
index 2dd7354..ceac4cd 100644
--- a/src/FIRFilter.h
+++ b/src/FIRFilter.h
@@ -22,8 +22,7 @@
along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef FIRFILTER_H
-#define FIRFILTER_H
+#pragma once
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -98,7 +97,7 @@ class FIRFilterWorker {
class FIRFilter : public ModCodec, public RemoteControllable
{
public:
- FIRFilter(std::string& taps_file);
+ FIRFilter(const std::string& taps_file);
virtual ~FIRFilter();
FIRFilter(const FIRFilter&);
FIRFilter& operator=(const FIRFilter&);
@@ -115,14 +114,12 @@ public:
protected:
- void load_filter_taps(std::string tapsFile);
+ void load_filter_taps(const std::string &tapsFile);
- std::string& myTapsFile;
+ std::string myTapsFile;
FIRFilterWorker worker;
int number_of_runs;
struct FIRFilterWorkerData firwd;
};
-#endif //FIRFILTER_H
-
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 54a4161..a91077c 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -73,6 +73,7 @@ void printUsage(char* progName)
" requiring an external REFCLK and PPS signal and frames that do not contain a valid timestamp\n"
" get muted.\n\n");
fprintf(out, "-T taps_file: Enable filtering before the output, using the specified file containing the filter taps.\n");
+ fprintf(out, " Use 'default' as taps_file to use the internal taps.\n");
fprintf(out, "-a gain: Apply digital amplitude gain.\n");
fprintf(out, "-c rate: Set the DAC clock rate and enable Cic Equalisation.\n");
fprintf(out, "-g gainmode: Set computation gain mode: fix, max or var\n");