1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-21 12:26:34 -04:00
sdrangel/wdsp/TXA.cpp
2024-08-03 13:54:42 +02:00

1030 lines
42 KiB
C++

/* TXA.c
This file is part of a program that implements a Software-Defined Radio.
Copyright (C) 2013, 2014, 2016, 2017, 2021, 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
*/
#include "comm.hpp"
#include "ammod.hpp"
#include "meter.hpp"
#include "resample.hpp"
#include "patchpanel.hpp"
#include "amsq.hpp"
#include "eq.hpp"
#include "cfcomp.hpp"
#include "compress.hpp"
#include "bandpass.hpp"
#include "bps.hpp"
#include "osctrl.hpp"
#include "wcpAGC.hpp"
#include "emph.hpp"
#include "fmmod.hpp"
#include "siphon.hpp"
#include "gen.hpp"
#include "slew.hpp"
#include "iqc.hpp"
#include "cfir.hpp"
#include "fircore.hpp"
#include "phrot.hpp"
#include "fir.hpp"
#include "TXA.hpp"
namespace WDSP {
TXA::TXA(
int _in_rate, // input samplerate
int _out_rate, // output samplerate
int _dsp_rate, // sample rate for mainstream dsp processing
int _dsp_size // number complex samples processed per buffer in mainstream dsp processing
) : Unit(
_in_rate,
_out_rate,
_dsp_rate,
_dsp_size
)
{
mode = TXA_LSB;
f_low = -5000.0;
f_high = - 100.0;
rsmpin = new RESAMPLE(
0, // run - will be turned on below if needed
dsp_insize, // input buffer size
inbuff, // pointer to input buffer
midbuff, // pointer to output buffer
in_rate, // input sample rate
dsp_rate, // output sample rate
0.0, // select cutoff automatically
0, // select ncoef automatically
1.0); // gain
gen0 = new GEN(
0, // run
dsp_size, // buffer size
midbuff, // input buffer
midbuff, // output buffer
dsp_rate, // sample rate
2); // mode
panel = new PANEL(
1, // run
dsp_size, // size
midbuff, // pointer to input buffer
midbuff, // pointer to output buffer
1.0, // gain1
1.0, // gain2I
1.0, // gain2Q
2, // 1 to use Q, 2 to use I for input
0); // 0, no copy
phrot = new PHROT(
0, // run
dsp_size, // size
midbuff, // input buffer
midbuff, // output buffer
dsp_rate, // samplerate
338.0, // 1/2 of phase frequency
8); // number of stages
micmeter = new METER(
1, // run
nullptr, // optional pointer to another 'run'
dsp_size, // size
midbuff, // pointer to buffer
dsp_rate, // samplerate
0.100, // averaging time constant
0.100, // peak decay time constant
meter, // result vector
TXA_MIC_AV, // index for average value
TXA_MIC_PK, // index for peak value
-1, // index for gain value
nullptr); // pointer for gain computation
amsq = new AMSQ(
0, // run
dsp_size, // size
midbuff, // input buffer
midbuff, // output buffer
midbuff, // trigger buffer
dsp_rate, // sample rate
0.010, // time constant for averaging signal
0.004, // up-slew time
0.004, // down-slew time
0.180, // signal level to initiate tail
0.200, // signal level to initiate unmute
0.000, // minimum tail length
0.025, // maximum tail length
0.200); // muted gain
{
std::array<float, 11> default_F = {0.0, 32.0, 63.0, 125.0, 250.0, 500.0, 1000.0, 2000.0, 4000.0, 8000.0, 16000.0};
std::array<float, 11> default_G = {0.0, -12.0, -12.0, -12.0, -1.0, +1.0, +4.0, +9.0, +12.0, -10.0, -10.0};
//float default_G[11] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
eqp = new EQP (
0, // run - OFF by default
dsp_size, // size
std::max(2048, dsp_size), // number of filter coefficients
0, // minimum phase flag
midbuff, // pointer to input buffer
midbuff, // pointer to output buffer
10, // nfreqs
default_F.data(), // vector of frequencies
default_G.data(), // vector of gain values
0, // cutoff mode
0, // wintype
dsp_rate); // samplerate
}
eqmeter = new METER(
1, // run
&(eqp->run), // pointer to eqp 'run'
dsp_size, // size
midbuff, // pointer to buffer
dsp_rate, // samplerate
0.100, // averaging time constant
0.100, // peak decay time constant
meter, // result vector
TXA_EQ_AV, // index for average value
TXA_EQ_PK, // index for peak value
-1, // index for gain value
nullptr); // pointer for gain computation
preemph = EMPHP::create_emphp (
0, // run
1, // position
dsp_size, // size
std::max(2048, dsp_size), // number of filter coefficients
0, // minimum phase flag
midbuff, // input buffer
midbuff, // output buffer,
dsp_rate, // sample rate
0, // pre-emphasis type
300.0, // f_low
3000.0); // f_high
leveler = new WCPAGC(
0, // run - OFF by default
5, // mode
0, // 0 for max(I,Q), 1 for envelope
midbuff, // input buff pointer
midbuff, // output buff pointer
dsp_size, // io_buffsize
dsp_rate, // sample rate
0.001, // tau_attack
0.500, // tau_decay
6, // n_tau
1.778, // max_gain
1.0, // var_gain
1.0, // fixed_gain
1.0, // max_input
1.05, // out_targ
0.250, // tau_fast_backaverage
0.005, // tau_fast_decay
5.0, // pop_ratio
0, // hang_enable
0.500, // tau_hang_backmult
0.500, // hangtime
2.000, // hang_thresh
0.100); // tau_hang_decay
lvlrmeter = new METER(
1, // run
&(leveler->run), // pointer to leveler 'run'
dsp_size, // size
midbuff, // pointer to buffer
dsp_rate, // samplerate
0.100, // averaging time constant
0.100, // peak decay time constant
meter, // result vector
TXA_LVLR_AV, // index for average value
TXA_LVLR_PK, // index for peak value
TXA_LVLR_GAIN, // index for gain value
&leveler->gain); // pointer for gain computation
{
std::array<float, 5> default_F = {200.0, 1000.0, 2000.0, 3000.0, 4000.0};
std::array<float, 5> default_G = { 0.0, 5.0, 10.0, 10.0, 5.0};
std::array<float, 5> default_E = { 7.0, 7.0, 7.0, 7.0, 7.0};
cfcomp = CFCOMP::create_cfcomp(
0, // run
0, // position
0, // post-equalizer run
dsp_size, // size
midbuff, // input buffer
midbuff, // output buffer
2048, // fft size
4, // overlap
dsp_rate, // samplerate
1, // window type
0, // compression method
5, // nfreqs
0.0, // pre-compression
0.0, // pre-postequalization
default_F.data(), // frequency array
default_G.data(), // compression array
default_E.data(), // eq array
0.25, // metering time constant
0.50); // display time constant
}
cfcmeter = new METER(
1, // run
&(cfcomp->run), // pointer to eqp 'run'
dsp_size, // size
midbuff, // pointer to buffer
dsp_rate, // samplerate
0.100, // averaging time constant
0.100, // peak decay time constant
meter, // result vector
TXA_CFC_AV, // index for average value
TXA_CFC_PK, // index for peak value
TXA_CFC_GAIN, // index for gain value
(double*) &cfcomp->gain); // pointer for gain computation
bp0 = new BANDPASS(
1, // always runs
0, // position
dsp_size, // size
std::max(2048, dsp_size), // number of coefficients
0, // flag for minimum phase
midbuff, // pointer to input buffer
midbuff, // pointer to output buffer
f_low, // low freq cutoff
f_high, // high freq cutoff
dsp_rate, // samplerate
1, // wintype
2.0); // gain
compressor = COMPRESSOR::create_compressor (
0, // run - OFF by default
dsp_size, // size
midbuff, // pointer to input buffer
midbuff, // pointer to output buffer
3.0); // gain
bp1 = new BANDPASS(
0, // ONLY RUNS WHEN COMPRESSOR IS USED
0, // position
dsp_size, // size
std::max(2048, dsp_size), // number of coefficients
0, // flag for minimum phase
midbuff, // pointer to input buffer
midbuff, // pointer to output buffer
f_low, // low freq cutoff
f_high, // high freq cutoff
dsp_rate, // samplerate
1, // wintype
2.0); // gain
osctrl = OSCTRL::create_osctrl (
0, // run
dsp_size, // size
midbuff, // input buffer
midbuff, // output buffer
dsp_rate, // sample rate
1.95f); // gain for clippings
bp2 = new BANDPASS(
0, // ONLY RUNS WHEN COMPRESSOR IS USED
0, // position
dsp_size, // size
std::max(2048, dsp_size), // number of coefficients
0, // flag for minimum phase
midbuff, // pointer to input buffer
midbuff, // pointer to output buffer
f_low, // low freq cutoff
f_high, // high freq cutoff
dsp_rate, // samplerate
1, // wintype
1.0); // gain
compmeter = new METER(
1, // run
&(compressor->run), // pointer to compressor 'run'
dsp_size, // size
midbuff, // pointer to buffer
dsp_rate, // samplerate
0.100, // averaging time constant
0.100, // peak decay time constant
meter, // result vector
TXA_COMP_AV, // index for average value
TXA_COMP_PK, // index for peak value
-1, // index for gain value
nullptr); // pointer for gain computation
alc = new WCPAGC(
1, // run - always ON
5, // mode
1, // 0 for max(I,Q), 1 for envelope
midbuff, // input buff pointer
midbuff, // output buff pointer
dsp_size, // io_buffsize
dsp_rate, // sample rate
0.001, // tau_attack
0.010, // tau_decay
6, // n_tau
1.0, // max_gain
1.0, // var_gain
1.0, // fixed_gain
1.0, // max_input
1.0, // out_targ
0.250, // tau_fast_backaverage
0.005, // tau_fast_decay
5.0, // pop_ratio
0, // hang_enable
0.500, // tau_hang_backmult
0.500, // hangtime
2.000, // hang_thresh
0.100); // tau_hang_decay
ammod = AMMOD::create_ammod (
0, // run - OFF by default
0, // mode: 0=>AM, 1=>DSB
dsp_size, // size
midbuff, // pointer to input buffer
midbuff, // pointer to output buffer
0.5); // carrier level
fmmod = FMMOD::create_fmmod (
0, // run - OFF by default
dsp_size, // size
midbuff, // pointer to input buffer
midbuff, // pointer to input buffer
dsp_rate, // samplerate
5000.0, // deviation
300.0, // low cutoff frequency
3000.0, // high cutoff frequency
1, // ctcss run control
0.10f, // ctcss level
100.0, // ctcss frequency
1, // run bandpass filter
std::max(2048, dsp_size), // number coefficients for bandpass filter
0); // minimum phase flag
gen1 = new GEN(
0, // run
dsp_size, // buffer size
midbuff, // input buffer
midbuff, // output buffer
dsp_rate, // sample rate
0); // mode
uslew = USLEW::create_uslew (
this,
&upslew, // pointer to channel upslew flag
dsp_size, // buffer size
midbuff, // input buffer
midbuff, // output buffer
(float) dsp_rate, // sample rate
0.000, // delay time
0.005f); // upslew time
alcmeter = new METER(
1, // run
nullptr, // optional pointer to a 'run'
dsp_size, // size
midbuff, // pointer to buffer
dsp_rate, // samplerate
0.100, // averaging time constant
0.100, // peak decay time constant
meter, // result vector
TXA_ALC_AV, // index for average value
TXA_ALC_PK, // index for peak value
TXA_ALC_GAIN, // index for gain value
&alc->gain); // pointer for gain computation
sip1 = new SIPHON(
1, // run
0, // position
0, // mode
0, // disp
dsp_size, // input buffer size
midbuff, // input buffer
16384, // number of samples to buffer
16384, // fft size for spectrum
1); // specmode
// txa->calcc = create_calcc (
// channel, // channel number
// 1, // run calibration
// 1024, // input buffer size
// in_rate, // samplerate
// 16, // ints
// 256, // spi
// (1.0 / 0.4072), // hw_scale
// 0.1, // mox delay
// 0.0, // loop delay
// 0.8, // ptol
// 0, // mox
// 0, // solidmox
// 1, // pin mode
// 1, // map mode
// 0, // stbl mode
// 256, // pin samples
// 0.9); // alpha
iqc.p0 = iqc.p1 = IQC::create_iqc (
0, // run
dsp_size, // size
midbuff, // input buffer
midbuff, // output buffer
(float)dsp_rate, // sample rate
16, // ints
0.005f, // changeover time
256); // spi
cfir = CFIR::create_cfir(
0, // run
dsp_size, // size
std::max(2048, dsp_size), // number of filter coefficients
0, // minimum phase flag
midbuff, // input buffer
midbuff, // output buffer
dsp_rate, // input sample rate
out_rate, // CIC input sample rate
1, // CIC differential delay
640, // CIC interpolation factor
5, // CIC integrator-comb pairs
20000.0, // cutoff frequency
2, // brick-wall windowed rolloff
0.0, // raised-cosine transition width
0); // window type
rsmpout = new RESAMPLE(
0, // run - will be turned ON below if needed
dsp_size, // input size
midbuff, // pointer to input buffer
outbuff, // pointer to output buffer
dsp_rate, // input sample rate
out_rate, // output sample rate
0.0, // select cutoff automatically
0, // select ncoef automatically
0.980); // gain
outmeter = new METER(
1, // run
nullptr, // optional pointer to another 'run'
dsp_outsize, // size
outbuff, // pointer to buffer
out_rate, // samplerate
0.100, // averaging time constant
0.100, // peak decay time constant
meter, // result vector
TXA_OUT_AV, // index for average value
TXA_OUT_PK, // index for peak value
-1, // index for gain value
nullptr); // pointer for gain computation
// turn OFF / ON resamplers as needed
resCheck();
}
TXA::~TXA()
{
// in reverse order, free each item we created
delete outmeter;
delete rsmpout;
CFIR::destroy_cfir(cfir);
IQC::destroy_iqc (iqc.p0);
delete sip1;
delete alcmeter;
USLEW::destroy_uslew (uslew);
delete gen1;
FMMOD::destroy_fmmod (fmmod);
AMMOD::destroy_ammod (ammod);
delete alc;
delete compmeter;
delete bp2;
OSCTRL::destroy_osctrl (osctrl);
delete bp1;
COMPRESSOR::destroy_compressor (compressor);
delete bp0;
delete cfcmeter;
CFCOMP::destroy_cfcomp (cfcomp);
delete lvlrmeter;
delete leveler;
EMPHP::destroy_emphp (preemph);
delete eqmeter;
delete eqp;
delete amsq;
delete micmeter;
delete phrot;
delete panel;
delete gen0;
delete rsmpin;
}
void TXA::flush()
{
Unit::flushBuffers();
rsmpin->flush();
gen0->flush();
panel->flush ();
phrot->flush();
micmeter->flush ();
amsq->flush ();
eqp->flush();
eqmeter->flush ();
EMPHP::flush_emphp (preemph);
leveler->flush();
lvlrmeter->flush ();
CFCOMP::flush_cfcomp (cfcomp);
cfcmeter->flush ();
bp0->flush ();
COMPRESSOR::flush_compressor (compressor);
bp1->flush ();
OSCTRL::flush_osctrl (osctrl);
bp2->flush ();
compmeter->flush ();
alc->flush ();
AMMOD::flush_ammod (ammod);
FMMOD::flush_fmmod (fmmod);
gen1->flush();
USLEW::flush_uslew (uslew);
alcmeter->flush ();
sip1->flush();
IQC::flush_iqc (iqc.p0);
CFIR::flush_cfir(cfir);
rsmpout->flush();
outmeter->flush ();
}
void TXA::execute()
{
rsmpin->execute(); // input resampler
gen0->execute(); // input signal generator
panel->execute(); // includes MIC gain
phrot->execute(); // phase rotator
micmeter->execute (); // MIC meter
amsq->xcap (); // downward expander capture
amsq->execute (); // downward expander action
eqp->execute (); // pre-EQ
eqmeter->execute (); // EQ meter
EMPHP::xemphp (preemph, 0); // FM pre-emphasis (first option)
leveler->execute (); // Leveler
lvlrmeter->execute (); // Leveler Meter
CFCOMP::xcfcomp (cfcomp, 0); // Continuous Frequency Compressor with post-EQ
cfcmeter->execute (); // CFC+PostEQ Meter
bp0->execute (0); // primary bandpass filter
COMPRESSOR::xcompressor (compressor); // COMP compressor
bp1->execute (0); // aux bandpass (runs if COMP)
OSCTRL::xosctrl (osctrl); // CESSB Overshoot Control
bp2->execute (0); // aux bandpass (runs if CESSB)
compmeter->execute (); // COMP meter
alc->execute (); // ALC
AMMOD::xammod (ammod); // AM Modulator
EMPHP::xemphp (preemph, 1); // FM pre-emphasis (second option)
FMMOD::xfmmod (fmmod); // FM Modulator
gen1->execute(); // output signal generator (TUN and Two-tone)
USLEW::xuslew (uslew); // up-slew for AM, FM, and gens
alcmeter->execute (); // ALC Meter
sip1->execute(0); // siphon data for display
IQC::xiqc (iqc.p0); // PureSignal correction
CFIR::xcfir(cfir); // compensating FIR filter (used Protocol_2 only)
rsmpout->execute(); // output resampler
outmeter->execute (); // output meter
}
void TXA::setInputSamplerate(int in_rate)
{
Unit::setBuffersInputSamplerate(in_rate);
// input resampler
rsmpin->setBuffers(inbuff, midbuff);
rsmpin->setSize(dsp_insize);
rsmpin->setInRate(in_rate);
resCheck();
}
void TXA::setOutputSamplerate(int out_rate)
{
Unit::setBuffersOutputSamplerate(out_rate);
// cfir - needs to know input rate of firmware CIC
CFIR::setOutRate_cfir (cfir, out_rate);
// output resampler
rsmpout->setBuffers(midbuff, outbuff);
rsmpout->setOutRate(out_rate);
resCheck();
// output meter
outmeter->setBuffers(outbuff);
outmeter->setSize(dsp_outsize);
outmeter->setSamplerate (out_rate);
}
void TXA::setDSPSamplerate(int dsp_rate)
{
Unit::setBuffersDSPSamplerate(dsp_rate);
// input resampler
rsmpin->setBuffers(inbuff, midbuff);
rsmpin->setSize(dsp_insize);
rsmpin->setOutRate(dsp_rate);
// dsp_rate blocks
gen0->setSamplerate(dsp_rate);
panel->setSamplerate(dsp_rate);
phrot->setSamplerate(dsp_rate);
micmeter->setSamplerate (dsp_rate);
amsq->setSamplerate (dsp_rate);
eqp->setSamplerate (dsp_rate);
eqmeter->setSamplerate (dsp_rate);
EMPHP::setSamplerate_emphp (preemph, dsp_rate);
leveler->setSamplerate (dsp_rate);
lvlrmeter->setSamplerate (dsp_rate);
CFCOMP::setSamplerate_cfcomp (cfcomp, dsp_rate);
cfcmeter->setSamplerate (dsp_rate);
bp0->setSamplerate (dsp_rate);
COMPRESSOR::setSamplerate_compressor (compressor, dsp_rate);
bp1->setSamplerate (dsp_rate);
OSCTRL::setSamplerate_osctrl (osctrl, dsp_rate);
bp2->setSamplerate (dsp_rate);
compmeter->setSamplerate (dsp_rate);
alc->setSamplerate (dsp_rate);
AMMOD::setSamplerate_ammod (ammod, dsp_rate);
FMMOD::setSamplerate_fmmod (fmmod, dsp_rate);
gen1->setSamplerate(dsp_rate);
USLEW::setSamplerate_uslew (uslew, dsp_rate);
alcmeter->setSamplerate (dsp_rate);
sip1->setSamplerate (dsp_rate);
IQC::setSamplerate_iqc (iqc.p0, dsp_rate);
CFIR::setSamplerate_cfir (cfir, dsp_rate);
// output resampler
rsmpout->setBuffers(midbuff, outbuff);
rsmpout->setInRate(dsp_rate);
resCheck();
// output meter
outmeter->setBuffers(outbuff);
outmeter->setSize (dsp_outsize);
}
void TXA::setDSPBuffsize(int dsp_size)
{
Unit::setBuffersDSPBuffsize(dsp_size);
// input resampler
rsmpin->setBuffers(inbuff, midbuff);
rsmpin->setSize(dsp_insize);
// dsp_size blocks
gen0->setBuffers(midbuff, midbuff);
gen0->setSize(dsp_size);
panel->setBuffers(midbuff, midbuff);
panel->setSize(dsp_size);
phrot->setBuffers(midbuff, midbuff);
phrot->setSize(dsp_size);
micmeter->setBuffers (midbuff);
micmeter->setSize (dsp_size);
amsq->setBuffers (midbuff, midbuff, midbuff);
amsq->setSize (dsp_size);
eqp->setBuffers (midbuff, midbuff);
eqp->setSize (dsp_size);
eqmeter->setBuffers (midbuff);
eqmeter->setSize (dsp_size);
EMPHP::setBuffers_emphp (preemph, midbuff, midbuff);
EMPHP::setSize_emphp (preemph, dsp_size);
leveler->setBuffers(midbuff, midbuff);
leveler->setSize(dsp_size);
lvlrmeter->setBuffers(midbuff);
lvlrmeter->setSize(dsp_size);
CFCOMP::setBuffers_cfcomp (cfcomp, midbuff, midbuff);
CFCOMP::setSize_cfcomp (cfcomp, dsp_size);
cfcmeter->setBuffers(midbuff);
cfcmeter->setSize(dsp_size);
bp0->setBuffers (midbuff, midbuff);
bp0->setSize (dsp_size);
COMPRESSOR::setBuffers_compressor (compressor, midbuff, midbuff);
COMPRESSOR::setSize_compressor (compressor, dsp_size);
bp1->setBuffers (midbuff, midbuff);
bp1->setSize (dsp_size);
OSCTRL::setBuffers_osctrl (osctrl, midbuff, midbuff);
OSCTRL::setSize_osctrl (osctrl, dsp_size);
bp2->setBuffers (midbuff, midbuff);
bp2->setSize (dsp_size);
compmeter->setBuffers(midbuff);
compmeter->setSize(dsp_size);
alc->setBuffers(midbuff, midbuff);
alc->setSize( dsp_size);
AMMOD::setBuffers_ammod (ammod, midbuff, midbuff);
AMMOD::setSize_ammod (ammod, dsp_size);
FMMOD::setBuffers_fmmod (fmmod, midbuff, midbuff);
FMMOD::setSize_fmmod (fmmod, dsp_size);
gen1->setBuffers(midbuff, midbuff);
gen1->setSize(dsp_size);
USLEW::setBuffers_uslew (uslew, midbuff, midbuff);
USLEW::setSize_uslew (uslew, dsp_size);
alcmeter->setBuffers (midbuff);
alcmeter->setSize(dsp_size);
sip1->setBuffers (midbuff);
sip1->setSize (dsp_size);
IQC::setBuffers_iqc (iqc.p0, midbuff, midbuff);
IQC::setSize_iqc (iqc.p0, dsp_size);
CFIR::setBuffers_cfir (cfir, midbuff, midbuff);
CFIR::setSize_cfir (cfir, dsp_size);
// output resampler
rsmpout->setBuffers(midbuff, outbuff);
rsmpout->setSize(dsp_size);
// output meter
outmeter->setBuffers(outbuff);
outmeter->setSize(dsp_outsize);
}
/********************************************************************************************************
* *
* TXA Properties *
* *
********************************************************************************************************/
void TXA::setMode(int _mode)
{
if (mode != _mode)
{
mode = _mode;
ammod->run = 0;
fmmod->run = 0;
preemph->run = 0;
switch (_mode)
{
case TXA_AM:
case TXA_SAM:
ammod->run = 1;
ammod->mode = 0;
break;
case TXA_DSB:
ammod->run = 1;
ammod->mode = 1;
break;
case TXA_AM_LSB:
case TXA_AM_USB:
ammod->run = 1;
ammod->mode = 2;
break;
case TXA_FM:
fmmod->run = 1;
preemph->run = 1;
break;
default:
break;
}
setupBPFilters();
}
}
void TXA::setBandpassFreqs(float _f_low, float _f_high)
{
if ((f_low != _f_low) || (f_high != _f_high))
{
f_low = _f_low;
f_high = _f_high;
setupBPFilters();
}
}
/********************************************************************************************************
* *
* TXA Internal Functions *
* *
********************************************************************************************************/
void TXA::resCheck()
{
RESAMPLE *a = rsmpin;
if (in_rate != dsp_rate)
a->run = 1;
else
a->run = 0;
a = rsmpout;
if (dsp_rate != out_rate)
a->run = 1;
else
a->run = 0;
}
int TXA::uslewCheck()
{
return (ammod->run == 1) ||
(fmmod->run == 1) ||
(gen0->run == 1) ||
(gen1->run == 1);
}
void TXA::setupBPFilters()
{
bp0->run = 1;
bp1->run = 0;
bp2->run = 0;
switch (mode)
{
case TXA_LSB:
case TXA_USB:
case TXA_CWL:
case TXA_CWU:
case TXA_DIGL:
case TXA_DIGU:
case TXA_SPEC:
case TXA_DRM:
bp0->calcBandpassFilter (f_low, f_high, 2.0);
if (compressor->run)
{
bp1->calcBandpassFilter (f_low, f_high, 2.0);
bp1->run = 1;
if (osctrl->run)
{
bp2->calcBandpassFilter (f_low, f_high, 1.0);
bp2->run = 1;
}
}
break;
case TXA_DSB:
case TXA_AM:
case TXA_SAM:
case TXA_FM:
if (compressor->run)
{
bp0->calcBandpassFilter (0.0, f_high, 2.0);
bp1->calcBandpassFilter (0.0, f_high, 2.0);
bp1->run = 1;
if (osctrl->run)
{
bp2->calcBandpassFilter (0.0, f_high, 1.0);
bp2->run = 1;
}
}
else
{
bp0->calcBandpassFilter (f_low, f_high, 1.0);
}
break;
case TXA_AM_LSB:
bp0->calcBandpassFilter (-f_high, 0.0, 2.0);
if (compressor->run)
{
bp1->calcBandpassFilter (-f_high, 0.0, 2.0);
bp1->run = 1;
if (osctrl->run)
{
bp2->calcBandpassFilter (-f_high, 0.0, 1.0);
bp2->run = 1;
}
}
break;
case TXA_AM_USB:
bp0->calcBandpassFilter (0.0, f_high, 2.0);
if (compressor->run)
{
bp1->calcBandpassFilter (0.0, f_high, 2.0);
bp1->run = 1;
if (osctrl->run)
{
bp2->calcBandpassFilter(0.0, f_high, 1.0);
bp2->run = 1;
}
}
break;
default:
break;
}
}
void TXA::setBandpassNC(int _nc)
{
// NOTE: 'nc' must be >= 'size'
BANDPASS *a;
a = bp0;
if (a->nc != _nc)
{
a->nc = _nc;
float* impulse = FIR::fir_bandpass (
a->nc,
a->f_low,
a->f_high,
a->samplerate,
a->wintype,
1,
a->gain / (double)(2 * a->size)
);
FIRCORE::setNc_fircore (a->fircore, a->nc, impulse);
delete[] impulse;
}
a = bp1;
if (a->nc != _nc)
{
a->nc = _nc;
float* impulse = FIR::fir_bandpass (
a->nc,
a->f_low,
a->f_high,
a->samplerate,
a->wintype,
1,
a->gain / (double)(2 * a->size)
);
FIRCORE::setNc_fircore (a->fircore, a->nc, impulse);
delete[] impulse;
}
a = bp2;
if (a->nc != _nc)
{
a->nc = _nc;
float* impulse = FIR::fir_bandpass (
a->nc,
a->f_low,
a->f_high,
a->samplerate,
a->wintype,
1,
a->gain / (double)(2 * a->size)
);
FIRCORE::setNc_fircore (a->fircore, a->nc, impulse);
delete[] impulse;
}
}
void TXA::setBandpassMP(int _mp)
{
BANDPASS *a;
a = bp0;
if (_mp != a->mp)
{
a->mp = _mp;
FIRCORE::setMp_fircore (a->fircore, a->mp);
}
a = bp1;
if (_mp != a->mp)
{
a->mp = _mp;
FIRCORE::setMp_fircore (a->fircore, a->mp);
}
a = bp2;
if (_mp != a->mp)
{
a->mp = _mp;
FIRCORE::setMp_fircore (a->fircore, a->mp);
}
}
/********************************************************************************************************
* *
* Collectives *
* *
********************************************************************************************************/
void TXA::setNC(int _nc)
{
int oldstate = state;
setBandpassNC (_nc);
EMPHP::SetFMEmphNC (*this, _nc);
eqp->setNC (_nc);
FMMOD::SetFMNC (*this, _nc);
CFIR::SetCFIRNC (*this, _nc);
state = oldstate;
}
void TXA::setMP(int _mp)
{
setBandpassMP (_mp);
EMPHP::SetFMEmphMP (*this, _mp);
eqp->setMP (_mp);
FMMOD::SetFMMP (*this, _mp);
}
void TXA::setFMAFFilter(float _low, float _high)
{
EMPHP::SetFMPreEmphFreqs (*this, _low, _high);
FMMOD::SetFMAFFreqs (*this, _low, _high);
}
} // namespace WDSP