diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-08-25 17:17:02 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-08-25 17:17:02 +0200 |
commit | 2b5eac085fa2482fa3ee062d079a03454f05b390 (patch) | |
tree | 15b4a995070079273e3eeac8a6c884acf95f9b46 | |
parent | 7bf3f2b9747a9f49a29a836d7c4b60f3c1070fd8 (diff) | |
download | dabmod-2b5eac085fa2482fa3ee062d079a03454f05b390.tar.gz dabmod-2b5eac085fa2482fa3ee062d079a03454f05b390.tar.bz2 dabmod-2b5eac085fa2482fa3ee062d079a03454f05b390.zip |
Put both AM/AM and AM/PM coefs to one file
This partly reverts commit 28462b9d8bb08609810ea9a9882c5fa9205b8b80.
-rw-r--r-- | dpd/dpd.ini | 3 | ||||
-rwxr-xr-x | dpd/main.py | 25 | ||||
-rw-r--r-- | dpd/poly.coef | 11 | ||||
-rw-r--r-- | dpd/poly_am.coef | 6 | ||||
-rw-r--r-- | dpd/poly_pm.coef | 6 | ||||
-rw-r--r-- | dpd/src/Adapt.py | 42 | ||||
-rw-r--r-- | src/ConfigParser.cpp | 9 | ||||
-rw-r--r-- | src/ConfigParser.h | 3 | ||||
-rw-r--r-- | src/DabModulator.cpp | 6 | ||||
-rw-r--r-- | src/MemlessPoly.cpp | 165 | ||||
-rw-r--r-- | src/MemlessPoly.h | 16 |
11 files changed, 108 insertions, 184 deletions
diff --git a/dpd/dpd.ini b/dpd/dpd.ini index 54af9ce..1bc51de 100644 --- a/dpd/dpd.ini +++ b/dpd/dpd.ini @@ -22,8 +22,7 @@ enabled=1 [poly] enabled=1 -polycoeffileam=dpd/poly_am.coef -polycoeffilepm=dpd/poly_pm.coef +polycoeffile=dpd/poly.coef # How many threads to use for the predistorter. # If not set, detect automatically. diff --git a/dpd/main.py b/dpd/main.py index 7e1041b..ea570d3 100755 --- a/dpd/main.py +++ b/dpd/main.py @@ -38,12 +38,9 @@ parser.add_argument('--rc-port', default='9400', parser.add_argument('--samplerate', default='8192000', help='Sample rate', required=False) -parser.add_argument('--coefs_am', default='poly_am.coef', - help='File with DPD Amplitude coefficients, which will be read by ODR-DabMod', +parser.add_argument('--coefs', default='poly.coef', + help='File with DPD coefficients, which will be read by ODR-DabMod', required=False) -parser.add_argument('--coefs_pm', default='poly_am.coef', - help='File with DPD Phase coefficients, which will be read by ODR-DabMod', - required=False) parser.add_argument('--samps', default='10240', help='Number of samples to request from ODR-DabMod', required=False) @@ -52,37 +49,33 @@ cli_args = parser.parse_args() port = int(cli_args.port) port_rc = int(cli_args.rc_port) -coef_am_path = cli_args.coefs_am -coef_pm_path = cli_args.coefs_pm +coef_path = cli_args.coefs num_req = int(cli_args.samps) samplerate = int(cli_args.samplerate) meas = Measure.Measure(samplerate, port, num_req) -adapt = Adapt.Adapt(port_rc, coef_am_path, coef_pm_path) -coefs_am = adapt.get_coefs_am() -coefs_pm = adapt.get_coefs_pm() +adapt = Adapt.Adapt(port_rc, coef_path) +coefs_am, coefs_pm = adapt.get_coefs() #model = Model.Model(coefs) -model = Model.Model([2.2, 0, 0, 0, 0], [0, 0, 0, 0, 0]) +model = Model.Model([1, 0, 0, 0, 0], [0, 0, 0, 0, 0]) adapt.set_txgain(70) adapt.set_rxgain(30) tx_gain = adapt.get_txgain() rx_gain = adapt.get_rxgain() -dpd_coefs_am = adapt.get_coefs_am() -dpd_coefs_pm = adapt.get_coefs_pm() +dpd_coefs_am, dpd_coefs_pm = adapt.get_coefs() logging.info( "TX gain {}, RX gain {}, dpd_coefs_am {}, dpd_coefs_pm {}".format( tx_gain, rx_gain, dpd_coefs_am, dpd_coefs_pm ) ) -for i in range(500): +for i in range(1): txframe_aligned, tx_ts, rxframe_aligned, rx_ts = meas.get_samples() logging.debug("tx_ts {}, rx_ts {}".format(tx_ts, rx_ts)) coefs_am, coefs_pm = model.get_next_coefs(txframe_aligned, rxframe_aligned) - adapt.set_coefs_am(coefs_am) - adapt.set_coefs_pm(coefs_pm) + adapt.set_coefs(coefs_am, coefs_pm) # The MIT License (MIT) # diff --git a/dpd/poly.coef b/dpd/poly.coef new file mode 100644 index 0000000..d1e9967 --- /dev/null +++ b/dpd/poly.coef @@ -0,0 +1,11 @@ +5 +0.9999999999999999 +0.013989416705029524 +-0.17875129566117912 +1.189037605717911 +-1.7871717414839607 +-0.005118865951385803 +0.06831365867284998 +-0.32196849299538066 +0.6598790120324084 +-0.5099783166759195 diff --git a/dpd/poly_am.coef b/dpd/poly_am.coef deleted file mode 100644 index ff09e5a..0000000 --- a/dpd/poly_am.coef +++ /dev/null @@ -1,6 +0,0 @@ -5 -2.2 -1.16110192544 --13.7895532562 -55.107515965 --53.8583673922 diff --git a/dpd/poly_pm.coef b/dpd/poly_pm.coef deleted file mode 100644 index ae91b12..0000000 --- a/dpd/poly_pm.coef +++ /dev/null @@ -1,6 +0,0 @@ -5 -0.141477421551 --0.654864288614 -1.00568534673 --0.588530075442 -0.0935391293974 diff --git a/dpd/src/Adapt.py b/dpd/src/Adapt.py index cc4c8c7..2fb596f 100644 --- a/dpd/src/Adapt.py +++ b/dpd/src/Adapt.py @@ -23,11 +23,10 @@ class Adapt: ZMQ remote control. """ - def __init__(self, port, coef_am_path, coef_pm_path): + def __init__(self, port, coef_path): logging.info("Instantiate Adapt object") self.port = port - self.coef_am_path = coef_am_path - self.coef_pm_path = coef_pm_path + self.coef_path = coef_path self.host = "localhost" self._context = zmq.Context() @@ -112,8 +111,10 @@ class Adapt: return self.send_receive("get uhd rxgain") def _read_coef_file(self, path): - """Load the coefficients from the file in the format given in the README""" - coefs_out = [] + """Load the coefficients from the file in the format given in the README, + return ([AM coef], [PM coef])""" + coefs_am_out = [] + coefs_pm_out = [] f = open(path, 'r') lines = f.readlines() n_coefs = int(lines[0]) @@ -121,35 +122,34 @@ class Adapt: i = 0 for c in coefs: if i < n_coefs: - coefs_out.append(c) + coefs_am_out.append(c) + elif i < 2*n_coefs: + coefs_pm_out.append(c) else: raise ValueError( "Incorrect coef file format: too many coefficients in {}, should be {}, coefs are {}" .format(path, n_coefs, coefs)) i += 1 f.close() - return coefs_out + return (coefs_am_out, coefs_pm_out) - def get_coefs_am(self): - return self._read_coef_file(self.coef_am_path) + def get_coefs(self): + return self._read_coef_file(self.coef_path) - def get_coefs_pm(self): - return self._read_coef_file(self.coef_pm_path) + def _write_coef_file(self, coefs_am, coefs_pm, path): + assert(len(coefs_am) == len(coefs_pm)) - def _write_coef_file(self, coefs, path): f = open(path, 'w') - f.write("{}\n".format(len(coefs))) - for coef in coefs: + f.write("{}\n".format(len(coefs_am))) + for coef in coefs_am: + f.write("{}\n".format(coef)) + for coef in coefs_pm: f.write("{}\n".format(coef)) f.close() - def set_coefs_am(self, coefs): - self._write_coef_file(coefs, self.coef_am_path) - self.send_receive("set memlesspoly coeffile_am {}".format(self.coef_am_path)) - - def set_coefs_pm(self, coefs): - self._write_coef_file(coefs, self.coef_pm_path) - self.send_receive("set memlesspoly coeffile_pm {}".format(self.coef_pm_path)) + def set_coefs(self, coefs_am, coefs_pm): + self._write_coef_file(coefs_am, coefs_pm, self.coef_path) + self.send_receive("set memlesspoly coeffile {}".format(self.coef_path)) # The MIT License (MIT) # diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 062660b..9ac1280 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -168,13 +168,10 @@ static void parse_configfile( pt.get<std::string>("firfilter.filtertapsfile", "default"); } - // Poly coefficients amplitude: + // Poly coefficients: if (pt.get("poly.enabled", 0) == 1) { - mod_settings.polyCoefFilenameAm = - pt.get<std::string>("poly.polycoeffileam", "dpd/poly_am.coef"); - - mod_settings.polyCoefFilenamePm = - pt.get<std::string>("poly.polycoeffilepm", "dpd/poly_pm.coef"); + mod_settings.polyCoefFilename = + pt.get<std::string>("poly.polycoeffile", "dpd/poly.coef"); mod_settings.polyNumThreads = pt.get<int>("poly.num_threads", 0); diff --git a/src/ConfigParser.h b/src/ConfigParser.h index d99fa08..89f0fb7 100644 --- a/src/ConfigParser.h +++ b/src/ConfigParser.h @@ -74,8 +74,7 @@ struct mod_settings_t { std::string filterTapsFilename = ""; - std::string polyCoefFilenameAm = ""; - std::string polyCoefFilenamePm = ""; + std::string polyCoefFilename = ""; unsigned polyNumThreads = 0; #if defined(HAVE_OUTPUT_UHD) diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index f7f583a..cc2642a 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -204,10 +204,8 @@ int DabModulator::process(Buffer* dataOut) } shared_ptr<MemlessPoly> cifPoly; - if (not m_settings.polyCoefFilenameAm.empty() and - not m_settings.polyCoefFilenamePm.empty() ) { - cifPoly = make_shared<MemlessPoly>(m_settings.polyCoefFilenameAm, - m_settings.polyCoefFilenamePm, + if (not m_settings.polyCoefFilename.empty()) { + cifPoly = make_shared<MemlessPoly>(m_settings.polyCoefFilename, m_settings.polyNumThreads); rcs.enrol(cifPoly.get()); } diff --git a/src/MemlessPoly.cpp b/src/MemlessPoly.cpp index 7fe465b..d5188f2 100644 --- a/src/MemlessPoly.cpp +++ b/src/MemlessPoly.cpp @@ -47,24 +47,20 @@ using namespace std; -#define NUM_COEFS_AM 5 -#define NUM_COEFS_PM 5 +// Number of AM/AM coefs, identical to number of AM/PM coefs +#define NUM_COEFS 5 -MemlessPoly::MemlessPoly(const std::string& coefs_am_file, const std::string& coefs_pm_file, unsigned int num_threads) : +MemlessPoly::MemlessPoly(const std::string& coefs_file, unsigned int num_threads) : PipelinedModCodec(), RemoteControllable("memlesspoly"), m_num_threads(num_threads), m_coefs_am(), - m_coefs_am_file(coefs_am_file), - m_coefs_am_mutex(), m_coefs_pm(), - m_coefs_pm_file(coefs_pm_file), - m_coefs_pm_mutex() + m_coefs_file(coefs_file), + m_coefs_mutex() { PDEBUG("MemlessPoly::MemlessPoly(%s) @ %p\n", - coefs_am_file.c_str(), this); - PDEBUG("MemlessPoly::MemlessPoly(%s) @ %p\n", - coefs_pm_file.c_str(), this); + coefs_file.c_str(), this); if (m_num_threads == 0) { const unsigned int hw_concurrency = std::thread::hardware_concurrency(); @@ -76,98 +72,64 @@ MemlessPoly::MemlessPoly(const std::string& coefs_am_file, const std::string& co m_num_threads << " threads (set in config file)"; } - RC_ADD_PARAMETER(ncoefs_am, "(Read-only) number of coefficients for amplitude."); - RC_ADD_PARAMETER(coeffile_am, "Filename containing coefficients for amplitude. When written to, the new file gets automatically loaded."); - - RC_ADD_PARAMETER(ncoefs_pm, "(Read-only) number of coefficients for phase."); - RC_ADD_PARAMETER(coeffile_pm, "Filename containing coefficients for amplitude. When written to, the new file gets automatically loaded."); + RC_ADD_PARAMETER(ncoefs, "(Read-only) number of coefficients."); + RC_ADD_PARAMETER(coeffile, "Filename containing coefficients. " + "When set, the file gets loaded."); - load_coefficients_am(m_coefs_am_file); - load_coefficients_pm(m_coefs_pm_file); + load_coefficients(m_coefs_file); start_pipeline_thread(); } -void MemlessPoly::load_coefficients_am(const std::string &coefFile_am) +void MemlessPoly::load_coefficients(const std::string &coefFile) { std::vector<float> coefs_am; - std::ifstream coef_fstream_am(coefFile_am.c_str()); - if (!coef_fstream_am) { - throw std::runtime_error("MemlessPoly: Could not open file with coefs_am!"); + std::vector<float> coefs_pm; + std::ifstream coef_fstream(coefFile.c_str()); + if (!coef_fstream) { + throw std::runtime_error("MemlessPoly: Could not open file with coefs!"); } - int n_coefs_am; - coef_fstream_am >> n_coefs_am; + int n_coefs; + coef_fstream >> n_coefs; - if (n_coefs_am <= 0) { - throw std::runtime_error("MemlessPoly: coefs_am file has invalid format."); + if (n_coefs <= 0) { + throw std::runtime_error("MemlessPoly: coefs file has invalid format."); } - else if (n_coefs_am != NUM_COEFS_AM) { - throw std::runtime_error("MemlessPoly: invalid number of coefs_am: " + - std::to_string(n_coefs_am) + " expected " + std::to_string(NUM_COEFS_AM)); + else if (n_coefs != NUM_COEFS) { + throw std::runtime_error("MemlessPoly: invalid number of coefs: " + + std::to_string(n_coefs) + " expected " + std::to_string(NUM_COEFS)); } - etiLog.log(debug, "MemlessPoly: Reading %d coefs_am...", n_coefs_am); + const size_t n_entries = 2 * n_coefs; - coefs_am.resize(n_coefs_am); - - for (int n = 0; n < n_coefs_am; n++) { - float a; - coef_fstream_am >> a; - coefs_am[n] = a; - - if (coef_fstream_am.eof()) { - etiLog.log(error, "MemlessPoly: file %s should contains %d coefs_am, " - "but EOF reached after %d coefs_am !", - coefFile_am.c_str(), n_coefs_am, n); - throw std::runtime_error("MemlessPoly: coefs_am file invalid !"); - } - } - - { - std::lock_guard<std::mutex> lock(m_coefs_am_mutex); - - m_coefs_am = coefs_am; - } -} - -void MemlessPoly::load_coefficients_pm(const std::string &coefFile_pm) -{ - std::vector<float> coefs_pm; - std::ifstream coef_fstream_pm(coefFile_pm.c_str()); - if (!coef_fstream_pm) { - throw std::runtime_error("MemlessPoly: Could not open file with coefs_pm!"); - } - int n_coefs_pm; - coef_fstream_pm >> n_coefs_pm; + etiLog.log(debug, "MemlessPoly: Reading %d coefs...", n_entries); - if (n_coefs_pm <= 0) { - throw std::runtime_error("MemlessPoly: coefs_pm file has invalid format."); - } - else if (n_coefs_pm != NUM_COEFS_PM) { - throw std::runtime_error("MemlessPoly: invalid number of coefs_pm: " + - std::to_string(n_coefs_pm) + " expected " + std::to_string(NUM_COEFS_PM)); - } + coefs_am.resize(n_coefs); + coefs_pm.resize(n_coefs); - etiLog.log(debug, "MemlessPoly: Reading %d coefs_pm...", n_coefs_pm); + for (int n = 0; n < n_entries; n++) { + float a; + coef_fstream >> a; - coefs_pm.resize(n_coefs_pm); + if (n < n_coefs) { + coefs_am[n] = a; + } + else { + coefs_pm[n - n_coefs] = a; + } - for (int n = 0; n < n_coefs_pm; n++) { - float a; - coef_fstream_pm >> a; - coefs_pm[n] = a; - - if (coef_fstream_pm.eof()) { - etiLog.log(error, "MemlessPoly: file %s should contains %d coefs_pm, " - "but EOF reached after %d coefs_pm !", - coefFile_pm.c_str(), n_coefs_pm, n); - throw std::runtime_error("MemlessPoly: coefs_pm file invalid !"); + if (coef_fstream.eof()) { + etiLog.log(error, "MemlessPoly: file %s should contains %d coefs, " + "but EOF reached after %d coefs !", + coefFile.c_str(), n_entries, n); + throw std::runtime_error("MemlessPoly: coefs file invalid !"); } } { - std::lock_guard<std::mutex> lock(m_coefs_pm_mutex); + std::lock_guard<std::mutex> lock(m_coefs_mutex); + m_coefs_am = coefs_am; m_coefs_pm = coefs_pm; } } @@ -176,8 +138,7 @@ void MemlessPoly::load_coefficients_pm(const std::string &coefFile_pm) * instead, and this allows the compiler to auto-vectorize the loop. */ static void apply_coeff( - const vector<float> &coefs_am, - const vector<float> &coefs_pm, + const vector<float> &coefs_am, const vector<float> &coefs_pm, const complexf *__restrict in, size_t start, size_t stop, complexf *__restrict out) { @@ -226,8 +187,7 @@ int MemlessPoly::internal_process(Buffer* const dataIn, Buffer* dataOut) size_t sizeOut = dataOut->getLength() / sizeof(complexf); { - std::lock_guard<std::mutex> lock_am(m_coefs_am_mutex); - std::lock_guard<std::mutex> lock_pm(m_coefs_pm_mutex); + std::lock_guard<std::mutex> lock(m_coefs_mutex); const unsigned int hw_concurrency = std::thread::hardware_concurrency(); const unsigned int num_threads = @@ -240,7 +200,8 @@ int MemlessPoly::internal_process(Buffer* const dataIn, Buffer* dataOut) size_t start = 0; for (size_t i = 0; i < num_threads - 1; i++) { flags.push_back(async(launch::async, apply_coeff, - m_coefs_am, m_coefs_pm, in, start, start + step, out)); + m_coefs_am, m_coefs_pm, + in, start, start + step, out)); start += step; } @@ -266,25 +227,13 @@ void MemlessPoly::set_parameter(const string& parameter, const string& value) stringstream ss(value); ss.exceptions ( stringstream::failbit | stringstream::badbit ); - if (parameter == "ncoefs_am") { - throw ParameterError("Parameter 'ncoefs_am' is read-only"); - } - else if (parameter == "ncoefs_pm") { - throw ParameterError("Parameter 'ncoefs_pm' is read-only"); + if (parameter == "ncoefs") { + throw ParameterError("Parameter 'ncoefs' is read-only"); } - else if (parameter == "coeffile_am") { + else if (parameter == "coeffile") { try { - load_coefficients_am(value); - m_coefs_am_file = value; - } - catch (std::runtime_error &e) { - throw ParameterError(e.what()); - } - } - else if (parameter == "coeffile_pm") { - try { - load_coefficients_pm(value); - m_coefs_pm_file = value; + load_coefficients(value); + m_coefs_file = value; } catch (std::runtime_error &e) { throw ParameterError(e.what()); @@ -301,17 +250,11 @@ void MemlessPoly::set_parameter(const string& parameter, const string& value) const string MemlessPoly::get_parameter(const string& parameter) const { stringstream ss; - if (parameter == "ncoefs_am") { + if (parameter == "ncoefs") { ss << m_coefs_am.size(); } - else if (parameter == "ncoefs_pm") { - ss << m_coefs_pm.size(); - } - else if (parameter == "coeffile_am") { - ss << m_coefs_am_file; - } - else if (parameter == "coeffile_pm") { - ss << m_coefs_pm_file; + else if (parameter == "coeffile") { + ss << m_coefs_file; } else { ss << "Parameter '" << parameter << diff --git a/src/MemlessPoly.h b/src/MemlessPoly.h index 536b054..4dcd44a 100644 --- a/src/MemlessPoly.h +++ b/src/MemlessPoly.h @@ -52,7 +52,7 @@ typedef std::complex<float> complexf; class MemlessPoly : public PipelinedModCodec, public RemoteControllable { public: - MemlessPoly(const std::string& coefs_am_file, const std::string& coefs_pm_file, unsigned int num_threads); + MemlessPoly(const std::string& coefs_file, unsigned int num_threads); virtual const char* name() { return "MemlessPoly"; } @@ -65,16 +65,12 @@ public: private: int internal_process(Buffer* const dataIn, Buffer* dataOut); - void load_coefficients_am(const std::string &coefFile_am); - void load_coefficients_pm(const std::string &coefFile_pm); + void load_coefficients(const std::string &coefFile); unsigned int m_num_threads; - std::vector<float> m_coefs_am; - std::string m_coefs_am_file; - mutable std::mutex m_coefs_am_mutex; - - std::vector<float> m_coefs_pm; - std::string m_coefs_pm_file; - mutable std::mutex m_coefs_pm_mutex; + std::vector<float> m_coefs_am; // AM/AM coefficients + std::vector<float> m_coefs_pm; // AM/PM coefficients + std::string m_coefs_file; + mutable std::mutex m_coefs_mutex; }; |