Commit Graph

214 Commits (master)

Author SHA1 Message Date
Mooneer Salem 102aa6e483
FreeDV Reporter: don't select the row under the mouse on focus without a click; begin 2.4.2 development (#1611)
* FreeDV Reporter: only select the row under the mouse on focus if a button is down.

OnSetFocus() selected whatever row the mouse was over whenever the list
gained the focus, including when that came from the window being brought
to the front or a tooltip closing rather than a click. On Linux the
selection guard doesn't stop this either, as hovering over a row already
allows selections. This caused an occasional gui_reporter_row_actions
failure on v3.0-dev ("Selected stations after hovering messages is
['K1ABC']").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019q8F5ZSDKDxXJoLJTFQ8wN

* Add PR #1611 to changelog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019q8F5ZSDKDxXJoLJTFQ8wN

* Re-enable dev version tag and six-month build expiry now that 2.4.1 is out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019q8F5ZSDKDxXJoLJTFQ8wN

* Increment version to 2.4.2 to begin development.

Also builds against freedv-backend's main branch again instead of the
v1.0.1 release, as was done when 2.4.1 development began (#1473).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019q8F5ZSDKDxXJoLJTFQ8wN

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:11:38 -07:00
Mooneer Salem 321db15f63
Add freedv-backend bug fixes to the 2.4.1 changelog (#1608)
* Add freedv-backend bug fixes to the 2.4.1 changelog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019q8F5ZSDKDxXJoLJTFQ8wN

* Add freedv-backend PR #78 fixes to the 2.4.1 changelog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019q8F5ZSDKDxXJoLJTFQ8wN

* Prepare for 2.4.1 release.

* Update freedv-backend to point to newly tagged release.

* Warn instead of refusing to start when a mic/speaker device is below 16 kHz.

FreeDV resamples every device to the rate each step needs, so an 8 kHz
mic or speaker (e.g. a Bluetooth headset using HFP's narrowband codec)
still works; it just loses audio above 4 kHz. Devices below 8 kHz are
still rejected. The warning lists the affected devices and is shown at
most once per session; each Start also logs it.

Fixes #1610.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019q8F5ZSDKDxXJoLJTFQ8wN

* Avoid listing duplicate device names for the Low Sample Rate warning.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 16:36:05 -07:00
Mooneer Salem 764deda2e5
Update documentation to reflect new repo URL. (#1569)
* Update documentation to reflect new repo URL.

* Remove no longer needed Python package script.

* Add PR #1569 to changelog.
2026-10-19 09:08:23 -07:00
Mooneer Salem 7596752e73
Cache only the CI builds that compile wxWidgets and LibreSSL, and build those two without debugging information (#1561)
* Cache only the CI builds that compile wxWidgets and LibreSSL, and build those two without debugging information

One branch's compiler caches didn't fit in the repository's 10 GB of
Actions caches, so they evicted each other and builds started cold.

* ccache is now only used by the builds that compile wxWidgets and
  LibreSSL (the AppImage, Windows and macOS PGO-instrumented builds).
  The Linux and macOS lint and test jobs use the system's or Homebrew's,
  compile about 250 files and gain a minute or two from a cache.
* Each cache is limited to 1 GB rather than 5.
* wxWidgets and LibreSSL are built optimised and without debugging
  information whatever FreeDV itself is built as. Their debugging
  information was most of what was cached.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BpmjFvzRZPSFGZLhgvhqDp

* Add PR #1561 to the release notes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BpmjFvzRZPSFGZLhgvhqDp

* Save each shared Windows compiler cache from one job only

The sanitizer and unit test builds of the same sanitizer and architecture
share a cache key, and both saved it: two copies of nearly the same thing
from every run, only the newer of which is ever restored. The sanitizer
build (which compiles the whole application) now saves it alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BpmjFvzRZPSFGZLhgvhqDp

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:08:57 -07:00
Mooneer Salem b9aabc29c3
Add unit tests for non-GUI code and fix the defects they found (#1542)
* Add unit tests for non-GUI code and fix the defects they found

Adds a DefineFreeDVUnitTest CMake macro and 18 CTest unit test programs
covering the pipeline steps, configuration storage and migration, WSJT-X
logging, Hamlib rig control, the voice keyer file cache, tab layout
serialization and equalizer filter design.

Fixes found while writing them:

* Equalizer bass/treble filters were always designed for 8 kHz rather
  than the device's sample rate.
* Frequency list entries could be saved 1 Hz low due to truncation.
* WSJT-X doubles were sent in host rather than network byte order.
* Text settings resembling environment variables (e.g. $HOME) were
  expanded when loaded.
* Hamlib: a frequency set before connecting was dropped, and stale
  frequency/mode was reapplied when reconnecting the same controller.
* OmniRig: frequency/mode set before connecting was dropped.
* "Play File - From Radio" accepted stereo files, which played at half
  speed; these are now rejected.
* Beeps shorter than 10 ms did not fade out.

The equalizer filter design moves out of MainFrame into eq_design.cpp
so that it can be tested, and WSJTXNetworkLogger takes an optional
heartbeat interval for the same reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Add release notes for PR #1542

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Fix wording flagged by codespell

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Fix problems found by CI and by building on Linux

Production code:

* ParallelStep: wait for each worker thread to exit before destroying
  its semaphore. Previously the thread could go on to wait on a
  semaphore that had already been released, which either crashed or
  hung on shutdown.
* HamlibRigController: make destroying_ and rigResponseTime_ atomic as
  both are accessed from more than one thread.
* sox_biquad: avoid left shifting negative samples (undefined behavior).

Tests and build:

* Don't rely on wxString::utf8_string() or a stream operator for
  wxString, neither of which exist in wxWidgets 3.0.
* Link the bundled Hamlib and wxWidgets into the tests when those are
  built as part of FreeDV, and set the build RPATH for all tests so
  that codec2/RADE can be found.
* Accept the VFO names reported by older versions of Hamlib.
* Construct objects that own threads in memory that isn't reused, and
  skip the voice keyer cache tests under thread sanitizer, to avoid
  false positives caused by threads that thread sanitizer can't tell
  have finished.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Free memory retained by unit tests on exit

LeakSanitizer otherwise reports it as leaked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Keep RecordStepTest clean under RealtimeSanitizer on macOS

RecordStep::execute() logs when its queue fills up. On macOS the first
log call on a thread allocates that thread's local storage, which
RealtimeSanitizer rejects inside a real-time function. Log once from
the test's main thread before any test case runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Add additional missed coverage.

* Extend unit test coverage of rig control and fix the defects found

Tests:
* HamlibRigController: error paths, mode changes while transmitting
  and the connection settings passed to Hamlib.
* New SerialPortRigControllerTest covering the serial port PTT
  controllers using a pseudo-terminal.
* New UtilTest for the non-GUI helpers in util.cpp.
* Additional voice keyer cache and PlaybackStep cases.
* XDG log path tests only run on Linux, with an equivalent check for
  the Documents folder elsewhere.
* Remove the 800XA transmit test, as that mode isn't supported.

Fixes:
* Serial port PTT input: disconnecting when the port was never opened
  joined a thread that was never started, and the destructor cleared
  event handlers and joined the polling thread while the controller's
  thread could still be using them.
* Serial port controllers: make fields shared between threads atomic.
* Hamlib: reapply the 625 ms timeout after rig_open(), which replaces
  it with the radio's default in some versions of Hamlib.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Add TxRxThreadTest.

* Cover FreeDVInterface and the rest of TxRxThread with unit tests

Add FreeDVInterfaceTest, which exercises the legacy modes (mode names,
frame sizes, test frame statistics, typed and reliable text, multiple
mode receive, squelch) and RADE (loopback that syncs and delivers the
callsign in the end of over).

Extend TxRxThreadTest with transmit and voice keyer monitoring, looping
playback, playing and recording on the radio side, queued resync, the
time-out beep and end of over handling in both legacy modes and RADE.

To make RADE startable without the application object,
FreeDVInterface::start() now takes the verbose setting as an argument
rather than reading it from wxGetApp().

Fixes found along the way:

* voicekeyer_cache: don't call memcpy() with a null source when reading
  from an empty in-memory file (reported by UBSAN in CI).
* TxRxThreadTest: make the fake real-time helper's counters atomic, as
  they are read while the thread under test updates them (reported by
  ThreadSanitizer).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Move grid square math and serial port listing out of dialogs and test them

The grid square, distance, bearing and compass point calculations used by
the FreeDV Reporter window now live in gui/util/GridSquare, and the band
lookup sits beside the FilterFrequency enum. The serial port enumeration,
device filtering and numeric-aware sorting that the PTT and Easy Setup
windows each had an identical copy of now live in gui/util/SerialPortList.

Add GridSquareTest, FilterFrequencyTest and SerialPortListTest.

Fix found along the way: the user's own grid square was only checked for
being non-empty, so an incomplete one (e.g. "FN") was read past its end
and produced meaningless distances and headings. Both grid squares are
now validated the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Test the remaining switchable stages of the transmit and receive pipelines

TxRxThreadTest now covers the tone interferer, recording of microphone
audio and of what's sent to the radio and to the speaker, automatic gain
control, noise reduction, the transmit frequency offset and stopping
early when the real-time helper says time is up.

FreeDVInterfaceTest now covers transmit and receive frequency offsets
passed through the interface, and RADE bandwidth expansion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Build the unit tests for Windows and run them in CI

The Windows workflow gains two jobs: build-unit-tests cross-compiles the
unit tests (plain, UBSAN and, on x86_64, ASAN) and gathers them with the
DLLs they need, and unit-tests runs them on Windows itself.

* A "unit_tests" target builds every unit test and only what they need.
* A "collect_unit_tests" target (Windows builds) copies the test
  executables and the DLLs they import that aren't part of Windows into
  one folder (cmake/CollectUnitTests.cmake.in).
* test/RunUnitTests.ps1 runs every *Test.exe in a folder and reports
  which failed or took too long.

Changes needed for the tests to build and pass on Windows:

* Temporary files go through a new unitTestTempPath() helper instead of
  assuming /tmp and getpid().
* VoiceKeyerFileCacheTest uses std::filesystem to resize files and to
  change their permissions and modification times; the unreadable file
  case is skipped on Windows.
* HamlibRigControllerTest allows for the device prefix that Hamlib puts
  in front of port names on Windows.
* M_PI is defined by the shared test header if the compiler doesn't, and
  TxRxThreadTest includes wxWidgets ahead of anything that may include
  windows.h.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Fix collecting the Windows unit tests with CMake 3.31

The collection script runs on its own (cmake -P), so no policies are set
for it unless it asks for a minimum version, and without them CMake 3.31
doesn't recognise IN_LIST in if().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

* Give unit tests that use wxWidgets a manifest on Windows

wxWidgets' GUI library imports functions that only version 6 of the
common controls library exports by name, and Windows only gives that
version to programs whose manifest asks for it. Without one, the six
tests that link it failed to start on Windows ("entry point not found").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqtgkshQCiTgcMW4Tiu4jG

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:39:11 -07:00
Mooneer Salem 89fd7c4005
Reduce full and incremental build times (#1538)
* Reduce full and incremental build times.

- Move the build date out of a global compile definition and into a
  generated build_date.cpp. The definition changed every compile command
  each day, forcing a full rebuild (wxWidgets included) after any
  reconfigure and defeating ccache across days.
- Enable wxWidgets precompiled headers.
- Download the wxWidgets release tarball instead of git cloning it, and
  apply our patch with patch(1). git apply silently skips every hunk when
  the sources have no .git of their own and sit inside another repo.
- Stop building wx::xrc, which nothing links, and drop unused xrc includes.
- Precompile <wx/wx.h> for FreeDV's GUI-facing targets.
- Make ccache work with precompiled headers: set CCACHE_SLOPPINESS in CI
  and the build scripts, and pass -fno-pch-timestamp to Clang.
- Fix CCACHE_ARGS in build_osx.sh, which was missing quotes, so ccache was
  never actually enabled for USE_CCACHE=1 builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011sR6sG6MEefCKp5bKJjWE2

* Disable precompiled headers in the Linux lint job.

The lint build uses GCC, so compile_commands.json pointed clang-tidy at
GCC .gch files, which it rejects (clang-diagnostic-ignored-gch, an error
under WarningsAsErrors).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011sR6sG6MEefCKp5bKJjWE2

* [skip ci] Add PR #1538 to changelog.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 17:05:24 -07:00
Mooneer Salem a86125dc60
Only use system libraries that can actually be linked (#1520)
* Only use system libraries that can actually be linked.

find_library() can return libraries that can't be linked with the
current toolchain, e.g. MacPorts' libhamlib.a when cross-compiling for
Windows with LLVM-MinGW (resulting in undefined rig_* symbols at link
time), or single-architecture libraries when building macOS universal
binaries.

Add CheckLibraryUsable(), which compiles and links a test program
against the found library using the target toolchain, and fall back to
building the dependency ourselves when it fails. Applied to hamlib,
sndfile and PortAudio. PortAudio now also falls back to a static build
instead of erroring out when no usable system copy is found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GxwHpb9KR3ymB15RFPGtR6

* Add PR #1521 to changelog.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 22:08:16 -07:00
Mooneer Salem 82787f1853
Fix bundled libsndfile build on lib64 systems and strncpy build error (#1510)
* Fix bundled libsndfile build on lib64 systems.

On distros such as Fedora x86_64, GNUInstallDirs defaults
CMAKE_INSTALL_LIBDIR to lib64, so libsndfile.a was installed to
external/dist/lib64 instead of the expected external/dist/lib. Force
CMAKE_INSTALL_LIBDIR=lib.

Also link libsndfile.a before mpg123/mp3lame so that its references to
those libraries resolve with static linking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix unterminated strncpy in OnReliableTextRx_.

strncpy() was bounded by the full destination size, so received text of
RELIABLE_TEXT_FIFO_SIZE or more characters would leave tmpBuf without a
null terminator. This also triggered -Werror=stringop-truncation in
optimized GCC builds. Leave room for the terminator, matching
OnRadeTextRx_.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LMBgG3zymVyaeK8vo5arWD

* Add PR #1510 to changelog.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 11:56:32 -07:00
Mooneer Salem c4ec703b73
Fix autotools dependency configure failures on newer Xcode toolchains (#1505)
* Fix autotools dependency configure failures on newer Xcode toolchains

On recent Xcode toolchains, CMAKE_C_COMPILER can resolve to the raw
absolute path inside XcodeDefault.xctoolchain rather than /usr/bin/cc
or `xcrun cc`. When hamlib/lame/mpg123's own ./configure invokes that
compiler to check it works, the driver no longer auto-discovers the
default SDK and linking fails with "ld: library 'System' not found",
breaking any full/clean build that builds these deps from source
(BOOTSTRAP_WXWIDGETS / USE_STATIC_SNDFILE, or a missing system
hamlib). Pass -isysroot explicitly via a shared
EXTERNAL_PROJECT_APPLE_ISYSROOT variable to fix this, mirroring the
same fix already applied to the RNNoise build in the freedv-backend
repo (tmiw/freedv-backend#59).

Also adds the -mmacosx-version-min=11.0/CFLAGS previously missing from
the non-universal (BUILD_OSX_UNIVERSAL=0) branches of BuildLame.cmake
and BuildMpg123.cmake, matching the flags already used in their
universal-build branches and in BuildHamlib.cmake -- without any
CFLAGS at all there, the same raw-CC-path SDK lookup failure hit those
configure invocations regardless of deployment target.

freedv-gui's own CMAKE_OSX_DEPLOYMENT_TARGET was already 11.0
(CMakeLists.txt), so no version bump was needed here.

Verified by forcing source builds of hamlib, lame, and mpg123
(USE_STATIC_SNDFILE=1, hamlib not found on system) from a clean build
directory: hamlib and mpg123 now configure and build successfully.
lame's ./configure now succeeds too; its build fails for an unrelated,
pre-existing reason -- LAME 3.100's bundled mpg123.h macro-redefines
memcpy() via bcopy() without including <strings.h>, which newer Clang
now treats as a hard error (implicit-function-declaration) instead of
a warning.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Also pass -isysroot via CPPFLAGS to fix LAME build under newer Xcode

The previous commit fixed autoconf's compiler-works check by passing
-isysroot via CFLAGS/CXXFLAGS, but autoconf determines its own CPP
command ("checking how to run the C preprocessor") as plain "$CC -E",
independent of CFLAGS. Header checks that go through CPP directly
(e.g. AC_HEADER_STDC's AC_EGREP_HEADER calls) therefore still failed
to find SDK headers, silently reporting STDC_HEADERS as undefined
even though string.h/stdlib.h etc. are all present.

For LAME specifically, this broke the build: its bundled mpglib/
mpg123.h only includes <string.h> under "#ifdef STDC_HEADERS" --
otherwise it falls back to K&R-style declarations and redefines
memcpy()/memset() via bcopy() without a prototype, which newer Clang
now treats as a hard error (implicit-function-declaration) instead of
a warning, so the fallback path no longer compiles at all.

Passing -isysroot via CPPFLAGS as well fixes CPP-based checks the
same way CFLAGS fixed compiler-based ones, so STDC_HEADERS is
correctly defined and the broken legacy fallback path in LAME's
mpg123.h is never taken.

LAME itself has had no upstream release since 3.100 (2017) to upgrade
to; MacPorts still packages 3.100 with unrelated patches, so fixing
the build here is the only option short of switching encoders.

Verified by forcing source builds of hamlib, lame, and mpg123 from a
clean build directory: all three now configure and build successfully
end-to-end (previously lame's build step failed on the bcopy/
memcpy issue described above).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* [skip ci] Add PR #1505 to changelog.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 16:04:43 -07:00
Mooneer Salem 2125e5cd7a
Refactor CI workflows into reusable composite actions; fix ccache gaps in ExternalProject deps (#1498)
* Refactor CI workflows to use reusable composite actions

Extracts duplicated step sequences from cmake-linux.yml, cmake-macos.yml,
and cmake-windows.yml into shared composite actions under .github/actions/,
and consolidates the near-identical Windows "test"/"test-sanitizer" jobs
into a single parameterized reusable workflow (windows-audio-test.yml).

New composite actions:
- install-llvm-apt-pool: apt.llvm.org pool install (was duplicated 3x)
- setup-rtkit-linux: rtkit/polkit setup for Ubuntu (was duplicated 3x)
- setup-pulseaudio-legacy: PulseAudio config for Ubuntu 22.04 (was 3x)
- setup-rade-python-env: RADE venv + torch/matplotlib install (was 5x)
- run-linux-gui-test: Xvfb/dbus/metacity display setup (was 4x)
- setup-macos-virtual-audio: VB-Cable + permission workarounds (was 3x)
- download-mingw-llvm: pinned llvm-mingw toolchain download (was 3x)
- setup-windows-audio-drivers / configure-windows-audio-devices: VAC/
  VB-Cable install and Windows audio device configuration (was 3x)
- configure-windows-crash-dumps: WER crash dump registry setup (was 2x)

This reduces cmake-linux.yml, cmake-macos.yml, and cmake-windows.yml by
about 820 lines combined while preserving existing job behavior. A few
inert simplifications were made along the way (e.g. reordering some
macOS setup steps, unifying near-identical if/else branches whose bodies
differed only in already-duplicated display-setup code) and are called
out in the accompanying summary.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Route Hamlib's autotools build through the configured ccache launcher

Hamlib is built via ExternalProject_Add's own ./configure && make
invocation, which CMake just shells out to. That means it never sees
CMAKE_C_COMPILER_LAUNCHER/CMAKE_CXX_COMPILER_LAUNCHER (e.g. ccache) --
those only apply to CMake's own compile rules -- so Hamlib's compile
was previously uncached everywhere except one macOS job that happened
to have ccache-action's create-symlink PATH workaround enabled.

Bake the launcher into CC/CXX for all three configure branches (mingw
cross-compile, Apple, and Linux) instead, so Hamlib gets cached the
same way as the rest of the project on every platform, without needing
create-symlink enabled on every runner that builds it from source.

Verified empirically with a standalone CMake script that the resulting
CONFIGURE_COMMAND list element is exactly "CC=ccache <compiler>" (one
list element, not split) when a launcher is set, and plain "CC=<compiler>"
with no leading space when it isn't.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Extend ccache launcher forwarding to the other ExternalProject deps

Reviewed every ExternalProject_Add-based dependency for the same gap
found in Hamlib: FetchContent-based deps (freedv_backend, wxWidgets,
portaudio) are compiled via add_subdirectory() as part of the same
CMake generation, so they already inherit CMAKE_C_COMPILER_LAUNCHER/
CMAKE_CXX_COMPILER_LAUNCHER automatically -- no change needed there.
The remaining ExternalProject_Add deps did need it:

- Extract the CC/CXX-with-launcher logic out of BuildHamlib.cmake into
  a shared cmake/ExternalProjectCCache.cmake, defining
  EXTERNAL_PROJECT_CC/EXTERNAL_PROJECT_CXX for any autotools-based
  ExternalProject to reuse instead of duplicating the same if/else.
- Apply it to BuildLame.cmake and BuildMpg123.cmake, which build via
  ./configure the same way Hamlib does and had the identical gap:
  neither previously set CC/CXX at all, so both relied entirely on
  autoconf's own PATH-based (or --host-triggered) compiler detection.
- BuildCodec2.cmake and BuildSndfile.cmake build CMake-based deps as a
  *nested* ExternalProject cmake invocation (CMAKE_ARGS), which gets
  its own fresh CMakeCache.txt and doesn't inherit the parent's
  compiler-launcher settings either -- forward
  CMAKE_C_COMPILER_LAUNCHER/CMAKE_CXX_COMPILER_LAUNCHER there instead,
  since that's the correct mechanism for a nested CMake build (as
  opposed to baking it into CC/CXX, which is only needed for autotools).

Verified against real generated build.make/CMakeCache output (not just
the CMake list/string semantics) for both the launcher-set and
launcher-unset cases, and for the mingw-cross-compile, Apple, and
native-Linux configure branches.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Fix CI: composite action steps don't support timeout-minutes

CI run on PR #1498 confirmed a real error: GitHub Actions rejected
setup-macos-virtual-audio/action.yml with "Unexpected value
'timeout-minutes'" -- that key is only valid on a normal job step, not
on a step inside a composite action's own `runs.steps` list. This broke
every macOS job that calls the action (test, dist-pgo-instrument, and
transitively test-app-folder/dist-pgo-build via needs:).

Move the timeout from the inner "Workaround macOS permission issues"
step (which can't have it) to the outer `uses:` call site in all three
callers instead, covering the whole composite action's four steps.

CI results otherwise confirmed the rest of the refactor and the ccache
changes are working: every Linux and Windows job passed, including the
new windows-audio-test.yml reusable workflow (test/test-sanitizer) and
all the other extracted composite actions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Add workflow to delete a PR branch's Actions caches when it closes

While investigating whether the repo was at risk of hitting the 10GB
Actions cache quota (it was: 10.03 GiB across 111 entries, meaning
GitHub was almost certainly already silently evicting caches), found
that 40% of that usage (4.06 GiB / 43 entries) was superseded
duplicates -- ccache-action's default append-timestamp behavior writes
a brand-new, uniquely-keyed cache blob on every run and never removes
the previous one, so every active branch's cache footprint only grows
for as long as the branch exists. Deleted those 43 stale entries
(repo-wide, confirmed via the caches API), freeing the repo back down
to ~5.98 GiB.

That only clears the backlog once, though -- it doesn't stop the same
accumulation from happening again on every other branch. This adds the
other half: delete a PR branch's cache entries once the PR closes, so
finished work stops permanently reserving quota that active branches
need.

Loops over `gh cache list`/`gh cache delete` rather than a single
capped call, since a long-lived PR can accumulate more than one page
of cache entries. Uses refs/heads/<branch> (not refs/pull/<n>/merge,
which is what GitHub's own docs example uses) for the BRANCH filter,
since our build workflows trigger on push, not pull_request, so that's
the ref every cache entry we inspected was actually scoped to -- the
docs example wouldn't have matched anything in this repo. Runs on
pull_request_target (not pull_request) so it also covers PRs from
forks; safe here since the job never checks out or executes the PR's
code, only calls the cache API for its branch name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Add scheduled job to prune stale Actions caches on every branch

cleanup-caches.yml only handles a branch's caches when its PR closes,
which leaves the default branch (no PR to close) and any other
long-lived branch's older cache generations unaddressed -- those keep
accumulating for as long as the branch exists, since ccache-action
writes a brand-new timestamped cache blob every run and nothing else
ever removes the previous one.

Adds a daily scheduled workflow (plus workflow_dispatch for manual
runs) that lists every cache entry repo-wide, groups them by (ref, key
with its trailing timestamp stripped), and deletes every entry in a
group except the most recently created one. It never touches the
newest cache for any (branch, job) pair, so nothing still reachable by
ccache-action's restore step is removed.

Verified the grouping/survivor logic against the repo's live cache
list (94 entries, 68 distinct branch+job groups): every group retained
exactly its newest entry with zero errors, and it correctly identified
26 already-superseded duplicates (~2.8 GiB) that have accumulated
again since the one-time manual cleanup, which is exactly the ongoing
drift this job is meant to catch automatically going forward.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Bring in VB-Cable latency tuning from ms-audio-fifo-wasapi-fixes

That branch (PR #1496) independently added CI steps to override
VB-Cable's default audio latency on both macOS and Windows, inserted at
the same points in the audio setup sequence that are now consolidated
into setup-macos-virtual-audio and setup-windows-audio-drivers here --
applying its changes on top of master directly would have conflicted
with this refactor. Ported both changes into the composite actions
instead, and the corresponding revert is going out on that branch
separately so the two don't diverge or duplicate the work:

- setup-macos-virtual-audio: adds "Override VB-Cable latency settings",
  copying the new ci/com.vbaudio.vbcable.plist into
  /Library/Preferences, right after "Install VB-Cable".
- setup-windows-audio-drivers: adds "Set VB-Cable Registry settings"
  (VBAudioCableWDM/_Latency under HKLM\SOFTWARE\VB-Audio\Cable and the
  matching CurrentControlSet\Services key), right after "Install VAC"
  and before "Install VB-Cable", matching the original ordering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Pin freedv_backend to last known-good commit -- RNNoise build regression

CI on this PR surfaced a real failure: the macOS lint job's RNNoise
ExternalProject build now fails with "C compiler cannot create
executables" during ./configure. This traces to freedv-backend#55
(merged 2026-09-18, mine), which baked the ccache launcher into
RNNoise's CC ("ccache <compiler>") -- something about that combination
breaks RNNoise's own configure script on this macOS/LLVM setup in a way
the earlier verification (checking the generated ExternalProject
command file) didn't catch, since that only confirmed the argument was
passed through correctly, not that RNNoise's ./configure would accept
it.

Ebur128 and RADE's launcher forwarding from the same PR use a different
mechanism (CMAKE_ARGS on a nested cmake invocation, not CC) and aren't
implicated by this failure -- but freedv-gui has no way to revert just
one file's change from a merged commit in another repo, so pinning
GIT_TAG back to the immediate parent commit is the only fix available
without editing freedv-backend itself, which is out of scope here.

The three application-level test failures on this same run
(rade_reporting_awgn on Linux, TestFreeDVFullDuplex on both Windows
runners) are the same pre-existing RADE audio-timing flakiness already
seen on earlier runs, unrelated to this change or the CI refactor --
not touched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Move freedv_backend back to main -- RNNoise regression fixed upstream

freedv-backend#56 (merged) replaces the two-word CC/CXX that broke
RNNoise's ./configure on macOS lint CI with a generated wrapper script,
so the pin from the previous commit is no longer needed. main's HEAD
is now 3d605c7, which includes both the original ccache-forwarding fix
(#55: Ebur128/RADE/RNNoise) and the RNNoise follow-up fix (#56).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* macOS lint: use Homebrew llvm@20 instead of install-llvm-action

Diagnostic swap for the RNNoise ccache failure investigation. Two
independent fix attempts in freedv-backend (two-word CC, then a wrapper
script) both failed identically in this job, but the same
ccache-launcher-forwarding mechanism works fine elsewhere: Linux's lint
job uses the exact same explicit -DCMAKE_C_COMPILER_LAUNCHER=ccache
forwarding (clang-21 from apt.llvm.org's llvm.sh) and passes; macOS's
dist-pgo-instrument/dist-pgo-build jobs pass too, though those rely on
ccache-action's create-symlink PATH trick rather than this job's
explicit forwarding. The one thing unique to this failing job is the
compiler binary itself: KyleMayes/install-llvm-action's LLVM 20.1.

Swap that for `brew install llvm@20 lld@20` (matching
dist-pgo-instrument/dist-pgo-build's own package list and comment about
LLVM 21 incompatibilities) and prepend its bin dir to PATH via
GITHUB_PATH, the same mechanism install-llvm-action used internally.
CC=clang/CXX=clang++ and run-clang-tidy in the later steps are unchanged
and will resolve through the new PATH entry.

Deliberately not touching create-symlink on this job's ccache step --
keeping the explicit -DCMAKE_C_COMPILER_LAUNCHER=ccache forwarding as
the only ccache-wiring mechanism in play isolates whether the compiler
binary was actually the variable that mattered, since dist-pgo-instrument
conflates "Homebrew LLVM" with "create-symlink" and doesn't answer that
on its own.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* macOS lint: fix clang-tidy sysroot detection with Homebrew llvm@20

Switching to Homebrew's llvm@20 fixed the RNNoise ccache failure, but
surfaced a different problem: run-clang-tidy failed on all 106 files
with errors like "no member named 'ldiv'" and "'TargetConditionals.h'
file not found" -- Homebrew's llvm@20, unlike Apple's own clang or
install-llvm-action's redistributable, doesn't auto-detect the active
Xcode SDK. The actual build step doesn't hit this (CMake sets
CMAKE_OSX_SYSROOT itself via its own xcrun-based detection, independent
of which clang compiled it), but clang-tidy re-invoking the compiler
directly needs the sysroot spelled out.

Pass it explicitly via --extra-arg=-isysroot --extra-arg="$(xcrun
--show-sdk-path)".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Fix run-clang-tidy flag syntax: single-dash -extra-arg, not --extra-arg

The previous commit used GNU-style --extra-arg=, but run-clang-tidy.py
(confirmed against LLVM 20's actual source) defines this as a
single-dash LLVM-style flag: parser.add_argument("-extra-arg", ...).
The existing "-p ." usage in this same command is the same convention
-- should have followed it. Python's argparse rejected the double-dash
form outright: "unrecognized arguments: --extra-arg=-isysroot
--extra-arg=...", never reaching clang-tidy at all. RNNoise's ccache
build itself succeeded in this run (confirmed in the logs), so this
was the only remaining problem.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BRyLXHuZHy1b9oLt4wJFi

* Add PR #1498 to changelog.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-18 11:07:41 -07:00
Mooneer Salem fe0986d497
Fix compiler error with Hamlib 5.0. (#1477)
* Fix compiler error with Hamlib 5.0.

* Fix typo.

* Bring back old code for Ubuntu 22.04.

* Update CMake to explicitly look for rig_state.h.

* Add PR #1477 to changelog.

* Fix typo.
2026-09-02 21:46:35 -07:00
Mooneer Salem 8df2ffd578
Increment version to 2.4.1 to begin development. (#1473)
* Increment version to 2.4.1 to begin development.

* Add changelog section.
2026-08-25 23:43:56 -07:00
Mooneer Salem 6eaaebcc05
Release version 2.4.0. (#1471)
* Release version 2.4.0.

* Move old changelog out of user manual.
2026-08-24 21:34:09 -07:00
Mooneer Salem d60339922f
Upgrade wxWidgets to 3.3.3. (#1439)
* Upgrade wxWidgets to 3.3.3.

* Add PR #1439 to changelog.
2026-07-20 16:45:51 -07:00
Mooneer Salem 4818cb0fde
Enable TLS connections for FreeDV Reporter. (#1422)
* Enable TLS connections for FreeDV Reporter.

* Add additional ntdll.dll file to exclude list.

* Exclude crypt32.dll from package generation.

* Suppress clang-tidy for FetchContent code.

* Try installing LibreTLS packages before running clang-tidy.

* Use OpenSSL instead for lint.

* Force LibreSSL to be built for 'dist' CI build.

* Add GUI configuration to enable/disable TLS.

* Add PR #1422 to changelog.

* verbose ssh logging

* Revert "verbose ssh logging"

This reverts commit 342525a5fe.

* Fix bug preventing signing of AppImages.

* Revert "Enable TLS connections for FreeDV Reporter."

This reverts commit 4e4e6fb32f.
2026-07-05 11:00:48 -07:00
Mooneer Salem d9982139d9
Upgrade Hamlib to 4.7.2. (#1413)
* Upgrade Hamlib to 4.7.2.

* Add PR #1413 to changelog.
2026-06-23 15:20:14 -07:00
Mooneer Salem b21d3b7750
Debug Windows build size issue. (#1386)
* Debug Windows build size issue.

* Revert previous change and MakeAvailable usage for wxWidgets.

* Use non-deprecated version of FetchContent_Populate.

* Need to provide other parameters to Populate.

* Add EXCLUDE_FROM_ALL for new enough CMake.

* Add PR #1386 to changelog.
2026-06-11 16:38:30 -07:00
Mooneer Salem 4ebe052a95
Clear CMake deprecation warnings in FreeDV. (#1383)
* Clear CMake deprecation warnings in FreeDV.

* Clear DBus CMake warnings.

* Add PR #1383 to changelog.
2026-06-09 19:33:46 -07:00
Mooneer Salem 2722510606
Remove freedv-backend and freedv-integrations code from freedv-gui (#1368)
* Remove FreeDV integrations and all common files in favor of freedv-backend versions.

* Fix CI due to use of freedv-backend.

* Add README pointing to new location of integrations.

* Add missed file.

* Fix linker errors.

* Clean up AppImage generation script.

* Make sure we have loss.py available when running loss test.

* Fix macOS lint failure during CI run.

* Fix include file paths in Windows build.

* Need to include fdv_util for OmniRig.

* Try hardcoding RADE search path for Windows installer.

* Make sure prerequisite files exist for reporting tests.

* Add PR #1368 to changelog.

* Update to use samplerate.

* Revert "Update to use samplerate."

This reverts commit 16ceb638f3.
2026-05-31 23:15:31 -07:00
Mooneer Salem 0105613f17
Flex: Use version number without Git hash for waveform registration. (#1359)
* Flex: Use version number without Git hash for waveform registration.

* Add PR #1359 to changelog.
2026-05-23 00:08:27 -07:00
Barry Jackson d7fe11ee4e
Fix missing Hamlib defines when building from source (#1353)
* Add missing defines when building Hamlib from source.

When building Hamlib from source (BuildHamlib.cmake always fetches 4.7.1),
HAMLIB_USE_FRIENDLY_ERRORS and HAMLIB_CONST_WORKAROUND were never defined,
causing a -Werror=deprecated-declarations build failure on rig_get_conf().
The system Hamlib path already sets these via a version check; mirror them
here since the bundled version is known to support both.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add PR #1353 to changelog.

---------

Co-authored-by: Barry Jackson <barjac@mageia.org>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
2026-05-20 00:24:42 -07:00
Mooneer Salem e04e746a51
Update Hamlib to 4.7.1. (#1314)
* Update Hamlib to 4.7.1.

* Add PR #1314 to changelog.

* Work around SmartSDR race condition on connect.

* Ensure that radio gets frequency change on start.

* Revert previous changes, didn't seem to fix the problem.

* We'll need to suppress up to the first two frequency/mode updates.

* Revert "We'll need to suppress up to the first two frequency/mode updates."

This reverts commit e537d92e8a.

* Make frequency and mode changes more atomic.

* Revert "Make frequency and mode changes more atomic."

This reverts commit 31e45b8224.

* Prevent frequency update timer from firing during initial frequency/mode setting.

* Update frequency/mode on connection start.

* Add bugfix to changelog.
2026-04-30 18:28:34 -07:00
Mooneer Salem 97c464b7fc
Enable use of remote USB token for signing automated Windows builds. (#1312)
* Temporarily disable all but Windows CI builds for testing.

* Add logic to Windows CI build to sign with remote USB token.

* Temporarily disable ARM build to reduce runtime.

* Fix syntax errors.

* Fix another syntax error.

* Add forgotten pipe symbol.

* Fix SSH tunnel specification.

* Use full path to SSH key.

* Add separate SSH_USER secret for configuring SSH username.

* Need to create .ssh folder.

* Need to specify port for ssh-keyscan.

* chmod 600 private key.

* Need to pass -N to ssh to keep tunnel up.

* Create SSH tunnel just prior to building.

* Explicitly specify localhost for port forward hostname.

* Keep SSH connection alive.

* Ran into known segfault issue on 24.04.

* Update pkg-config.

* Kill SSH after completion of build.

* Revert "Temporarily disable ARM build to reduce runtime."

This reverts commit db1cee1ce9.

* Add macOS/Linux and GH Action info to documentation.

* Revert "Temporarily disable all but Windows CI builds for testing."

This reverts commit 4b76d359f3.

* Add additional information to documentation about remote USB keys.

* Add code signing documentation link to README.

* Add PR #1312 to changelog.

* Add support for signing with a second certificate.

* Fix typos.

* Ensure installer components get secondary signed too.

* Fix spurious codec2-related signing error.
2026-04-30 07:28:53 -07:00
Mooneer Salem 813fb4e91e
Fix sudden compilation errors related to Opus. (#1299)
* Fix sudden compilation errors related to Opus.

* Revert unintended ccommit.

* Include rade_api after Opus to ensure correct config flags exist.

* Fix remaining x86_64 compiler errors.

* Add PR #1299 to changelog.
2026-04-19 17:41:52 -07:00
Mooneer Salem 4394d37851
Remove Speex in favor of RNNoise. (#1276)
* Remove Speex in favor of RNNoise.

* Fix Linux compiler errors.

* Fix clang-tidy failures.

* Additional compiler error fixes.

* Add --enable-x86-rtcd for non-macOS builds as well.

* Add PR #1276 to changelog.

* Clarify in Filter dialog that NR is during TX.

* Should not divide/multiply by SHRT_MAX.

* Remove missed Python initialization logic from initial C port.

* Ensure line appears at y=0 on plots when fully silent.

* Change offset so that the zero line is right at y=0.
2026-04-03 08:03:10 -07:00
Mooneer Salem b200766857
Use C port of RADEV1. (#1251)
* WIP integration of radae_nopy.

* Use tmiw fork of radae_nopy.

* Add additional unit test debugging.

* Update to reflect making RADE a shared library again.

* Fix Windows installer generation.

* TBD: Disable Windows reporting test as Python isn't available for mock rig.

* Remove rade_integ.

* Remove Python from binary builds.

* Forgot to remove rade_integ from lint.

* Additional CI build fixes.

* More build fixes.

* Fix Flex/KA9Q compiler errors.

* Attempt to fix macOS tests.

* Force Homebrew macOS.

* Try venv for macOS.

* Fix remaining macOS test failures.

* Python is actually on the GitHub runner, let's see if RADE Reporting test will work.

* Update documentation and add PR #1251 to changelog.
2026-03-17 16:07:16 -07:00
Mooneer Salem 44e4dd9d8c
Update wxWidgets to 3.3.2. (macOS/Windows/AppImage only) (#1244)
* Update wxWidgets to 3.3.2. (macOS/Windows/AppImage only)

* Fix patch and deprecation failures.

* Add PR #1244 to changelog.
2026-03-03 16:16:31 -08:00
Mooneer Salem 6a4cc08f89
Update Hamlib to 4.7. (#1226)
* Update Hamlib to 4.7.

* Disable libusb on macOS.

* Update pkg-config.

* Use official 4.7.0 release.

* Add PR #1226 to changelog.
2026-02-16 07:30:19 -05:00
Mooneer Salem abc62e6b4b
Force numpy to 2.3.x due to illegal instruction errors. (#1230)
* Force numpy to 2.3.x due to illegal instruction errors.

* Need to force explicit numpy version.

* Add PR #1230 to changelog.
2026-02-15 13:53:45 -08:00
Mooneer Salem ad2537fefc
Windows/macOS: Update Python to 3.14.3. (#1221)
* Windows/macOS: Update Python to 3.14.3.

* Add PR #1221 to changelog.
2026-02-11 14:36:12 -05:00
Mooneer Salem fe11db9e2e
macOS: Add /Applications shortcut to generated DMG. (#1206)
* macOS: Add /Applications shortcut to generated DMG.

* Add PR #1206 to changelog.
2026-01-31 14:32:00 -08:00
Mooneer Salem 89a406b717
Enable Linux AppImage builds for Profile Guided Optimization (PGO). (#1173)
* Enable Linux AppImage builds for Profile Guided Optimization (PGO).

* Fix typo.

* Fix another typo.

* oops, need to install pulseaudio.

* Need to set PYTHONPATH.

* Make sure dbus is installed.

* Don't strip symbols (debugging).

* Some fixes that should hopefully reverse performance regression.

* Enable temporal-profile.

* Use lld for linking instead.

* Add PR #1173 to changelog.

* Enable PGO for macOS DMG builds.

* Don't use LLVM Clang.

* Revert macOS PGO changes.

* Use -O3 for AppImages.

* Have CMake add PGO flags.

* Enable PGO again on macOS.

* Fix typos.

* Force Apple ld.

* Make absolutely sure we're using Apple ar and ranlib.

* Use Release for DMG build.

* Enable verbose build output for debugging.

* Force /usr to be first in PATH.

* Force LLD linker.

* Oops, need CMAKE_LINKER_TYPE instead.

* Use same Clang as in lint.

* Override ar path.

* AppleClang on macOS 26 supports PGO.

* Need to install Homebrew LLVM for profdata.

* Try deferring LLVM 19 install until time to run profgen.

* LLVM without LTO.

* Adapt use of libtool from LLVM.

* Try forcing libtool usage in Codec2 too.

* Disable verbose build.

* Explicitly pass CMAKE_AR and CMAKE_RANLIB into dependent projects.

* Fix typo.

* Use LLVM 20 instead of 21.

* Ensure all macOS dependencies use -O3 and 11.0 min.

* Cache Python generation during macOS build.

* Fix typos.

* Revert previous changes.

* Make sure FreeDV Reporter window is visible during PGO data collection.

* Fix waterfall rendering issue with multiple plots displayed at once.

* Disable PGO on macOS except for official releases.

* Revert logging previously committed.

* Linux: test -O3 only, no PGO.

* UdpHandler: fix crash when unable to resolve DNS.

* Revert "Linux: test -O3 only, no PGO."

This reverts commit 26da306b48.

* Revert "Disable PGO on macOS except for official releases."

This reverts commit a7cc6852db.

* Allow DMG generation to run during lint.

* Ensure debug symbols are enabled even for Release builds.

* Linux: allow AppImages to build during lint.

* Add documentation for building with PGO.

* macOS: Try performing non-universal instrumented build to improve CI performance.

* Enable LTO for macOS DMG build.

* Revert "Enable LTO for macOS DMG build."

This reverts commit 6e54a1c39d.

* Another attempt at enabling LTO for macOS.

* Revert "Another attempt at enabling LTO for macOS."

This reverts commit 60080db6b2.

* Upgrade MinGW LLVM to 20251216.

* Experiment: collect profiling data for legacy modes as well.

* Disable PGO on macOS due to long build times.

* No difference in CPU usage when profiling legacy modes, so just profile RADE.

* Forgot to change utmode back to RADEV1.
2026-01-28 13:00:49 -08:00
Mooneer Salem 8a240f8a99
Add button to record decoded audio. (#1145)
* Add button to record decoded audio.

* Fix TSan bug discovered in a merged PR's build.

* Make Record buttons horizontal.

* Add additional Tools menu option for decoder recording.

* Consolidate all Record logic to single button.

This commit does the following:

* Removes all Tools->Start Record File... options from menu bar.
* Reverts back to single Record button on main window.
* Record button now pops up file dialog with additional controls for raw/decoded recording.
  (default raw recording)

* Remove Quick Record options as they are no longer necessary.

* Revert "Remove Quick Record options as they are no longer necessary."

This reverts commit 0d0c069d48.

* Add additional config option for decoded recordings.

* Replace file chooser with simpler record setup dialog.

* Remove unused config items.

* Add PR #1145 to changelog.

* Build LAME and mpg123 into FreeDV version of libsndfile.

* Add MP3 format as option for recording.

* Update control labels.

* Fix non-macOS build.

* Fix mpg123 build as well.

* Fix Windows build.

* Disable MP3 support if system sndfile doesn't support it.

* Need to invert test.

* Try regenerating autoconf files for mpg123 to work around Windows build failure.

* Need libltdl-dev for autoreconf to work.

* Disable MP3 recording when recording raw audio.

* Swap ordering of filters for the voice keyer dialogs.

* Allow voice keyer to be turned on during TX.

* Allow voice keyer file to be selected during TX.

* Default suffix to drop-down list entry or FreeDV Reporter selection.

* Revert "Swap ordering of filters for the voice keyer dialogs."

This reverts commit a504063ff2.

* Try installing git from Homebrew to work around macOS CI problem.

* Revert "Try installing git from Homebrew to work around macOS CI problem."

This reverts commit e4cdeb47f1.

* Force not retrieving submodules.

* Explicitly disable submodule recursion.

* Try macos-26 for lint.

* Uninstall Homebrew git due to libiconv problems.
2026-01-08 10:07:26 -08:00
Mooneer Salem 8f23911e66
Fix GitHub Actions failures on Linux (#1149)
* GHA: Try forcing PulseAudio to 48000 Hz sample rate.

* Fix syntax errors.

* Experiment: try building AppImages with LLVM instead of gcc.

* Oops, accidentally deleted something I shouldn't have.

* Fix accidental word wrap.

* Fix again.

* Try to work around compiler error.

* Use system zlib for Linux wxWidgets.

* Add clarifying comments.

* Update integration READMEs to use rade_integ_src.

* Add PR #1149 to changelog.

* Make sure audio doesn't suspend on idle.

* Try alternative method of screenshotting.

* Try another way of starting screen capture tool.

* Only take screenshot if failed.

* Only pass outbound audio if all samples available.

* Revert "Only pass outbound audio if all samples available."

This reverts commit 6aa73f3e36.
2025-12-28 08:10:15 -08:00
Mooneer Salem 88ac98a370
Upgrade Python 3.14.0->3.14.2. (Windows/macOS only) (#1124)
* Upgrade Python 3.14.0->3.14.1. (Windows/macOS only)

* Actually, looks like 3.14.2 was just released.

* Add PR #1124 to changelog.
2025-12-07 18:26:53 -08:00
Mooneer Salem b023b97d11
Upgrade built-in Python to 3.14.0. (#1109)
* Upgrade built-in Python to 3.14.0.

* Need to update GH environment for Windows Python 3.14.

* Forgot to adjust path for pip.

* Additional forgotten change.

* TEST ONLY: Use non-main for RADE.

* Use Python 3.14 for AppImages.

* Need to exclude 3.14 DLL during installer step.

* Update ASAN suppressions for 3.14.

* Revert "TEST ONLY: Use non-main for RADE."

This reverts commit 14b711b5a9.

* Use rade_src instead of rade_integ_src.

* Update AppRun scripts.

* Upgrade custom PyTorch macOS wheel to 2.9.1 and Python 3.14.

* PYTHONOPTIMIZE doesn't seem to work on macOS now.

* Apparently PYTHONOPTIMIZE was in there twice.

* Reenable PYTHONOPTIMIZE, disable built-in mimalloc.

* Disable mimalloc in GH Actions as well.

* Try reenabling mimalloc just for Linux.

* Add PR #1109 to changelog.

* Remove mimalloc altogether.

* Forgot to clean up mimalloc code in source files.

* Lock PyTorch release inside GH Actions.
2025-11-30 19:02:40 -08:00
Mooneer Salem 539bd55969
Set thread names for additional threads in system. (#1103)
* Set thread names for additional threads in system.

* Fix linting errors.

* Add additional thread names for Mac and Windows.

* Use const reference for SetThreadName.

* Fix more linting errors.

* Fix PortAudio compiler error.

* Add missed thread names.

* VOX tone atomic doesn't need seq_cst.

* Only wake up non-RT playback thread if FIFO is less than half full.

* Only wake up the TX/RX threads after all audio received.

* Optimized RADE is only for radio integrations.

* Add missed changes.

* Need to build integ in order for lint to work.

* remove invalid target.

* Fix additional Linux compiler failures from previous changes.

* Additional compiler fixes.

* Exclude duplicate tests.

* Fix macOS CI failure.
2025-11-24 14:55:13 -08:00
Mooneer Salem 9010d9be8a
Update VC Redistributable again. (#1102)
* Update VC Redistributable again.

* Add PR #1102 to changelog.

* Run brew directly due to GH failures.
2025-11-23 11:10:42 -08:00
Mooneer Salem b486ca8356
Use last working version of Opus. (#1083)
* Use last working version of Opus.

* Try change to improve mpp test reliability.

* Adjust the noise level the other way.
2025-11-05 11:55:56 -08:00
Mooneer Salem 4d4e556969
Force all compiler warnings to report as errors. (#1076)
* Force all compiler warnings to report as errors.

* Fix missed errors.

* Additional Linux and Windows compiler fixes.

* Additional macOS audio compiler error fixes.

* Fix Windows build once and for all.

* Fix remaining uninitialized warnings.

* Fix data race in Socket.IO handling.

* We want to immediately fail when running sanitizers, not re-attempt tests.

* Revert accidental removals in macOS CI config.

* Add PR #1076 to changelog.
2025-11-01 13:54:30 -07:00
Mooneer Salem 4118ae7bff
Update Visual Studio Redistributable link to the latest. (#1074)
* Update Visual Studio Redistributable link to the latest.

* Add PR #1074 to changelog.
2025-10-31 16:16:42 -07:00
Mooneer Salem c4bd1e5f52
Add support for BBWENet BW expander. (#1065)
* Prototype BBWNet BW expander.

* Add new Speaker Audio section in Filter window.

* Add PR #1065 to changelog.

* Add BBWENet to FreeDV rig integrations.

* Resolve compiler warnings in Flex waveform.

* Further warning cleanup while compiling Flex waveform.
2025-10-29 12:38:27 -07:00
Mooneer Salem 394dc76e4f
Add KA9Q radio integration to FreeDV source tree. (#1066)
* Reorganize FlexRadio integration so we can share code with KA9Q console app.

* Fix rtkit file path.

* Use same variable for both static and non-static Speex DSP library.

* Update Linux CI to reflect new paths.

* Refactor more common code for use by other integrations.

* Create skeleton KA9Q appplication, need to read/write from/to stdin/stdout to get basics up.

* Need to link against fdv_os_wrapper in common.

* Actually fix Linux linker failure in Flex waveform.

* Allow software name to be passed into ReportingController.

* Read audio from stdin and write to stdout.

* Fix crash on shutdown due to threads not being freed.

* Add pauses to make sure audio is handled live (i.e. not faster than RT).

* Add command line options to freedv-ka9q tool.

* Flesh out ka9q README.

* Clean up AppImage generation and enable CI for KA9Q integration.

* Add missed speex dependency.

* Forgot to change references to APPEXEC.

* Fix app paths for AppImages.

* Force AppImage file name.

* Use separate desktop files to avoid needing to override linuxdeploy.

* Use echo instead of ls for AppImage name generation.

* Fix test-appimage and enable verification on ARM targets.

* Need to use pattern, not glob.

* Need to use step ID.

* More fixes.

* Re-add accidentally deleted ./ from Fedora container execution.

* Add arm64 Fedora testing.

* Use RADE main again as a test.

* Revert "Use RADE main again as a test."

This reverts commit 60559ef0bc.

* Switch to raw file I/O.

* Update command line usage message.

* Add PR #1066 to changelog.

* Fix compiler error.

* Report RX only to FreeDV Reporter to indicate we can't TX.

* Fix crash on shutdown.

* Actually have audio process live.

* Fix typo in build_linux.sh.

* Enable ThreadSanitizer checks for CI builds.

* Make sure we're not actually checking for test results with tsan.

* Enable sanitizers on 22.04 and ARM runners.

* Suppress sanitizer errors in Ubuntu 22.04.

* We probably need Clang 22 to have Ubuntu 22.04 RTsan tests work properly.

* Use LLVM 22 for ASAN too to see if that will suppress the final leaks.

* Add missed lock in onRecvEnd.

* [no-ci] Update documentation.

* [no-ci] Further tweaks to user manual wording.
2025-10-29 08:42:48 -07:00
Mooneer Salem d716e41769
Flex waveform development (#1018)
* Create infrastructure to build freedv-flex binaries.

* Begin porting some ezDV Flex files to freedv-gui.

* Do not build Flex waveform for Windows.

* Port FlexVitaTask from ezDV, link to main() to print available radios.

* Fix Linux compiler error.

* Disable mimalloc for Flex waveform.

* Port FlexTcpTask from ezDV.

* Add beginning of initialization logic for waveform.

* Set up IRealtimeHelper for Flex waveform.

* Adjust FIFO usage to match what FlexVitaTask expects.

* Add linkage between TCP and VITA tasks.

* Use correct FIFO size calculation.

* Force single-threading for PyTorch/numpy.

* We don't need verbosity for RADE.

* Need to let the VITA task know about the radio IP too.

* Enable rtkit.

* Use rtkit for FlexVitaTask too.

* Fix issue causing minPacketsRequired_ to continually increase.

* Adjust MAX_VITA_SAMPLES to reflect no longer doing resampling itself.

* Fix spelling mistake.

* Update comment.

* Try previous TX scale factor to make a TX level 100 = ~100W.

* Tweak TX scale factor so we don't actually overdrive the signal.

* Don't build waveform by default.

* Enable AppImage generation for waveform.

* Update wrong script reference in CI build.

* Use correct filename generated by linuxdeploy.

* Warning cleanup.

* Tweaks to hopefully help reduce dropouts.

* timestamp_type defs from Flex SDK didn't work for some reason.

* Make sure we're always sending stuff back to the radio.

* Try ms-disable-python-gc again as it has a ~10% CPU usage reduction on RX.

* Try implementing timestamp type changes from Flex waveform SDK again.

* No difference with unconditional reads.

* Use Semaphore for pausing TX/RX threads.

* Actually eliminate audio dropouts.

* Connect UDP socket to slightly reduce system CPU consumption.

* Fix memory corruption from recent changes.

* Revert "Use Semaphore for pausing TX/RX threads."

This reverts commit cf7d076ef1.

* Normalize incoming audio so that we don't clip when converting to int16.

* Initial support for sending EOO.

* Add 40ms additional silence to ensure SmartSDR fully transmits EOO.

* Add the 40ms of silence elsewhere to avoid interference with regular freedv-gui.

* Add hooks to at least get FreeDV Reporter connections up and running.

* Add spotting support for FreeDV Reporter.

* Update README based on attempting to compile for rPi.

* Send waveform cleanup commands on startup (avoiding duplicate FDVU/FDVL entries in SmartSDR for Mac).

* Forgot to actually use report_wo role for FreeDV Reporter.

* Work around segfault when switchingn away from FDVU/FDVL.

* Fix stuttering issue on beginning TX.

* Integrate AGC to Flex waveform.

* Fix waveform compiler errors.

* Sleep for as long as it takes to find a radio on the network.

* Add support for processing SSDR_RADIO_ADDRESS envionrment variable.

* Fix compiler errors.

* Ephemeral ports for VITA don't actually work.

* Use same version number as FreeDV proper, cleanup FreeDV Reporter init.

* Support reporting the grid square if the radio has a built-in GPS.

* Add Speex noise reduction to TX pipeline.

* Code cleanup.

* Fix deadlock during radio discovery.

* src/os only needs wxWidgets if on Windows.

* Add missing packages for building Flex AppImage.

* GPS updates use a different delimiter than other update types.

* GitHub runner is forcing Ubuntu 24.04 for ARM.

* Revert "GitHub runner is forcing Ubuntu 24.04 for ARM."

This reverts commit e267fe216b.

* Add cleanup and logging to FreeDV Reporter logic.

* Need to capture newGridSquare.

* Bail out on empty grid square.

* Refactor ReportingController to separate file.

* Report RX prior to receiving callsign.

* Generate waveform Docker container.

* Need Docker Buildx action.

* Fix AppImage filename.

* Check for null before trying to report RX.

* Increment to 2.0.3.

* Fix compiler errors from previous merge.

* Fix typo from previous PR.

* Force mimalloc to be built in Release mode.

* Forgot to support universal macOS build for mimalloc.

* Switch Flex container to Ubuntu, install AppImage prerequisites.

* Remove add-apt-repository call.

* Can't rely on using FUSE, try --appimage-extract-and-run.

* Initialize sync_ variable to avoid spurious calls to FreeDV Reporter.

* Do appimage-extract during container build process.

* Extract AppImage prior to running Docker.

* Add debugging to make sure we're deploying the correct contents.

* Include mimalloc config from main FreeDV application.

* Add README for the Flex waveform.

* Fix typos in README.

* Add PR #1018 to changelog.
2025-10-20 12:34:40 -07:00
Mooneer Salem df704a0fab
Reduce CPU usage in Xwayland process when using AppImage. (#1064)
* Reduce CPU usage in Xwayland process when using AppImage.

* Reduce Xwayland CPU usage in the Spectrum plot as well.

* Have separate avmag arrays for each plot.

* Fix typo from previous PR.

* Avoid duplicate MoveToPoint calls.

* Remove spinlock for RX spectrum.

* Spectrum plot: reduce the number of lines drawn without affecting visual quality.

* Experiment: disable arch-specific optimizations for mimalloc.

* Use 5Hz steps.

* Fix typos in spectrum plot calculation.

* From Radio and similar: Use single filled path to represent plot.

* Remove 1 dB minimum difference requirement for Spectrum plot.

* Make sure spectrum plot arrays are cleared on start.

* Warning cleanup.

* Reenable mimalloc optimization flags for Macs.

* Use GenericFIFO for scalar plots.

* Reduce the amount of gray rendered in waterfall before actual RF spectrum is shown.

* Don't redraw text on Spectrum plot unless necessary.

* Add PR #1064 to changelog.

* Don't force Xwayland on AppImage.

* Add Xwayland instructions to Troubleshooting section of manual.
2025-10-19 09:03:03 -07:00
Mooneer Salem 89e12a5644
Reduce memory allocations in main thread. (#1035)
* Reduce memory allocations in main thread.

* Cache configured FreeDV Reporter colors.

* Move capture into FreeDV Reporter GUI handlers.

* Further constant cleanup in FreeDV Reporter.

* Try disabling mimalloc to see if it helps the macOS tests run.

* Revert "Try disabling mimalloc to see if it helps the macOS tests run."

This reverts commit 81a20cbd3f.

* Define strings inside respective objects to hopefully avoid minmalloc-related crash on macOS.

* Make const strings member variables.

* 25% reduction in allocations by waterfall rendering code.

* Further memory allocation reduction in the waterfall plot.

* FreeDV Reporter: reduce allocations during handler processing.

* Only save callsign to wxString if non-empty.

* ebur128 should be compiled in release mode.

* Add PR #1035 to changelog.

* Don't wait for extended tests to finish to test the AppImage.
2025-09-24 19:27:08 -07:00
Mooneer Salem 93a01c7e19
Use EBU R 128 based loudness measurement to implement AGC. (#1024)
* Switch AGC implementation to WebRTC.

* Forgot to check in files.

* Add PR #1024 to changelog.

* WebRTC only supports a limited set of sample rates.

* inMicLevel needs to be 0.

* Forgot some calls to make AGC work.

* Unconditionally enable AGC setting in Filter window.

* Test to increase AGC level.

* Adjust target level so that peaks are +/- 0.4.

* Reduce target level a bit.

* Revert "Reduce target level a bit."

This reverts commit 6282992544.

* Add 4dB pad after AGC.

* More tweaks.

* First pass at AGC implementation using libebur128.

* Try defining CMAKE_POLICY_VERSION_MINIMUM to get around GH build error.

* Swap attack/release naming to match actual definitions.

* Equalizer and speech in plotting should be based on pre-AGC audio.

* Warning cleanup.

* Fix CMake issues on ebur128 in GitHub environment.

* Avoid overshooting target gain.

* Remove CMake debugging.

* current = target AGC check not 100% correct, so don't bother.

* Set limiter level to -1 dB.

* Switch voice keyer button label based on state.

* Add 'Switch to' to beginning of Analog/Digital button.

* User manual update.

* Only update Voice Keyer button on state transitions.

* Revert "Equalizer and speech in plotting should be based on pre-AGC audio."

This reverts commit 206a4d4fcb.

* To Spkr/Hdphns -> Frm Decoder.

* Add 'Modem' to Start/Stop button label.

* all.wav is too long for rade_reporting_mpp, use shorter TX file to improve pass rate.

* Increase silence threshold to -33 LUFS.

* Oops, speech out plot should be before equalizer.

* g_agcEnabled needs memory_order_release on modification.

* Suppress monitor audio from 'From Decoder' plot during TX.
2025-09-16 12:17:39 -07:00
Mooneer Salem b8c66668bc
Update Hamlib to version 4.6.5. (#1030)
* Update Hamlib to 4.6.5.

* all.wav is too long for rade_reporting_mpp, use shorter TX file to improve pass rate.

* Add PR #1030 to changelog.
2025-09-16 00:37:53 -07:00
Mooneer Salem 6dbb3b7f8f
Debug and fixing of unit tests (#1023)
* Add tooling to enable debugging of hung tests.

* Force rebuild.

* Revert "Force rebuild."

This reverts commit 6f13e7382b.

* Add five minute timeout for unit tests.

* Fix max time calculation and increase to 10mins.

* Increase timeout to 20 minutes.

* We were actually calculating the counter wrong.

* Use atomics for UT related globals.

* Force build for more testing.

* Revert README change.

* Add retry logic for hdiutil due to known bugs.

* Encode EOO as a single unit.

* Revert GitHub debugging.

* Add PR #1023 to changelog.
2025-09-14 00:52:50 -07:00
Mooneer Salem 8dcee0d0c5
Linux: fix rendering bug for mic/speaker slider when transitioning from TX to RX. (#1021)
* Remove space between number and 'dB'.

* Linux: redraw mic/speaker level slider on update to ensure it remains in sync.

* Add PR #1021 to changelog.

* Make sure redraw happens on some environments.

* Revert accidental change to RADE build config.
2025-09-07 10:16:48 -07:00