first pass at 700E integration

dr-700e
drowe67 2020-12-18 15:14:01 +10:30 committed by David Rowe
parent 409600d480
commit ca79b5ca33
7 changed files with 239 additions and 264 deletions

View File

@ -48,8 +48,8 @@ message(STATUS "Compilation date = XX${DATE_RESULT}XX")
# Set FreeDV version and generate src/version.h
#
set(FREEDV_VERSION_MAJOR 1)
set(FREEDV_VERSION_MINOR 4)
set(FREEDV_VERSION_PATCH 3)
set(FREEDV_VERSION_MINOR 5)
set(FREEDV_VERSION_PATCH 0)
set(FREEDV_VERSION_SUFFIX "devel")
set(FREEDV_VERSION ${FREEDV_VERSION_MAJOR}.${FREEDV_VERSION_MINOR})

View File

@ -123,6 +123,8 @@ nudged. More **is not better** with the FreeDV transmit signal.
Overdriving your transmitter will lead to a distorted transit signal, and
a poor SNR at the receiver. This is a very common problem.
1. FreeDV 700D and 700E can drive your transmitter at an average power of 40% of it's peak power rating. For example 40W RMS for a 100W PEP radio. Make sure your transmitter can handle continuous power output at these levels, and reduce the power if necessary.
1. Adjust the microphone audio so the peaks are not clipping, and the
average is about half the maximum.
@ -198,12 +200,7 @@ As an aid to the above, FreeDV will show the current mode on the bottom of the w
### Overdriving Transmit Level
This is a very common problem for first time FreeDV users. Adjust
your transmit levels so the ALC is just being nudged. For a 100W
PEP radio, your average power should be 20W.
More power is not better with FreeDV. An overdriven signal will have
poor SNR at the receiver.
This is a very common problem for first time FreeDV users. Adjust your transmit levels so the ALC is just being nudged. More power is not better with FreeDV. An overdriven signal will have poor SNR at the receiver. For FreeDV 700D/700E operation with the clipper, make sure your transmitter can sustain high average power levels without damage (e.g. 40W RMS on a 100W PEP radio).
### I can't set up FreeDV, especially the Sound Cards
@ -239,7 +236,7 @@ looks and sounds like.
### Trouble getting Sync with 700D
You need to be within +/- 60 Hz on the transmit signal. It helps if
both the tx and rx stations tune to known, exact frequencies such as
both the Tx and Rx stations tune to known, exact frequencies such as
exactly 7.177MHz. On channels with fast fading sync may take a few
seconds.
@ -344,8 +341,9 @@ Mode | Min SNR | Fading | Latency | Speech Bandwidth | Speech Quality
SSB | 0 | 8/10 | low | 2600 | 5/10
1600 | 4 | 3/10 | low | 4000 | 4/10
700C | 2 | 6/10 | low | 4000 | 3/10
700D | -2 | 7/10 | high | 4000 | 3/10
2020 | 4 | 5/10 | high | 8000 | 7/10
700D | -2 | 4/10 | high | 4000 | 3/10
700E | 1 | 7/10 | medium | 4000 | 3/10
2020 | 4 | 4/10 | high | 8000 | 7/10
Skype | - |- | medium | 8000 | 8/10
The Min SNR is roughly the SNR where you cannot converse without
@ -374,43 +372,11 @@ FreeDV 700D is sensitive to tuning. To obtain sync you must be within
modern radios which are generally accurate to +/-1 Hz, but requires
skill and practice when used with older, VFO based radios.
_The rest of this section describes features and options specific to
FreeDV 700D._
### FreeDV 700E
Main GUI Page:
FreeDV 700E was developed in December 2020 using lessons learned from on air operation of 700C and 700D. A variant of 700D, it uses a shorter frame size (80ms) to reduce latency and sync time. It is optimised for fast fading channels channels with up to 4Hz Doppler spread and 6ms delay spread. FreeDV 7000E uses the same 700 bit/s codec as FreeDV 700C and 700D. It requires about 3dB more power than 700D, but can operate reliably on fast fading channels.
1. Separate indication of Modem and (for 700D) Interleaver Sync. The
number on the Interleaver Sync indicator is the interleaver size in
160ms frames. This is usually set to 1.
1. ReSync button breaks 700D sync and forces it to try again. Useful
if 700D gets a false sync in low SNR channels.
Tools - Options dialog:
1. Clipping: For 700C and 700D reduces the Peak/Average Power Ratio
(PAPR) (also known as Crest Factor) from 12dB to 8dB by clipping the
Tx signal. This will add a little noise to the Tx spectrum and Rx
Scatter diagram, but MAY enable you to drive your Power Amplifier
harder. Use with caution to avoid overloading your Power Amplifier.
1. Tx Band Pass Filter: limits the transmit bandwidth to about 1000
Hz. Usually left on.
1. 700D Interleaver: The interleaver averages out errors over several
frames, which improves performance for fast fading channels and
channels with burst errors. A 16 frame interleaver will improve
performance by 4dB. However interleaving adds delay, and delays sync.
Both the tx and rx must have the same interleaver setting. For
example a setting of 2 means we average errors over 2 160ms frames,
and introduces 2x160=320ms delay in both the Tx and Rx (640ms total).
The interleaver is usually set to 1.
1. 700D Manual Unsync: Sync must be broken manually (ReSync button)
when this option is selected. Disables automatic falling out of
sync. An experimental feature that may be useful for ensuring 700D stays
in sync during long fades, to avoid long resync delays with the
interleaver.
The 700E release also includes optional compression (clipping) of the 700D an 700E transmit waveforms to reduce the Peak to Average Power Ratio to about 4dB. For example a 100W PEP transmitter can be driven to about 40W RMS. This is an improvement of 6dB over previous releases of FreeDV 700D. Before enabling the clipper make sure your transmitter is capable of handling sustained high average power without damage. Clipping can be enabled via Tools-Options.
### FreeDV 2020
@ -466,7 +432,7 @@ This section describes features on Tools-Options. Many of these features are al
Control | Description
--- | --- |
Clipping | Hard clipping of transmit waveform to increase the average power, at the expense of some distortion
Clipping | Increases the average power (700C/700D/700E). Make sure you transmitter can handle high RMS powers before using!
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
@ -647,6 +613,11 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
## Release Notes
### V1.5.0 December 2020
1. FreeDV 700E, better performance than 700D on fast fading channels
1. FreeDV 700D/700E clipper to increase average transmit power by 6dB
### V1.4.3 August 2020
1. Maintenance Release (no major new features)

View File

@ -92,9 +92,9 @@ FilterDlg::FilterDlg(wxWindow* parent, bool running, bool *newMicInFilter, bool
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);
m_ckbox700C_EQ = new wxCheckBox(this, wxID_ANY, _("700C/700D/700E 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"));
m_ckbox700C_EQ->SetToolTip(_("Automatic equalisation for FreeDV 700C/700D/700E Codec input audio"));
bSizer30->Add(sbSizer_speexpp, 0, wxALL, 0);
@ -606,7 +606,7 @@ void FilterDlg::OnSpeexppEnable(wxScrollEvent& event) {
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))) {
if (m_running && ((g_mode == FREEDV_MODE_700C) || (g_mode == FREEDV_MODE_700D) || (g_mode == FREEDV_MODE_700E))) {
freedv_set_eq(g_pfreedv, wxGetApp().m_700C_EQ);
}
}

View File

@ -578,14 +578,16 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
if (mode == 4)
m_rb700d->SetValue(1);
if (mode == 5)
m_rb800xa->SetValue(1);
m_rb700e->SetValue(1);
if (mode == 6)
m_rb800xa->SetValue(1);
if (mode == 7)
m_rb2400b->SetValue(1);
#ifdef __HORUS__
if (mode == 7)
if (mode == 8)
m_rbHorusBinary->SetValue(1);
#endif
if (mode == 8 && isAvxPresent)
if ((mode == 9) && isAvxPresent)
m_rb2020->SetValue(1);
pConfig->SetPath(wxT("/"));
@ -832,16 +834,18 @@ MainFrame::~MainFrame()
mode = 3;
if (m_rb700d->GetValue())
mode = 4;
if (m_rb800xa->GetValue())
if (m_rb700e->GetValue())
mode = 5;
if (m_rb2400b->GetValue())
if (m_rb800xa->GetValue())
mode = 6;
if (m_rb2400b->GetValue())
mode = 7;
#ifdef __HORUS__
if (m_rbHorusBinary->GetValue())
mode = 7;
mode = 8;
#endif
if (m_rb2020->GetValue())
mode = 8;
mode = 9;
pConfig->Write(wxT("/Audio/mode"), mode);
}
@ -944,11 +948,12 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
if ((freedv_get_mode(g_pfreedv) == FREEDV_MODE_1600)
|| (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700D)
|| (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700E)
|| (freedv_get_mode(g_pfreedv) == FREEDV_MODE_2020)) {
m_panelScatter->add_new_samples_scatter(&g_stats.rx_symbols[r][0]);
}
if (/*(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) ||*/(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
if ((freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
if (wxGetApp().m_FreeDV700Combine) {
m_panelScatter->setNc(g_Nc/2); /* m_FreeDV700Combine may have changed at run time */
@ -1108,7 +1113,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
m_textSync->SetLabel("Modem");
}
g_prev_State = g_State;
if ((g_mode == FREEDV_MODE_700D) || (g_mode == FREEDV_MODE_2020)){
if ((g_mode == FREEDV_MODE_700D) || (g_mode == FREEDV_MODE_700E) || (g_mode == FREEDV_MODE_2020)){
if (g_interleaverSyncState) {
m_textInterleaverSync->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
m_textInterleaverSync->SetLabel("Intrlvr ("+wxString::Format(wxT("%i"),wxGetApp().m_FreeDV700Interleave)+")");
@ -1254,8 +1259,8 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
else {
// set some run time options (if applicable to this mode)
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_clip(g_pfreedv, (int)wxGetApp().m_FreeDV700txClip); // 700C/700D/700E/2020
freedv_set_tx_bpf(g_pfreedv, (int)wxGetApp().m_FreeDV700txBPF); // 700D/700E
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
@ -1290,7 +1295,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
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)) {
if ((g_mode == FREEDV_MODE_700C) || (g_mode == FREEDV_MODE_700D) || (g_mode == FREEDV_MODE_700E)) {
struct CODEC2 *c2 = freedv_get_codec2(g_pfreedv);
assert(c2 != NULL);
float var = codec2_get_var(c2);
@ -1341,7 +1346,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
m_panelTestFrameErrorsHist->add_new_samples(0, ber, 2*MODEM_STATS_NC_MAX);
}
if (/*(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) || */(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
if ((freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
int c;
//fprintf(stderr, "after g_error_pattern_fifo read 2\n");
@ -2668,6 +2673,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
m_rb1600->Disable();
m_rb700c->Disable();
m_rb700d->Disable();
m_rb700e->Disable();
m_rb800xa->Disable();
m_rb2400b->Disable();
#ifdef __HORUS__
@ -2702,6 +2708,11 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
g_Nc = 17; /* TODO: be nice if we didn't have to hard code this, maybe API call? */
m_panelScatter->setNc(g_Nc);
}
if (m_rb700e->GetValue()) {
g_mode = FREEDV_MODE_700E;
g_Nc = 17;
m_panelScatter->setNc(g_Nc);
}
if (m_rb800xa->GetValue()) {
g_mode = FREEDV_MODE_800XA;
}
@ -2740,7 +2751,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
m_btnTogPTT->Enable();
m_togBtnVoiceKeyer->Enable();
if ((g_mode == FREEDV_MODE_700D) || (g_mode == FREEDV_MODE_2020)) {
if ((g_mode == FREEDV_MODE_700D) || (g_mode == FREEDV_MODE_700E) || (g_mode == FREEDV_MODE_2020)) {
// 700D has some init time stuff so treat it special
struct freedv_advanced adv;
adv.interleave_frames = wxGetApp().m_FreeDV700Interleave;
@ -2757,7 +2768,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
}
// Codec 2 VQ Equaliser
if ((g_mode == FREEDV_MODE_700C) || (g_mode == FREEDV_MODE_700D)) {
if ((g_mode == FREEDV_MODE_700C) || (g_mode == FREEDV_MODE_700D) || (g_mode == FREEDV_MODE_700E)) {
freedv_set_eq(g_pfreedv, wxGetApp().m_700C_EQ);
}
@ -2953,6 +2964,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
m_rb1600->Enable();
m_rb700c->Enable();
m_rb700d->Enable();
m_rb700e->Enable();
m_rb800xa->Enable();
m_rb2400b->Enable();
#ifdef __HORUS__

View File

@ -338,20 +338,12 @@ TopFrame::TopFrame(wxString plugInName, wxWindow* parent, wxWindowID id, const w
wxStaticBoxSizer* sbSizer_mode;
sbSizer_mode = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mode")), wxVERTICAL);
#ifdef DISABLED_FEATURE
m_rb1400old = new wxRadioButton( this, wxID_ANY, wxT("1400 V0.91"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
sbSizer_mode->Add(m_rb1400old, 0, wxALIGN_LEFT|wxALL, 1);
m_rb1400 = new wxRadioButton( this, wxID_ANY, wxT("1400"), wxDefaultPosition, wxDefaultSize, 0);
sbSizer_mode->Add(m_rb1400, 0, wxALIGN_LEFT|wxALL, 1);
m_rb700 = new wxRadioButton( this, wxID_ANY, wxT("700"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
sbSizer_mode->Add(m_rb700, 0, wxALIGN_LEFT|wxALL, 1);
m_rb700b = new wxRadioButton( this, wxID_ANY, wxT("700B"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
sbSizer_mode->Add(m_rb700b, 0, wxALIGN_LEFT|wxALL, 1);
#endif
m_rb700c = new wxRadioButton( this, wxID_ANY, wxT("700C"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
sbSizer_mode->Add(m_rb700c, 0, wxALIGN_LEFT|wxALL, 1);
m_rb700d = new wxRadioButton( this, wxID_ANY, wxT("700D"), wxDefaultPosition, wxDefaultSize, 0);
sbSizer_mode->Add(m_rb700d, 0, wxALIGN_LEFT|wxALL, 1);
m_rb700e = new wxRadioButton( this, wxID_ANY, wxT("700E"), wxDefaultPosition, wxDefaultSize, 0);
sbSizer_mode->Add(m_rb700e, 0, wxALIGN_LEFT|wxALL, 1);
m_rb800xa = new wxRadioButton( this, wxID_ANY, wxT("800XA"), wxDefaultPosition, wxDefaultSize, 0);
sbSizer_mode->Add(m_rb800xa, 0, wxALIGN_LEFT|wxALL, 1);
m_rb1600 = new wxRadioButton( this, wxID_ANY, wxT("1600"), wxDefaultPosition, wxDefaultSize, 0);
@ -632,4 +624,3 @@ TopFrame::~TopFrame()
m_btnTogPTT->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
}

View File

@ -115,6 +115,7 @@ class TopFrame : public wxFrame
wxRadioButton *m_rb700c;
wxRadioButton *m_rb700d;
wxRadioButton *m_rb700e;
wxRadioButton *m_rb800xa;
wxRadioButton *m_rb1600;
wxRadioButton *m_rb2400a;

BIN
wav/ve9qrp_700e.wav 100644

Binary file not shown.