Merge pull request #25 from drowe67/dr-phase_est_bw
High bandwidth phase est mode & VQ EQ & DPSK & FreeDV 1.4pull/30/head
commit
8f457ab4b5
|
@ -45,7 +45,7 @@ message(STATUS "Compilation date = XX${DATE_RESULT}XX")
|
|||
set(FREEDV_VERSION_MAJOR 1)
|
||||
set(FREEDV_VERSION_MINOR 4)
|
||||
set(FREEDV_VERSION_PATCH FALSE)
|
||||
set(FREEDV_VERSION_SUFFIX "devel")
|
||||
set(FREEDV_VERSION_SUFFIX FALSE)
|
||||
|
||||
set(FREEDV_VERSION ${FREEDV_VERSION_MAJOR}.${FREEDV_VERSION_MINOR})
|
||||
if(FREEDV_VERSION_PATCH)
|
||||
|
|
|
@ -12,6 +12,8 @@ This document describes how to build the FreeDV GUI program for various operatin
|
|||
$ sudo apt install libc6-i386 libspeexdsp-dev libsamplerate0-dev sox git \
|
||||
libwxgtk3.0-dev portaudio19-dev libhamlib-dev libasound2-dev libao-dev \
|
||||
libgsm1-dev libsndfile-dev cmake
|
||||
$ git clone https://github.com/drowe67/freedv-gui.git
|
||||
$ cd freedv-gui
|
||||
$ ./build_linux.sh
|
||||
```
|
||||
|
||||
|
@ -21,6 +23,8 @@ This document describes how to build the FreeDV GUI program for various operatin
|
|||
$ sudo dnf install cmake wxGTK3-devel portaudio-devel libsamplerate-devel \
|
||||
libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
|
||||
gsm-devel
|
||||
$ git clone https://github.com/drowe67/freedv-gui.git
|
||||
$ cd freedv-gui
|
||||
$ ./build_linux.sh
|
||||
```
|
||||
|
||||
|
|
|
@ -372,7 +372,6 @@ about 90% of speakers tested work well.
|
|||
section below).
|
||||
1. It requires a modern (post 2010) Intel CPU with AVX support. If you
|
||||
don't have AVX the FreeDV 2020 mode button will be grayed out.
|
||||
1. The audio in **Analog** mode is choppy.
|
||||
|
||||
### Horus Binary Mode
|
||||
|
||||
|
@ -396,6 +395,44 @@ work in Windows if Tools-Options "Windows Debug Console" is checked.
|
|||
A Python script is required to upload the telemetry messages to the HabHub
|
||||
server, please see https://github.com/projecthorus/horusbinary#usage---via-freedv
|
||||
|
||||
## Tools - Filter
|
||||
|
||||
This section describes features on Tools-Filter.
|
||||
|
||||
Control | Description
|
||||
--- | --- |
|
||||
Noise Supression | Enable noise supression, dereverberation, AGC of mic signal using the Speex pre-processor
|
||||
700C/700D Auto EQ | Automatic equalisation for FreeDV 700C and FreeDV 700D Codec input audio
|
||||
|
||||
Auto EQ (Automatic Equalisation) adjusts the input speech spectrum to best fit the speech codec. It can remove annoying bass artefacts and make the codec speech easier to understand.
|
||||
|
||||
[Blog Post on Auto EQ Part 1](http://www.rowetel.com/?p=6778)
|
||||
[Blog Post on Auto EQ Part 2](http://www.rowetel.com/?p=6860)
|
||||
|
||||
## Tools - Options
|
||||
|
||||
This section describes features on Tools-Options. Many of these features are also described in other parts of this manual.
|
||||
|
||||
### FreeDV 700 Options
|
||||
|
||||
Control | Description
|
||||
--- | --- |
|
||||
Clipping | Hard clipping of transmit waveform to increase the average power, at the expense of some distortion
|
||||
700C Diversity Combine | Combining of two sets of 700C carriers for better fading channel performance
|
||||
700D Interleaver | How many 700D frames to Interleave, larger leads to better fading channel performance but more latency
|
||||
700D Tx Band Pass Filter | Reduces 700D TX spectrum bandwidth
|
||||
700D Manual Unsync | Forces 700D to remain in sync, and not drop sync automatically
|
||||
|
||||
### OFDM Modem Phase Estimator Options
|
||||
|
||||
These options apply to the FreeDV 700D and 2020 modes that use the OFDM modem:
|
||||
|
||||
1. The High Bandwidth option gives better performance on channels where the phase changes quickly, for example fast fading HF channels, and the Es'Hail 2 satellite. When unchecked, the phase estimator bandwidth is automatically selected. It starts off high to enable fast sync, then switches to low bandwidth to optimise performance for low SNR HF channels.
|
||||
|
||||
1. The DPSK (differential PSK) checkbox has a similar effect - better performance on High SNR channels where the phase changes rapidly. This option converts the OFDM modem to use differential PSK, rather than coherent PSK. DPSK is used by earlier FreeDV modes such as FreeDV 1600. It affects the Tx and Rx side, so both sides must select DPSK.
|
||||
|
||||
If you problems with 700D or 2020 sync even though you have a strong signal - try these option.
|
||||
|
||||
## Advanced/Developer Features
|
||||
|
||||
### Stats Window
|
||||
|
@ -410,6 +447,7 @@ Resyncs | Number of times the demodulator has resynced
|
|||
ClkOff | Estimated sample clock offset in parts per million
|
||||
FreqOff | Estimated frequency offset in Hz
|
||||
Sync | Sync metric (OFDM modes like 700D and 2020)
|
||||
Var | Speech encoder distortion for 700C/700D (see Auto EQ)
|
||||
|
||||
The sample clock offset is the estimated difference between the
|
||||
modulator (tx) and demodulator (rx) sample clocks. For example if the
|
||||
|
@ -561,12 +599,13 @@ LDPC | Low Density Parity Check Codes, a powerful family of FEC codes
|
|||
|
||||
## Release Notes
|
||||
|
||||
### V1.4 June-August 2019
|
||||
### V1.4 June-October 2019
|
||||
|
||||
1. FreeDV 2020 Beta, Project Horus Binary Mode.
|
||||
1. [Improved OFDM Modem Acquisition](http://www.rowetel.com/?p=6824), this will improve sync time on
|
||||
FreeDV 700D and 2020 on HF fading channels. We can also handle +/- 60 Hz frequency offsets now.
|
||||
1. FreeDV 2020, Project Horus Binary Modes.
|
||||
1. [Improved OFDM Modem Acquisition](http://www.rowetel.com/?p=6824), this will improve sync time on FreeDV 700D and 2020 on HF fading channels, and can also handle +/- 60 Hz frequency offsets when tuning.
|
||||
1. Fixed FreeDV 700C frequency offset bug fix, was losing sync at certain frequency offsets.
|
||||
1. Wide bandwidth phase estimation and DPSK for OFDM modes (700D/2020) for fast fading/QO-100 channels (Tools-Options)
|
||||
1. Better speech quality on FreeDV 700C/700D with Auto equaliser (Tools-Filter)
|
||||
|
||||
### V1.3 May 2018
|
||||
|
||||
|
|
|
@ -8,10 +8,13 @@ export FREEDVGUIDIR=${PWD}
|
|||
export CODEC2DIR=$FREEDVGUIDIR/codec2
|
||||
export LPCNETDIR=$FREEDVGUIDIR/LPCNet
|
||||
|
||||
# change this when working on combined codec2/freedv-gui changes
|
||||
CODEC2_BRANCH=master
|
||||
|
||||
# First build and install vanilla codec2 as we need -lcodec2 to build LPCNet
|
||||
cd $FREEDVGUIDIR
|
||||
git clone https://github.com/drowe67/codec2.git
|
||||
cd codec2 && git checkout master && git pull
|
||||
cd codec2 && git checkout $CODEC2_BRANCH && git pull
|
||||
mkdir -p build_linux && cd build_linux && rm -Rf * && cmake .. && make
|
||||
|
||||
# OK, build and test LPCNet
|
||||
|
|
|
@ -11,9 +11,6 @@ docker-compose -f docker-compose-win.yml build
|
|||
```
|
||||
## Running the image(s)
|
||||
```bash
|
||||
export DEV_STLINK=`./get_stlink.sh`
|
||||
export GIT_REF=my-super-branch
|
||||
export GIT_REPO=http://github.com/dummy/codec2.git
|
||||
docker-compose -f docker-compose-win.yml up
|
||||
```
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ echo "FDV_CMAKE=$CMAKE"
|
|||
# OK lets get started -----------------------------------------------
|
||||
|
||||
if [ ! -d freedv-gui ] ; then git clone --depth=1 $GIT_REPO ; fi
|
||||
cd freedv-gui && git checkout $GIT_BRANCH && git pull
|
||||
cd freedv-gui && git pull && git checkout $GIT_BRANCH
|
||||
echo "--------------------- starting build_windows.sh ---------------------"
|
||||
GIT_REPO=$GIT_REPO GIT_REF=$GIT_REF CMAKE=$CMAKE ./build_windows.sh
|
||||
if [ $CMAKE = "mingw64-cmake" ]; then
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#define F_MAG_N (int)(MAX_F_HZ/F_STEP_DFT) // number of frequency steps
|
||||
|
||||
extern struct freedv *g_pfreedv;
|
||||
extern int g_mode;
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class FilterDlg
|
||||
|
@ -84,12 +85,16 @@ FilterDlg::FilterDlg(wxWindow* parent, bool running, bool *newMicInFilter, bool
|
|||
// Speex pre-processor --------------------------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_speexpp;
|
||||
wxStaticBox *sb_speexpp = new wxStaticBox(this, wxID_ANY, _("Speex Mic Audio Pre-Processor"));
|
||||
sbSizer_speexpp = new wxStaticBoxSizer(sb_speexpp, wxVERTICAL);
|
||||
wxStaticBox *sb_speexpp = new wxStaticBox(this, wxID_ANY, _("Mic Audio Pre-Processing"));
|
||||
sbSizer_speexpp = new wxStaticBoxSizer(sb_speexpp, wxHORIZONTAL);
|
||||
|
||||
m_ckboxSpeexpp = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sb_speexpp->SetToolTip(_("Enable noise supression, dereverberation, AGC of mic signal"));
|
||||
m_ckboxSpeexpp = new wxCheckBox(this, wxID_ANY, _("Speex Noise Suppression"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sbSizer_speexpp->Add(m_ckboxSpeexpp, wxALIGN_LEFT, 2);
|
||||
m_ckboxSpeexpp->SetToolTip(_("Enable noise supression, dereverberation, AGC of mic signal"));
|
||||
|
||||
m_ckbox700C_EQ = new wxCheckBox(this, wxID_ANY, _("700C/700D Auto EQ"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sbSizer_speexpp->Add(m_ckbox700C_EQ, wxALIGN_LEFT, 2);
|
||||
m_ckbox700C_EQ->SetToolTip(_("Automatic equalisation for FreeDV 700C and FreeDV 700D Codec input audio"));
|
||||
|
||||
bSizer30->Add(sbSizer_speexpp, 0, wxALL, 0);
|
||||
|
||||
|
@ -180,6 +185,7 @@ FilterDlg::FilterDlg(wxWindow* parent, bool running, bool *newMicInFilter, bool
|
|||
m_LPCPostFilterDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
|
||||
|
||||
m_ckboxSpeexpp->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpeexppEnable), NULL, this);
|
||||
m_ckbox700C_EQ->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::On700C_EQ), NULL, this);
|
||||
|
||||
m_MicInBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
|
||||
m_MicInBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
|
||||
|
@ -224,6 +230,8 @@ FilterDlg::~FilterDlg()
|
|||
m_codec2LPCPostFilterGamma->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
|
||||
m_LPCPostFilterDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
|
||||
|
||||
m_ckboxSpeexpp->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpeexppEnable), NULL, this);
|
||||
|
||||
m_MicInBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
|
||||
m_MicInBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
|
||||
m_MicInTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
|
||||
|
@ -316,6 +324,9 @@ void FilterDlg::ExchangeData(int inout, bool storePersistent)
|
|||
|
||||
m_ckboxSpeexpp->SetValue(wxGetApp().m_speexpp_enable);
|
||||
|
||||
// Codec 2 700C EQ
|
||||
m_ckbox700C_EQ->SetValue(wxGetApp().m_700C_EQ);
|
||||
|
||||
// Mic In Equaliser
|
||||
|
||||
m_MicInBass.freqHz = wxGetApp().m_MicInBassFreqHz;
|
||||
|
@ -386,8 +397,10 @@ void FilterDlg::ExchangeData(int inout, bool storePersistent)
|
|||
wxGetApp().m_codec2LPCPostFilterGamma = m_gamma;
|
||||
|
||||
// Speex Pre-Processor
|
||||
|
||||
wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
|
||||
|
||||
// Codec 2 700C EQ
|
||||
wxGetApp().m_700C_EQ = m_ckbox700C_EQ->GetValue();
|
||||
|
||||
// Mic In Equaliser
|
||||
|
||||
|
@ -421,6 +434,8 @@ void FilterDlg::ExchangeData(int inout, bool storePersistent)
|
|||
|
||||
pConfig->Write(wxT("/Filter/speexpp_enable"), wxGetApp().m_speexpp_enable);
|
||||
|
||||
pConfig->Write(wxT("/Filter/700C_EQ"), wxGetApp().m_700C_EQ);
|
||||
|
||||
pConfig->Write(wxT("/Filter/MicInBassFreqHz"), (int)m_MicInBass.freqHz);
|
||||
pConfig->Write(wxT("/Filter/MicInBassGaindB"), (int)(10.0*m_MicInBass.gaindB));
|
||||
pConfig->Write(wxT("/Filter/MicInTrebleFreqHz"), (int)m_MicInTreble.freqHz);
|
||||
|
@ -545,10 +560,13 @@ void FilterDlg::setBeta(void) {
|
|||
|
||||
void FilterDlg::setCodec2(void) {
|
||||
if (m_running) {
|
||||
codec2_set_lpc_post_filter(freedv_get_codec2(g_pfreedv),
|
||||
m_codec2LPCPostFilterEnable->GetValue(),
|
||||
m_codec2LPCPostFilterBassBoost->GetValue(),
|
||||
m_beta, m_gamma);
|
||||
struct CODEC2 *c2 = freedv_get_codec2(g_pfreedv);
|
||||
if (c2 != NULL) {
|
||||
codec2_set_lpc_post_filter(c2,
|
||||
m_codec2LPCPostFilterEnable->GetValue(),
|
||||
m_codec2LPCPostFilterBassBoost->GetValue(),
|
||||
m_beta, m_gamma);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,6 +604,13 @@ void FilterDlg::OnSpeexppEnable(wxScrollEvent& event) {
|
|||
wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
|
||||
}
|
||||
|
||||
void FilterDlg::On700C_EQ(wxScrollEvent& event) {
|
||||
wxGetApp().m_700C_EQ = m_ckbox700C_EQ->GetValue();
|
||||
if (m_running && ((g_mode == FREEDV_MODE_700C) || (g_mode == FREEDV_MODE_700D))) {
|
||||
freedv_set_eq(g_pfreedv, wxGetApp().m_700C_EQ);
|
||||
}
|
||||
}
|
||||
|
||||
void FilterDlg::OnMicInEnable(wxScrollEvent& event) {
|
||||
wxGetApp().m_MicInEQEnable = m_MicInEnable->GetValue();
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ class FilterDlg : public wxDialog
|
|||
void OnBassBoost(wxScrollEvent& event);
|
||||
|
||||
void OnSpeexppEnable(wxScrollEvent& event);
|
||||
void On700C_EQ(wxScrollEvent& event);
|
||||
|
||||
void OnMicInBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInBass, true); }
|
||||
void OnMicInBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInBass, true); }
|
||||
|
@ -125,7 +126,8 @@ class FilterDlg : public wxDialog
|
|||
wxButton* m_LPCPostFilterDefault;
|
||||
|
||||
wxCheckBox* m_ckboxSpeexpp;
|
||||
|
||||
wxCheckBox* m_ckbox700C_EQ;
|
||||
|
||||
wxStdDialogButtonSizer* m_sdbSizer5;
|
||||
wxButton* m_sdbSizer5OK;
|
||||
wxButton* m_sdbSizer5Cancel;
|
||||
|
|
|
@ -115,6 +115,21 @@ OptionsDlg::OptionsDlg(wxWindow* parent, wxWindowID id, const wxString& title, c
|
|||
|
||||
bSizer30->Add(sbSizer_freedv700, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// Phase Est Options
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_freedvPhaseEst;
|
||||
wxStaticBox *sb_freedvPhaseEst = new wxStaticBox(this, wxID_ANY, _("OFDM Modem Phase Estimator Options"));
|
||||
sbSizer_freedvPhaseEst = new wxStaticBoxSizer(sb_freedvPhaseEst, wxHORIZONTAL);
|
||||
|
||||
m_ckboxPhaseEstBW = new wxCheckBox(this, wxID_ANY, _("High Bandwidth"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sbSizer_freedvPhaseEst->Add(m_ckboxPhaseEstBW, 0, wxALIGN_LEFT, 0);
|
||||
m_ckboxPhaseEstDPSK = new wxCheckBox(this, wxID_ANY, _("DPSK"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sbSizer_freedvPhaseEst->Add(m_ckboxPhaseEstDPSK, 0, wxALIGN_LEFT, 0);
|
||||
|
||||
bSizer30->Add(sbSizer_freedvPhaseEst, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// Half/Full duplex selection
|
||||
//------------------------------
|
||||
|
@ -489,6 +504,9 @@ void OptionsDlg::ExchangeData(int inout, bool storePersistent)
|
|||
m_txtInterleave->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_FreeDV700Interleave));
|
||||
m_ckboxFreeDV700ManualUnSync->SetValue(wxGetApp().m_FreeDV700ManualUnSync);
|
||||
|
||||
m_ckboxPhaseEstBW->SetValue(wxGetApp().m_PhaseEstBW);
|
||||
m_ckboxPhaseEstDPSK->SetValue(wxGetApp().m_PhaseEstDPSK);
|
||||
|
||||
#ifdef __WXMSW__
|
||||
m_ckboxDebugConsole->SetValue(wxGetApp().m_debug_console);
|
||||
#endif
|
||||
|
@ -593,6 +611,9 @@ void OptionsDlg::ExchangeData(int inout, bool storePersistent)
|
|||
wxGetApp().m_FreeDV700Interleave = (int)interleave;
|
||||
wxGetApp().m_FreeDV700ManualUnSync = m_ckboxFreeDV700ManualUnSync->GetValue();
|
||||
|
||||
wxGetApp().m_PhaseEstBW = m_ckboxPhaseEstBW->GetValue();
|
||||
wxGetApp().m_PhaseEstDPSK = m_ckboxPhaseEstDPSK->GetValue();
|
||||
|
||||
#ifdef __WXMSW__
|
||||
wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
|
||||
#endif
|
||||
|
|
|
@ -114,6 +114,9 @@ class OptionsDlg : public wxDialog
|
|||
wxTextCtrl *m_txtInterleave;
|
||||
wxCheckBox *m_ckboxFreeDV700ManualUnSync;
|
||||
|
||||
wxCheckBox *m_ckboxPhaseEstBW;
|
||||
wxCheckBox *m_ckboxPhaseEstDPSK;
|
||||
|
||||
wxRadioButton *m_rb_textEncoding1;
|
||||
wxRadioButton *m_rb_textEncoding2;
|
||||
wxCheckBox *m_ckboxEnableChecksum;
|
||||
|
|
|
@ -501,6 +501,7 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
|
|||
//printf("main(): m_codec2LPCPostFilterBeta: %f\n", wxGetApp().m_codec2LPCPostFilterBeta);
|
||||
|
||||
wxGetApp().m_speexpp_enable = pConfig->Read(wxT("/Filter/speexpp_enable"), t);
|
||||
wxGetApp().m_700C_EQ = pConfig->Read(wxT("/Filter/700C_EQ"), t);
|
||||
|
||||
wxGetApp().m_MicInBassFreqHz = (float)pConfig->Read(wxT("/Filter/MicInBassFreqHz"), 1);
|
||||
wxGetApp().m_MicInBassGaindB = (float)pConfig->Read(wxT("/Filter/MicInBassGaindB"), (long)0)/10.0;
|
||||
|
@ -550,6 +551,9 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
|
|||
wxGetApp().m_FreeDV700Interleave = (int)pConfig->Read(wxT("/FreeDV700/interleave"), 1);
|
||||
wxGetApp().m_FreeDV700ManualUnSync = (float)pConfig->Read(wxT("/FreeDV700/manualUnSync"), f);
|
||||
|
||||
wxGetApp().m_PhaseEstBW = (float)pConfig->Read(wxT("/OFDM/PhaseEstBW"), f);
|
||||
wxGetApp().m_PhaseEstDPSK = (float)pConfig->Read(wxT("/OFDM/PhaseEstDPSK"), f);
|
||||
|
||||
wxGetApp().m_noise_snr = (float)pConfig->Read(wxT("/Noise/noise_snr"), 2);
|
||||
|
||||
wxGetApp().m_debug_console = (float)pConfig->Read(wxT("/Debug/console"), f);
|
||||
|
@ -814,6 +818,8 @@ MainFrame::~MainFrame()
|
|||
pConfig->Write(wxT("/Filter/SpkOutEQEnable"), wxGetApp().m_SpkOutEQEnable);
|
||||
|
||||
pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
|
||||
pConfig->Write(wxT("/OFDM/PhaseEstBW"), wxGetApp().m_PhaseEstBW);
|
||||
pConfig->Write(wxT("/OFDM/PhaseEstDPSK"), wxGetApp().m_PhaseEstDPSK);
|
||||
pConfig->Write(wxT("/Noise/noise_snr"), wxGetApp().m_noise_snr);
|
||||
|
||||
pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
|
||||
|
@ -1241,11 +1247,13 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
|
|||
//wxString clockoffset_string(clockoffset); m_textClockOffset->SetLabel(clockoffset_string);
|
||||
}
|
||||
else {
|
||||
// Run time update of FreeDV 700 tx clipper and 700D BPF
|
||||
// set some run time options (if applicable to this mode)
|
||||
|
||||
freedv_set_clip(g_pfreedv, (int)wxGetApp().m_FreeDV700txClip);
|
||||
freedv_set_tx_bpf(g_pfreedv, (int)wxGetApp().m_FreeDV700txBPF);
|
||||
|
||||
freedv_set_clip(g_pfreedv, (int)wxGetApp().m_FreeDV700txClip); // 700C/700D/2020
|
||||
freedv_set_tx_bpf(g_pfreedv, (int)wxGetApp().m_FreeDV700txBPF); // 700D
|
||||
freedv_set_phase_est_bandwidth_mode(g_pfreedv, (int)wxGetApp().m_PhaseEstBW); // 700D/2020
|
||||
freedv_set_dpsk(g_pfreedv, (int)wxGetApp().m_PhaseEstDPSK); // 700D/2020
|
||||
|
||||
// Test Frame Bit Error Updates ------------------------------------
|
||||
|
||||
// Toggle test frame mode at run time
|
||||
|
@ -1275,6 +1283,15 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
|
|||
wxString freqoffset_string(freqoffset); m_textFreqOffset->SetLabel(freqoffset_string);
|
||||
sprintf(syncmetric, "Sync: %3.2f", g_stats.sync_metric);
|
||||
wxString syncmetric_string(syncmetric); m_textSyncMetric->SetLabel(syncmetric_string);
|
||||
|
||||
// Codec 2 700C VQ "auto EQ" equaliser variance
|
||||
if ((g_mode == FREEDV_MODE_700C) || (g_mode == FREEDV_MODE_700D)) {
|
||||
struct CODEC2 *c2 = freedv_get_codec2(g_pfreedv);
|
||||
assert(c2 != NULL);
|
||||
float var = codec2_get_var(c2);
|
||||
char var_str[80]; sprintf(var_str, "Var: %4.1f", var);
|
||||
wxString var_string(var_str); m_textCodec2Var->SetLabel(var_string);
|
||||
}
|
||||
|
||||
if (g_State) {
|
||||
|
||||
|
@ -1949,6 +1966,8 @@ void MainFrame::OnBerReset(wxCommandEvent& event)
|
|||
g_error_hist[i] = 0;
|
||||
g_error_histn[i] = 0;
|
||||
}
|
||||
// resets variance stats every time it is called
|
||||
freedv_set_eq(g_pfreedv, wxGetApp().m_700C_EQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2072,7 +2091,7 @@ void MainFrame::OnPlayFileFromRadio(wxCommandEvent& event)
|
|||
printf("OnPlayFileFromRadio:: %d\n", (int)g_playFileFromRadio);
|
||||
if (g_playFileFromRadio)
|
||||
{
|
||||
printf("OnPlayFileFromRadio:: Stop\n");
|
||||
fprintf(stderr, "OnPlayFileFromRadio:: Stop\n");
|
||||
g_mutexProtectingCallbackData.Lock();
|
||||
g_playFileFromRadio = false;
|
||||
sf_close(g_sfPlayFileFromRadio);
|
||||
|
@ -2177,7 +2196,7 @@ void MainFrame::OnRecFileFromRadio(wxCommandEvent& event)
|
|||
wxUnusedVar(event);
|
||||
|
||||
if (g_recFileFromRadio) {
|
||||
printf("Stopping Record....\n");
|
||||
fprintf(stderr, "Stopping Record....\n");
|
||||
g_mutexProtectingCallbackData.Lock();
|
||||
g_recFileFromRadio = false;
|
||||
sf_close(g_sfRecFile);
|
||||
|
@ -2607,6 +2626,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
|
|||
|
||||
if (startStop.IsSameAs("Start"))
|
||||
{
|
||||
fprintf(stderr, "Start .....\n");
|
||||
//
|
||||
// Start Running -------------------------------------------------
|
||||
//
|
||||
|
@ -2672,6 +2692,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
|
|||
|
||||
m_textSync->Disable();
|
||||
m_textInterleaverSync->SetLabel("");
|
||||
g_modemInbufferSize = (int)(FRAME_DURATION * horus_get_Fs(g_horus));
|
||||
}
|
||||
if (m_rb2020->GetValue() && isAvxPresent) {
|
||||
g_mode = FREEDV_MODE_2020;
|
||||
|
@ -2703,6 +2724,11 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
|
|||
m_textInterleaverSync->SetLabel("");
|
||||
}
|
||||
|
||||
// Codec 2 VQ Equaliser
|
||||
if ((g_mode == FREEDV_MODE_700C) || (g_mode == FREEDV_MODE_700D)) {
|
||||
freedv_set_eq(g_pfreedv, wxGetApp().m_700C_EQ);
|
||||
}
|
||||
|
||||
if (g_freedv_verbose)
|
||||
freedv_set_verbose(g_pfreedv, 2);
|
||||
else
|
||||
|
@ -2819,7 +2845,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
|
|||
// Stop was pressed or start up failed
|
||||
|
||||
if (startStop.IsSameAs("Stop") || !m_RxRunning ) {
|
||||
|
||||
fprintf(stderr, "Stop .....\n");
|
||||
//
|
||||
// Stop Running -------------------------------------------------
|
||||
//
|
||||
|
@ -3024,9 +3050,9 @@ void MainFrame::startRxStream()
|
|||
bool two_rx=false;
|
||||
bool two_tx=false;
|
||||
|
||||
fprintf(stderr, "startRxStream .....\n");
|
||||
if(!m_RxRunning) {
|
||||
m_RxRunning = true;
|
||||
|
||||
if(Pa_Initialize())
|
||||
{
|
||||
wxMessageBox(wxT("Port Audio failed to initialize"), wxT("Pa_Initialize"), wxOK);
|
||||
|
@ -3038,7 +3064,7 @@ void MainFrame::startRxStream()
|
|||
if(g_soundCard2InDeviceNum != g_soundCard2OutDeviceNum)
|
||||
two_tx=true;
|
||||
|
||||
//fprintf(stderr, "two_rx: %d two_tx: %d\n", two_rx, two_tx);
|
||||
fprintf(stderr, "two_rx: %d two_tx: %d\n", two_rx, two_tx);
|
||||
if(two_rx)
|
||||
m_rxOutPa = new PortAudioWrap();
|
||||
else
|
||||
|
@ -3061,7 +3087,7 @@ void MainFrame::startRxStream()
|
|||
wxMessageBox(wxT("Sound Card 1 not present"), wxT("Error"), wxOK);
|
||||
delete m_rxInPa;
|
||||
if(two_rx)
|
||||
delete m_rxOutPa;
|
||||
delete m_rxOutPa;
|
||||
m_RxRunning = false;
|
||||
return;
|
||||
}
|
||||
|
@ -3322,6 +3348,8 @@ void MainFrame::startRxStream()
|
|||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "started stream 1\n");
|
||||
|
||||
// Start sound card 2 ----------------------------------------------------------
|
||||
|
||||
if (g_nSoundCards == 2) {
|
||||
|
@ -3437,6 +3465,8 @@ void MainFrame::startRxStream()
|
|||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "starting tx/rx processing thread\n");
|
||||
|
||||
// start tx/rx processing thread
|
||||
|
||||
m_txRxThread = new txRxThread;
|
||||
|
@ -3735,9 +3765,10 @@ void txRxProcessing()
|
|||
// (20ms), number of samples is scaled for the sound card sample
|
||||
// rate, so we get the right number of samples for the output
|
||||
// decoded audio
|
||||
|
||||
|
||||
int nsam = g_soundCard1SampleRate * (float)g_modemInbufferSize/freedv_samplerate;
|
||||
assert(nsam <= 10*N48);
|
||||
assert(nsam != 0);
|
||||
while ((codec2_fifo_read(cbData->infifo1, insound_card, nsam) == 0) && ((g_half_duplex && !g_tx) || !g_half_duplex)) {
|
||||
|
||||
/* convert sound card sample rate FreeDV input sample rate */
|
||||
|
@ -3895,13 +3926,27 @@ void txRxProcessing()
|
|||
codec2_fifo_write(cbData->outfifo1, outsound_card, nout);
|
||||
}
|
||||
else {
|
||||
nout = resample(cbData->outsrc2, outsound_card, outfreedv, g_soundCard1SampleRate, freedv_get_speech_sample_rate(g_pfreedv), N48, g_speechOutbufferSize);
|
||||
if (g_analog) /* special case */
|
||||
nout = resample(cbData->outsrc2, outsound_card, outfreedv, g_soundCard1SampleRate, freedv_get_modem_sample_rate(g_pfreedv), N48, nfreedv);
|
||||
else
|
||||
nout = resample(cbData->outsrc2, outsound_card, outfreedv, g_soundCard1SampleRate, freedv_get_speech_sample_rate(g_pfreedv), N48, g_speechOutbufferSize);
|
||||
codec2_fifo_write(cbData->outfifo1, outsound_card, nout);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nout = resample(cbData->outsrc2, outsound_card, outfreedv, g_soundCard2SampleRate, freedv_get_speech_sample_rate(g_pfreedv), N48, g_speechOutbufferSize);
|
||||
codec2_fifo_write(cbData->outfifo2, outsound_card, nout);
|
||||
if (g_mode == -1) {
|
||||
// Horus demod is special case, just echo input samples as it's nice to hear the
|
||||
// off-air modem signal
|
||||
nout = resample(cbData->outsrc2, outsound_card, infreedv, g_soundCard1SampleRate, freedv_samplerate, N48, nfreedv);
|
||||
codec2_fifo_write(cbData->outfifo2, outsound_card, nout);
|
||||
}
|
||||
else {
|
||||
if (g_analog) /* special case */
|
||||
nout = resample(cbData->outsrc2, outsound_card, outfreedv, g_soundCard2SampleRate, freedv_get_modem_sample_rate(g_pfreedv), N48, nfreedv);
|
||||
else
|
||||
nout = resample(cbData->outsrc2, outsound_card, outfreedv, g_soundCard2SampleRate, freedv_get_speech_sample_rate(g_pfreedv), N48, g_speechOutbufferSize);
|
||||
codec2_fifo_write(cbData->outfifo2, outsound_card, nout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4041,7 +4086,10 @@ void txRxProcessing()
|
|||
|
||||
// output one frame of modem signal
|
||||
|
||||
nout = resample(cbData->outsrc1, outsound_card, outfreedv, g_soundCard1SampleRate, freedv_samplerate, 10*N48, nfreedv);
|
||||
if (g_analog)
|
||||
nout = resample(cbData->outsrc1, outsound_card, outfreedv, g_soundCard1SampleRate, freedv_get_speech_sample_rate(g_pfreedv), 10*N48, nfreedv);
|
||||
else
|
||||
nout = resample(cbData->outsrc1, outsound_card, outfreedv, g_soundCard1SampleRate, freedv_samplerate, 10*N48, nfreedv);
|
||||
if (g_dump_fifo_state) {
|
||||
fprintf(stderr, " nout: %d\n", nout);
|
||||
}
|
||||
|
@ -4054,7 +4102,6 @@ void txRxProcessing()
|
|||
if (g_dump_timing) {
|
||||
fprintf(stderr, "%4ld", sw.Time());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
|
|
@ -228,6 +228,8 @@ class MainApp : public wxApp
|
|||
|
||||
// Speex Pre-Processor
|
||||
bool m_speexpp_enable;
|
||||
// Codec 2 700C Equaliser
|
||||
bool m_700C_EQ;
|
||||
|
||||
// Mic In Equaliser
|
||||
float m_MicInBassFreqHz;
|
||||
|
@ -311,6 +313,9 @@ class MainApp : public wxApp
|
|||
bool m_FreeDV700Combine;
|
||||
int m_FreeDV700Interleave;
|
||||
bool m_FreeDV700ManualUnSync;
|
||||
|
||||
bool m_PhaseEstBW;
|
||||
bool m_PhaseEstDPSK;
|
||||
|
||||
// Noise simulation
|
||||
|
||||
|
|
|
@ -187,6 +187,8 @@ TopFrame::TopFrame(wxString plugInName, wxWindow* parent, wxWindowID id, const w
|
|||
sbSizer_ber->Add(m_textFreqOffset, 0, wxALIGN_LEFT, 1);
|
||||
m_textSyncMetric = new wxStaticText(this, wxID_ANY, wxT("Sync: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
sbSizer_ber->Add(m_textSyncMetric, 0, wxALIGN_LEFT, 1);
|
||||
m_textCodec2Var = new wxStaticText(this, wxID_ANY, wxT("Var: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
sbSizer_ber->Add(m_textCodec2Var, 0, wxALIGN_LEFT, 1);
|
||||
|
||||
leftSizer->Add(sbSizer_ber,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ class TopFrame : public wxFrame
|
|||
wxStaticText *m_textClockOffset;
|
||||
wxStaticText *m_textFreqOffset;
|
||||
wxStaticText *m_textSyncMetric;
|
||||
wxStaticText *m_textCodec2Var;
|
||||
|
||||
wxStaticText *m_textSync;
|
||||
wxStaticText *m_textInterleaverSync;
|
||||
|
|
Loading…
Reference in New Issue