Compare commits
7 Commits
freedv-3.0
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
56da90b9b1 | |
|
|
1e062689da | |
|
|
102aa6e483 | |
|
|
321db15f63 | |
|
|
932b90e15f | |
|
|
5834e2f45f | |
|
|
9e7d24c244 |
|
|
@ -15,7 +15,7 @@ endif()
|
|||
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum OS X deployment version")
|
||||
|
||||
set(PROJECT_NAME FreeDV)
|
||||
set(PROJECT_VERSION 2.4.1)
|
||||
set(PROJECT_VERSION 2.4.2)
|
||||
set(PROJECT_DESCRIPTION "HF Digital Voice for Radio Amateurs")
|
||||
set(PROJECT_HOMEPAGE_URL "https://freedv.org")
|
||||
|
||||
|
|
|
|||
156
USER_MANUAL.html
156
USER_MANUAL.html
|
|
@ -139,30 +139,30 @@ sent <strong>to</strong> your radio for transmission over the air.</p>
|
|||
<col style="width: 42%" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<tr>
|
||||
<th>Tab</th>
|
||||
<th>Sound Device</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>Receive Tab</td>
|
||||
<td>Input To Computer From Radio</td>
|
||||
<td>The off air FreeDV signal <strong>from</strong> your radio rig
|
||||
interface to your computer</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>Receive Tab</td>
|
||||
<td>Output From Computer To Speaker/Headphones</td>
|
||||
<td>The decoded audio from your computer to your Speaker/Headphones</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>Transmit Tab</td>
|
||||
<td>Input From Microphone To Computer</td>
|
||||
<td>Your voice from the microphone to your computer</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>Transmit Tab</td>
|
||||
<td>Output From Computer To Radio</td>
|
||||
<td>The FreeDV signal from your computer sent <strong>to</strong> your
|
||||
|
|
@ -254,21 +254,21 @@ locations depending on platform:</p>
|
|||
<col style="width: 86%" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<tr>
|
||||
<th>Platform</th>
|
||||
<th>Typical Location</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>Windows</td>
|
||||
<td>C:\Program Files\FreeDV [version]\share\freedv-gui\wav</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td>/usr/share/freedv-gui/wav or /usr/local/share/freedv-gui/wav</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>macOS</td>
|
||||
<td>See https://github.com/freedv/freedv-gui/tree/master/wav</td>
|
||||
</tr>
|
||||
|
|
@ -379,25 +379,25 @@ untested).</p>
|
|||
are below:</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<tr>
|
||||
<th>Mode</th>
|
||||
<th>Width (kHz)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>1600</td>
|
||||
<td>1.125</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>700D</td>
|
||||
<td>1.000</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>700E</td>
|
||||
<td>1.500</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>RADEV1</td>
|
||||
<td>1.500</td>
|
||||
</tr>
|
||||
|
|
@ -612,7 +612,7 @@ class="header-section-number">10</span> FreeDV Modes</h1>
|
|||
SSB and Skype as anchors for a rough guide to audio quality:</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<tr>
|
||||
<th>Mode</th>
|
||||
<th style="text-align: center;">Min SNR</th>
|
||||
<th style="text-align: center;">Fading</th>
|
||||
|
|
@ -622,7 +622,7 @@ SSB and Skype as anchors for a rough guide to audio quality:</p>
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>SSB</td>
|
||||
<td style="text-align: center;">0</td>
|
||||
<td style="text-align: center;">8/10</td>
|
||||
|
|
@ -630,7 +630,7 @@ SSB and Skype as anchors for a rough guide to audio quality:</p>
|
|||
<td style="text-align: center;">2600</td>
|
||||
<td style="text-align: center;">5/10</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>1600 (*)</td>
|
||||
<td style="text-align: center;">4</td>
|
||||
<td style="text-align: center;">3/10</td>
|
||||
|
|
@ -638,7 +638,7 @@ SSB and Skype as anchors for a rough guide to audio quality:</p>
|
|||
<td style="text-align: center;">4000</td>
|
||||
<td style="text-align: center;">4/10</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>700D (*)</td>
|
||||
<td style="text-align: center;">-2</td>
|
||||
<td style="text-align: center;">4/10</td>
|
||||
|
|
@ -646,7 +646,7 @@ SSB and Skype as anchors for a rough guide to audio quality:</p>
|
|||
<td style="text-align: center;">4000</td>
|
||||
<td style="text-align: center;">3/10</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>700E (*)</td>
|
||||
<td style="text-align: center;">1</td>
|
||||
<td style="text-align: center;">7/10</td>
|
||||
|
|
@ -654,7 +654,7 @@ SSB and Skype as anchors for a rough guide to audio quality:</p>
|
|||
<td style="text-align: center;">4000</td>
|
||||
<td style="text-align: center;">3/10</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>RADEV1</td>
|
||||
<td style="text-align: center;">-2</td>
|
||||
<td style="text-align: center;">8/10</td>
|
||||
|
|
@ -662,7 +662,7 @@ SSB and Skype as anchors for a rough guide to audio quality:</p>
|
|||
<td style="text-align: center;">8000</td>
|
||||
<td style="text-align: center;">7/10</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>Skype</td>
|
||||
<td style="text-align: center;">-</td>
|
||||
<td style="text-align: center;">-</td>
|
||||
|
|
@ -781,18 +781,18 @@ class="header-section-number">11.1</span> Tools - Filter</h2>
|
|||
<col style="width: 73%" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<tr>
|
||||
<th>Control</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>Noise Suppression</td>
|
||||
<td>Enable noise suppression, de-reverberation, AGC of mic signal using
|
||||
the Speex pre-processor</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>700D Auto EQ</td>
|
||||
<td>Automatic equalization for FreeDV 700D/E Codec input audio</td>
|
||||
</tr>
|
||||
|
|
@ -821,18 +821,18 @@ class="header-section-number">11.2.1</span> Modem Options</h3>
|
|||
<col style="width: 71%" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<tr>
|
||||
<th>Control</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>Clipping</td>
|
||||
<td>Increases the average power. Ensure your transmitter can handle high
|
||||
RMS powers before using!</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>TX Band Pass Filter</td>
|
||||
<td>Reduces TX spectrum bandwidth</td>
|
||||
</tr>
|
||||
|
|
@ -876,9 +876,10 @@ the menu bar by a similar process.</p>
|
|||
border and clicking and holding the left mouse button and dragging to
|
||||
required size.</p>
|
||||
<p>By default, the tab layout is not saved. However, by enabling
|
||||
experimental features (see “Advanced/Developer Features”), experimental
|
||||
support for saving and restoring the tab layout will be enabled. This
|
||||
has not been well tested and may have hidden bugs or other issues.</p>
|
||||
experimental features (see <a href="#experimental-features">Experimental
|
||||
Features</a>), experimental support for saving and restoring the tab
|
||||
layout will be enabled. This has not been well tested and may have
|
||||
hidden bugs or other issues.</p>
|
||||
<figure>
|
||||
<img src="contrib/multiple_panes.png" alt="Multiple Panes" />
|
||||
<figcaption aria-hidden="true">Multiple Panes</figcaption>
|
||||
|
|
@ -890,37 +891,37 @@ class="header-section-number">14.1</span> Stats Window</h2>
|
|||
<p>Located on the lower left hand side of the main screen.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<tr>
|
||||
<th>Term</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>Bits</td>
|
||||
<td>Number of bits demodulated</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>Errs</td>
|
||||
<td>Number of bit errors detected</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>Resyncs</td>
|
||||
<td>Number of times the demodulator has resynced</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>ClkOff</td>
|
||||
<td>Estimated sample clock offset in parts per million</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>FreqOff</td>
|
||||
<td>Estimated frequency offset in Hz</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>Sync</td>
|
||||
<td>Sync metric (OFDM modes like 700D/E)</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>Var</td>
|
||||
<td>Speech encoder distortion for 700D (see Auto EQ)</td>
|
||||
</tr>
|
||||
|
|
@ -1243,23 +1244,23 @@ class="header-section-number">18</span> Glossary</h1>
|
|||
<col style="width: 93%" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<tr>
|
||||
<th>Term</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>AWGN</td>
|
||||
<td>Additive White Gaussian Noise - a channel with just noise and no
|
||||
fading (like VHF)</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr>
|
||||
<td>FEC</td>
|
||||
<td>Forward Error Correction - extra bits to we send to protect the
|
||||
speech codec bits</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr>
|
||||
<td>LDPC</td>
|
||||
<td>Low Density Parity Check Codes - a family of powerful FEC codes</td>
|
||||
</tr>
|
||||
|
|
@ -1267,8 +1268,22 @@ speech codec bits</td>
|
|||
</table>
|
||||
<h1 data-number="19" id="release-notes"><span
|
||||
class="header-section-number">19</span> Release Notes</h1>
|
||||
<h2 data-number="19.1" id="v2.4.1-tbd-2026"><span
|
||||
class="header-section-number">19.1</span> V2.4.1 TBD 2026</h2>
|
||||
<h2 data-number="19.1" id="v2.4.2-tbd-2026"><span
|
||||
class="header-section-number">19.1</span> V2.4.2 TBD 2026</h2>
|
||||
<ol type="1">
|
||||
<li>Bugfixes:
|
||||
<ul>
|
||||
<li>FreeDV Reporter: don’t select the station under the mouse when the
|
||||
list gains focus without a click. (PR #1611)</li>
|
||||
</ul></li>
|
||||
<li>Documentation:
|
||||
<ul>
|
||||
<li>User manual: Update reference to Experimental Features section. (PR
|
||||
#1613)</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
<h2 data-number="19.2" id="v2.4.1-october-2026"><span
|
||||
class="header-section-number">19.2</span> V2.4.1 October 2026</h2>
|
||||
<ol type="1">
|
||||
<li>Bugfixes:
|
||||
<ul>
|
||||
|
|
@ -1303,7 +1318,7 @@ displays. (PR #1514)</li>
|
|||
<li>Fix possible deadlock on playback completion. (PR #1533)</li>
|
||||
<li>Windows: add logic to detect audio device stalls. (PR #1537)</li>
|
||||
<li>Keep RX muted after TX until the radio confirms PTT off. (PR #1536,
|
||||
#1603)</li>
|
||||
#1603, #1605)</li>
|
||||
<li>Fix FreeDV hanging when starting the Voice Keyer with a cloud-backed
|
||||
file. (PR #1534)</li>
|
||||
<li>Fix data races on settings read by the audio threads. (PR
|
||||
|
|
@ -1424,6 +1439,39 @@ mode from starting. (PR #1594)</li>
|
|||
<li>PlotScalar: draw the trace when the plot is wider than its sample
|
||||
count. (PR #1597) - thanks <span class="citation"
|
||||
data-cites="barjac">@barjac</span>!</li>
|
||||
<li>Linux/FreeDV Reporter: fix uninitialized value deciding whether a
|
||||
selection is honored. (PR #1606)</li>
|
||||
<li>Allow microphone and speaker devices below 16 kHz (such as Bluetooth
|
||||
headsets in call mode) with a warning instead of refusing to start. (PR
|
||||
#1608)</li>
|
||||
<li>FreeDV Reporter: fix possible crash when repeatedly connecting and
|
||||
disconnecting. (freedv-backend PR #44)</li>
|
||||
<li>FreeDV Reporter: fix exiting FreeDV taking up to 60 seconds when the
|
||||
server stalls setting up the secure connection; give up on it after 10
|
||||
seconds instead. (freedv-backend PR #63)</li>
|
||||
<li>FreeDV Reporter: fix memory leak when FreeDV exits just as FreeDV
|
||||
Reporter connects. (freedv-backend PR #75)</li>
|
||||
<li>Recording: fix up to the last 100 ms of audio being lost when a
|
||||
recording stops, and log when audio has to be dropped. (freedv-backend
|
||||
PR #71, #72)</li>
|
||||
<li>Fix conversion of 16-bit audio to floating point going slightly past
|
||||
full scale. (freedv-backend PR #60)</li>
|
||||
<li>Fix buffer overruns when one RADE receive call decodes several
|
||||
frames and when resampling 8 kHz audio by large ratios. (freedv-backend
|
||||
PR #78)</li>
|
||||
<li>Fix the audio pipeline rebuilding its resampler when the sample rate
|
||||
is unchanged but not when it changes, and freeing the kept resampler
|
||||
twice. (freedv-backend PR #78)</li>
|
||||
<li>FreeDV Reporter: refuse a secure connection if TLS 1.2 or
|
||||
certificate hostname checking can’t be enforced. (freedv-backend PR
|
||||
#78)</li>
|
||||
<li>macOS/FreeDV Reporter: fix endless loop and log spam when the
|
||||
connection closes while sending. (freedv-backend PR #78)</li>
|
||||
<li>Fix network and threading code continuing after a failed socket or
|
||||
semaphore setup, Linux semaphore waits ending early on a signal, and a
|
||||
macOS crash on an empty background task. (freedv-backend PR #78)</li>
|
||||
<li>Windows: fix exiting FreeDV taking 20 seconds or more while logging
|
||||
heavily. (freedv-backend PR #78)</li>
|
||||
</ul></li>
|
||||
<li>Build system:
|
||||
<ul>
|
||||
|
|
@ -1443,6 +1491,14 @@ information, and only use ccache in CI for the builds that compile them.
|
|||
<li>Add tests of whole transmissions through the TX/RX threads without
|
||||
sound cards. (PR #1567)</li>
|
||||
<li>Resolve build failure on OpenSUSE Tumbleweed. (PR #1577)</li>
|
||||
<li>Fix Windows build failures with newer llvm-mingw (clang/libc++)
|
||||
releases. (freedv-backend PR #51)</li>
|
||||
<li>Fix Windows build with older mingw-w64 headers that don’t declare
|
||||
SetThreadDescription. (freedv-backend PR #60)</li>
|
||||
<li>macOS: fix RNNoise build failure with newer Xcode versions.
|
||||
(freedv-backend PR #59)</li>
|
||||
<li>Fix build errors with GCC 16 and with OpenSSL 4 deprecations.
|
||||
(freedv-backend PR #41, #73)</li>
|
||||
</ul></li>
|
||||
<li>Documentation:
|
||||
<ul>
|
||||
|
|
@ -1455,10 +1511,12 @@ sound cards. (PR #1567)</li>
|
|||
<li>Windows audio thread timing improvements. (PR #1488)</li>
|
||||
<li>Log when the sound server puts a PulseAudio stream on another
|
||||
device. (PR #1591)</li>
|
||||
<li>Log from the audio threads without blocking them. (freedv-backend PR
|
||||
#60)</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
<h2 data-number="19.2" id="v2.4.0-august-2026"><span
|
||||
class="header-section-number">19.2</span> V2.4.0 August 2026</h2>
|
||||
<h2 data-number="19.3" id="v2.4.0-august-2026"><span
|
||||
class="header-section-number">19.3</span> V2.4.0 August 2026</h2>
|
||||
<ol type="1">
|
||||
<li>Bugfixes:
|
||||
<ul>
|
||||
|
|
@ -1569,8 +1627,8 @@ data-cites="barjac">@barjac</span>!</li>
|
|||
#1435)</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
<h2 data-number="19.3" id="earlier-than-v2.3.0"><span
|
||||
class="header-section-number">19.3</span> Earlier than V2.3.0</h2>
|
||||
<h2 data-number="19.4" id="earlier-than-v2.3.0"><span
|
||||
class="header-section-number">19.4</span> Earlier than V2.3.0</h2>
|
||||
<p>See <a
|
||||
href="https://github.com/freedv/freedv-gui/blob/master/CHANGELOG_OLD.md">this</a>
|
||||
for more information about changes in versions prior to 2.3.0.</p>
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ As the Tab is dragged into position a faint blue/gray image will show the positi
|
|||
|
||||
Tabs can be resized as required by hovering the cursor over the border and clicking and holding the left mouse button and dragging to required size.
|
||||
|
||||
By default, the tab layout is not saved. However, by enabling experimental features (see "Advanced/Developer Features"), experimental support for
|
||||
By default, the tab layout is not saved. However, by enabling experimental features (see [Experimental Features](#experimental-features)), experimental support for
|
||||
saving and restoring the tab layout will be enabled. This has not been well tested and may have hidden bugs or other issues.
|
||||
|
||||

|
||||
|
|
@ -947,7 +947,14 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
|
|||
|
||||
# Release Notes
|
||||
|
||||
## V2.4.1 TBD 2026
|
||||
## V2.4.2 TBD 2026
|
||||
|
||||
1. Bugfixes:
|
||||
* FreeDV Reporter: don't select the station under the mouse when the list gains focus without a click. (PR #1611)
|
||||
2. Documentation:
|
||||
* User manual: Update reference to Experimental Features section. (PR #1613)
|
||||
|
||||
## V2.4.1 October 2026
|
||||
|
||||
1. Bugfixes:
|
||||
* Add logic to prevent FIFO sizes that are too small to allow TX thread to function. (PR #1474)
|
||||
|
|
@ -1026,6 +1033,19 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
|
|||
* Stop the radio recording budget at zero instead of wrapping it. (PR #1592)
|
||||
* Windows: Fix issue preventing audio devices that don't support raw mode from starting. (PR #1594)
|
||||
* PlotScalar: draw the trace when the plot is wider than its sample count. (PR #1597) - thanks @barjac!
|
||||
* Linux/FreeDV Reporter: fix uninitialized value deciding whether a selection is honored. (PR #1606)
|
||||
* Allow microphone and speaker devices below 16 kHz (such as Bluetooth headsets in call mode) with a warning instead of refusing to start. (PR #1608)
|
||||
* FreeDV Reporter: fix possible crash when repeatedly connecting and disconnecting. (freedv-backend PR #44)
|
||||
* FreeDV Reporter: fix exiting FreeDV taking up to 60 seconds when the server stalls setting up the secure connection; give up on it after 10 seconds instead. (freedv-backend PR #63)
|
||||
* FreeDV Reporter: fix memory leak when FreeDV exits just as FreeDV Reporter connects. (freedv-backend PR #75)
|
||||
* Recording: fix up to the last 100 ms of audio being lost when a recording stops, and log when audio has to be dropped. (freedv-backend PR #71, #72)
|
||||
* Fix conversion of 16-bit audio to floating point going slightly past full scale. (freedv-backend PR #60)
|
||||
* Fix buffer overruns when one RADE receive call decodes several frames and when resampling 8 kHz audio by large ratios. (freedv-backend PR #78)
|
||||
* Fix the audio pipeline rebuilding its resampler when the sample rate is unchanged but not when it changes, and freeing the kept resampler twice. (freedv-backend PR #78)
|
||||
* FreeDV Reporter: refuse a secure connection if TLS 1.2 or certificate hostname checking can't be enforced. (freedv-backend PR #78)
|
||||
* macOS/FreeDV Reporter: fix endless loop and log spam when the connection closes while sending. (freedv-backend PR #78)
|
||||
* Fix network and threading code continuing after a failed socket or semaphore setup, Linux semaphore waits ending early on a signal, and a macOS crash on an empty background task. (freedv-backend PR #78)
|
||||
* Windows: fix exiting FreeDV taking 20 seconds or more while logging heavily. (freedv-backend PR #78)
|
||||
2. Build system:
|
||||
* Windows versions are now built with llvm-mingw 20260908 (PR #1489)
|
||||
* Ccache support extended to third party dependencies. (PR #1498, #1505))
|
||||
|
|
@ -1036,12 +1056,17 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
|
|||
* Add unit tests for non-GUI code. (PR #1542)
|
||||
* Add tests of whole transmissions through the TX/RX threads without sound cards. (PR #1567)
|
||||
* Resolve build failure on OpenSUSE Tumbleweed. (PR #1577)
|
||||
* Fix Windows build failures with newer llvm-mingw (clang/libc++) releases. (freedv-backend PR #51)
|
||||
* Fix Windows build with older mingw-w64 headers that don't declare SetThreadDescription. (freedv-backend PR #60)
|
||||
* macOS: fix RNNoise build failure with newer Xcode versions. (freedv-backend PR #59)
|
||||
* Fix build errors with GCC 16 and with OpenSSL 4 deprecations. (freedv-backend PR #41, #73)
|
||||
3. Documentation:
|
||||
* Update documentation to reflect new repo URL. (PR #1569)
|
||||
4. Other:
|
||||
* Various GUI performance improvements. (PR #1481, #1521, #1524, #1527, #1531)
|
||||
* Windows audio thread timing improvements. (PR #1488)
|
||||
* Log when the sound server puts a PulseAudio stream on another device. (PR #1591)
|
||||
* Log from the audio threads without blocking them. (freedv-backend PR #60)
|
||||
|
||||
## V2.4.0 August 2026
|
||||
|
||||
|
|
|
|||
BIN
USER_MANUAL.pdf
BIN
USER_MANUAL.pdf
Binary file not shown.
|
|
@ -1815,6 +1815,15 @@ void FreeDVReporterDialog::OnLeftClickTooltip(wxMouseEvent& event)
|
|||
|
||||
void FreeDVReporterDialog::OnSetFocus(wxFocusEvent& event)
|
||||
{
|
||||
// Only select the item under the mouse if the focus came from clicking
|
||||
// on it, not from e.g. the window being brought to the front or a
|
||||
// tooltip closing while the mouse happens to be over the list.
|
||||
if (!wxGetMouseState().ButtonIsDown(wxMOUSE_BTN_ANY))
|
||||
{
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
CallAfter([this]() {
|
||||
const wxPoint pt = wxGetMousePosition();
|
||||
int mouseX = pt.x - m_listSpots->GetScreenPosition().x;
|
||||
|
|
|
|||
|
|
@ -527,7 +527,9 @@ class FreeDVReporterDialog : public wxFrame
|
|||
|
||||
};
|
||||
|
||||
bool isSelectionPossible_;
|
||||
// Linux workaround to avoid inadvertent selections: set once the
|
||||
// pointer has been over a row.
|
||||
bool isSelectionPossible_ = false;
|
||||
|
||||
void createColumn_(int col, bool visible);
|
||||
wxDataViewColumn* getColumnForModelColId_(unsigned int col);
|
||||
|
|
|
|||
101
src/main.cpp
101
src/main.cpp
|
|
@ -4106,47 +4106,78 @@ bool MainFrame::validateSoundCardSetup(bool silent)
|
|||
}
|
||||
else
|
||||
{
|
||||
const int MIN_SAMPLE_RATE_ANALOG = 16000;
|
||||
const int MIN_SAMPLE_RATE_RADIO = 8000;
|
||||
int failedSampleRate = 0;
|
||||
int expectedSampleRate = 0;
|
||||
int expectedSampleRate1Out = (g_nSoundCards.load(std::memory_order_acquire) == 1 ? MIN_SAMPLE_RATE_ANALOG : MIN_SAMPLE_RATE_RADIO);
|
||||
|
||||
// Validate sample rates
|
||||
if (wxGetApp().appConfiguration.audioConfiguration.soundCard1In.deviceName != "none" && wxGetApp().appConfiguration.audioConfiguration.soundCard1In.sampleRate < MIN_SAMPLE_RATE_RADIO)
|
||||
// Below 8 kHz, FreeDV can't run at all. Mic and speaker devices
|
||||
// below 16 kHz still work (audio is resampled), but they can't carry
|
||||
// the upper half of RADE's 8 kHz audio bandwidth, so warn instead.
|
||||
const int MIN_SAMPLE_RATE = 8000;
|
||||
const int MIN_SAMPLE_RATE_ANALOG_RECOMMENDED = 16000;
|
||||
auto& audioConfig = wxGetApp().appConfiguration.audioConfiguration;
|
||||
bool oneSoundCard = g_nSoundCards.load(std::memory_order_acquire) == 1;
|
||||
|
||||
struct DeviceToCheck
|
||||
{
|
||||
failedDeviceName = wxGetApp().appConfiguration.audioConfiguration.soundCard1In.deviceName.get();
|
||||
failedSampleRate = wxGetApp().appConfiguration.audioConfiguration.soundCard1In.sampleRate;
|
||||
expectedSampleRate = MIN_SAMPLE_RATE_RADIO;
|
||||
canRun = false;
|
||||
wxString deviceName;
|
||||
int sampleRate;
|
||||
bool isAnalog;
|
||||
};
|
||||
DeviceToCheck devicesToCheck[] = {
|
||||
{ audioConfig.soundCard1In.deviceName, audioConfig.soundCard1In.sampleRate, false },
|
||||
{ audioConfig.soundCard1Out.deviceName, audioConfig.soundCard1Out.sampleRate, oneSoundCard },
|
||||
{ audioConfig.soundCard2In.deviceName, audioConfig.soundCard2In.sampleRate, true },
|
||||
{ audioConfig.soundCard2Out.deviceName, audioConfig.soundCard2Out.sampleRate, true },
|
||||
};
|
||||
|
||||
std::vector<wxString> lowRateDeviceList;
|
||||
wxString lowRateAnalogDevices;
|
||||
for (auto& device : devicesToCheck)
|
||||
{
|
||||
const wxString& deviceName = device.deviceName;
|
||||
if (deviceName == "none")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (device.sampleRate < MIN_SAMPLE_RATE)
|
||||
{
|
||||
if (!silent)
|
||||
{
|
||||
wxMessageBox(wxString::Format(
|
||||
"Your %s device is set to use a sample rate of %d, which is less than the minimum of %d. Please go to Tools->Audio Config... to check your settings.",
|
||||
deviceName, device.sampleRate, MIN_SAMPLE_RATE), wxT("Sample Rate Too Low"), wxOK, this);
|
||||
}
|
||||
canRun = false;
|
||||
break;
|
||||
}
|
||||
else if (device.isAnalog && device.sampleRate < MIN_SAMPLE_RATE_ANALOG_RECOMMENDED)
|
||||
{
|
||||
log_warn("%s is using a sample rate of %d; audio above %d Hz will be lost", (const char*)deviceName.ToUTF8(), device.sampleRate, device.sampleRate / 2);
|
||||
wxString lowRateDeviceString = wxString::Format("%s (%d Hz)", deviceName, device.sampleRate);
|
||||
bool found = false;
|
||||
for (auto& str : lowRateDeviceList)
|
||||
{
|
||||
if (str == lowRateDeviceString)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) lowRateDeviceList.push_back(lowRateDeviceString);
|
||||
}
|
||||
}
|
||||
else if (wxGetApp().appConfiguration.audioConfiguration.soundCard1Out.deviceName != "none" && wxGetApp().appConfiguration.audioConfiguration.soundCard1Out.sampleRate < expectedSampleRate1Out)
|
||||
|
||||
// Only warn once per session so that each Start doesn't bring this up again.
|
||||
for (auto& str : lowRateDeviceList)
|
||||
{
|
||||
failedDeviceName = wxGetApp().appConfiguration.audioConfiguration.soundCard1Out.deviceName.get();
|
||||
failedSampleRate = wxGetApp().appConfiguration.audioConfiguration.soundCard1Out.sampleRate;
|
||||
expectedSampleRate = expectedSampleRate1Out;
|
||||
canRun = false;
|
||||
lowRateAnalogDevices += wxString::Format("\n%s", str);
|
||||
}
|
||||
else if (wxGetApp().appConfiguration.audioConfiguration.soundCard2In.deviceName != "none" && wxGetApp().appConfiguration.audioConfiguration.soundCard2In.sampleRate < MIN_SAMPLE_RATE_ANALOG)
|
||||
{
|
||||
failedDeviceName = wxGetApp().appConfiguration.audioConfiguration.soundCard2In.deviceName.get();
|
||||
failedSampleRate = wxGetApp().appConfiguration.audioConfiguration.soundCard2In.sampleRate;
|
||||
expectedSampleRate = MIN_SAMPLE_RATE_ANALOG;
|
||||
canRun = false;
|
||||
}
|
||||
else if (wxGetApp().appConfiguration.audioConfiguration.soundCard2Out.deviceName != "none" && wxGetApp().appConfiguration.audioConfiguration.soundCard2Out.sampleRate < MIN_SAMPLE_RATE_ANALOG)
|
||||
{
|
||||
failedDeviceName = wxGetApp().appConfiguration.audioConfiguration.soundCard2Out.deviceName.get();
|
||||
failedSampleRate = wxGetApp().appConfiguration.audioConfiguration.soundCard2Out.sampleRate;
|
||||
expectedSampleRate = MIN_SAMPLE_RATE_ANALOG;
|
||||
canRun = false;
|
||||
}
|
||||
|
||||
if (!canRun && !silent)
|
||||
|
||||
static bool lowRateWarningShown = false;
|
||||
if (canRun && !silent && !lowRateAnalogDevices.IsEmpty() && !lowRateWarningShown)
|
||||
{
|
||||
lowRateWarningShown = true;
|
||||
wxMessageBox(wxString::Format(
|
||||
"Your %s device is set to use a sample rate of %d, which is less than the minimum of %d. Please go to Tools->Audio Config... to check your settings.",
|
||||
failedDeviceName, failedSampleRate, expectedSampleRate), wxT("Sample Rate Too Low"), wxOK, this);
|
||||
"The following microphone/speaker devices are set to a sample rate below the recommended minimum of %d Hz:\n%s\n\nFreeDV will still work, but speech will sound muffled to you or to other stations, depending on which device it is. If your device supports a sample rate higher than 16 kHz, consider enabling it.",
|
||||
MIN_SAMPLE_RATE_ANALOG_RECOMMENDED, lowRateAnalogDevices), wxT("Low Sample Rate"), wxOK | wxICON_WARNING, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,15 +147,24 @@ bool recordsSamplesInOrder()
|
|||
{
|
||||
Recording recording;
|
||||
|
||||
// Pace things the way the audio device would so that this is about
|
||||
// ordering rather than how much can be queued at once.
|
||||
// Let each burst reach the file before queuing the next so that this is
|
||||
// about ordering rather than how much can be queued at once (a fixed sleep
|
||||
// isn't enough when the writer thread is starved, as on Windows runners).
|
||||
std::vector<short> expected;
|
||||
for (int block = 0; block < 100; block++)
|
||||
{
|
||||
auto samples = ramp(BLOCK_SIZE, block * BLOCK_SIZE);
|
||||
expected.insert(expected.end(), samples.begin(), samples.end());
|
||||
recording.record(samples);
|
||||
if (block % 10 == 9) std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
if (block % 10 == 9)
|
||||
{
|
||||
auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5);
|
||||
while (recording.numSamplesReported < (int)expected.size() &&
|
||||
std::chrono::steady_clock::now() < deadline)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return samplesAre(recording.finish(), expected);
|
||||
|
|
|
|||
Loading…
Reference in New Issue