| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | /*  fmd.c
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This file is part of a program that implements a Software-Defined Radio. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Copyright (C) 2013, 2023 Warren Pratt, NR0V | 
					
						
							|  |  |  | Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 2 | 
					
						
							|  |  |  | 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, write to the Free Software | 
					
						
							|  |  |  | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The author can be reached by email at | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | warren@wpratt.com | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  | #include <array>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | #include "comm.hpp"
 | 
					
						
							| 
									
										
										
										
											2024-07-13 03:20:26 +02:00
										 |  |  | #include "fircore.hpp"
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | #include "fcurve.hpp"
 | 
					
						
							|  |  |  | #include "fir.hpp"
 | 
					
						
							|  |  |  | #include "wcpAGC.hpp"
 | 
					
						
							| 
									
										
										
										
											2024-07-31 01:37:17 +02:00
										 |  |  | #include "snotch.hpp"
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | #include "fmd.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace WDSP { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::calc() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     // pll
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     omega_min = TWOPI * fmin / rate; | 
					
						
							|  |  |  |     omega_max = TWOPI * fmax / rate; | 
					
						
							|  |  |  |     g1 = 1.0 - exp(-2.0 * omegaN * zeta / rate); | 
					
						
							|  |  |  |     g2 = -g1 + 2.0 * (1 - exp(-omegaN * zeta / rate) * cos(omegaN / rate * sqrt(1.0 - zeta * zeta))); | 
					
						
							|  |  |  |     phs = 0.0; | 
					
						
							|  |  |  |     fil_out = 0.0; | 
					
						
							|  |  |  |     omega = 0.0; | 
					
						
							|  |  |  |     pllpole = omegaN * sqrt(2.0 * zeta * zeta + 1.0 + sqrt((2.0 * zeta * zeta + 1.0) * (2.0 * zeta * zeta + 1.0) + 1)) / TWOPI; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // dc removal
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     mtau = exp(-1.0 / (rate * tau)); | 
					
						
							|  |  |  |     onem_mtau = 1.0 - mtau; | 
					
						
							|  |  |  |     fmdc = 0.0; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // pll audio gain
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     again = rate / (deviation * TWOPI); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // CTCSS Removal
 | 
					
						
							| 
									
										
										
										
											2024-08-01 00:31:28 +02:00
										 |  |  |     sntch = new SNOTCH( | 
					
						
							|  |  |  |         1, | 
					
						
							|  |  |  |         size, | 
					
						
							|  |  |  |         out, | 
					
						
							|  |  |  |         out, | 
					
						
							|  |  |  |         (int) rate, | 
					
						
							|  |  |  |         ctcss_freq, | 
					
						
							|  |  |  |         0.0002) | 
					
						
							|  |  |  |     ; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // detector limiter
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     plim = new WCPAGC( | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         1,                                          // run - always ON
 | 
					
						
							|  |  |  |         5,                                          // mode
 | 
					
						
							|  |  |  |         1,                                          // 0 for max(I,Q), 1 for envelope
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         out,                                     // input buff pointer
 | 
					
						
							|  |  |  |         out,                                     // output buff pointer
 | 
					
						
							|  |  |  |         size,                                    // io_buffsize
 | 
					
						
							|  |  |  |         (int)rate,                               // sample rate
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         0.001,                                      // tau_attack
 | 
					
						
							|  |  |  |         0.008,                                      // tau_decay
 | 
					
						
							|  |  |  |         4,                                          // n_tau
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         lim_gain,                                // max_gain (sets threshold, initial value)
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         1.0,                                        // var_gain / slope
 | 
					
						
							|  |  |  |         1.0,                                        // fixed_gain
 | 
					
						
							|  |  |  |         1.0,                                        // max_input
 | 
					
						
							|  |  |  |         0.9,                                        // out_targ
 | 
					
						
							|  |  |  |         0.250,                                      // tau_fast_backaverage
 | 
					
						
							|  |  |  |         0.004,                                      // tau_fast_decay
 | 
					
						
							|  |  |  |         4.0,                                        // pop_ratio
 | 
					
						
							|  |  |  |         0,                                          // hang_enable
 | 
					
						
							|  |  |  |         0.500,                                      // tau_hang_backmult
 | 
					
						
							|  |  |  |         0.500,                                      // hangtime
 | 
					
						
							|  |  |  |         2.000,                                      // hang_thresh
 | 
					
						
							|  |  |  |         0.100);                                     // tau_hang_decay
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::decalc() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     delete plim; | 
					
						
							|  |  |  |     delete sntch; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | FMD::FMD( | 
					
						
							|  |  |  |     int _run, | 
					
						
							|  |  |  |     int _size, | 
					
						
							|  |  |  |     float* _in, | 
					
						
							|  |  |  |     float* _out, | 
					
						
							|  |  |  |     int _rate, | 
					
						
							|  |  |  |     double _deviation, | 
					
						
							|  |  |  |     double _f_low, | 
					
						
							|  |  |  |     double _f_high, | 
					
						
							|  |  |  |     double _fmin, | 
					
						
							|  |  |  |     double _fmax, | 
					
						
							|  |  |  |     double _zeta, | 
					
						
							|  |  |  |     double _omegaN, | 
					
						
							|  |  |  |     double _tau, | 
					
						
							|  |  |  |     double _afgain, | 
					
						
							|  |  |  |     int _sntch_run, | 
					
						
							|  |  |  |     double _ctcss_freq, | 
					
						
							|  |  |  |     int _nc_de, | 
					
						
							|  |  |  |     int _mp_de, | 
					
						
							|  |  |  |     int _nc_aud, | 
					
						
							|  |  |  |     int _mp_aud | 
					
						
							|  |  |  | ) : | 
					
						
							|  |  |  |     run(_run), | 
					
						
							|  |  |  |     size(_size), | 
					
						
							|  |  |  |     in(_in), | 
					
						
							|  |  |  |     out(_out), | 
					
						
							|  |  |  |     rate((double) _rate), | 
					
						
							|  |  |  |     f_low(_f_low), | 
					
						
							|  |  |  |     f_high(_f_high), | 
					
						
							|  |  |  |     fmin(_fmin), | 
					
						
							|  |  |  |     fmax(_fmax), | 
					
						
							|  |  |  |     zeta(_zeta), | 
					
						
							|  |  |  |     omegaN(_omegaN), | 
					
						
							|  |  |  |     tau(_tau), | 
					
						
							|  |  |  |     deviation(_deviation), | 
					
						
							|  |  |  |     nc_de(_nc_de), | 
					
						
							|  |  |  |     mp_de(_mp_de), | 
					
						
							|  |  |  |     nc_aud(_nc_aud), | 
					
						
							|  |  |  |     mp_aud(_mp_aud), | 
					
						
							|  |  |  |     afgain(_afgain), | 
					
						
							|  |  |  |     sntch_run(_sntch_run), | 
					
						
							|  |  |  |     ctcss_freq(_ctcss_freq), | 
					
						
							|  |  |  |     lim_run(0), | 
					
						
							|  |  |  |     lim_gain(0.0001), // 2.5
 | 
					
						
							|  |  |  |     lim_pre_gain(0.01) // 0.4
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     calc(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // de-emphasis filter
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     audio.resize(size * 2); | 
					
						
							| 
									
										
										
										
											2024-08-08 09:09:40 +02:00
										 |  |  |     std::vector<float> impulse(2 * nc_de); | 
					
						
							|  |  |  |     FCurve::fc_impulse ( | 
					
						
							|  |  |  |         impulse, | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |         nc_de, | 
					
						
							|  |  |  |         (float) f_low, | 
					
						
							|  |  |  |         (float) f_high, | 
					
						
							|  |  |  |         (float) (+20.0 * log10(f_high / f_low)), | 
					
						
							|  |  |  |         0.0, 1, | 
					
						
							|  |  |  |         (float) rate, | 
					
						
							|  |  |  |         (float) (1.0 / (2.0 * size)), | 
					
						
							|  |  |  |         0, | 
					
						
							|  |  |  |         0 | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |     pde = new FIRCORE(size, audio.data(), out, mp_de, impulse); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // audio filter
 | 
					
						
							| 
									
										
										
										
											2024-08-10 06:40:35 +02:00
										 |  |  |     std::vector<float> impulseb; | 
					
						
							|  |  |  |     FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |     paud = new FIRCORE(size, out, out, mp_aud, impulseb); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | FMD::~FMD() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-10 09:59:42 +02:00
										 |  |  |     delete paud; | 
					
						
							|  |  |  |     delete pde; | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     decalc(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::flush() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-28 11:36:45 +02:00
										 |  |  |     std::fill(audio.begin(), audio.end(), 0); | 
					
						
							| 
									
										
										
										
											2024-08-06 06:26:53 +02:00
										 |  |  |     pde->flush(); | 
					
						
							|  |  |  |     paud->flush(); | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     phs = 0.0; | 
					
						
							|  |  |  |     fil_out = 0.0; | 
					
						
							|  |  |  |     omega = 0.0; | 
					
						
							|  |  |  |     fmdc = 0.0; | 
					
						
							| 
									
										
										
										
											2024-08-01 00:31:28 +02:00
										 |  |  |     sntch->flush(); | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     plim->flush(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::execute() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     if (run) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         int i; | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |         double det; | 
					
						
							|  |  |  |         double del_out; | 
					
						
							|  |  |  |         std::array<double, 2> vco; | 
					
						
							|  |  |  |         std::array<double, 2> corr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         for (i = 0; i < size; i++) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             // pll
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |             vco[0]  = cos (phs); | 
					
						
							|  |  |  |             vco[1]  = sin (phs); | 
					
						
							|  |  |  |             corr[0] = + in[2 * i + 0] * vco[0] + in[2 * i + 1] * vco[1]; | 
					
						
							|  |  |  |             corr[1] = - in[2 * i + 0] * vco[1] + in[2 * i + 1] * vco[0]; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             if ((corr[0] == 0.0) && (corr[1] == 0.0)) corr[0] = 1.0; | 
					
						
							|  |  |  |             det = atan2 (corr[1], corr[0]); | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |             del_out = fil_out; | 
					
						
							|  |  |  |             omega += g2 * det; | 
					
						
							|  |  |  |             if (omega < omega_min) omega = omega_min; | 
					
						
							|  |  |  |             if (omega > omega_max) omega = omega_max; | 
					
						
							|  |  |  |             fil_out = g1 * det + omega; | 
					
						
							|  |  |  |             phs += del_out; | 
					
						
							|  |  |  |             while (phs >= TWOPI) phs -= TWOPI; | 
					
						
							|  |  |  |             while (phs < 0.0) phs += TWOPI; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             // dc removal, gain, & demod output
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |             fmdc = mtau * fmdc + onem_mtau * fil_out; | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |             audio[2 * i + 0] = (float) (again * (fil_out - fmdc)); | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |             audio[2 * i + 1] = audio[2 * i + 0]; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         // de-emphasis
 | 
					
						
							| 
									
										
										
										
											2024-08-06 06:26:53 +02:00
										 |  |  |         pde->execute(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         // audio filter
 | 
					
						
							| 
									
										
										
										
											2024-08-06 06:26:53 +02:00
										 |  |  |         paud->execute(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         // CTCSS Removal
 | 
					
						
							| 
									
										
										
										
											2024-08-01 00:31:28 +02:00
										 |  |  |         sntch->execute(); | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         if (lim_run) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |             for (i = 0; i < 2 * size; i++) | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |                 out[i] *= (float) lim_pre_gain; | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             plim->execute(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     else if (in != out) | 
					
						
							|  |  |  |         std::copy( in,  in + size * 2, out); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setBuffers(float* _in, float* _out) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     decalc(); | 
					
						
							|  |  |  |     in = _in; | 
					
						
							|  |  |  |     out = _out; | 
					
						
							|  |  |  |     calc(); | 
					
						
							| 
									
										
										
										
											2024-08-06 06:26:53 +02:00
										 |  |  |     pde->setBuffers(audio.data(), out); | 
					
						
							|  |  |  |     paud->setBuffers(out, out); | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     plim->setBuffers(out, out); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setSamplerate(int _rate) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     decalc(); | 
					
						
							|  |  |  |     rate = _rate; | 
					
						
							|  |  |  |     calc(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // de-emphasis filter
 | 
					
						
							| 
									
										
										
										
											2024-08-08 09:09:40 +02:00
										 |  |  |     std::vector<float> impulse(2 * nc_de); | 
					
						
							|  |  |  |     FCurve::fc_impulse ( | 
					
						
							|  |  |  |         impulse, | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |         nc_de, | 
					
						
							|  |  |  |         (float) f_low, | 
					
						
							|  |  |  |         (float) f_high, | 
					
						
							|  |  |  |         (float) (+20.0 * log10(f_high / f_low)), | 
					
						
							|  |  |  |         0.0, | 
					
						
							|  |  |  |         1, | 
					
						
							|  |  |  |         (float) rate, | 
					
						
							|  |  |  |         (float) (1.0 / (2.0 * size)), | 
					
						
							|  |  |  |         0, | 
					
						
							|  |  |  |         0 | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |     pde->setImpulse(impulse, 1); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // audio filter
 | 
					
						
							| 
									
										
										
										
											2024-08-10 06:40:35 +02:00
										 |  |  |     std::vector<float> impulseb; | 
					
						
							|  |  |  |     FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |     paud->setImpulse(impulseb, 1); | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     plim->setSamplerate((int) rate); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setSize(int _size) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     decalc(); | 
					
						
							|  |  |  |     size = _size; | 
					
						
							|  |  |  |     calc(); | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     audio.resize(size * 2); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // de-emphasis filter
 | 
					
						
							| 
									
										
										
										
											2024-08-10 09:59:42 +02:00
										 |  |  |     delete pde; | 
					
						
							| 
									
										
										
										
											2024-08-08 09:09:40 +02:00
										 |  |  |     std::vector<float> impulse(2 * nc_de); | 
					
						
							|  |  |  |     FCurve::fc_impulse ( | 
					
						
							|  |  |  |         impulse, | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |         nc_de, | 
					
						
							|  |  |  |         (float) f_low, | 
					
						
							|  |  |  |         (float) f_high, | 
					
						
							|  |  |  |         (float) (+20.0 * log10(f_high / f_low)), | 
					
						
							|  |  |  |         0.0, | 
					
						
							|  |  |  |         1, | 
					
						
							|  |  |  |         (float) rate, | 
					
						
							|  |  |  |         (float) (1.0 / (2.0 * size)), | 
					
						
							|  |  |  |         0, | 
					
						
							|  |  |  |         0 | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |     pde = new FIRCORE(size, audio.data(), out, mp_de, impulse); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     // audio filter
 | 
					
						
							| 
									
										
										
										
											2024-08-10 09:59:42 +02:00
										 |  |  |     delete paud; | 
					
						
							| 
									
										
										
										
											2024-08-10 06:40:35 +02:00
										 |  |  |     std::vector<float> impulseb; | 
					
						
							|  |  |  |     FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |     paud = new FIRCORE(size, out, out, mp_aud, impulseb); | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     plim->setSize(size); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************************************************
 | 
					
						
							|  |  |  | *                                                                                                       * | 
					
						
							|  |  |  | *                                           RXA Properties                                              * | 
					
						
							|  |  |  | *                                                                                                       * | 
					
						
							|  |  |  | ********************************************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setDeviation(double _deviation) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     deviation = _deviation; | 
					
						
							|  |  |  |     again = rate / (deviation * TWOPI); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setCTCSSFreq(double freq) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     ctcss_freq = freq; | 
					
						
							| 
									
										
										
										
											2024-08-01 00:31:28 +02:00
										 |  |  |     sntch->setFreq(ctcss_freq); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  | void FMD::setCTCSSRun(int _run) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     sntch_run = _run; | 
					
						
							| 
									
										
										
										
											2024-08-01 00:31:28 +02:00
										 |  |  |     sntch->setRun(sntch_run); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setNCde(int nc) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     if (nc_de != nc) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         nc_de = nc; | 
					
						
							| 
									
										
										
										
											2024-08-08 09:09:40 +02:00
										 |  |  |         std::vector<float> impulse(2 * nc_de); | 
					
						
							|  |  |  |         FCurve::fc_impulse ( | 
					
						
							|  |  |  |             impulse, | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |             nc_de, | 
					
						
							|  |  |  |             (float) f_low, | 
					
						
							|  |  |  |             (float) f_high, | 
					
						
							|  |  |  |             (float) (+20.0 * log10(f_high / f_low)), | 
					
						
							|  |  |  |             0.0, | 
					
						
							|  |  |  |             1, | 
					
						
							|  |  |  |             (float) rate, | 
					
						
							|  |  |  |             (float) (1.0 / (2.0 * size)), | 
					
						
							|  |  |  |             0, | 
					
						
							|  |  |  |             0 | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |         pde->setNc(impulse); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setMPde(int mp) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     if (mp_de != mp) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         mp_de = mp; | 
					
						
							| 
									
										
										
										
											2024-08-06 06:26:53 +02:00
										 |  |  |         pde->setMp(mp_de); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setNCaud(int nc) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     if (nc_aud != nc) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         nc_aud = nc; | 
					
						
							| 
									
										
										
										
											2024-08-10 06:40:35 +02:00
										 |  |  |         std::vector<float> impulse; | 
					
						
							|  |  |  |         FIR::fir_bandpass(impulse, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |         paud->setNc(impulse); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setMPaud(int mp) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     if (mp_aud != mp) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         mp_aud = mp; | 
					
						
							| 
									
										
										
										
											2024-08-06 06:26:53 +02:00
										 |  |  |         paud->setMp(mp_aud); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  | void FMD::setLimRun(int _run) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     if (lim_run != _run) { | 
					
						
							|  |  |  |         lim_run = _run; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setLimGain(double gaindB) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-06 03:25:41 +02:00
										 |  |  |     double gain = pow(10.0, gaindB / 20.0); | 
					
						
							| 
									
										
										
										
											2024-07-13 23:59:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     if (lim_gain != gain) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         decalc(); | 
					
						
							|  |  |  |         lim_gain = gain; | 
					
						
							|  |  |  |         calc(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  | void FMD::setAFFilter(double low, double high) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |     if (f_low != low || f_high != high) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-26 19:10:53 +02:00
										 |  |  |         f_low = low; | 
					
						
							|  |  |  |         f_high = high; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         // de-emphasis filter
 | 
					
						
							| 
									
										
										
										
											2024-08-08 09:09:40 +02:00
										 |  |  |         std::vector<float> impulse(2 * nc_de); | 
					
						
							|  |  |  |         FCurve::fc_impulse ( | 
					
						
							|  |  |  |             impulse, | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |             nc_de, | 
					
						
							|  |  |  |             (float) f_low, | 
					
						
							|  |  |  |             (float) f_high, | 
					
						
							|  |  |  |             (float) (+20.0 * log10(f_high / f_low)), | 
					
						
							|  |  |  |             0.0, | 
					
						
							|  |  |  |             1, | 
					
						
							|  |  |  |             (float) rate, | 
					
						
							|  |  |  |             (float) (1.0 / (2.0 * size)), | 
					
						
							|  |  |  |             0, | 
					
						
							|  |  |  |             0 | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |         pde->setImpulse(impulse, 1); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         // audio filter
 | 
					
						
							| 
									
										
										
										
											2024-08-10 06:40:35 +02:00
										 |  |  |         std::vector<float> impulseb; | 
					
						
							|  |  |  |         FIR::fir_bandpass (impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); | 
					
						
							| 
									
										
										
										
											2024-08-10 12:21:04 +02:00
										 |  |  |         paud->setImpulse(impulseb, 1); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace WDSP
 |