PowerSDR-2.8.0-SDR1000/Source/Console/dsp.cs

2254 lines
56 KiB
C#

//=================================================================
// dsp.cs
//=================================================================
// PowerSDR is a C# implementation of a Software Defined Radio.
// Copyright (C) 2003-2013 FlexRadio Systems
//
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// You may contact us via email at: gpl@flexradio.com.
// Paper mail may be sent to:
// FlexRadio Systems
// 4616 W. Howard Lane Suite 1-150
// Austin, TX 78728
// USA
//=================================================================
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Globalization;
using System.IO;
using System.IO.Ports;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Text;
using System.Windows.Forms;
namespace PowerSDR
{
#region DSP Class
public class DSP
{
private const int NUM_RX_THREADS = 2;
private const int NUM_RX_PER_THREAD = 2;
private DSPRX[][] dsp_rx;
private DSPTX[] dsp_tx;
public DSP()
{
Debug.WriteLine("DSP HERE==========================");
CreateDSP();
Thread.Sleep(100);
DttSP.ReleaseUpdate();
dsp_rx = new DSPRX[NUM_RX_THREADS][];
for(int i=0; i<NUM_RX_THREADS; i++)
{
dsp_rx[i] = new DSPRX[NUM_RX_PER_THREAD];
for(int j=0; j<NUM_RX_PER_THREAD; j++)
dsp_rx[i][j] = new DSPRX((uint)i*2, (uint)j);
}
dsp_tx = new DSPTX[1];
dsp_tx[0] = new DSPTX(1);
dsp_rx[0][0].Active = true; // enable main RX
//dsp_tx[0].Active = true; // enable main TX
// set for half duplex
DttSP.SetThreadProcessingMode(0,2);
DttSP.SetThreadProcessingMode(1,1);
}
public DSPRX GetDSPRX(int thread, int subrx)
{
return dsp_rx[thread][subrx];
}
public DSPTX GetDSPTX(int thread)
{
return dsp_tx[thread];
}
public static void SyncStatic() // ke9ns: called from setup
{
DSP.SampleRate = DSP.SampleRate; //double sample_rate
}
public static void SyncHiRes(int hires1) // ke9ns: called from setup (hires)
{
hires = hires1;
DSP.HiResPan = DSP.HiResPan;
// Debug.WriteLine("SyncHIRes HERE " + hires);
}
#region Static Properties and Routines
public void CreateDSP()
{
System.String app_data_path = "";
Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
System.String version = fvi.FileVersion.Substring(0, fvi.FileVersion.LastIndexOf("."));
app_data_path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
+ "\\FlexRadio Systems\\PowerSDR v" + version + "\\wisdom";
DttSP.SetupSDR(app_data_path);
}
public static void DestroyDSP()
{
DttSP.Exit();
}
private static double sample_rate = 48000.0;
public static double SampleRate
{
get { return sample_rate; }
set
{
sample_rate = value;
DttSP.SetSampleRate(value);
}
}
// ke9ns add
private static int hires = 4096;
public static int HiResPan
{
get { return hires; }
set
{
hires = value;
DttSP.SetHiResPan(value);
}
}
public static void SetThreadNumber(uint num)
{
DttSP.SetThreadNo(num);
// Debug.WriteLine("THREAD NUMBER ======================" + num);
}
public static void SetThreadCom(uint num)
{
DttSP.SetThreadCom(num);
}
#endregion
}
#endregion
#region DSPRX Class
public class DSPRX
{
private uint thread;
private uint subrx;
//=====================================================================================
public DSPRX(uint t, uint rx)
{
thread = t;
subrx = rx;
DttSP.SetTRX(t, false);
}
//=====================================================================================
public void Copy(DSPRX rx)
{
this.AudioSize = rx.audio_size;
this.DSPMode = rx.dsp_mode;
this.SetRXFilter(rx.rx_filter_low, rx.rx_filter_high);
this.NoiseReduction = rx.noise_reduction;
this.SetNRVals(rx.nr_taps, rx.nr_delay, rx.nr_gain, rx.nr_leak);
this.AutoNotchFilter = rx.auto_notch_filter;
this.SetANFVals(rx.anf_taps, rx.anf_delay, rx.anf_gain, rx.anf_leak);
this.RXAGCMode = rx.rx_agc_mode;
this.RXEQNumBands = rx_eq_num_bands;
if (this.rx_eq_num_bands == 3)
{
this.RXEQ10 = rx.rx_eq10;
this.RXEQ3 = rx.rx_eq3;
}
else
{
this.RXEQ3 = rx.rx_eq3;
this.RXEQ10 = rx.rx_eq10;
}
this.RXEQOn = rx.rx_eq_on;
this.NBOn = rx.nb_on;
this.NBThreshold = rx.nb_threshold;
this.RXCorrectIQMu = rx.rx_correct_iq_mu;
this.SDROM = rx.sdrom;
this.SDROMThreshold = rx.sdrom_threshold;
this.RXFixedAGC = rx.rx_fixed_agc;
this.RXAGCMaxGain = rx.rx_agc_max_gain;
this.RXAGCAttack = rx.rx_agc_attack;
this.RXAGCDecay = rx.rx_agc_decay;
this.RXAGCHang = rx.rx_agc_hang;
this.RXOutputGain = rx.rx_output_gain;
this.RXAGCSlope = rx.rx_agc_slope;
this.RXAGCHangThreshold = rx.rx_agc_hang_threshold;
this.CurrentWindow = rx.current_window;
this.SpectrumPolyphase = rx.spectrum_polyphase;
this.BinOn = rx.bin_on;
this.RXSquelchThreshold = rx.rx_squelch_threshold;
this.FMSquelchThreshold = rx.fm_squelch_threshold;
this.RXSquelchOn = rx.rx_squelch_on;
this.SpectrumPreFilter = rx.spectrum_pre_filter;
this.Active = rx.active;
this.Pan = rx.pan;
this.RXOsc = rx.rx_osc;
this.DCBlock = rx.dc_block;
this.RXFMDeviation = rx.rx_fm_deviation;
} // copy(DSPRX )
//=====================================================================================
private void SyncAll()
{
//BufferSize = buffer_size;
SetRXCorrectIQW(rx_correct_iq_w_real, rx_correct_iq_w_imag);
AudioSize = audio_size;
DSPMode = dsp_mode;
SetRXFilter(rx_filter_low, rx_filter_high);
NoiseReduction = noise_reduction;
SetNRVals(nr_taps, nr_delay, nr_gain, nr_leak);
AutoNotchFilter = auto_notch_filter;
SetANFVals(anf_taps, anf_delay, anf_gain, anf_leak);
RXAGCMode = rx_agc_mode;
if(rx_eq_num_bands == 3)
{
RXEQ10 = rx_eq10;
RXEQ3 = rx_eq3;
}
else
{
RXEQ3 = rx_eq3;
RXEQ10 = rx_eq10;
}
RXEQOn = rx_eq_on;
NBOn = nb_on;
NBThreshold = nb_threshold;
RXCorrectIQMu = rx_correct_iq_mu;
SDROM = sdrom;
SDROMThreshold = sdrom_threshold;
RXFixedAGC = rx_fixed_agc;
RXAGCMaxGain = rx_agc_max_gain;
RXAGCAttack = rx_agc_attack;
RXAGCDecay = rx_agc_decay;
RXAGCHang = rx_agc_hang;
RXOutputGain = rx_output_gain;
RXAGCSlope = rx_agc_slope;
RXAGCHangThreshold = rx_agc_hang_threshold;
CurrentWindow = current_window;
SpectrumPolyphase = spectrum_polyphase;
BinOn = bin_on;
RXSquelchThreshold = rx_squelch_threshold;
RXSquelchOn = rx_squelch_on;
FMSquelchThreshold = fm_squelch_threshold;
SpectrumPreFilter = spectrum_pre_filter;
Active = active;
Pan = pan;
RXOsc = rx_osc;
DCBlock = dc_block;
RXFMDeviation = rx_fm_deviation;
for (uint i = 0; i < 9; i++)
SetNotchOn(i, notch_on[i]);
}
#region Non-Static Properties & Routines
//=====================================================================================
/// <summary>
/// Controls whether updates to following properties call the DSP.
/// Each property uses this value and a copy of the last thing sent to
/// the DSP to update in a minimal fashion.
/// </summary>
private bool update = false;
public bool Update
{
get { return update; }
set
{
update = value;
if(value) SyncAll();
}
}
//=====================================================================================
/// <summary>
/// Used to force properties to update even if the DSP copy matches the
/// new setting. Mainly used to resync the DSP after having to rebuild
/// when resetting DSP Block Size or Sample Rate.
/// </summary>
private bool force = false;
public bool Force
{
get { return force; }
set { force = value; }
}
//================================================================================= DSPRX Class
private int buffer_size_dsp = 2048;
private int buffer_size = 2048;
public int BufferSize
{
get { return buffer_size; }
set
{
buffer_size = value;
if(update)
{
if(value != buffer_size_dsp || force)
{
//Debug.WriteLine("RX "+thread+":"+subrx+" "+value);
DttSP.ResizeSDR(thread, value); // ke9ns calls setdspbuflen in update.c
buffer_size_dsp = value;
//SyncAll();
}
}
}
} // buffersize
//=====================================================================================
private int audio_size_dsp = 2048;
private int audio_size = 2048;
public int AudioSize
{
get { return audio_size; }
set
{
audio_size = value;
if(update)
{
if(value != audio_size_dsp || force)
{
DttSP.SetAudioSize(value);
audio_size_dsp = value;
}
}
}
}
//=====================================================================================
private DSPMode dsp_mode_dsp = DSPMode.USB;
private DSPMode dsp_mode = DSPMode.USB;
public DSPMode DSPMode
{
get { return dsp_mode; }
set
{
dsp_mode = value;
if(update)
{
if(value != dsp_mode_dsp || force)
{
DttSP.SetMode(thread, subrx, value);
dsp_mode_dsp = value;
}
}
}
}
//=====================================================================================
public void SetRXFilter(int low, int high)
{
//Debug.WriteLine("SetRXFilter[" + thread + "][" + subrx + " ](" + low + ", " + high + ") ");
rx_filter_low = low;
rx_filter_high = high;
if(update)
{
if(low != rx_filter_low_dsp || high != rx_filter_high_dsp || force)
{
DttSP.SetRXFilter(thread, subrx, low, high);
rx_filter_low_dsp = low;
rx_filter_high_dsp = high;
}
}
}
//=====================================================================================
private int rx_filter_low_dsp;
private int rx_filter_low;
public int RXFilterLow
{
get { return rx_filter_low; }
set
{
rx_filter_low = value;
if(update)
{
if(value != rx_filter_low_dsp || force)
{
DttSP.SetRXFilter(thread, subrx, value, rx_filter_high);
rx_filter_low_dsp = value;
}
}
}
}
//=====================================================================================
private int rx_filter_high_dsp;
private int rx_filter_high;
public int RXFilterHigh
{
get { return rx_filter_high; }
set
{
rx_filter_high = value;
if(update)
{
if(value != rx_filter_high_dsp || force)
{
DttSP.SetRXFilter(thread, subrx, rx_filter_low, value);
rx_filter_high_dsp = value;
}
}
}
}
//=====================================================================================
private bool noise_reduction_dsp = false;
private bool noise_reduction = false;
public bool NoiseReduction
{
get { return noise_reduction; }
set
{
noise_reduction = value;
if(update)
{
if(value != noise_reduction_dsp || force)
{
DttSP.SetNR(thread, subrx, value);
noise_reduction_dsp = value;
}
}
}
}
//=====================================================================================
private int nr_taps_dsp = 64;
private int nr_taps = 64;
private int nr_delay_dsp = 64;
private int nr_delay = 64;
private double nr_gain_dsp = 16e-4;
private double nr_gain = 16e-4;
private double nr_leak_dsp = 10e-7;
private double nr_leak = 10e-7;
public void SetNRVals(int taps, int delay, double gain, double leak)
{
nr_taps = taps;
nr_delay = delay;
nr_gain = gain;
nr_leak = leak;
if(update)
{
if(taps != nr_taps_dsp || delay != nr_delay_dsp ||
gain != nr_gain_dsp || leak != nr_leak_dsp || force)
{
DttSP.SetNRvals(thread, subrx, taps, delay, gain, leak);
nr_taps_dsp = taps;
nr_delay_dsp = delay;
nr_gain_dsp = gain;
nr_leak_dsp = leak;
}
}
}
private bool auto_notch_filter_dsp = false;
private bool auto_notch_filter = false;
public bool AutoNotchFilter
{
get { return auto_notch_filter; }
set
{
auto_notch_filter = value;
if(update)
{
if(value != auto_notch_filter_dsp || force)
{
DttSP.SetANF(thread, subrx, value);
auto_notch_filter_dsp = value;
}
}
}
}
//=====================================================================================
private int anf_taps_dsp = 64;
private int anf_taps = 64;
private int anf_delay_dsp = 64;
private int anf_delay = 64;
private double anf_gain_dsp = 10e-4;
private double anf_gain = 10e-4;
private double anf_leak_dsp = 1e-7;
private double anf_leak = 1e-7;
public void SetANFVals(int taps, int delay, double gain, double leak)
{
anf_taps = taps;
anf_delay = delay;
anf_gain = gain;
anf_leak = leak;
if(update)
{
if(taps != anf_taps_dsp || delay != anf_delay_dsp ||
gain != anf_gain_dsp || leak != anf_leak_dsp || force)
{
DttSP.SetANFvals(thread, subrx, taps, delay, gain, leak);
anf_taps_dsp = taps;
anf_delay_dsp = delay;
anf_gain_dsp = gain;
anf_leak_dsp = leak;
}
}
}
//=====================================================================================
private AGCMode rx_agc_mode_dsp = AGCMode.MED;
private AGCMode rx_agc_mode = AGCMode.MED;
public AGCMode RXAGCMode
{
get { return rx_agc_mode; }
set
{
rx_agc_mode = value;
switch(rx_agc_mode)
{
case AGCMode.LONG:
rx_agc_attack = rx_agc_attack_dsp = 2;
rx_agc_hang = rx_agc_hang_dsp = 750;
rx_agc_decay = rx_agc_decay_dsp = 2000;
break;
case AGCMode.SLOW:
rx_agc_attack = rx_agc_attack_dsp = 2;
rx_agc_hang = rx_agc_hang_dsp = 500;
rx_agc_decay = rx_agc_decay_dsp = 500;
break;
case AGCMode.MED:
rx_agc_attack = rx_agc_attack_dsp = 2;
rx_agc_hang = rx_agc_hang_dsp = 250;
rx_agc_decay = rx_agc_decay_dsp = 250;
break;
case AGCMode.FAST:
rx_agc_attack = rx_agc_attack_dsp = 2;
rx_agc_hang = rx_agc_hang_dsp = 100;
rx_agc_decay = rx_agc_decay_dsp = 100;
break;
}
if(update)
{
if(value != rx_agc_mode_dsp || force)
{
DttSP.SetRXAGC(thread, subrx, value);
rx_agc_mode_dsp = value;
}
}
}
}
//=====================================================================================
private int rx_eq_num_bands = 3;
public int RXEQNumBands
{
get { return rx_eq_num_bands; }
set { rx_eq_num_bands = value; }
}
//=====================================================================================
private int[] rx_eq3_dsp = new int[4];
private int[] rx_eq3 = new int[4];
public int[] RXEQ3
{
get { return rx_eq3; }
set
{
for(int i=0; i<rx_eq3.Length && i<value.Length; i++)
rx_eq3[i] = value[i];
if(update)
{
/*bool need_update = false;
for(int i=0; i<rx_eq3_dsp.Length && i<value.Length; i++)
{
if(value[i] != rx_eq3_dsp[i] || force)
{
need_update = true;
break;
}
}
if(need_update)
{*/
DttSP.SetGrphRXEQ(thread, subrx, rx_eq3);
for(int i=0; i<rx_eq3_dsp.Length && i<value.Length; i++)
rx_eq3_dsp[i] = value[i];
//}
}
}
}
//=====================================================================================
private int[] rx_eq10_dsp = new int[11];
private int[] rx_eq10 = new int[11];
public int[] RXEQ10
{
get { return rx_eq10; }
set
{
for(int i=0; i<rx_eq10.Length && i<value.Length; i++)
rx_eq10[i] = value[i];
if(update)
{
/*bool need_update = false;
for(int i=0; i<rx_eq10_dsp.Length && i<value.Length; i++)
{
if(value[i] != rx_eq10_dsp[i] || force)
{
need_update = true;
break;
}
}
if(need_update)
{*/
DttSP.SetGrphRXEQ10(thread, subrx, rx_eq10);
for(int i=0; i<rx_eq10_dsp.Length && i<value.Length; i++)
rx_eq10_dsp[i] = value[i];
//}
}
}
}
//=====================================================================================
private bool rx_eq_on_dsp = false;
private bool rx_eq_on = false;
public bool RXEQOn
{
get { return rx_eq_on; }
set
{
rx_eq_on = value;
if(update)
{
if(value != rx_eq_on_dsp || force)
{
DttSP.SetGrphRXEQcmd(thread, subrx, value);
rx_eq_on_dsp = value;
}
}
}
}
//=====================================================================================
private bool nb_on_dsp = false;
private bool nb_on = false;
public bool NBOn
{
get { return nb_on; }
set
{
nb_on = value;
if(update)
{
if(value != nb_on_dsp || force)
{
DttSP.SetNB(thread, subrx, value);
nb_on_dsp = value;
}
}
}
}
//=====================================================================================
private double nb_threshold_dsp = 3.3;
private double nb_threshold = 3.3;
public double NBThreshold
{
get { return nb_threshold; }
set
{
nb_threshold = value;
if(update)
{
if(value != nb_threshold_dsp || force)
{
DttSP.SetNBvals(thread, subrx, value);
nb_threshold_dsp = value;
}
}
}
}
//=====================================================================================
private float rx_correct_iq_w_real_dsp = 0.0f;
private float rx_correct_iq_w_real = 0.0f;
public float RXCorrectIQWReal
{
get { return rx_correct_iq_w_real; }
}
//=====================================================================================
private float rx_correct_iq_w_imag_dsp = 0.0f;
private float rx_correct_iq_w_imag = 0.0f;
public float RXCorrectIQWImag
{
get { return rx_correct_iq_w_imag; }
}
//=====================================================================================
public void SetRXCorrectIQW(float real, float imag)
{
//Debug.WriteLine("RX IQ Gain "+thread+" "+subrx+": "+value.ToString("f4"));
rx_correct_iq_w_real = real;
rx_correct_iq_w_imag = imag;
if(update)
{
if((real != rx_correct_iq_w_real_dsp) ||
(imag != rx_correct_iq_w_imag_dsp) || force)
{
DttSP.SetCorrectRXIQw(thread, subrx, real, imag, 0);
rx_correct_iq_w_real_dsp = real;
rx_correct_iq_w_imag_dsp = imag;
}
}
}
//=====================================================================================
private double rx_correct_iq_mu_dsp = 0.005;
private double rx_correct_iq_mu = 0.005;
public double RXCorrectIQMu
{
get { return rx_correct_iq_mu; }
set
{
//Debug.WriteLine("RX WBIR Mu "+thread+" "+subrx+": "+value.ToString("f4"));
rx_correct_iq_mu = value;
if(update)
{
if(value != rx_correct_iq_mu_dsp || force)
{
DttSP.SetCorrectIQMu(thread, subrx, value);
rx_correct_iq_mu_dsp = value;
}
}
}
}
//=====================================================================================
private bool sdrom_dsp = false;
private bool sdrom = false;
public bool SDROM
{
get { return sdrom; }
set
{
sdrom = value;
if(update)
{
if(value != sdrom_dsp || force)
{
DttSP.SetSDROM(thread, subrx, value);
sdrom_dsp = value;
}
}
}
}
//=====================================================================================
private double sdrom_threshold_dsp = 2.475;
private double sdrom_threshold = 2.475;
public double SDROMThreshold
{
get { return sdrom_threshold; }
set
{
sdrom_threshold = value;
if(update)
{
if(value != sdrom_threshold_dsp || force)
{
DttSP.SetSDROMvals(thread, subrx, value);
sdrom_threshold_dsp = value;
}
}
}
}
//=====================================================================================
private double rx_fixed_agc_dsp = 20.0;
private double rx_fixed_agc = 20.0;
public double RXFixedAGC
{
get { return rx_fixed_agc; }
set
{
rx_fixed_agc = value;
if(update)
{
if(value != rx_fixed_agc_dsp || force)
{
DttSP.SetFixedAGC(thread, subrx, value);
rx_fixed_agc_dsp = value;
}
}
}
}
//=====================================================================================
private double rx_agc_max_gain_dsp = 90.0;
private double rx_agc_max_gain = 90.0;
public double RXAGCMaxGain
{
get { return rx_agc_max_gain; }
set
{
rx_agc_max_gain = value;
if(update)
{
if(value != rx_agc_max_gain_dsp || force)
{
DttSP.SetRXAGCMaxGain(thread, subrx, value);
rx_agc_max_gain_dsp = value;
}
}
}
}
//=====================================================================================
private int rx_agc_attack_dsp = 2;
private int rx_agc_attack = 2;
public int RXAGCAttack
{
get { return rx_agc_attack; }
set
{
rx_agc_attack = value;
if(update)
{
if(value != rx_agc_attack_dsp || force)
{
DttSP.SetRXAGCAttack(thread, subrx, value);
rx_agc_attack_dsp = value;
}
}
}
}
//=====================================================================================
private int rx_agc_decay_dsp = 250;
private int rx_agc_decay = 250;
public int RXAGCDecay
{
get { return rx_agc_decay; }
set
{
rx_agc_decay = value;
if(update)
{
if(value != rx_agc_decay_dsp || force)
{
DttSP.SetRXAGCDecay(thread, subrx, value);
rx_agc_decay_dsp = value;
}
}
}
}
//=====================================================================================
private int rx_agc_hang_dsp = 250;
private int rx_agc_hang = 250;
public int RXAGCHang
{
get { return rx_agc_hang; }
set
{
rx_agc_hang = value;
if(update)
{
if(value != rx_agc_hang_dsp || force)
{
DttSP.SetRXAGCHang(thread, subrx, value);
rx_agc_hang_dsp = value;
}
}
}
}
//=====================================================================================
private double rx_output_gain_dsp = 0.5;
private double rx_output_gain = 0.5;
public double RXOutputGain
{
get { return rx_output_gain; }
set
{
rx_output_gain = value;
if(update)
{
if(value != rx_output_gain_dsp || force)
{
DttSP.SetRXOutputGain(thread, subrx, value);
rx_output_gain_dsp = value;
}
}
}
}
//=====================================================================================
private int rx_agc_slope_dsp = 0;
private int rx_agc_slope = 0;
public int RXAGCSlope
{
get { return rx_agc_slope; }
set
{
rx_agc_slope = value;
if(update)
{
if(value != rx_agc_slope_dsp || force)
{
DttSP.SetRXAGCSlope(thread, subrx, value);
rx_agc_slope_dsp = value;
}
}
}
}
//=====================================================================================
private int rx_agc_hang_threshold_dsp = 0;
private int rx_agc_hang_threshold = 0;
public int RXAGCHangThreshold
{
get { return rx_agc_hang_threshold; }
set
{
rx_agc_hang_threshold = value;
if(update)
{
if(value != rx_agc_hang_threshold_dsp || force)
{
DttSP.SetRXAGCHangThreshold(thread, subrx, value);
rx_agc_hang_threshold_dsp = value;
}
}
}
}
//=====================================================================================
private Window current_window_dsp = Window.BLKHARRIS;
private Window current_window = Window.BLKHARRIS;
public Window CurrentWindow
{
get { return current_window; }
set
{
current_window = value;
if(update)
{
if(value != current_window_dsp || force)
{
DttSP.SetWindow(thread, value);
current_window_dsp = value;
}
}
}
}
//=====================================================================================
private bool spectrum_polyphase_dsp = false;
private bool spectrum_polyphase = false;
public bool SpectrumPolyphase
{
get { return spectrum_polyphase; }
set
{
spectrum_polyphase = value;
if(update)
{
if(value != spectrum_polyphase_dsp || force)
{
DttSP.SetSpectrumPolyphase(thread, value);
spectrum_polyphase_dsp = value;
}
}
}
}
//=====================================================================================
private bool bin_on_dsp = false;
private bool bin_on = false;
public bool BinOn
{
get { return bin_on; }
set
{
bin_on = value;
if(update)
{
if(value != bin_on_dsp || force)
{
DttSP.SetBIN(thread, subrx, value);
bin_on_dsp = value;
}
}
}
}
//=====================================================================================
private float rx_squelch_threshold_dsp = -150.0f;
private float rx_squelch_threshold = -150.0f;
public float RXSquelchThreshold
{
get { return rx_squelch_threshold; }
set
{
//Debug.WriteLine("Squelch Threshold: "+value);
rx_squelch_threshold = value;
if (update)
{
if (value != rx_squelch_threshold_dsp || force)
{
DttSP.SetSquelchVal(thread, subrx, value);
rx_squelch_threshold_dsp = value;
}
}
}
}
//=====================================================================================
private float fm_squelch_threshold = 1.0f;
private float fm_squelch_threshold_dsp = 1.0f;
public float FMSquelchThreshold
{
get { return fm_squelch_threshold; }
set
{
fm_squelch_threshold = value;
if (update)
if (value != fm_squelch_threshold_dsp || force)
{
{
DttSP.SetFMSquelchThreshold(thread, subrx, value);
fm_squelch_threshold_dsp = value;
}
}
}
}
//=====================================================================================
private bool rx_squelch_on_dsp = false;
private bool rx_squelch_on = false;
public bool RXSquelchOn
{
get { return rx_squelch_on; }
set
{
rx_squelch_on = value;
if(update)
{
if(value != rx_squelch_on_dsp || force)
{
DttSP.SetSquelchState(thread, subrx, value);
rx_squelch_on_dsp = value;
}
}
}
}
//=====================================================================================
private bool spectrum_pre_filter_dsp = true;
private bool spectrum_pre_filter = true;
public bool SpectrumPreFilter
{
get { return spectrum_pre_filter; }
set
{
spectrum_pre_filter = value;
if(update)
{
if(value != spectrum_pre_filter_dsp || force)
{
//Debug.WriteLine(thread+" "+subrx+" SpectrumPreFilter: "+value);
DttSP.SetPWSmode(thread, subrx, value);
spectrum_pre_filter_dsp = value;
}
}
}
}
//=====================================================================================
private bool active_dsp = false;
private bool active = false;
public bool Active
{
get { return active; }
set
{
active = value;
if(update)
{
if(value != active_dsp || force)
{
DttSP.SetRXOn(thread, subrx, value);
active_dsp = value;
}
}
}
}
//=====================================================================================
private float pan_dsp = 0.5f;
private float pan = 0.5f;
/// <summary>
/// Determines the left (0.0) to right (1.0) audio field for this RX.
/// </summary>
public float Pan
{
get { return pan; }
set
{
pan = value;
if(update)
{
if(value != pan_dsp || force)
{
DttSP.SetRXPan(thread, subrx, value);
pan_dsp = value;
}
}
}
}
//=====================================================================================
private double rx_osc_dsp = 0.011025;
private double rx_osc = 0.011025;
public double RXOsc
{
get { return rx_osc; }
set
{
rx_osc = value;
if(update)
{
if(value != rx_osc_dsp || force)
{
DttSP.SetRXOsc(thread, subrx, value);
rx_osc_dsp = value;
}
}
}
}
//=====================================================================================
private double osc_phase_dsp = 0.0;
public double OSC_PHASE_DSP
{
get { return osc_phase_dsp; }
set
{
if(update)
{
if (value != osc_phase_dsp || force)
{
osc_phase_dsp = value;
DttSP.SetOscPhase(osc_phase_dsp);
}
}
}
}
//=====================================================================================
private bool dc_block_dsp = false;
private bool dc_block = false;
public bool DCBlock
{
get { return dc_block; }
set
{
//Debug.WriteLine("DC Block (" + thread + ", " + subrx + "): " + value +" -- "+update);
dc_block = value;
if (update)
{
if (value != dc_block_dsp || force)
{
DttSP.SetRXDCBlock(thread, subrx, value);
dc_block_dsp = value;
}
}
}
}
//=====================================================================================
private double rx_fm_deviation = 5000.0;
private double rx_fm_deviation_dsp = 5000.0;
public double RXFMDeviation
{
get { return rx_fm_deviation; }
set
{
rx_fm_deviation = value;
if (update)
{
if (value != rx_fm_deviation_dsp || force)
{
DttSP.SetRXFMDeviation(thread, subrx,value);
rx_fm_deviation_dsp = value;
}
}
}
}
//=====================================================================================
private const int MAX_NOTCHES_IN_PASSBAND = 18;
private bool[] notch_on = new bool[MAX_NOTCHES_IN_PASSBAND];
private bool[] notch_on_dsp = new bool[MAX_NOTCHES_IN_PASSBAND];
public bool GetNotchOn(int index)
{
return notch_on[index];
}
//=====================================================================================
public void SetNotchOn(uint index, bool b)
{
notch_on[index] = b;
if (update)
{
if (b != notch_on_dsp[index] || force)
{
DttSP.SetRXManualNotchEnable(thread, subrx, index, b);
notch_on_dsp[index] = b;
}
}
}
//=====================================================================================
private double[] notch_freq = new double[MAX_NOTCHES_IN_PASSBAND];
private double[] notch_freq_dsp = new double[MAX_NOTCHES_IN_PASSBAND];
public double GetNotchFreq(uint index)
{
return notch_freq[index];
}
//=====================================================================================
public void SetNotchFreq(uint index, double freq)
{
notch_freq[index] = freq;
if (update)
{
if (freq != notch_freq_dsp[index] || force)
{
DttSP.SetRXManualNotchFreq(thread, subrx, index, freq);
notch_freq_dsp[index] = freq;
}
}
}
//=====================================================================================
private double[] notch_bw = new double[MAX_NOTCHES_IN_PASSBAND];
private double[] notch_bw_dsp = new double[MAX_NOTCHES_IN_PASSBAND];
public double GetNotchBW(uint index)
{
return notch_bw[index];
}
//=====================================================================================
/// <summary>
/// Sets the notch bandwidth
/// </summary>
/// <param name="index">index of notch to set</param>
/// <param name="bw">Bandwidth in Hz</param>
public void SetNotchBW(uint index, double bw)
{
notch_bw[index] = bw;
if (update)
{
if (bw != notch_bw_dsp[index] || force)
{
DttSP.SetRXManualNotchBW(thread, subrx, index, bw);
notch_bw_dsp[index] = bw;
}
}
}
#endregion
} //DSPRX
#endregion
#region DSPTX Class
public class DSPTX
{
private uint thread;
public DSPTX(uint t)
{
thread = t;
DttSP.SetTRX(t, true);
}
//============================================================================
private void SyncAll()
{
//BufferSize = buffer_size;
AudioSize = audio_size;
CurrentDSPMode = current_dsp_mode;
SetTXFilter(tx_filter_low, tx_filter_high);
TXOsc = tx_osc;
DCBlock = dc_block;
if(tx_eq_num_bands == 3)
{
TXEQ28 = tx_eq28;// ke9ns add
TXEQ10 = tx_eq10;
TXEQ3 = tx_eq3;
}
else
{
if (tx_eq_num_bands == 28)
{
TXEQ3 = tx_eq3;
TXEQ10 = tx_eq10;
TXEQ28 = tx_eq28; // ke9ns add
}
else
{
TXEQ28 = tx_eq28; // ke9ns add
TXEQ3 = tx_eq3;
TXEQ10 = tx_eq10;
}
}
TXEQOn = tx_eq_on;
Notch160 = notch_160;
TXCorrectIQGain = tx_correct_iq_gain;
TXCorrectIQPhase = tx_correct_iq_phase;
TXCorrectIQMu = tx_correct_iq_mu;
TXAMCarrierLevel = tx_am_carrier_level;
TXALCBottom = tx_alc_bottom;
TXALCAttack = tx_alc_attack;
TXALCDecay = tx_alc_decay;
TXALCHang = tx_alc_hang;
TXLevelerMaxGain = tx_leveler_max_gain;
TXLevelerAttack = tx_leveler_attack;
TXLevelerDecay = tx_leveler_decay;
TXLevelerHang = tx_leveler_hang;
TXLevelerOn = tx_leveler_on;
CurrentWindow = current_window;
SpectrumPolyphase = spectrum_polyphase;
TXSquelchThreshold = tx_squelch_threshold;
TXSquelchAttenuate = tx_squelch_attenuate;
TXSquelchOn = tx_squelch_on;
TXCompandOn = tx_compand_on;
TXCompandLevel = tx_compand_level;
SpectrumPreFilter = spectrum_pre_filter;
CTCSSFreqHz = ctcss_freq_hz;
TXFMDeviation = tx_fm_deviation;
CTCSSFlag = ctcss_flag;
TXFMDataMode = fm_data_mode; // ke9ns add
} // syncall
#region Non-Static Properties & Routines
//=====================================================================================
/// <summary>
/// Controls whether updates to following properties call the DSP.
/// Each property uses this value and a copy of the last thing sent to
/// the DSP to update in a minimal fashion.
/// </summary>
private bool update = false;
public bool Update
{
get { return update; }
set
{
update = value;
if(value) SyncAll();
}
}
//=====================================================================================
/// <summary>
/// Used to force properties to update even if the DSP copy matches the
/// new setting. Mainly used to resync the DSP after having to rebuild
/// when resetting DSP Block Size or Sample Rate.
/// </summary>
private bool force = false;
public bool Force
{
get { return force; }
set { force = value; }
}
//=====================================================================================
private int buffer_size_dsp = 2048;
private int buffer_size = 2048;
public int BufferSize
{
get { return buffer_size; }
set
{
buffer_size = value;
if(update)
{
if(value != buffer_size_dsp || force)
{
//Debug.WriteLine("TX "+thread+" "+value);
DttSP.ResizeSDR(thread, value);
buffer_size_dsp = value;
//SyncAll();
}
}
}
}
//=====================================================================================
private int audio_size_dsp = 2048;
private int audio_size = 2048;
public int AudioSize
{
get { return audio_size; }
set
{
audio_size = value;
if(update)
{
if(value != audio_size_dsp || force)
{
DttSP.SetAudioSize(value);
audio_size_dsp = value;
}
}
}
}
//=====================================================================================
private DSPMode current_dsp_mode_dsp = DSPMode.USB;
private DSPMode current_dsp_mode = DSPMode.USB;
public DSPMode CurrentDSPMode
{
get { return current_dsp_mode; }
set
{
current_dsp_mode = value;
if(update)
{
if(value != current_dsp_mode_dsp || force)
{
DttSP.SetTXMode(thread, value);
current_dsp_mode_dsp = value;
}
}
}
}
//=====================================================================================
public void SetTXFilter(int low, int high)
{
tx_filter_low = low;
tx_filter_high = high;
if(update)
{
if(low != tx_filter_low_dsp || high != tx_filter_high_dsp || force)
{
DttSP.SetTXFilter(thread, low, high);
tx_filter_low_dsp = low;
tx_filter_high_dsp = high;
}
}
}
//=====================================================================================
private int tx_filter_low_dsp;
private int tx_filter_low;
public int TXFilterLow
{
get { return tx_filter_low; }
set
{
tx_filter_low = value;
if(update)
{
if(value != tx_filter_low_dsp || force)
{
DttSP.SetTXFilter(thread, value, tx_filter_high);
tx_filter_low_dsp = value;
}
}
}
}
//=====================================================================================
private int tx_filter_high_dsp;
private int tx_filter_high;
public int TXFilterHigh
{
get { return tx_filter_high; }
set
{
tx_filter_high = value;
if(update)
{
if(value != tx_filter_high_dsp || force)
{
DttSP.SetTXFilter(thread, tx_filter_low, value);
tx_filter_high_dsp = value;
}
}
}
}
//=====================================================================================
private double tx_osc_dsp = 0.0f;
private double tx_osc = 0.0;
public double TXOsc
{
get { return tx_osc; }
set
{
tx_osc = value;
if(update)
{
if(value != tx_osc_dsp || force)
{
DttSP.SetTXOsc(thread, value);
tx_osc_dsp = value;
}
}
}
}
//=====================================================================================
private bool dc_block_dsp;
private bool dc_block;
public bool DCBlock
{
get { return dc_block; }
set
{
dc_block = value;
if(update)
{
if(value != dc_block_dsp || force)
{
DttSP.SetTXDCBlock(thread, value);
dc_block_dsp = value;
}
}
}
}
//=====================================================================================
// ke9ns set to 10 or 3
private int tx_eq_num_bands = 3;
public int TXEQNumBands
{
get { return tx_eq_num_bands; }
set { tx_eq_num_bands = value; }
}
//=====================================================================================
// ke9ns set when 3 band EQ enabled
private int[] tx_eq3_dsp = new int[4];
private int[] tx_eq3 = new int[4];
public int[] TXEQ3
{
get { return tx_eq3; }
set
{
for (int i = 0; i < tx_eq3.Length && i < value.Length; i++)
{
tx_eq3[i] = value[i];
}
if(update)
{
DttSP.SetGrphTXEQ(thread, tx_eq3); // ke9ns this routine is in update.c code
for (int i = 0; i < tx_eq3_dsp.Length && i < value.Length; i++)
{
tx_eq3_dsp[i] = value[i];
}
}
}
}
//=====================================================================================
// ke9ns called by eqform when you enable the 10 band EQ
private int[] tx_eq10_dsp = new int[11];
private int[] tx_eq10 = new int[11];
public int[] TXEQ10
{
get { return tx_eq10; }
set
{
for (int i = 0; i < tx_eq10.Length && i < value.Length; i++)
{
tx_eq10[i] = value[i];
}
if (update)
{
DttSP.SetGrphTXEQ10(thread, tx_eq10); // ke9ns this routine is in update.c code
for (int i = 0; i < tx_eq10_dsp.Length && i < value.Length; i++)
{
tx_eq10_dsp[i] = value[i];
}
} // update
} // set
} // TXEQ10
//=====================================================================================
// ke9ns called by eqform when you enable the 10 band EQ
private int[] tx_eq28_dsp = new int[30];
private int[] tx_eq28= new int[30];
public int[] TXEQ28
{
get { return tx_eq28; }
set
{
for (int i = 0; i < tx_eq28.Length && i < value.Length; i++)
{
tx_eq28[i] = value[i];
}
if (update)
{
DttSP.SetGrphTXEQ28(thread, tx_eq28); // ke9ns this routine is in update.c code
for (int i = 0; i < tx_eq28_dsp.Length && i < value.Length; i++)
{
tx_eq28_dsp[i] = value[i];
}
} // update
} // set
} // TXEQ28
//======================================================================================
// ke9ns called by eqform when you ENABLE TX eq
private bool tx_eq_on_dsp = false;
private bool tx_eq_on = false;
public bool TXEQOn
{
get { return tx_eq_on; }
set
{
tx_eq_on = value;
if(update)
{
if(value != tx_eq_on_dsp || force)
{
DttSP.SetGrphTXEQcmd(thread, value); // ke9ns this routine is in update.c code
tx_eq_on_dsp = value;
}
}
}
}
//=============================================================================
private bool notch_160_dsp = false;
private bool notch_160 = false;
public bool Notch160
{
get { return notch_160; }
set
{
notch_160 = value;
if(update)
{
if(value != notch_160_dsp || force)
{
DttSP.SetNotch160(thread, value);
notch_160_dsp = value;
}
}
}
}
private double tx_correct_iq_gain_dsp = 0.0;
private double tx_correct_iq_gain = 0.0;
public double TXCorrectIQGain
{
get { return tx_correct_iq_gain; }
set
{
tx_correct_iq_gain = value;
if(update)
{
if(value != tx_correct_iq_gain_dsp || force)
{
DttSP.SetTXIQGain(thread, value);
tx_correct_iq_gain_dsp = value;
}
}
}
}
private double tx_fm_deviation = 5000.0;
private double tx_fm_deviation_dsp = 5000.0;
public double TXFMDeviation
{
get { return tx_fm_deviation; }
set
{
tx_fm_deviation = value;
if (update)
{
if (value != tx_fm_deviation_dsp || force)
{
DttSP.SetTXFMDeviation(thread, value);
tx_fm_deviation_dsp = value;
}
}
}
} // TXFMDeviation
//========================================================================================
// ke9ns add FMData turn off K_Preemphasis and K_Deemphasis here
// this calls dttsp.cs, which calls update.c, which sdr.c will read the tx[thread].fm struct
// console calls dsp.GetDSPTX(0).TXFMDataMode
private bool fm_data_mode = false; // true = no preemphasis, no deemphasis and 15k bandwidth
private bool fm_data_mode_dsp = false; // true = no preemphasis, no deemphasis and 15k bandwidth
public bool TXFMDataMode
{
get { return fm_data_mode; }
set
{
fm_data_mode = value;
if (update)
{
if (value != fm_data_mode_dsp || force)
{
DttSP.SetTXFMDataMode(thread, value); // dttsp.cs update.c place value into tx[thread].fm.fmdata struct sdr.c will then use it
fm_data_mode_dsp = value;
}
}
}
} // TXFMDataMode
//==================================================================================
private double ctcss_freq_hz = 100.0;
private double ctcss_freq_hz_dsp = 100.0;
public double CTCSSFreqHz
{
get { return ctcss_freq_hz; }
set
{
ctcss_freq_hz = value;
if (update)
{
if (value != ctcss_freq_hz_dsp || force)
{
DttSP.SetCTCSSFreq(thread, value);
ctcss_freq_hz_dsp = value;
}
}
}
}
private bool ctcss_flag = false;
private bool ctcss_flag_dsp = false;
public bool CTCSSFlag
{
get { return ctcss_flag; }
set
{
ctcss_flag = value;
if (update)
if (value != ctcss_flag_dsp || force)
{
{
DttSP.SetCTCSSFlag(thread, value);
ctcss_flag_dsp = value;
}
}
}
}
private double tx_correct_iq_phase_dsp = 0.0;
private double tx_correct_iq_phase = 0.0;
public double TXCorrectIQPhase
{
get { return tx_correct_iq_phase; }
set
{
tx_correct_iq_phase = value;
if(update)
{
if(value != tx_correct_iq_phase_dsp || force)
{
DttSP.SetTXIQPhase(thread, value);
tx_correct_iq_phase_dsp = value;
}
}
}
}
private double tx_correct_iq_mu_dsp = 0.0;
private double tx_correct_iq_mu = 0.0;
public double TXCorrectIQMu
{
get { return tx_correct_iq_mu; }
set
{
tx_correct_iq_mu = value;
if(update)
{
if(value != tx_correct_iq_mu_dsp || force)
{
DttSP.SetTXIQMu(thread, value);
tx_correct_iq_mu_dsp = value;
}
}
}
}
private double tx_am_carrier_level_dsp = 0.35;
private double tx_am_carrier_level = 0.35;
public double TXAMCarrierLevel
{
get { return tx_am_carrier_level; }
set
{
tx_am_carrier_level = value;
if(update)
{
if(value != tx_am_carrier_level_dsp || force)
{
//Debug.WriteLine("TXAMCArrierLevel: "+tx_am_carrier_level.ToString("f3"));
DttSP.SetTXAMCarrierLevel(thread, value);
tx_am_carrier_level_dsp = value;
}
}
}
}
private int tx_alc_bottom_dsp = -120;
private int tx_alc_bottom = -120;
private int TXALCBottom
{
get { return tx_alc_bottom; }
set
{
tx_alc_bottom = value;
if(update)
{
if(value != tx_alc_bottom_dsp || force)
{
DttSP.SetTXALCBot(thread, value);
tx_alc_bottom_dsp = value;
}
}
}
}
private int tx_alc_attack_dsp = 2;
private int tx_alc_attack = 2;
public int TXALCAttack
{
get { return tx_alc_attack; }
set
{
tx_alc_attack = value;
if(update)
{
if(value != tx_alc_attack_dsp || force)
{
DttSP.SetTXALCAttack(thread, value);
tx_alc_attack_dsp = value;
}
}
}
}
private int tx_alc_decay_dsp = 10;
private int tx_alc_decay = 10;
public int TXALCDecay
{
get { return tx_alc_decay; }
set
{
tx_alc_decay = value;
if(update)
{
if(value != tx_alc_decay_dsp || force)
{
DttSP.SetTXALCDecay(thread, value);
tx_alc_decay_dsp = value;
}
}
}
}
private int tx_alc_hang = 500;
public int TXALCHang
{
get { return tx_alc_hang; }
set
{
tx_alc_hang = value;
DttSP.SetTXALCHang(thread, value);
}
}
private double tx_leveler_max_gain_dsp = 5.0;
private double tx_leveler_max_gain = 5.0;
public double TXLevelerMaxGain
{
get { return tx_leveler_max_gain; }
set
{
tx_leveler_max_gain = value;
if(update)
{
if(value != tx_leveler_max_gain_dsp || force)
{
DttSP.SetTXLevelerMaxGain(thread, value);
tx_leveler_max_gain_dsp = value;
}
}
}
}
private int tx_leveler_attack_dsp = 2;
private int tx_leveler_attack = 2;
public int TXLevelerAttack
{
get { return tx_leveler_attack; }
set
{
tx_leveler_attack = value;
if(update)
{
if(value != tx_leveler_attack_dsp || force)
{
DttSP.SetTXLevelerAttack(thread, value);
tx_leveler_attack_dsp = value;
}
}
}
}
private int tx_leveler_decay_dsp = 500;
private int tx_leveler_decay = 500;
public int TXLevelerDecay
{
get { return tx_leveler_decay; }
set
{
tx_leveler_decay = value;
if(update)
{
if(value != tx_leveler_decay_dsp || force)
{
DttSP.SetTXLevelerDecay(thread, value);
tx_leveler_decay_dsp = value;
}
}
}
}
private int tx_leveler_hang_dsp = 500;
private int tx_leveler_hang = 500;
public int TXLevelerHang
{
get { return tx_leveler_hang; }
set
{
tx_leveler_hang = value;
if(update)
{
if(value != tx_leveler_hang_dsp || force)
{
DttSP.SetTXLevelerHang(thread, value);
tx_leveler_hang_dsp = value;
}
}
}
}
private bool tx_leveler_on_dsp = true;
private bool tx_leveler_on = true;
public bool TXLevelerOn
{
get { return tx_leveler_on; }
set
{
tx_leveler_on = value;
if(update)
{
if(value != tx_leveler_on_dsp || force)
{
DttSP.SetTXLevelerSt(thread, value);
tx_leveler_on_dsp = value;
}
}
}
}
private Window current_window_dsp = Window.BLKHARRIS;
private Window current_window = Window.BLKHARRIS;
public Window CurrentWindow
{
get { return current_window; }
set
{
current_window = value;
if(update)
{
if(value != current_window_dsp || force)
{
DttSP.SetWindow(thread, value);
current_window_dsp = value;
}
}
}
}
private bool spectrum_polyphase_dsp = false;
private bool spectrum_polyphase = false;
public bool SpectrumPolyphase
{
get { return spectrum_polyphase; }
set
{
spectrum_polyphase = value;
if(update)
{
if(value != spectrum_polyphase_dsp || force)
{
DttSP.SetSpectrumPolyphase(thread, value);
spectrum_polyphase_dsp = value;
}
}
}
}
private float tx_squelch_threshold_dsp = -40.0f;
private float tx_squelch_threshold = -40.0f;
public float TXSquelchThreshold
{
get { return tx_squelch_threshold; }
set
{
tx_squelch_threshold = value;
if(update)
{
if(value != tx_squelch_threshold_dsp || force)
{
DttSP.SetTXSquelchVal(thread, value);
tx_squelch_threshold_dsp = value;
}
}
}
}
private float tx_squelch_attenuate_dsp = 80.0f;
private float tx_squelch_attenuate = 80.0f;
public float TXSquelchAttenuate
{
get { return tx_squelch_attenuate; }
set
{
tx_squelch_attenuate = value;
if(update)
{
if(value != tx_squelch_attenuate_dsp || force)
{
DttSP.SetTXSquelchAtt(thread, value);
tx_squelch_attenuate_dsp = value;
}
}
}
}
private bool tx_squelch_on_dsp = false;
private bool tx_squelch_on = false;
public bool TXSquelchOn
{
get { return tx_squelch_on; }
set
{
tx_squelch_on = value;
if(update)
{
if(value != tx_squelch_on_dsp || force)
{
DttSP.SetTXSquelchState(thread, value);
tx_squelch_on_dsp = value;
}
}
}
}
private bool tx_compand_on_dsp = false;
private bool tx_compand_on = false;
public bool TXCompandOn
{
get { return tx_compand_on; }
set
{
tx_compand_on = value;
if(update)
{
if(value != tx_compand_on_dsp || force)
{
DttSP.SetTXCompandSt(thread, value);
tx_compand_on_dsp = value;
//Debug.WriteLine("TXCompandOn: "+value.ToString());
}
}
}
}
private double tx_compand_level_dsp = 0.1;
private double tx_compand_level = 0.1;
public double TXCompandLevel
{
get { return tx_compand_level; }
set
{
tx_compand_level = value;
if(update)
{
if(value != tx_compand_level_dsp || force)
{
DttSP.SetTXCompand(thread, value);
tx_compand_level_dsp = value;
//Debug.WriteLine("TXCompandLevel: "+value.ToString("f2"));
}
}
}
}
private bool spectrum_pre_filter_dsp = true;
private bool spectrum_pre_filter = true;
public bool SpectrumPreFilter
{
get { return spectrum_pre_filter; }
set
{
spectrum_pre_filter = value;
if(update)
{
if(value != spectrum_pre_filter_dsp || force)
{
DttSP.SetTXPWSmode(thread, value);
spectrum_pre_filter_dsp = value;
}
}
}
}
/*
private bool active_dsp = false;
private bool active = false;
public bool Active
{
get { return active; }
set
{
active = value;
if(update)
{
if(value != active_dsp || force)
{
DttSP.SetRXOn(thread, subrx, value);
active_dsp = value;
}
}
}
}
private float pan_dsp = 0.5f;
private float pan = 0.5f;
public float Pan
{
get { return pan; }
set
{
pan = value;
if(update)
{
if(value != pan_dsp || force)
{
DttSP.SetRXPan(thread, subrx, value);
pan_dsp = value;
}
}
}
}
*/
#endregion
}
#endregion
}