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.
ms-last-selected-logging-row
Mooneer Salem 2026-01-28 13:00:49 -08:00 committed by GitHub
parent 7fd61178df
commit 89a406b717
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 524 additions and 41 deletions

View File

@ -55,7 +55,7 @@ jobs:
run-clang-tidy-22 -p .
build-appimage:
needs: lint
#needs: lint
env:
FREEDV_LINUX_CODE_SIGNING_KEY_ID: ${{ secrets.FREEDV_LINUX_CODE_SIGNING_KEY_ID }}
@ -78,7 +78,15 @@ jobs:
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 22 all
- name: Install rtkit for RT threading
shell: bash
run: |
sudo apt-get update
sudo apt-get install dbus-x11 rtkit libdbus-1-dev polkitd
sudo sed -i 's/no/yes/g' /usr/share/polkit-1/actions/org.freedesktop.RealtimeKit1.policy
sudo systemctl restart polkit
- name: Install required packages
shell: bash
run: |
@ -86,7 +94,11 @@ jobs:
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt update
sudo apt-get install libpulse-dev sox git libasound2-dev libao-dev libgsm1-dev xvfb pipewire pulseaudio-utils pipewire-pulse wireplumber metacity at-spi2-core libdbus-1-dev libgtk-3-dev python3.14 python3.14-dev python3.14-venv libebur128-dev
sudo apt-get install libpulse-dev sox git libasound2-dev libao-dev libgsm1-dev xvfb pulseaudio pulseaudio-utils metacity at-spi2-core libdbus-1-dev libgtk-3-dev python3.14 python3.14-dev python3.14-venv libebur128-dev
mkdir -p ~/.config/pulse
echo "default-sample-rate = 48000" >~/.config/pulse/daemon.conf
sudo sed 's/load-module module-suspend-on-idle/#load-module module-suspend-on-idle/' /etc/pulse/default.pa -i
systemctl --user --now enable pulseaudio.service pulseaudio.socket
- name: Install Python required modules
shell: bash
@ -101,13 +113,43 @@ jobs:
if: ${{ matrix.target == 'freedv-flex' }}
uses: docker/setup-buildx-action@v3
- name: Build freedv-gui using PulseAudio
- name: Build instrumented freedv-gui
shell: bash
working-directory: ${{github.workspace}}
if: ${{ matrix.target == 'all' }}
run: |
. ./rade-venv/bin/activate
CC=clang-22 CXX=clang++-22 ENABLE_LTO=1 STATIC_LIBGCC=1 ./build_linux.sh
BUILD_TYPE=Release CC=clang-22 CXX=clang++-22 PGO_INSTRUMENT=1 ENABLE_LTO=1 STATIC_LIBGCC=1 ./build_linux.sh
- name: Generate optimization profile
shell: bash
working-directory: ${{github.workspace}}
if: ${{ matrix.target == 'all' }}
run: |
sudo systemctl enable rtkit-daemon
sudo systemctl start rtkit-daemon
Xvfb :99 -screen 0 1920x1080x16 &
sleep 5
export DISPLAY=:99.0
export XDG_RUNTIME_DIR=/run/user/$(id -u)
mkdir -p $XDG_RUNTIME_DIR
chmod 700 $XDG_RUNTIME_DIR
eval "$(dbus-launch --sh-syntax --exit-with-x11)"
metacity --sm-disable --replace &
sleep 5
. ./rade-venv/bin/activate
cd build_linux
LLVM_PROFILE_FILE="code-%p.profraw" PYTHONPATH=$(pwd)/rade_src ../test/generate_pgo_profiles.sh 2>&1
llvm-profdata-22 merge -output ${{ github.workspace }}/code.profdata code-*.profraw
- name: Build PGO optimized freedv-gui
shell: bash
working-directory: ${{github.workspace}}
if: ${{ matrix.target == 'all' }}
run: |
. ./rade-venv/bin/activate
rm -rf build_linux
BUILD_TYPE=Release CC=clang-22 CXX=clang++-22 PGO_USE_PROFILE=${{github.workspace}}/code.profdata ENABLE_LTO=1 STATIC_LIBGCC=1 ./build_linux.sh
- name: Build target
shell: bash
@ -408,7 +450,7 @@ jobs:
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt update
sudo apt-get install libpulse-dev libspeexdsp-dev libsamplerate0-dev sox git portaudio19-dev libhamlib-dev libasound2-dev libao-dev libgsm1-dev libsndfile-dev xvfb pipewire pulseaudio-utils pipewire-pulse wireplumber metacity at-spi2-core libebur128-dev python3.14 python3.14-dev python3.14-venv
sudo apt-get install libpulse-dev libspeexdsp-dev libsamplerate0-dev sox git portaudio19-dev libhamlib-dev libasound2-dev libao-dev libgsm1-dev libsndfile-dev xvfb pulseaudio-utils metacity at-spi2-core libebur128-dev python3.14 python3.14-dev python3.14-venv
- name: Install version-specific packages
if: ${{ matrix.os == 'ubuntu-22.04' || matrix.os == 'ubuntu-22.04-arm' }}

View File

@ -126,7 +126,7 @@ jobs:
runs-on: macos-latest
env:
MACOS_NOTARYTOOL_PROFILE_NAME: "FreeDVCodeSigning"
needs: ['lint']
#needs: ['lint']
steps:
- uses: actions/checkout@v4
@ -138,7 +138,7 @@ jobs:
- name: Install needed packages
run: |
brew install automake libtool numpy sox
brew install automake libtool numpy sox llvm@20 lld@20 # note: LLVM 21 introduces incompatibilities - see https://github.com/Homebrew/homebrew-core/issues/235411
brew uninstall git # workaround, forces use of Apple git
- name: Initialize code signing infrastructure
@ -161,17 +161,57 @@ jobs:
security find-identity -v macos-build.keychain
xcrun notarytool store-credentials --apple-id "${{ env.MACOS_CODE_SIGNING_USERNAME }}" --password "${{ env.MACOS_CODE_SIGNING_PASSWORD }}" --team-id "${{ vars.FREEDV_MACOS_CODE_SIGNING_TEAM_ID }}" ${{ env.MACOS_NOTARYTOOL_PROFILE_NAME }}
- name: Build universal freedv-gui (unsigned)
- name: Install VB-Cable
shell: bash
working-directory: ${{github.workspace}}
run: |
brew install vb-cable
- name: Install other virtual audio devices
shell: bash
working-directory: ${{github.workspace}}
run: ./build_macos_sound_drivers.sh
- name: Workaround macOS permission issues
run: |
sqlite3 $HOME/Library/Application\ Support/com.apple.TCC/TCC.db "BEGIN TRANSACTION; INSERT OR IGNORE INTO access VALUES ('kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159,NULL,NULL,'UNUSED',1687786159); INSERT OR IGNORE INTO access VALUES ('kTCCServiceMicrophone','/opt/off/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159,NULL,NULL,'UNUSED',1687786159); COMMIT;"
- name: Make sure resource hogs aren't running
shell: bash
run: |
sudo launchctl unload /System/Library/LaunchDaemons/com.apple.cloudd.plist
sudo mdutil -a -i off
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
#- name: Build instrumented freedv-gui
# shell: bash
# working-directory: ${{github.workspace}}
# run: |
# BUILD_TYPE=Release UT_ENABLE=0 BUILD_DEPS=1 PGO_INSTRUMENT=1 CC=$(brew --prefix llvm@20)/bin/clang CXX=$(brew --prefix llvm@20)/bin/clang++ OBJCXX=$(brew --prefix llvm@20)/bin/clang ./build_osx.sh
#- name: Generate optimization profile
# shell: bash
# working-directory: ${{github.workspace}}
# run: |
# cd build_osx
# LLVM_PROFILE_FILE="code-%p.profraw" FREEDV_COMPUTER_TO_RADIO_DEVICE="VB-Cable" FREEDV_RADIO_TO_COMPUTER_DEVICE="VB-Cable" FREEDV_COMPUTER_TO_SPEAKER_DEVICE="BlackHole1 2ch" FREEDV_MICROPHONE_TO_COMPUTER_DEVICE="BlackHole2 2ch" ../test/generate_pgo_profiles.sh 2>&1
# $(brew --prefix llvm@20)/bin/llvm-profdata merge -output ${{ github.workspace }}/code.profdata code-*.profraw
- name: Build freedv-gui (unsigned)
if: ${{ vars.FREEDV_MACOS_CODE_SIGNING_TEAM_ID == '' }}
shell: bash
working-directory: ${{github.workspace}}
run: UT_ENABLE=0 UNIV_BUILD=1 BUILD_DEPS=1 ENABLE_LTO=1 ./build_osx.sh
run: |
rm -rf build_osx
BUILD_TYPE=Release UT_ENABLE=0 UNIV_BUILD=1 BUILD_DEPS=1 ./build_osx.sh
- name: Build universal freedv-gui (signed)
- name: Build freedv-gui (signed)
if: ${{ vars.FREEDV_MACOS_CODE_SIGNING_TEAM_ID != '' }}
shell: bash
working-directory: ${{github.workspace}}
run: UT_ENABLE=0 UNIV_BUILD=1 BUILD_DEPS=1 ENABLE_LTO=1 CODESIGN_IDENTITY=${{ vars.FREEDV_MACOS_CODE_SIGNING_TEAM_ID }} CODESIGN_KEYCHAIN_PROFILE=${{ env.MACOS_NOTARYTOOL_PROFILE_NAME }} ./build_osx.sh
run: |
rm -rf build_osx
BUILD_TYPE=Release UT_ENABLE=0 UNIV_BUILD=1 BUILD_DEPS=1 CODESIGN_IDENTITY=${{ vars.FREEDV_MACOS_CODE_SIGNING_TEAM_ID }} CODESIGN_KEYCHAIN_PROFILE=${{ env.MACOS_NOTARYTOOL_PROFILE_NAME }} ./build_osx.sh
- name: Package executable
working-directory: ${{github.workspace}}/build_osx

View File

@ -61,15 +61,15 @@ jobs:
shell: bash
working-directory: ${{github.workspace}}
run: |
wget https://github.com/mstorsjo/llvm-mingw/releases/download/20250430/llvm-mingw-20250430-ucrt-ubuntu-22.04-x86_64.tar.xz
tar xvf llvm-mingw-20250430-ucrt-ubuntu-22.04-x86_64.tar.xz
wget https://github.com/mstorsjo/llvm-mingw/releases/download/20251216/llvm-mingw-20251216-ucrt-ubuntu-22.04-x86_64.tar.xz
tar xvf llvm-mingw-20251216-ucrt-ubuntu-22.04-x86_64.tar.xz
- name: Configure freedv-gui
shell: bash
working-directory: ${{github.workspace}}
run: |
export WINEPREFIX=`pwd`/wine-env
export PATH=${{github.workspace}}/llvm-mingw-20250430-ucrt-ubuntu-22.04-x86_64/bin:$PATH
export PATH=${{github.workspace}}/llvm-mingw-20251216-ucrt-ubuntu-22.04-x86_64/bin:$PATH
mkdir build_windows
cd build_windows
cmake -DENABLE_LTO=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/cross-compile/freedv-mingw-llvm-x86_64.cmake -DPython3_ROOT_DIR=$WINEPREFIX/drive_c/Program\ Files/Python314 ..
@ -78,7 +78,7 @@ jobs:
shell: bash
working-directory: ${{github.workspace}}/build_windows
run: |
export PATH=${{github.workspace}}/llvm-mingw-20250430-ucrt-ubuntu-22.04-x86_64/bin:$PATH
export PATH=${{github.workspace}}/llvm-mingw-20251216-ucrt-ubuntu-22.04-x86_64/bin:$PATH
make -j$(nproc) package
- name: Calculate installer filename

View File

@ -44,7 +44,7 @@ else(APPLE)
HOMEPAGE_URL ${PROJECT_HOMEPAGE_URL}
LANGUAGES C CXX
)
endif(APPLE)
endif(APPLE)
if(NOT DEFINED LINUX)
string(FIND ${CMAKE_SYSTEM_NAME} "Linux" LINUX_LOC)
@ -109,10 +109,11 @@ include(cmake/CheckGit.cmake)
CheckGitSetup()
# Set default build flags.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g")
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} -g")
endif(APPLE)
set(CMAKE_CXX_STANDARD 17)
@ -154,6 +155,10 @@ set(STATIC_LIBGCC FALSE CACHE BOOL
endif (LINUX)
set(ENABLE_LTO FALSE CACHE BOOL
"Enable Link Time Optimization (LTO)")
set(PGO_INSTRUMENT CACHE BOOL
"Instrument for Profile Guided Optimization (PGO) (Clang only)")
set(PGO_USE_PROFILE CACHE STRING
"Use profile data generated by PGO_INSTRUMENT to optimize binary (Clang only)")
if(ENABLE_LTO)
include(CheckIPOSupported)
@ -163,6 +168,18 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif(result)
endif(ENABLE_LTO)
if(PGO_INSTRUMENT AND PGO_USE_PROFILE)
message(FATAL_ERROR "Cannot set both PGO_INSTRUMENT and PGO_USE_PROFILE.")
elseif(PGO_INSTRUMENT)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-generate -ftemporal-profile")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-generate -ftemporal-profile")
set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} -fprofile-generate -ftemporal-profile")
elseif(PGO_USE_PROFILE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-profile-instr-unprofiled -fprofile-use=${PGO_USE_PROFILE}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-profile-instr-unprofiled -fprofile-use=${PGO_USE_PROFILE}")
set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} -Wno-profile-instr-unprofiled -fprofile-use=${PGO_USE_PROFILE}")
endif(PGO_INSTRUMENT AND PGO_USE_PROFILE)
if(ENABLE_ASAN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")

View File

@ -176,3 +176,43 @@ cd build_osx
make release
```
## Building with Profile Guided Optimization (PGO)
Profile Guided Optimization is an optimization strategy supported by the Clang compiler that uses profiling data
to govern optimization decisions. This can significantly improve the runtime performance of many applications, especially
with higher optimization levels. In testing with FreeDV, the AppImages are able to use up to 25% less CPU using a
combination of `BUILD_TYPE=Release`, link-time optimization (LTO) and PGO. Currently this is supported for macOS and Linux
using the LLVM version of the Clang compiler (*not* the one Apple ships with Xcode).
To build with PGO enabled:
1. Perform an initial instrumented build using the `./build_linux.sh` (or `./build_osx.sh`) script, making sure to overide
the relevant environment variables to use the correct version of Clang. Example below with macOS and Homebrew:
```
$ BUILD_TYPE=Release UT_ENABLE=0 BUILD_DEPS=1 PGO_INSTRUMENT=1 CC=$(brew --prefix llvm@20)/bin/clang CXX=$(brew --prefix llvm@20)/bin/clang++ OBJCXX=$(brew --prefix llvm@20)/bin/clang ./build_osx.sh
```
2. Execute FreeDV and use normally to obtain sufficient profiling data. An automated script is available to do this:
```
cd build_osx
LLVM_PROFILE_FILE="code-%p.profraw" FREEDV_COMPUTER_TO_RADIO_DEVICE="VB-Cable" FREEDV_RADIO_TO_COMPUTER_DEVICE="VB-Cable" FREEDV_COMPUTER_TO_SPEAKER_DEVICE="BlackHole1 2ch" FREEDV_MICROPHONE_TO_COMPUTER_DEVICE="BlackHole2 2ch" ../test/generate_pgo_profiles.sh 2>&1
$(brew --prefix llvm@20)/bin/llvm-profdata merge -output $(pwd)/../code.profdata code-*.profraw
```
(`FREEDV_COMPUTER_TO_RADIO_DEVICE`, `FREEDV_RADIO_TO_COMPUTER_DEVICE`, `FREEDV_COMPUTER_TO_SPEAKER_DEVICE` and `FREEDV_MICROPHONE_TO_COMPUTER_DEVICE` are optional on Linux,
where PulseAudio/pipewire null sink(s) will be created if these are not provided).
3. Perform a final build with the collected profiling data:
```
rm -rf build_osx
BUILD_TYPE=Release UT_ENABLE=0 UNIV_BUILD=1 BUILD_DEPS=1 PGO_USE_PROFILE=$(pwd)/code.profdata CC=$(brew --prefix llvm@20)/bin/clang CXX=$(brew --prefix llvm@20)/bin/clang++ OBJCXX=$(brew --prefix llvm@20)/bin/clang ./build_osx.sh
```
Limitations:
1. The best results are obtained if having FreeDV build all required dependencies itself (`BUILD_DEPS=1`). The optimization process
is unable to touch already-compiled dyanmic libraries, so performance gains will likely be less without this option.
2. On that same note, this will not touch most of the RADE modem due to its use of Python. This may change in future releases.

View File

@ -933,6 +933,7 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
3. Build system:
* Use Clang to build AppImages for better performance. (PR #1149)
* Enable link-time optimization for AppImages, DMGs and Windows builds. (PR #1163)
* Enable profile-guided optimation for AppImages. (PR #1173)
4. Other:
* Remove 5.3665 MHz as a default frequency. (PR #1187)

View File

@ -24,6 +24,8 @@ APPDIR="$APPNAME.AppDir"
BUILDDIR="../"
MACH_ARCH=`uname -m`
export NO_STRIP=1
# Change to the directory where this script is located
cd "$(dirname "$(realpath "$0")")"

View File

@ -16,6 +16,8 @@ WITH_TSAN=${WITH_TSAN:-0}
WITH_UBSAN=${WITH_UBSAN:-0}
STATIC_LIBGCC=${STATIC_LIBGCC:-0}
ENABLE_LTO=${ENABLE_LTO:-0}
PGO_INSTRUMENT=${PGO_INSTRUMENT:-0}
PGO_USE_PROFILE=${PGO_USE_PROFILE:-}
export FREEDVGUIDIR=${PWD}
@ -25,5 +27,5 @@ if [ -d .git ]; then
git pull
fi
mkdir -p build_linux && cd build_linux && rm -Rf *
cmake -DENABLE_LTO=${ENABLE_LTO} -DSTATIC_LIBGCC=${STATIC_LIBGCC} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DUNITTEST=$UT_ENABLE ..
cmake -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DSTATIC_LIBGCC=${STATIC_LIBGCC} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DUNITTEST=$UT_ENABLE ..
make -j$(nproc)

View File

@ -17,14 +17,16 @@ export WITH_RTSAN=${WITH_RTSAN:-0}
export WITH_TSAN=${WITH_TSAN:-0}
export WITH_UBSAN=${WITH_UBSAN:-0}
export ENABLE_LTO=${ENABLE_LTO:-0}
export PGO_INSTRUMENT=${PGO_INSTRUMENT:-0}
export PGO_USE_PROFILE=${PGO_USE_PROFILE:-}
# Prerequisite: build dylibbundler
if [ ! -d macdylibbundler ]; then
git clone https://github.com/tmiw/macdylibbundler.git
cd macdylibbundler && git checkout main && git pull
make -j$(sysctl -n hw.logicalcpu)
cd ..
fi
cd macdylibbundler && git checkout main && git pull
make -j$(sysctl -n hw.logicalcpu)
cd ..
# Prerequisite: Python
if [ ! -d Python.framework ]; then
@ -32,12 +34,12 @@ if [ ! -d Python.framework ]; then
cd relocatable-python
./make_relocatable_python_framework.py --python-version 3.14.2 --os-version=11 --destination $PWD/../
cd ..
fi
# Prerequisite: Python packages
rm -rf pkg-tmp
./generate-univ-pkgs.sh
./Python.framework/Versions/Current/bin/pip3 install pkg-tmp/*.whl
# Prerequisite: Python packages
rm -rf pkg-tmp
./generate-univ-pkgs.sh
./Python.framework/Versions/Current/bin/pip3 install pkg-tmp/*.whl
fi
# Prerequisite: build hamlib
cd $FREEDVGUIDIR
@ -48,9 +50,9 @@ if [ $BUILD_DEPS == 1 ]; then
cd hamlib-code && git checkout 4.6.5 && git pull
./bootstrap
if [ $UNIV_BUILD == 1 ]; then
CFLAGS="-g -O2 -mmacosx-version-min=10.9 -arch x86_64 -arch arm64" CXXFLAGS="-g -O2 -mmacosx-version-min=10.9 -arch x86_64 -arch arm64" ./configure --enable-shared --prefix $HAMLIBDIR
CFLAGS="-g -O3 -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" CXXFLAGS="-g -O3 -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" ./configure --enable-shared --prefix $HAMLIBDIR
else
CFLAGS="-g -O2 -mmacosx-version-min=10.9" CXXFLAGS="-g -O2 -mmacosx-version-min=10.9" ./configure --enable-shared --prefix $HAMLIBDIR
CFLAGS="-g -O3 -mmacosx-version-min=11.0" CXXFLAGS="-g -O3 -mmacosx-version-min=11.0" ./configure --enable-shared --prefix $HAMLIBDIR
fi
make -j$(sysctl -n hw.logicalcpu)
@ -69,9 +71,9 @@ if [ "$CODESIGN_KEYCHAIN_PROFILE" != "" ]; then
fi
if [ $BUILD_DEPS == 1 ]; then
cmake -DENABLE_LTO=${ENABLE_LTO} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DPython3_ROOT_DIR=$PWD/../Python.framework/Versions/3.14 -DBUILD_OSX_UNIVERSAL=${UNIV_BUILD} -DUNITTEST=$UT_ENABLE -DBOOTSTRAP_WXWIDGETS=1 -DUSE_STATIC_SPEEXDSP=1 -DUSE_STATIC_PORTAUDIO=1 -DUSE_STATIC_SAMPLERATE=1 -DUSE_STATIC_SNDFILE=1 -DHAMLIB_INCLUDE_DIR=${HAMLIBDIR}/include -DHAMLIB_LIBRARY=${HAMLIBDIR}/lib/libhamlib.dylib -DMACOS_CODESIGN_IDENTITY=${CODESIGN_IDENTITY} ${CODESIGN_KEYCHAIN_PROFILE_ARG} ..
cmake -DCMAKE_AR=/usr/bin/ar -DCMAKE_RANLIB=/usr/bin/ranlib -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DPython3_ROOT_DIR=$PWD/../Python.framework/Versions/3.14 -DBUILD_OSX_UNIVERSAL=${UNIV_BUILD} -DUNITTEST=$UT_ENABLE -DBOOTSTRAP_WXWIDGETS=1 -DUSE_STATIC_SPEEXDSP=1 -DUSE_STATIC_PORTAUDIO=1 -DUSE_STATIC_SAMPLERATE=1 -DUSE_STATIC_SNDFILE=1 -DHAMLIB_INCLUDE_DIR=${HAMLIBDIR}/include -DHAMLIB_LIBRARY=${HAMLIBDIR}/lib/libhamlib.dylib -DMACOS_CODESIGN_IDENTITY=${CODESIGN_IDENTITY} ${CODESIGN_KEYCHAIN_PROFILE_ARG} ..
else
cmake -DENABLE_LTO=${ENABLE_LTO} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DPython3_ROOT_DIR=$PWD/../Python.framework/Versions/3.14 -DBUILD_OSX_UNIVERSAL=${UNIV_BUILD} -DUNITTEST=$UT_ENABLE -DMACOS_CODESIGN_IDENTITY=${CODESIGN_IDENTITY} ${CODESIGN_KEYCHAIN_PROFILE_ARG} ..
cmake -DCMAKE_AR=/usr/bin/ar -DCMAKE_RANLIB=/usr/bin/ranlib -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DPython3_ROOT_DIR=$PWD/../Python.framework/Versions/3.14 -DBUILD_OSX_UNIVERSAL=${UNIV_BUILD} -DUNITTEST=$UT_ENABLE -DMACOS_CODESIGN_IDENTITY=${CODESIGN_IDENTITY} ${CODESIGN_KEYCHAIN_PROFILE_ARG} ..
fi
make -j$(sysctl -n hw.logicalcpu)

View File

@ -1,5 +1,9 @@
set(CODEC2_CMAKE_ARGS -DUNITTEST=FALSE)
if(APPLE)
set(CODEC2_CMAKE_ARGS ${CODEC2_CMAKE_ARGS} -DCMAKE_AR=${CMAKE_AR} -DCMAKE_RANLIB=${CMAKE_RANLIB})
endif(APPLE)
if(CMAKE_CROSSCOMPILING)
set(CODEC2_CMAKE_ARGS ${CODEC2_CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
endif()

View File

@ -3,6 +3,10 @@ set(EBUR128_VERSION "1.2.6")
# Static libraries on some platforms need PIC
set(EBUR128_CMAKE_ARGS -DWITH_STATIC_PIC=1 -DBUILD_SHARED_LIBS=0)
if(APPLE)
set(EBUR128_CMAKE_ARGS ${EBUR128_CMAKE_ARGS} -DCMAKE_AR=${CMAKE_AR} -DCMAKE_RANLIB=${CMAKE_RANLIB})
endif(APPLE)
if(CMAKE_CROSSCOMPILING)
set(EBUR128_CMAKE_ARGS ${EBUR128_CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
endif()

View File

@ -1,13 +1,13 @@
if(MINGW AND CMAKE_CROSSCOMPILING)
set(CONFIGURE_COMMAND ./configure --host=${HOST} --target=${HOST} --without-cxx-binding --enable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist --without-libusb CFLAGS=-g\ -O2\ -fstack-protector CXXFLAGS=-g\ -O2\ -fstack-protector)
set(CONFIGURE_COMMAND ./configure --host=${HOST} --target=${HOST} --without-cxx-binding --enable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist --without-libusb CFLAGS=-g\ -O3\ -fstack-protector CXXFLAGS=-g\ -O3\ -fstack-protector)
set(HAMLIB_PATCH_CMD patch -p1 < ${CMAKE_SOURCE_DIR}/cmake/hamlib-windows.patch)
else(MINGW AND CMAKE_CROSSCOMPILING)
set(HAMLIB_PATCH_CMD "")
if(APPLE)
if(BUILD_OSX_UNIVERSAL)
set(CONFIGURE_COMMAND ./configure --enable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist --without-cxx-binding --without-libusb CFLAGS=-g\ -O2\ -mmacosx-version-min=10.9\ -arch\ x86_64\ -arch\ arm64 CXXFLAGS=-g\ -O2\ -mmacosx-version-min=10.9\ -arch\ x86_64\ -arch\ arm64)
set(CONFIGURE_COMMAND ./configure --enable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist --without-cxx-binding --without-libusb CFLAGS=-g\ -O3\ -mmacosx-version-min=11.0\ -arch\ x86_64\ -arch\ arm64 CXXFLAGS=-g\ -O3\ -mmacosx-version-min=11.0\ -arch\ x86_64\ -arch\ arm64)
else()
set(CONFIGURE_COMMAND ./configure --enable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist --without-cxx-binding --without-libusb CFLAGS=-g\ -O2\ -mmacosx-version-min=10.9 CXXFLAGS=-g\ -O2\ -mmacosx-version-min=10.9)
set(CONFIGURE_COMMAND ./configure --enable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist --without-cxx-binding --without-libusb CFLAGS=-g\ -O3\ -mmacosx-version-min=11.0 CXXFLAGS=-g\ -O3\ -mmacosx-version-min=11.0)
endif(BUILD_OSX_UNIVERSAL)
else()
set(CONFIGURE_COMMAND ./configure --enable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist --without-cxx-binding --without-libusb CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER})

View File

@ -14,7 +14,7 @@ if(APPLE AND BUILD_OSX_UNIVERSAL)
ExternalProject_Add(build_mp3lame_x86
DOWNLOAD_EXTRACT_TIMESTAMP NO
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=x86_64-apple-darwin --target=x86_64-apple-darwin CFLAGS=-arch\ x86_64\ -O2\ -mmacosx-version-min=10.11
CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=x86_64-apple-darwin --target=x86_64-apple-darwin CFLAGS=-arch\ x86_64\ -O3\ -mmacosx-version-min=11.0
BUILD_COMMAND $(MAKE) && $(MAKE) install
INSTALL_COMMAND ""
URL ${LAME_URL}
@ -23,7 +23,7 @@ ExternalProject_Add(build_mp3lame_x86
ExternalProject_Add(build_mp3lame_arm
DOWNLOAD_EXTRACT_TIMESTAMP NO
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=aarch64-apple-darwin --target=aarch64-apple-darwin CFLAGS=-arch\ arm64\ -O2\ -mmacosx-version-min=10.11
CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=aarch64-apple-darwin --target=aarch64-apple-darwin CFLAGS=-arch\ arm64\ -O3\ -mmacosx-version-min=11.0
BUILD_COMMAND $(MAKE) && $(MAKE) install
INSTALL_COMMAND ""
URL ${LAME_URL}

View File

@ -14,7 +14,7 @@ if(APPLE AND BUILD_OSX_UNIVERSAL)
ExternalProject_Add(build_mpg123_x86
DOWNLOAD_EXTRACT_TIMESTAMP NO
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=x86_64-apple-darwin --target=x86_64-apple-darwin CFLAGS=-arch\ x86_64\ -O2\ -mmacosx-version-min=10.11
CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=x86_64-apple-darwin --target=x86_64-apple-darwin CFLAGS=-arch\ x86_64\ -O3\ -mmacosx-version-min=11.0
BUILD_COMMAND $(MAKE) && $(MAKE) install
INSTALL_COMMAND ""
URL ${MPG123_URL}
@ -23,7 +23,7 @@ ExternalProject_Add(build_mpg123_x86
ExternalProject_Add(build_mpg123_arm
DOWNLOAD_EXTRACT_TIMESTAMP NO
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=aarch64-apple-darwin --target=aarch64-apple-darwin CFLAGS=-arch\ arm64\ -O2\ -mmacosx-version-min=10.11
CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=aarch64-apple-darwin --target=aarch64-apple-darwin CFLAGS=-arch\ arm64\ -O3\ -mmacosx-version-min=11.0
BUILD_COMMAND $(MAKE) && $(MAKE) install
INSTALL_COMMAND ""
URL ${MPG123_URL}

View File

@ -7,6 +7,10 @@ if(CMAKE_CROSSCOMPILING)
set(SNDFILE_CMAKE_ARGS ${SNDFILE_CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
endif()
if(APPLE)
set(SNDFILE_CMAKE_ARGS ${SNDFILE_CMAKE_ARGS} -DCMAKE_AR=${CMAKE_AR} -DCMAKE_RANLIB=${CMAKE_RANLIB})
endif(APPLE)
include(ExternalProject)
ExternalProject_Add(sndfile
URL https://github.com/libsndfile/libsndfile/archive/refs/tags/1.2.2.tar.gz

View File

@ -1,3 +1,3 @@
#!/usr/bin/env bash
CFLAGS="-g -O2 -mmacosx-version-min=10.9" ./configure --prefix=$1 --disable-examples
CFLAGS="-g -O3 -mmacosx-version-min=11.0" ./configure --prefix=$1 --disable-examples

View File

@ -1,3 +1,3 @@
#!/usr/bin/env bash
CFLAGS="-g -O2 -arch arm64 -arch x86_64 -mmacosx-version-min=10.9" ./configure --prefix=$1 --disable-examples
CFLAGS="-g -O3 -arch arm64 -arch x86_64 -mmacosx-version-min=11.0" ./configure --prefix=$1 --disable-examples

View File

@ -0,0 +1,192 @@
FirstTimeUse=0
ExperimentalFeatures=1
[Audio]
soundCard1SampleRate=-1
soundCard2SampleRate=-1
soundCard1InDeviceName=@FREEDV_RADIO_TO_COMPUTER_DEVICE@
soundCard1InSampleRate=48000
soundCard1OutDeviceName=@FREEDV_COMPUTER_TO_RADIO_DEVICE@
soundCard1OutSampleRate=48000
soundCard2InDeviceName=@FREEDV_MICROPHONE_TO_COMPUTER_DEVICE@
soundCard2InSampleRate=48000
soundCard2OutDeviceName=@FREEDV_COMPUTER_TO_SPEAKER_DEVICE@
soundCard2OutSampleRate=48000
SquelchActive=1
SquelchLevel=-4
fifoSize_ms=640
transmitLevel=0
snrSlow=0
mode=257
TxRxDelayMilliseconds=0
[Filter]
codec2LPCPostFilterGamma=50
codec2LPCPostFilterBeta=20
MicInBassFreqHz=100
MicInBassGaindB=0
MicInTrebleFreqHz=3000
MicInTrebleGaindB=0
MicInMidFreqHz=1500
MicInMidGaindB=0
MicInMidQ=100
MicInVolInDB=0
SpkOutBassFreqHz=100
SpkOutBassGaindB=0
SpkOutTrebleFreqHz=3000
SpkOutTrebleGaindB=0
SpkOutMidFreqHz=1500
SpkOutMidGaindB=0
SpkOutMidQ=100
SpkOutVolInDB=0
codec2LPCPostFilterEnable=1
codec2LPCPostFilterBassBoost=1
speexpp_enable=1
700C_EQ=1
[Filter/MicIn]
EQEnable=0
BassFreqHz=100
BassGaindB=0
TrebleFreqHz=3000
TrebleGaindB=0
MidFreqHz=1500
MidGaindB=0
MidQ=1
VolInDB=0
[Filter/SpkOut]
EQEnable=0
BassFreqHz=100
BassGaindB=0
TrebleFreqHz=3000
TrebleGaindB=0
MidFreqHz=1500
MidGaindB=0
MidQ=1
VolInDB=0
[Filter/codec2LPCPostFilter]
Gamma=50
Beta=20
[Hamlib]
UseForPTT=0
EnableFreqModeChanges=0
EnableFreqChangesOnly=0
UseAnalogModes=0
IcomCIVHex=0
RigNameStr=Hamlib NET rigctl
PttType=0
SerialRate=0
SerialPort=localhost:4575
PttSerialPort=localhost:4575
RigName=0
[Rig]
UseSerialPTT=0
Port=
UseRTS=1
RTSPolarity=1
UseDTR=0
DTRPolarity=0
UseSerialPTTInput=0
PttInPort=
CTSPolarity=0
leftChannelVoxTone=0
EnableSpacebarForPTT=1
HalfDuplex=1
MultipleRx=1
SingleRxThread=1
[PSKReporter]
Enable=0
Callsign=
GridSquare=
FrequencyHzStr=0
[Data]
CallSign=
[Reporting]
Enable=1
Callsign=ZZ0ZZZ
GridSquare=ZZ12ZZ
FrequencyAsKHz=0
FrequencyList=1.9970,3.6250,3.6430,3.6930,3.6970,3.8500,5.4035,5.3665,5.3685,7.1770,7.1970,14.2360,14.2400,18.1180,21.3130,24.9330,28.3300,28.7200,10489.6400
ManualFrequencyReporting=1
DirectionAsCardinal=0
Frequency=14236000
[Reporting/PSKReporter]
Enable=0
[Reporting/FreeDV]
Enable=1
Hostname=qso.freedv.org
CurrentBandFilter=0
UseMetricDistances=1
BandFilterTracksFrequency=0
ForceReceiveOnly=0
StatusText=FreeDV Automated Test System - https://github.com/drowe67/freedv-gui
RecentStatusTexts=
TxRowBackgroundColor=#fc4500
TxRowForegroundColor=#000000
RxRowBackgroundColor=#379baf
RxRowForegroundColor=#000000
MsgRowBackgroundColor=#E58BE5
MsgRowForegroundColor=#000000
[Reporting/FreeDV/BandFilterTracking]
TracksFreqBand=1
TracksExactFreq=0
[CallsignList]
UseUTCTime=0
[FreeDV2020]
Allowed=0
[MainFrame]
left=0
top=50
width=800
height=780
rxNbookCtrl=0
TabLayout=3fb6c00069659632006bc6da00000003=+1|3f62f8006965963700790cb800000004=+2|3f60e3006965964100b6e44400000005=+4|3f620e0069659660013d444300000007=+3|3f89f800696596640151d80e00000007=*0@layout2|name=dummy;caption=;state=2098174;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=180;besth=180;minw=180;minh=180;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=3fb6c00069659632006bc6da00000003;caption=;state=2098172;dir=5;layer=1;row=0;pos=0;prop=100000;bestw=425;besth=321;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=3f62f8006965963700790cb800000004;caption=;state=2098172;dir=1;layer=1;row=0;pos=1;prop=100000;bestw=180;besth=180;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=3f60e3006965964100b6e44400000005;caption=;state=2098172;dir=1;layer=1;row=0;pos=0;prop=100000;bestw=180;besth=180;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=3f620e0069659660013d444300000007;caption=;state=2098172;dir=1;layer=0;row=1;pos=0;prop=100000;bestw=180;besth=180;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=3f89f800696596640151d80e00000007;caption=;state=2098172;dir=1;layer=0;row=1;pos=1;prop=100000;bestw=180;besth=180;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,1,0)=230|dock_size(1,0,1)=182|dock_size(5,1,0)=427|
[Windows]
[Windows/AudioConfig]
left=26
top=23
width=918
height=739
[Windows/FreeDVReporter]
left=800
top=50
width=512
height=384
visible=1
currentSort=-1
currentSortDirection=1
reportingUserMsgColWidth=130
[File]
playFileToMicInPath=
recFileFromRadioPath=
recFileFromRadioSecs=60
recFileFromModulatorPath=
recFileFromModulatorSecs=60
playFileFromRadioPath=
[VoiceKeyer]
WaveFilePath=/home/mooneer/Documents
WaveFile=voicekeyer.wav
RxPause=10
Repeats=5
[FreeDV700]
txClip=1
txBPF=1
[Noise]
noise_snr=2
[Debug]
console=0
verbose=0
APIverbose=0
[Waterfall]
Color=0
[Stats]
ResetTime=10
[Plot]
[Plot/Spectrum]
CurrentAveraging=0
[Monitor]
VoiceKeyerAudio=0
TransmitAudio=0
VoiceKeyerAudioVol=0
TransmitAudioVol=0
[QuickRecord]
SavePath=/home/mooneer/Documents
[Modem]
enableLegacyModes=1

View File

@ -0,0 +1,133 @@
#!/bin/bash
# Determine sox driver to use for recording/playback
OPERATING_SYSTEM=`uname`
if [ "$OPERATING_SYSTEM" == "Darwin" ]; then
SOX_DRIVER=coreaudio
FREEDV_BINARY=${FREEDV_BINARY:-src/FreeDV.app/Contents/MacOS/FreeDV}
PYTHON_BINARY=${PYTHON_BINARY:-src/FreeDV.app/Contents/Frameworks/Python.framework/Versions/Current/bin/python3}
else
SOX_DRIVER=alsa
FREEDV_BINARY=${FREEDV_BINARY:-src/freedv}
PYTHON_BINARY=${PYTHON_BINARY:-python3}
fi
createVirtualAudioCable () {
CABLE_NAME=$1
pactl load-module module-null-sink sink_name=$CABLE_NAME sink_properties=device.description=$CABLE_NAME
}
waitForCableUp () {
CABLE_NAME=$1
until (pactl list short sinks | grep -E "^[0-9]+\\s+${CABLE_NAME}\\s+" >/dev/null)
do
echo "Waiting for $CABLE_NAME to come up..."
sleep 1;
done
}
FREEDV_RADIO_TO_COMPUTER_DEVICE="${FREEDV_RADIO_TO_COMPUTER_DEVICE:-FreeDV_Radio_To_Computer}"
FREEDV_COMPUTER_TO_SPEAKER_DEVICE="${FREEDV_COMPUTER_TO_SPEAKER_DEVICE:-FreeDV_Computer_To_Speaker}"
FREEDV_MICROPHONE_TO_COMPUTER_DEVICE="${FREEDV_MICROPHONE_TO_COMPUTER_DEVICE:-FreeDV_Microphone_To_Computer}"
FREEDV_COMPUTER_TO_RADIO_DEVICE="${FREEDV_COMPUTER_TO_RADIO_DEVICE:-FreeDV_Computer_To_Radio}"
# Automated script to help find audio dropouts.
# NOTE: this must be run from "build_*". Also assumes PulseAudio/pipewire or macOS Core Audio,
# does not work in Windows.
if [ "$OPERATING_SYSTEM" == "Linux" ]; then
DRIVER_INDEX_FREEDV_RADIO_TO_COMPUTER=$(createVirtualAudioCable FreeDV_Radio_To_Computer)
waitForCableUp FreeDV_Radio_To_Computer
DRIVER_INDEX_FREEDV_COMPUTER_TO_SPEAKER=$(createVirtualAudioCable FreeDV_Computer_To_Speaker)
waitForCableUp FreeDV_Computer_To_Speaker
DRIVER_INDEX_FREEDV_MICROPHONE_TO_COMPUTER=$(createVirtualAudioCable FreeDV_Microphone_To_Computer)
waitForCableUp FreeDV_Microphone_To_Computer
DRIVER_INDEX_FREEDV_COMPUTER_TO_RADIO=$(createVirtualAudioCable FreeDV_Computer_To_Radio)
waitForCableUp FreeDV_Computer_To_Radio
DRIVER_INDEX_LOOPBACK=`pactl load-module module-loopback source="FreeDV_Computer_To_Radio.monitor" sink="FreeDV_Radio_To_Computer"`
fi
# Determine correct record device to retrieve TX data
FREEDV_CONF_FILE=freedv-pgo.conf
PLAY_DEVICE="$FREEDV_RADIO_TO_COMPUTER_DEVICE"
if [ "$OPERATING_SYSTEM" == "Linux" ]; then
REC_DEVICE="$FREEDV_COMPUTER_TO_RADIO_DEVICE.monitor"
else
REC_DEVICE="$FREEDV_COMPUTER_TO_RADIO_DEVICE"
fi
# Generate config file
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
if [ "$FREEDV_RADIO_TO_COMPUTER_DEVICE" == "FreeDV_Radio_To_Computer" ] && [ "$OPERATING_SYSTEM" == "Linux" ]; then
sed "s/@FREEDV_RADIO_TO_COMPUTER_DEVICE@/$FREEDV_RADIO_TO_COMPUTER_DEVICE.monitor/g" $SCRIPTPATH/$FREEDV_CONF_FILE.tmpl > $(pwd)/$FREEDV_CONF_FILE
else
sed "s/@FREEDV_RADIO_TO_COMPUTER_DEVICE@/$FREEDV_RADIO_TO_COMPUTER_DEVICE/g" $SCRIPTPATH/$FREEDV_CONF_FILE.tmpl > $(pwd)/$FREEDV_CONF_FILE
fi
sed "s/@FREEDV_COMPUTER_TO_RADIO_DEVICE@/$FREEDV_COMPUTER_TO_RADIO_DEVICE/g" $(pwd)/$FREEDV_CONF_FILE > $(pwd)/$FREEDV_CONF_FILE.tmp
mv $(pwd)/$FREEDV_CONF_FILE.tmp $(pwd)/$FREEDV_CONF_FILE
sed "s/@FREEDV_COMPUTER_TO_SPEAKER_DEVICE@/$FREEDV_COMPUTER_TO_SPEAKER_DEVICE/g" $(pwd)/$FREEDV_CONF_FILE > $(pwd)/$FREEDV_CONF_FILE.tmp
mv $(pwd)/$FREEDV_CONF_FILE.tmp $(pwd)/$FREEDV_CONF_FILE
if [ "$FREEDV_MICROPHONE_TO_COMPUTER_DEVICE" == "FreeDV_Microphone_To_Computer" ] && [ "$OPERATING_SYSTEM" == "Linux" ]; then
sed "s/@FREEDV_MICROPHONE_TO_COMPUTER_DEVICE@/$FREEDV_MICROPHONE_TO_COMPUTER_DEVICE.monitor/g" $(pwd)/$FREEDV_CONF_FILE > $(pwd)/$FREEDV_CONF_FILE.tmp
else
sed "s/@FREEDV_MICROPHONE_TO_COMPUTER_DEVICE@/$FREEDV_MICROPHONE_TO_COMPUTER_DEVICE/g" $(pwd)/$FREEDV_CONF_FILE > $(pwd)/$FREEDV_CONF_FILE.tmp
fi
mv $(pwd)/$FREEDV_CONF_FILE.tmp $(pwd)/$FREEDV_CONF_FILE
# Resample test file to 48 kHz. Needed for CI environment to reduce CPU usage.
if [ ! -d "$(pwd)/rade_src" ]; then
git clone -b main https://github.com/drowe67/radae.git rade_src
fi
sox $(pwd)/rade_src/wav/all.wav -r 48000 $(pwd)/tx_in.wav
# Start recording
if [ "$OPERATING_SYSTEM" == "Linux" ]; then
parecord --channels=1 --file-format=wav --device "$REC_DEVICE" test.wav &
else
sox --buffer 32768 -t $SOX_DRIVER "$REC_DEVICE" -c 1 -t wav test.wav >/dev/null 2>&1 &
fi
RECORD_PID=$!
# Start FreeDV in test mode to record TX
TX_ARGS="-txfile $(pwd)/tx_in.wav -txfeaturefile $(pwd)/txfeatures.f32 "
$FREEDV_BINARY -f $(pwd)/$FREEDV_CONF_FILE -ut tx -utmode RADEV1 $TX_ARGS >tmp.log 2>&1 &
FDV_PID=$!
#if [ "$OPERATING_SYSTEM" != "Linux" ]; then
# xctrace record --template "Audio System Trace" --instrument "Time Profiler" --window 3m --output "instruments_trace_tx_${FDV_PID}.trace" --attach $FDV_PID
#fi
#sleep 30
#screencapture ../screenshot.png
#wpctl status
#pw-top -b -n 5
wait $FDV_PID
cat tmp.log
# Stop recording, play back in RX mode
kill $RECORD_PID
#cp $(pwd)/gmon.out $(pwd)/gmon.out.tx
$FREEDV_BINARY -f $(pwd)/$FREEDV_CONF_FILE -ut rx -utmode RADEV1 -rxfile $(pwd)/test.wav -rxfeaturefile $(pwd)/rxfeatures.f32 >tmp.log 2>&1 &
FDV_PID=$!
#if [ "$OPERATING_SYSTEM" != "Linux" ]; then
# xctrace record --template "Audio System Trace" --instrument "Time Profiler" --window 3m --output "instruments_trace_rx_${FDV_PID}.trace" --attach $FDV_PID
#fi
wait $FDV_PID
FREEDV_EXIT_CODE=$?
cat tmp.log
# Clean up PulseAudio virtual devices
if [ "$OPERATING_SYSTEM" == "Linux" ]; then
pactl unload-module $DRIVER_INDEX_LOOPBACK
pactl unload-module $DRIVER_INDEX_FREEDV_RADIO_TO_COMPUTER
pactl unload-module $DRIVER_INDEX_FREEDV_COMPUTER_TO_SPEAKER
pactl unload-module $DRIVER_INDEX_FREEDV_COMPUTER_TO_RADIO
pactl unload-module $DRIVER_INDEX_FREEDV_MICROPHONE_TO_COMPUTER
fi
exit $FREEDV_EXIT_CODE