Feat: big movement for ASIO
This commit is contained in:
@@ -3,8 +3,3 @@ MACOSX_DEPLOYMENT_TARGET = "12.0"
|
|||||||
|
|
||||||
[alias]
|
[alias]
|
||||||
xtask = "run --package xtask --release --"
|
xtask = "run --package xtask --release --"
|
||||||
|
|
||||||
[target.x86_64-pc-windows-gnu]
|
|
||||||
rustflags = [
|
|
||||||
"-C", "link-args=-Wl,-Bstatic -lstdc++ -lgcc -lgcc_eh -lpthread -Wl,-Bdynamic -lmingwex -lmsvcrt -lws2_32 -liphlpapi -lwinmm -lole32 -loleaut32 -luuid -lkernel32",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -1,135 +0,0 @@
|
|||||||
name: Assemble macOS Universal
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
assemble:
|
|
||||||
runs-on: macos-14
|
|
||||||
timeout-minutes: 10
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Download macOS artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
pattern: cagire-macos-*
|
|
||||||
path: artifacts
|
|
||||||
|
|
||||||
- name: Create universal CLI binary
|
|
||||||
run: |
|
|
||||||
lipo -create \
|
|
||||||
artifacts/cagire-macos-x86_64/cagire \
|
|
||||||
artifacts/cagire-macos-aarch64/cagire \
|
|
||||||
-output cagire
|
|
||||||
chmod +x cagire
|
|
||||||
lipo -info cagire
|
|
||||||
|
|
||||||
- name: Create universal app bundle
|
|
||||||
run: |
|
|
||||||
cd artifacts/cagire-macos-aarch64-desktop
|
|
||||||
unzip Cagire.app.zip
|
|
||||||
cd ../cagire-macos-x86_64-desktop
|
|
||||||
unzip Cagire.app.zip
|
|
||||||
cd ../..
|
|
||||||
cp -R artifacts/cagire-macos-aarch64-desktop/Cagire.app Cagire.app
|
|
||||||
lipo -create \
|
|
||||||
artifacts/cagire-macos-x86_64-desktop/Cagire.app/Contents/MacOS/cagire-desktop \
|
|
||||||
artifacts/cagire-macos-aarch64-desktop/Cagire.app/Contents/MacOS/cagire-desktop \
|
|
||||||
-output Cagire.app/Contents/MacOS/cagire-desktop
|
|
||||||
lipo -info Cagire.app/Contents/MacOS/cagire-desktop
|
|
||||||
zip -r Cagire.app.zip Cagire.app
|
|
||||||
|
|
||||||
- name: Create universal CLAP plugin
|
|
||||||
run: |
|
|
||||||
mkdir -p cagire-plugins.clap/Contents/MacOS
|
|
||||||
cp artifacts/cagire-macos-aarch64-clap/cagire-plugins.clap/Contents/Info.plist \
|
|
||||||
cagire-plugins.clap/Contents/ 2>/dev/null || true
|
|
||||||
cp artifacts/cagire-macos-aarch64-clap/cagire-plugins.clap/Contents/PkgInfo \
|
|
||||||
cagire-plugins.clap/Contents/ 2>/dev/null || true
|
|
||||||
lipo -create \
|
|
||||||
artifacts/cagire-macos-x86_64-clap/cagire-plugins.clap/Contents/MacOS/cagire-plugins \
|
|
||||||
artifacts/cagire-macos-aarch64-clap/cagire-plugins.clap/Contents/MacOS/cagire-plugins \
|
|
||||||
-output cagire-plugins.clap/Contents/MacOS/cagire-plugins
|
|
||||||
lipo -info cagire-plugins.clap/Contents/MacOS/cagire-plugins
|
|
||||||
|
|
||||||
- name: Create universal VST3 plugin
|
|
||||||
run: |
|
|
||||||
mkdir -p cagire-plugins.vst3/Contents/MacOS
|
|
||||||
cp -R artifacts/cagire-macos-aarch64-vst3/cagire-plugins.vst3/Contents/Info.plist \
|
|
||||||
cagire-plugins.vst3/Contents/ 2>/dev/null || true
|
|
||||||
cp artifacts/cagire-macos-aarch64-vst3/cagire-plugins.vst3/Contents/PkgInfo \
|
|
||||||
cagire-plugins.vst3/Contents/ 2>/dev/null || true
|
|
||||||
cp -R artifacts/cagire-macos-aarch64-vst3/cagire-plugins.vst3/Contents/Resources \
|
|
||||||
cagire-plugins.vst3/Contents/ 2>/dev/null || true
|
|
||||||
lipo -create \
|
|
||||||
artifacts/cagire-macos-x86_64-vst3/cagire-plugins.vst3/Contents/MacOS/cagire-plugins \
|
|
||||||
artifacts/cagire-macos-aarch64-vst3/cagire-plugins.vst3/Contents/MacOS/cagire-plugins \
|
|
||||||
-output cagire-plugins.vst3/Contents/MacOS/cagire-plugins
|
|
||||||
lipo -info cagire-plugins.vst3/Contents/MacOS/cagire-plugins
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
sparse-checkout: |
|
|
||||||
assets/DMG-README.txt
|
|
||||||
scripts/make-dmg.sh
|
|
||||||
clean: false
|
|
||||||
|
|
||||||
- name: Create DMG
|
|
||||||
run: |
|
|
||||||
chmod +x scripts/make-dmg.sh
|
|
||||||
scripts/make-dmg.sh Cagire.app .
|
|
||||||
|
|
||||||
- name: Build .pkg installer
|
|
||||||
run: |
|
|
||||||
VERSION="${GITEA_REF_NAME#v}"
|
|
||||||
mkdir -p pkg-root/Applications pkg-root/usr/local/bin
|
|
||||||
cp -R Cagire.app pkg-root/Applications/
|
|
||||||
cp cagire pkg-root/usr/local/bin/
|
|
||||||
pkgbuild --analyze --root pkg-root component.plist
|
|
||||||
plutil -replace BundleIsRelocatable -bool NO component.plist
|
|
||||||
pkgbuild --root pkg-root --identifier com.sova.cagire \
|
|
||||||
--version "$VERSION" --install-location / \
|
|
||||||
--component-plist component.plist \
|
|
||||||
"Cagire-${VERSION}-universal.pkg"
|
|
||||||
|
|
||||||
- name: Upload universal CLI
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-macos-universal
|
|
||||||
path: cagire
|
|
||||||
|
|
||||||
- name: Upload universal app bundle
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-macos-universal-desktop
|
|
||||||
path: Cagire.app.zip
|
|
||||||
|
|
||||||
- name: Prepare universal plugin staging
|
|
||||||
run: |
|
|
||||||
mkdir -p staging/clap staging/vst3
|
|
||||||
cp -R cagire-plugins.clap staging/clap/
|
|
||||||
cp -R cagire-plugins.vst3 staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload universal CLAP plugin
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-macos-universal-clap
|
|
||||||
path: staging/clap/
|
|
||||||
|
|
||||||
- name: Upload universal VST3 plugin
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-macos-universal-vst3
|
|
||||||
path: staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload DMG
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-macos-universal-dmg
|
|
||||||
path: Cagire-*.dmg
|
|
||||||
|
|
||||||
- name: Upload .pkg installer
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-macos-universal-pkg
|
|
||||||
path: Cagire-*-universal.pkg
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
name: Build Cross (Linux ARM64)
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: aarch64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
key: aarch64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Install cross
|
|
||||||
run: cargo install cross --git https://github.com/cross-rs/cross
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cross build --release --target aarch64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Build desktop
|
|
||||||
run: cross build --release --features desktop --bin cagire-desktop --target aarch64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Upload CLI artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-linux-aarch64
|
|
||||||
path: target/aarch64-unknown-linux-gnu/release/cagire
|
|
||||||
|
|
||||||
- name: Upload desktop artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-linux-aarch64-desktop
|
|
||||||
path: target/aarch64-unknown-linux-gnu/release/cagire-desktop
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
name: Build Linux
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
run-tests:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
run-clippy:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
build-packages:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
run-tests:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
run-clippy:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
build-packages:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: x86_64-unknown-linux-gnu
|
|
||||||
components: clippy
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
key: x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y build-essential cmake pkg-config libasound2-dev libclang-dev libjack-dev \
|
|
||||||
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-dev libgl1-mesa-dev \
|
|
||||||
libx11-dev libx11-xcb-dev libxcursor-dev libxrandr-dev libxi-dev libwayland-dev
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cargo build --release --target x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Build desktop
|
|
||||||
run: cargo build --release --features desktop --bin cagire-desktop --target x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
if: inputs.run-tests
|
|
||||||
run: cargo test --target x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Clippy
|
|
||||||
if: inputs.run-clippy
|
|
||||||
run: cargo clippy --target x86_64-unknown-linux-gnu -- -D warnings
|
|
||||||
|
|
||||||
- name: Install cargo-bundle
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: cargo install cargo-bundle
|
|
||||||
|
|
||||||
- name: Bundle desktop app
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: cargo bundle --release --features desktop --bin cagire-desktop --target x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Build AppImages
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: |
|
|
||||||
mkdir -p target/releases
|
|
||||||
scripts/make-appimage.sh target/x86_64-unknown-linux-gnu/release/cagire x86_64 target/releases
|
|
||||||
scripts/make-appimage.sh target/x86_64-unknown-linux-gnu/release/cagire-desktop x86_64 target/releases
|
|
||||||
|
|
||||||
- name: Bundle CLAP plugin
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: cargo xtask bundle cagire-plugins --release --target x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Upload CLI artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-linux-x86_64
|
|
||||||
path: target/x86_64-unknown-linux-gnu/release/cagire
|
|
||||||
|
|
||||||
- name: Upload desktop artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-linux-x86_64-desktop
|
|
||||||
path: target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb
|
|
||||||
|
|
||||||
- name: Upload AppImage artifacts
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-linux-x86_64-appimage
|
|
||||||
path: target/releases/*.AppImage
|
|
||||||
|
|
||||||
- name: Prepare plugin artifacts
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: |
|
|
||||||
mkdir -p staging/clap staging/vst3
|
|
||||||
cp -R target/bundled/cagire-plugins.clap staging/clap/
|
|
||||||
cp -R target/bundled/cagire-plugins.vst3 staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload CLAP artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-linux-x86_64-clap
|
|
||||||
path: staging/clap/
|
|
||||||
|
|
||||||
- name: Upload VST3 artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-linux-x86_64-vst3
|
|
||||||
path: staging/vst3/
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
name: Build macOS
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
run-tests:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
run-clippy:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
build-packages:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
matrix:
|
|
||||||
type: string
|
|
||||||
default: '[{"os":"macos-14","target":"aarch64-apple-darwin","artifact":"cagire-macos-aarch64"}]'
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
run-tests:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
run-clippy:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
build-packages:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
matrix:
|
|
||||||
type: string
|
|
||||||
default: '[{"os":"macos-14","target":"aarch64-apple-darwin","artifact":"cagire-macos-aarch64"}]'
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
MACOSX_DEPLOYMENT_TARGET: "12.0"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include: ${{ fromJSON(inputs.matrix) }}
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: ${{ matrix.target }}
|
|
||||||
components: clippy
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
key: ${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: brew list cmake &>/dev/null || brew install cmake
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cargo build --release --target ${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Build desktop
|
|
||||||
run: cargo build --release --features desktop --bin cagire-desktop --target ${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
if: inputs.run-tests
|
|
||||||
run: cargo test --target ${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Clippy
|
|
||||||
if: inputs.run-clippy
|
|
||||||
run: cargo clippy --target ${{ matrix.target }} -- -D warnings
|
|
||||||
|
|
||||||
- name: Bundle desktop app
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: scripts/make-app-bundle.sh ${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Bundle CLAP plugin
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: cargo xtask bundle cagire-plugins --release --target ${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Zip macOS app bundle
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: |
|
|
||||||
cd target/${{ matrix.target }}/release/bundle/osx
|
|
||||||
zip -r Cagire.app.zip Cagire.app
|
|
||||||
|
|
||||||
- name: Upload CLI artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.artifact }}
|
|
||||||
path: target/${{ matrix.target }}/release/cagire
|
|
||||||
|
|
||||||
- name: Upload desktop artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.artifact }}-desktop
|
|
||||||
path: target/${{ matrix.target }}/release/bundle/osx/Cagire.app.zip
|
|
||||||
|
|
||||||
- name: Prepare plugin artifacts
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: |
|
|
||||||
mkdir -p staging/clap staging/vst3
|
|
||||||
cp -R target/bundled/cagire-plugins.clap staging/clap/
|
|
||||||
cp -R target/bundled/cagire-plugins.vst3 staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload CLAP artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.artifact }}-clap
|
|
||||||
path: staging/clap/
|
|
||||||
|
|
||||||
- name: Upload VST3 artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.artifact }}-vst3
|
|
||||||
path: staging/vst3/
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
name: Build Plugins Linux
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
key: x86_64-unknown-linux-gnu-plugins
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y build-essential cmake pkg-config libasound2-dev libclang-dev libjack-dev \
|
|
||||||
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-dev libgl1-mesa-dev \
|
|
||||||
libx11-dev libx11-xcb-dev libxcursor-dev libxrandr-dev libxi-dev libwayland-dev
|
|
||||||
|
|
||||||
- name: Build plugins
|
|
||||||
run: cargo xtask bundle cagire-plugins --release --target x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Prepare plugin artifacts
|
|
||||||
run: |
|
|
||||||
mkdir -p staging/clap staging/vst3
|
|
||||||
cp -R target/bundled/cagire-plugins.clap staging/clap/
|
|
||||||
cp -R target/bundled/cagire-plugins.vst3 staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload CLAP artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: plugins-linux-x86_64-clap
|
|
||||||
path: staging/clap/
|
|
||||||
|
|
||||||
- name: Upload VST3 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: plugins-linux-x86_64-vst3
|
|
||||||
path: staging/vst3/
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
name: Build Plugins macOS
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
matrix:
|
|
||||||
type: string
|
|
||||||
default: '[{"os":"macos-14","target":"aarch64-apple-darwin","artifact":"plugins-macos-aarch64"},{"os":"macos-15-intel","target":"x86_64-apple-darwin","artifact":"plugins-macos-x86_64"}]'
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
matrix:
|
|
||||||
type: string
|
|
||||||
default: '[{"os":"macos-14","target":"aarch64-apple-darwin","artifact":"plugins-macos-aarch64"}]'
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
MACOSX_DEPLOYMENT_TARGET: "12.0"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include: ${{ fromJSON(inputs.matrix) }}
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: ${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
key: ${{ matrix.target }}-plugins
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: brew list cmake &>/dev/null || brew install cmake
|
|
||||||
|
|
||||||
- name: Build plugins
|
|
||||||
run: cargo xtask bundle cagire-plugins --release --target ${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Prepare plugin artifacts
|
|
||||||
run: |
|
|
||||||
mkdir -p staging/clap staging/vst3
|
|
||||||
cp -R target/bundled/cagire-plugins.clap staging/clap/
|
|
||||||
cp -R target/bundled/cagire-plugins.vst3 staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload CLAP artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.artifact }}-clap
|
|
||||||
path: staging/clap/
|
|
||||||
|
|
||||||
- name: Upload VST3 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.artifact }}-vst3
|
|
||||||
path: staging/vst3/
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
name: Build Plugins RPi
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: aarch64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
key: aarch64-unknown-linux-gnu-plugins
|
|
||||||
|
|
||||||
- name: Install cross
|
|
||||||
run: cargo install cross --git https://github.com/cross-rs/cross
|
|
||||||
|
|
||||||
- name: Build plugins
|
|
||||||
run: cross build --release -p cagire-plugins --target aarch64-unknown-linux-gnu
|
|
||||||
|
|
||||||
- name: Prepare plugin artifacts
|
|
||||||
run: |
|
|
||||||
mkdir -p target/bundled
|
|
||||||
cp target/aarch64-unknown-linux-gnu/release/libcagire_plugins.so target/bundled/cagire-plugins.clap
|
|
||||||
mkdir -p "target/bundled/cagire-plugins.vst3/Contents/aarch64-linux"
|
|
||||||
cp target/aarch64-unknown-linux-gnu/release/libcagire_plugins.so "target/bundled/cagire-plugins.vst3/Contents/aarch64-linux/cagire-plugins.so"
|
|
||||||
|
|
||||||
mkdir -p staging/clap staging/vst3
|
|
||||||
cp -R target/bundled/cagire-plugins.clap staging/clap/
|
|
||||||
cp -R target/bundled/cagire-plugins.vst3 staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload CLAP artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: plugins-linux-aarch64-clap
|
|
||||||
path: staging/clap/
|
|
||||||
|
|
||||||
- name: Upload VST3 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: plugins-linux-aarch64-vst3
|
|
||||||
path: staging/vst3/
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
name: Build Plugins Windows
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: windows-latest
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: x86_64-pc-windows-msvc
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
key: x86_64-pc-windows-msvc-plugins
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'
|
|
||||||
echo "C:\Program Files\CMake\bin" >> $env:GITHUB_PATH
|
|
||||||
|
|
||||||
- name: Build plugins
|
|
||||||
run: cargo xtask bundle cagire-plugins --release --target x86_64-pc-windows-msvc
|
|
||||||
|
|
||||||
- name: Prepare plugin artifacts
|
|
||||||
run: |
|
|
||||||
mkdir -p staging/clap staging/vst3
|
|
||||||
cp -R target/bundled/cagire-plugins.clap staging/clap/
|
|
||||||
cp -R target/bundled/cagire-plugins.vst3 staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload CLAP artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: plugins-windows-x86_64-clap
|
|
||||||
path: staging/clap/
|
|
||||||
|
|
||||||
- name: Upload VST3 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: plugins-windows-x86_64-vst3
|
|
||||||
path: staging/vst3/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
name: Build Plugins
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
linux:
|
|
||||||
uses: ./.gitea/workflows/build-plugins-linux.yml
|
|
||||||
|
|
||||||
macos:
|
|
||||||
uses: ./.gitea/workflows/build-plugins-macos.yml
|
|
||||||
|
|
||||||
windows:
|
|
||||||
uses: ./.gitea/workflows/build-plugins-windows.yml
|
|
||||||
|
|
||||||
rpi:
|
|
||||||
uses: ./.gitea/workflows/build-plugins-rpi.yml
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
name: Build Windows
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
run-tests:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
run-clippy:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
build-packages:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
run-tests:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
run-clippy:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
build-packages:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: windows-latest
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.2.2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: x86_64-pc-windows-msvc
|
|
||||||
components: clippy
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
key: x86_64-pc-windows-msvc
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'
|
|
||||||
echo "C:\Program Files\CMake\bin" >> $env:GITHUB_PATH
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cargo build --release --features asio --target x86_64-pc-windows-msvc
|
|
||||||
|
|
||||||
- name: Build desktop
|
|
||||||
run: cargo build --release --features desktop,asio --bin cagire-desktop --target x86_64-pc-windows-msvc
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
if: inputs.run-tests
|
|
||||||
run: cargo test --features asio --target x86_64-pc-windows-msvc
|
|
||||||
|
|
||||||
- name: Clippy
|
|
||||||
if: inputs.run-clippy
|
|
||||||
run: cargo clippy --features asio --target x86_64-pc-windows-msvc -- -D warnings
|
|
||||||
|
|
||||||
- name: Bundle CLAP plugin
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: cargo xtask bundle cagire-plugins --release --features asio --target x86_64-pc-windows-msvc
|
|
||||||
|
|
||||||
- name: Install NSIS
|
|
||||||
if: inputs.build-packages
|
|
||||||
run: choco install nsis
|
|
||||||
|
|
||||||
- name: Build NSIS installer
|
|
||||||
if: inputs.build-packages
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
$version = (Select-String -Path Cargo.toml -Pattern '^version\s*=\s*"(.+)"' | Select-Object -First 1).Matches.Groups[1].Value
|
|
||||||
$root = (Get-Location).Path
|
|
||||||
$target = "x86_64-pc-windows-msvc"
|
|
||||||
& "C:\Program Files (x86)\NSIS\makensis.exe" `
|
|
||||||
"-DVERSION=$version" `
|
|
||||||
"-DCLI_EXE=$root\target\$target\release\cagire.exe" `
|
|
||||||
"-DDESKTOP_EXE=$root\target\$target\release\cagire-desktop.exe" `
|
|
||||||
"-DICON=$root\assets\Cagire.ico" `
|
|
||||||
"-DOUTDIR=$root\target" `
|
|
||||||
nsis/cagire.nsi
|
|
||||||
|
|
||||||
- name: Upload CLI artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-windows-x86_64
|
|
||||||
path: target/x86_64-pc-windows-msvc/release/cagire.exe
|
|
||||||
|
|
||||||
- name: Upload desktop artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-windows-x86_64-desktop
|
|
||||||
path: target/x86_64-pc-windows-msvc/release/cagire-desktop.exe
|
|
||||||
|
|
||||||
- name: Upload installer artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-windows-x86_64-installer
|
|
||||||
path: target/cagire-*-setup.exe
|
|
||||||
|
|
||||||
- name: Prepare plugin artifacts
|
|
||||||
if: inputs.build-packages
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
mkdir -p staging/clap staging/vst3
|
|
||||||
cp -R target/bundled/cagire-plugins.clap staging/clap/
|
|
||||||
cp -R target/bundled/cagire-plugins.vst3 staging/vst3/
|
|
||||||
|
|
||||||
- name: Upload CLAP artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-windows-x86_64-clap
|
|
||||||
path: staging/clap/
|
|
||||||
|
|
||||||
- name: Upload VST3 artifact
|
|
||||||
if: inputs.build-packages
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cagire-windows-x86_64-vst3
|
|
||||||
path: staging/vst3/
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
linux:
|
|
||||||
uses: ./.gitea/workflows/build-linux.yml
|
|
||||||
with:
|
|
||||||
run-tests: true
|
|
||||||
run-clippy: true
|
|
||||||
|
|
||||||
macos:
|
|
||||||
uses: ./.gitea/workflows/build-macos.yml
|
|
||||||
with:
|
|
||||||
run-tests: true
|
|
||||||
run-clippy: true
|
|
||||||
|
|
||||||
windows:
|
|
||||||
uses: ./.gitea/workflows/build-windows.yml
|
|
||||||
with:
|
|
||||||
run-tests: true
|
|
||||||
run-clippy: true
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
linux:
|
|
||||||
uses: ./.gitea/workflows/build-linux.yml
|
|
||||||
with:
|
|
||||||
build-packages: true
|
|
||||||
|
|
||||||
macos:
|
|
||||||
uses: ./.gitea/workflows/build-macos.yml
|
|
||||||
with:
|
|
||||||
build-packages: true
|
|
||||||
matrix: >-
|
|
||||||
[
|
|
||||||
{"os":"macos-14","target":"aarch64-apple-darwin","artifact":"cagire-macos-aarch64"},
|
|
||||||
{"os":"macos-15-intel","target":"x86_64-apple-darwin","artifact":"cagire-macos-x86_64"}
|
|
||||||
]
|
|
||||||
|
|
||||||
windows:
|
|
||||||
uses: ./.gitea/workflows/build-windows.yml
|
|
||||||
with:
|
|
||||||
build-packages: true
|
|
||||||
|
|
||||||
cross:
|
|
||||||
uses: ./.gitea/workflows/build-cross.yml
|
|
||||||
|
|
||||||
assemble-macos:
|
|
||||||
needs: macos
|
|
||||||
uses: ./.gitea/workflows/assemble-macos.yml
|
|
||||||
|
|
||||||
release:
|
|
||||||
needs: [linux, macos, windows, cross, assemble-macos]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 10
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Download all artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
path: artifacts
|
|
||||||
|
|
||||||
- name: Prepare release files
|
|
||||||
run: |
|
|
||||||
mkdir -p release
|
|
||||||
for dir in artifacts/*/; do
|
|
||||||
name=$(basename "$dir")
|
|
||||||
if [[ "$name" == "cagire-macos-universal-dmg" ]]; then
|
|
||||||
cp "$dir"/*.dmg release/
|
|
||||||
elif [[ "$name" == "cagire-macos-universal-pkg" ]]; then
|
|
||||||
cp "$dir"/*.pkg release/
|
|
||||||
elif [[ "$name" == "cagire-macos-universal-desktop" ]]; then
|
|
||||||
cp "$dir/Cagire.app.zip" "release/cagire-macos-universal-desktop.app.zip"
|
|
||||||
elif [[ "$name" == "cagire-macos-universal" ]]; then
|
|
||||||
cp "$dir/cagire" "release/cagire-macos-universal"
|
|
||||||
elif [[ "$name" == "cagire-macos-universal-clap" ]]; then
|
|
||||||
cd "$dir" && zip -r "../../release/cagire-macos-universal-clap.zip" cagire-plugins.clap && cd ../..
|
|
||||||
elif [[ "$name" == "cagire-macos-universal-vst3" ]]; then
|
|
||||||
cd "$dir" && zip -r "../../release/cagire-macos-universal-vst3.zip" cagire-plugins.vst3 && cd ../..
|
|
||||||
elif [[ "$name" == *-clap ]]; then
|
|
||||||
base="${name%-clap}"
|
|
||||||
cd "$dir" && zip -r "../../release/${base}-clap.zip" cagire-plugins.clap && cd ../..
|
|
||||||
elif [[ "$name" == *-vst3 ]]; then
|
|
||||||
base="${name%-vst3}"
|
|
||||||
cd "$dir" && zip -r "../../release/${base}-vst3.zip" cagire-plugins.vst3 && cd ../..
|
|
||||||
elif [[ "$name" == *-installer ]]; then
|
|
||||||
cp "$dir"/*-setup.exe release/
|
|
||||||
elif [[ "$name" == *-appimage ]]; then
|
|
||||||
cp "$dir"/*.AppImage release/
|
|
||||||
elif [[ "$name" == *-desktop ]]; then
|
|
||||||
base="${name%-desktop}"
|
|
||||||
if ls "$dir"/*.deb 1>/dev/null 2>&1; then
|
|
||||||
cp "$dir"/*.deb "release/${base}-desktop.deb"
|
|
||||||
elif [ -f "$dir/Cagire.app.zip" ]; then
|
|
||||||
cp "$dir/Cagire.app.zip" "release/${base}-desktop.app.zip"
|
|
||||||
elif [ -f "$dir/cagire-desktop.exe" ]; then
|
|
||||||
cp "$dir/cagire-desktop.exe" "release/${base}-desktop.exe"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ -f "$dir/cagire.exe" ]; then
|
|
||||||
cp "$dir/cagire.exe" "release/${name}.exe"
|
|
||||||
elif [ -f "$dir/cagire" ]; then
|
|
||||||
cp "$dir/cagire" "release/${name}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Create Gitea release
|
|
||||||
env:
|
|
||||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
||||||
run: |
|
|
||||||
TAG="${GITEA_REF_NAME:-manual-$(date +%Y%m%d-%H%M%S)}"
|
|
||||||
API_URL="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases"
|
|
||||||
|
|
||||||
RELEASE_ID=$(curl -s -X POST "$API_URL" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"tag_name\": \"$TAG\", \"name\": \"$TAG\", \"draft\": true}" \
|
|
||||||
| jq -r '.id')
|
|
||||||
|
|
||||||
for file in release/*; do
|
|
||||||
filename=$(basename "$file")
|
|
||||||
curl -s -X POST "$API_URL/$RELEASE_ID/assets?name=$filename" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/octet-stream" \
|
|
||||||
--data-binary "@$file"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Release $TAG created as draft with $(ls release | wc -l) assets"
|
|
||||||
55
BUILDING.md
55
BUILDING.md
@@ -110,57 +110,49 @@ cargo run --release --features desktop --bin cagire-desktop
|
|||||||
|
|
||||||
## Cross-Compilation
|
## Cross-Compilation
|
||||||
|
|
||||||
[cross](https://github.com/cross-rs/cross) uses Docker to build for other platforms without installing their toolchains locally. It works on any OS that runs Docker.
|
|
||||||
|
|
||||||
### Targets
|
### Targets
|
||||||
|
|
||||||
| Target | Method | Binaries |
|
| Target | Method | Binaries |
|
||||||
|--------|--------|----------|
|
|--------|--------|----------|
|
||||||
| aarch64-apple-darwin | Native (macOS ARM only) | `cagire`, `cagire-desktop` |
|
| aarch64-apple-darwin | Native (macOS ARM only) | `cagire`, `cagire-desktop` |
|
||||||
| x86_64-apple-darwin | Native (macOS only) | `cagire`, `cagire-desktop` |
|
| x86_64-apple-darwin | Native (macOS only) | `cagire`, `cagire-desktop` |
|
||||||
| x86_64-unknown-linux-gnu | `cross build` | `cagire`, `cagire-desktop` |
|
| x86_64-unknown-linux-gnu | `cross build` (Docker) | `cagire`, `cagire-desktop` |
|
||||||
| aarch64-unknown-linux-gnu (RPi 64-bit) | `cross build` | `cagire`, `cagire-desktop` |
|
| aarch64-unknown-linux-gnu (RPi 64-bit) | `cross build` (Docker) | `cagire`, `cagire-desktop` |
|
||||||
| x86_64-pc-windows-gnu | `cross build` | `cagire`, `cagire-desktop` |
|
| x86_64-pc-windows-msvc | `cargo xwin build` (native) | `cagire`, `cagire-desktop` |
|
||||||
|
|
||||||
macOS targets can only be built on macOS — Apple does not support cross-compilation to macOS from other platforms. Linux and Windows targets can be cross-compiled from any OS. The aarch64-unknown-linux-gnu target covers Raspberry Pi (64-bit OS).
|
macOS targets can only be built on macOS. Linux targets are cross-compiled via Docker (`cross`). Windows targets are cross-compiled natively via `cargo-xwin` (downloads Windows SDK + MSVC CRT headers, no Docker needed).
|
||||||
|
|
||||||
### Windows ABI
|
|
||||||
|
|
||||||
CI produces `x86_64-pc-windows-msvc` binaries (native Windows build, better compatibility). Local cross-compilation from non-Windows hosts produces `x86_64-pc-windows-gnu` binaries (MinGW via Docker). Both work; MSVC is preferred for releases.
|
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
1. **Docker**: https://docs.docker.com/get-docker/
|
1. **Docker** + **cross** (Linux targets only): `cargo install cross --git https://github.com/cross-rs/cross`
|
||||||
2. **cross**: `cargo install cross --git https://github.com/cross-rs/cross`
|
2. **cargo-xwin** (Windows target): `cargo install cargo-xwin` and `rustup target add x86_64-pc-windows-msvc`
|
||||||
3. On macOS, add the Intel target: `rustup target add x86_64-apple-darwin`
|
3. On macOS, add the Intel target: `rustup target add x86_64-apple-darwin`
|
||||||
|
|
||||||
Docker must be running before invoking `cross` or `scripts/build-all.sh`.
|
|
||||||
|
|
||||||
### Building Individual Targets
|
### Building Individual Targets
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Linux x86_64
|
# Linux x86_64 (Docker)
|
||||||
cross build --release --target x86_64-unknown-linux-gnu
|
cross build --release --target x86_64-unknown-linux-gnu
|
||||||
cross build --release --features desktop --bin cagire-desktop --target x86_64-unknown-linux-gnu
|
cross build --release --features desktop --bin cagire-desktop --target x86_64-unknown-linux-gnu
|
||||||
|
|
||||||
# Linux aarch64
|
# Linux aarch64 (Docker)
|
||||||
cross build --release --target aarch64-unknown-linux-gnu
|
cross build --release --target aarch64-unknown-linux-gnu
|
||||||
cross build --release --features desktop --bin cagire-desktop --target aarch64-unknown-linux-gnu
|
cross build --release --features desktop --bin cagire-desktop --target aarch64-unknown-linux-gnu
|
||||||
|
|
||||||
# Windows x86_64
|
# Windows x86_64 (native, no Docker)
|
||||||
cross build --release --target x86_64-pc-windows-gnu
|
cargo xwin build --release --target x86_64-pc-windows-msvc
|
||||||
cross build --release --features desktop --bin cagire-desktop --target x86_64-pc-windows-gnu
|
cargo xwin build --release --features desktop --bin cagire-desktop --target x86_64-pc-windows-msvc
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building All Targets (macOS only)
|
### Building All Targets
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Interactive (prompts for platform/target selection):
|
# Interactive (prompts for platform/target selection):
|
||||||
scripts/build-all.sh
|
uv run scripts/build.py
|
||||||
|
|
||||||
# Non-interactive:
|
# Non-interactive:
|
||||||
scripts/build-all.sh --platforms macos-arm64,linux-x86_64 --targets cli,desktop --yes
|
uv run scripts/build.py --platforms macos-arm64,linux-x86_64 --targets cli,desktop
|
||||||
scripts/build-all.sh --all --yes
|
uv run scripts/build.py --all
|
||||||
```
|
```
|
||||||
|
|
||||||
Builds selected targets, producing binaries in `releases/`.
|
Builds selected targets, producing binaries in `releases/`.
|
||||||
@@ -170,18 +162,11 @@ Target aliases: `cli`, `desktop`, `plugins`.
|
|||||||
|
|
||||||
### Linux AppImage Packaging
|
### Linux AppImage Packaging
|
||||||
|
|
||||||
Linux releases ship as AppImages — self-contained executables that bundle all shared library dependencies (ALSA, JACK, X11, OpenGL). No runtime dependencies required.
|
Linux releases ship as AppImages — self-contained executables that bundle all shared library dependencies (ALSA, JACK, X11, OpenGL). No runtime dependencies required. `build.py` handles AppImage creation automatically for Linux targets.
|
||||||
|
|
||||||
After building a Linux target, produce an AppImage with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scripts/make-appimage.sh target/x86_64-unknown-linux-gnu/release/cagire x86_64 releases
|
|
||||||
```
|
|
||||||
|
|
||||||
`scripts/build-all.sh` does this automatically for every Linux target selected. The CI pipeline produces AppImages for the x86_64 Linux build. Cross-arch AppImage building (e.g. aarch64 on x86_64) is not supported — run on a matching host or in CI.
|
|
||||||
|
|
||||||
### Notes
|
### Notes
|
||||||
|
|
||||||
- Custom Dockerfiles in `cross/` install the native libraries Cagire depends on (ALSA, JACK, X11, cmake, libclang, etc.). `Cross.toml` maps each target to its Dockerfile.
|
- Custom Dockerfiles in `scripts/cross/` install the native libraries for Linux cross-compilation (ALSA, JACK, X11, cmake, libclang, etc.). `Cross.toml` maps each Linux target to its Dockerfile.
|
||||||
- The first build per target downloads Docker base images and installs packages. Subsequent builds use cached layers.
|
- The first Linux cross-build per target downloads Docker base images and installs packages. Subsequent builds use cached layers.
|
||||||
- Cross-architecture Docker builds (e.g. aarch64 on x86_64 or vice versa) run under QEMU emulation and are significantly slower.
|
- Cross-architecture Docker builds (e.g. aarch64 on x86_64) run under QEMU emulation and are significantly slower.
|
||||||
|
- Windows cross-compilation via `cargo-xwin` runs natively on the host (no Docker) and uses real Windows SDK headers, ensuring correct ABI and struct layouts.
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [0.1.5]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support i32/i16 sample formats at cpal boundary for ASIO compatibility
|
||||||
|
|
||||||
## [0.1.4]
|
## [0.1.4]
|
||||||
|
|
||||||
### Breaking
|
### Breaking
|
||||||
|
|||||||
36
Cargo.lock
generated
36
Cargo.lock
generated
@@ -894,7 +894,7 @@ dependencies = [
|
|||||||
"tachyonfx",
|
"tachyonfx",
|
||||||
"thread-priority",
|
"thread-priority",
|
||||||
"tui-big-text",
|
"tui-big-text",
|
||||||
"winres",
|
"winresource",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1825,6 +1825,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "doux"
|
name = "doux"
|
||||||
version = "0.0.18"
|
version = "0.0.18"
|
||||||
|
source = "git+https://github.com/sova-org/doux?tag=v0.0.18#4a5a065ba525657cf7ff1362f0b7e2f4f4f2b46c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -5595,15 +5596,6 @@ dependencies = [
|
|||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.5.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.7.8"
|
version = "0.7.8"
|
||||||
@@ -5631,6 +5623,21 @@ dependencies = [
|
|||||||
"winnow 0.7.15",
|
"winnow 0.7.15",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "1.0.6+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "399b1124a3c9e16766831c6bba21e50192572cdd98706ea114f9502509686ffc"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde_core",
|
||||||
|
"serde_spanned 1.0.4",
|
||||||
|
"toml_datetime 1.0.0+spec-1.1.0",
|
||||||
|
"toml_parser",
|
||||||
|
"toml_writer",
|
||||||
|
"winnow 0.7.15",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.11"
|
version = "0.6.11"
|
||||||
@@ -7085,12 +7092,13 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winres"
|
name = "winresource"
|
||||||
version = "0.1.12"
|
version = "0.1.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c"
|
checksum = "0986a8b1d586b7d3e4fe3d9ea39fb451ae22869dcea4aa109d287a374d866087"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"toml 0.5.11",
|
"toml 1.0.6+spec-1.1.0",
|
||||||
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ cagire-forth = { path = "crates/forth" }
|
|||||||
cagire-markdown = { path = "crates/markdown" }
|
cagire-markdown = { path = "crates/markdown" }
|
||||||
cagire-project = { path = "crates/project" }
|
cagire-project = { path = "crates/project" }
|
||||||
cagire-ratatui = { path = "crates/ratatui" }
|
cagire-ratatui = { path = "crates/ratatui" }
|
||||||
doux = { git = "https://github.com/sova-org/doux", tag = "v0.0.18", features = ["native", "soundfont"] }
|
doux = { git = "https://github.com/sova-org/doux", tag = "v0.0.19", features = ["native", "soundfont"] }
|
||||||
rusty_link = "0.4"
|
rusty_link = "0.4"
|
||||||
ratatui = "0.30"
|
ratatui = "0.30"
|
||||||
crossterm = "0.29"
|
crossterm = "0.29"
|
||||||
@@ -87,7 +87,7 @@ image = { version = "0.25", default-features = false, features = ["png"], option
|
|||||||
cpal = { version = "0.17", optional = true, features = ["jack"] }
|
cpal = { version = "0.17", optional = true, features = ["jack"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
winres = "0.1"
|
winresource = "0.1"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
@@ -105,9 +105,6 @@ egui-baseview = { path = "plugins/egui-baseview" }
|
|||||||
[patch."https://github.com/RustAudio/baseview.git"]
|
[patch."https://github.com/RustAudio/baseview.git"]
|
||||||
baseview = { path = "plugins/baseview" }
|
baseview = { path = "plugins/baseview" }
|
||||||
|
|
||||||
[patch.'https://github.com/sova-org/doux']
|
|
||||||
doux = { path = "/Users/bubo/doux" }
|
|
||||||
|
|
||||||
[package.metadata.bundle.bin.cagire-desktop]
|
[package.metadata.bundle.bin.cagire-desktop]
|
||||||
name = "Cagire"
|
name = "Cagire"
|
||||||
identifier = "com.sova.cagire"
|
identifier = "com.sova.cagire"
|
||||||
|
|||||||
@@ -3,6 +3,3 @@ dockerfile = "./scripts/cross/aarch64-linux.Dockerfile"
|
|||||||
|
|
||||||
[target.x86_64-unknown-linux-gnu]
|
[target.x86_64-unknown-linux-gnu]
|
||||||
dockerfile = "./scripts/cross/x86_64-linux.Dockerfile"
|
dockerfile = "./scripts/cross/x86_64-linux.Dockerfile"
|
||||||
|
|
||||||
[target.x86_64-pc-windows-gnu]
|
|
||||||
dockerfile = "./scripts/cross/x86_64-windows.Dockerfile"
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ A generative pattern using randomness, scales, and effects:
|
|||||||
```forth
|
```forth
|
||||||
sine sound 2 fm 0.5 fmh
|
sine sound 2 fm 0.5 fmh
|
||||||
0 7 rand minor 50 + note
|
0 7 rand minor 50 + note
|
||||||
.1 .8 rrand cutoff
|
.1 .8 rand lpf
|
||||||
1 4 irand 10 * delay .5 delayfb
|
1 4 rand 10 * delay .5 delayfeedback
|
||||||
.
|
.
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ To build from source instead, see [BUILDING.md](BUILDING.md).
|
|||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
Cagire includes interactive documentation with runnable code examples. Press **F1** in the application to open it.
|
Cagire includes interactive documentation with runnable code examples. Press **F4** in the application to open it.
|
||||||
|
|
||||||
- [Website](https://cagire.raphaelforment.fr)
|
- [Website](https://cagire.raphaelforment.fr)
|
||||||
- [BUILDING.md](BUILDING.md) — build instructions and CLI flags
|
- [BUILDING.md](BUILDING.md) — build instructions and CLI flags
|
||||||
|
|||||||
23
build.rs
23
build.rs
@@ -4,8 +4,6 @@ fn main() {
|
|||||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
|
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
|
||||||
|
|
||||||
if target_os == "windows" {
|
if target_os == "windows" {
|
||||||
// C++ runtime (stdc++, gcc, gcc_eh, pthread) linked statically via .cargo/config.toml
|
|
||||||
// using -Wl,-Bstatic. Only Windows system DLLs go here.
|
|
||||||
println!("cargo:rustc-link-lib=ws2_32");
|
println!("cargo:rustc-link-lib=ws2_32");
|
||||||
println!("cargo:rustc-link-lib=iphlpapi");
|
println!("cargo:rustc-link-lib=iphlpapi");
|
||||||
println!("cargo:rustc-link-lib=winmm");
|
println!("cargo:rustc-link-lib=winmm");
|
||||||
@@ -16,23 +14,12 @@ fn main() {
|
|||||||
if target_os == "windows" {
|
if target_os == "windows" {
|
||||||
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
let icon = format!("{manifest_dir}/assets/Cagire.ico");
|
let icon = format!("{manifest_dir}/assets/Cagire.ico");
|
||||||
let mut res = winres::WindowsResource::new();
|
winresource::WindowsResource::new()
|
||||||
// Cross-compiling from Unix: use prefixed MinGW tools
|
.set_icon(&icon)
|
||||||
if cfg!(unix) {
|
|
||||||
res.set_windres_path("x86_64-w64-mingw32-windres");
|
|
||||||
res.set_ar_path("x86_64-w64-mingw32-ar");
|
|
||||||
res.set_toolkit_path("/");
|
|
||||||
}
|
|
||||||
res.set_icon(&icon)
|
|
||||||
.set("ProductName", "Cagire")
|
.set("ProductName", "Cagire")
|
||||||
.set("FileDescription", "Forth-based music sequencer")
|
.set("FileDescription", "Forth-based music sequencer")
|
||||||
.set("LegalCopyright", "Copyright (c) 2025 Raphaël Forment");
|
.set("LegalCopyright", "Copyright (c) 2025 Raphaël Forment")
|
||||||
res.compile().expect("Failed to compile Windows resources");
|
.compile()
|
||||||
// GNU ld discards unreferenced sections from static archives,
|
.expect("Failed to compile Windows resources");
|
||||||
// so link the resource object directly to ensure .rsrc is kept.
|
|
||||||
if cfg!(unix) {
|
|
||||||
let out_dir = std::env::var("OUT_DIR").unwrap();
|
|
||||||
println!("cargo:rustc-link-arg-bins={out_dir}/resource.o");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
114
nsis/cagire.nsi
114
nsis/cagire.nsi
@@ -1,114 +0,0 @@
|
|||||||
; Cagire NSIS Installer Script
|
|
||||||
; Receives defines from command line:
|
|
||||||
; -DVERSION=x.y.z
|
|
||||||
; -DCLI_EXE=/path/to/cagire.exe
|
|
||||||
; -DDESKTOP_EXE=/path/to/cagire-desktop.exe
|
|
||||||
; -DICON=/path/to/Cagire.ico
|
|
||||||
; -DOUTDIR=/path/to/releases
|
|
||||||
|
|
||||||
!include "MUI2.nsh"
|
|
||||||
!include "WordFunc.nsh"
|
|
||||||
|
|
||||||
Name "Cagire ${VERSION}"
|
|
||||||
OutFile "${OUTDIR}\cagire-${VERSION}-windows-x86_64-setup.exe"
|
|
||||||
InstallDir "$PROGRAMFILES64\Cagire"
|
|
||||||
InstallDirRegKey HKLM "Software\Cagire" "InstallDir"
|
|
||||||
RequestExecutionLevel admin
|
|
||||||
Unicode True
|
|
||||||
|
|
||||||
!define MUI_ICON "${ICON}"
|
|
||||||
!define MUI_UNICON "${ICON}"
|
|
||||||
!define MUI_ABORTWARNING
|
|
||||||
|
|
||||||
!define MUI_HEADERIMAGE
|
|
||||||
!define MUI_HEADERIMAGE_BITMAP "header.bmp"
|
|
||||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "sidebar.bmp"
|
|
||||||
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "sidebar.bmp"
|
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_WELCOME
|
|
||||||
!insertmacro MUI_PAGE_COMPONENTS
|
|
||||||
!insertmacro MUI_PAGE_DIRECTORY
|
|
||||||
!insertmacro MUI_PAGE_INSTFILES
|
|
||||||
!insertmacro MUI_PAGE_FINISH
|
|
||||||
|
|
||||||
!insertmacro MUI_UNPAGE_CONFIRM
|
|
||||||
!insertmacro MUI_UNPAGE_INSTFILES
|
|
||||||
|
|
||||||
!insertmacro MUI_LANGUAGE "English"
|
|
||||||
|
|
||||||
Section "Cagire (required)" SecCore
|
|
||||||
SectionIn RO
|
|
||||||
SetOutPath "$INSTDIR"
|
|
||||||
!ifdef CLI_EXE
|
|
||||||
File "/oname=cagire.exe" "${CLI_EXE}"
|
|
||||||
!endif
|
|
||||||
!ifdef DESKTOP_EXE
|
|
||||||
File "/oname=cagire-desktop.exe" "${DESKTOP_EXE}"
|
|
||||||
!endif
|
|
||||||
|
|
||||||
WriteUninstaller "$INSTDIR\uninstall.exe"
|
|
||||||
WriteRegStr HKLM "Software\Cagire" "InstallDir" "$INSTDIR"
|
|
||||||
|
|
||||||
; Add/Remove Programs entry
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "DisplayName" "Cagire"
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "DisplayVersion" "${VERSION}"
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "Publisher" "Raphael Forment"
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "UninstallString" '"$INSTDIR\uninstall.exe"'
|
|
||||||
!ifdef DESKTOP_EXE
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "DisplayIcon" '"$INSTDIR\cagire-desktop.exe"'
|
|
||||||
!else
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "DisplayIcon" '"$INSTDIR\cagire.exe"'
|
|
||||||
!endif
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "URLInfoAbout" "https://git.raphaelforment.fr/BuboBubo/cagire"
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "HelpLink" "https://cagire.raphaelforment.fr"
|
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "NoModify" 1
|
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire" "NoRepair" 1
|
|
||||||
SectionEnd
|
|
||||||
|
|
||||||
Section "Add to PATH" SecPath
|
|
||||||
ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path"
|
|
||||||
StrCpy $0 "$0;$INSTDIR"
|
|
||||||
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$0"
|
|
||||||
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
|
|
||||||
SectionEnd
|
|
||||||
|
|
||||||
!ifdef DESKTOP_EXE
|
|
||||||
Section "Start Menu Shortcut" SecStartMenu
|
|
||||||
CreateDirectory "$SMPROGRAMS\Cagire"
|
|
||||||
CreateShortCut "$SMPROGRAMS\Cagire\Cagire.lnk" "$INSTDIR\cagire-desktop.exe" "" "$INSTDIR\cagire-desktop.exe" 0
|
|
||||||
CreateShortCut "$SMPROGRAMS\Cagire\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
|
||||||
SectionEnd
|
|
||||||
!endif
|
|
||||||
|
|
||||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
|
||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecCore} "Installs Cagire CLI and Desktop binaries."
|
|
||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPath} "Add the install location to the PATH system environment variable."
|
|
||||||
!ifdef DESKTOP_EXE
|
|
||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecStartMenu} "Add a Cagire shortcut to the Start Menu."
|
|
||||||
!endif
|
|
||||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
|
||||||
|
|
||||||
Section "Uninstall"
|
|
||||||
!ifdef CLI_EXE
|
|
||||||
Delete "$INSTDIR\cagire.exe"
|
|
||||||
!endif
|
|
||||||
!ifdef DESKTOP_EXE
|
|
||||||
Delete "$INSTDIR\cagire-desktop.exe"
|
|
||||||
!endif
|
|
||||||
Delete "$INSTDIR\uninstall.exe"
|
|
||||||
RMDir "$INSTDIR"
|
|
||||||
|
|
||||||
Delete "$SMPROGRAMS\Cagire\Cagire.lnk"
|
|
||||||
Delete "$SMPROGRAMS\Cagire\Uninstall.lnk"
|
|
||||||
RMDir "$SMPROGRAMS\Cagire"
|
|
||||||
|
|
||||||
; Remove from PATH
|
|
||||||
ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path"
|
|
||||||
; Remove ";$INSTDIR" from the path string
|
|
||||||
${WordReplace} $0 ";$INSTDIR" "" "+" $0
|
|
||||||
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$0"
|
|
||||||
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
|
|
||||||
|
|
||||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cagire"
|
|
||||||
DeleteRegKey HKLM "Software\Cagire"
|
|
||||||
SectionEnd
|
|
||||||
BIN
nsis/header.bmp
BIN
nsis/header.bmp
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
BIN
nsis/sidebar.bmp
BIN
nsis/sidebar.bmp
Binary file not shown.
|
Before Width: | Height: | Size: 151 KiB |
@@ -14,7 +14,7 @@ cagire = { path = "../..", default-features = false, features = ["block-renderer
|
|||||||
cagire-forth = { path = "../../crates/forth" }
|
cagire-forth = { path = "../../crates/forth" }
|
||||||
cagire-project = { path = "../../crates/project" }
|
cagire-project = { path = "../../crates/project" }
|
||||||
cagire-ratatui = { path = "../../crates/ratatui" }
|
cagire-ratatui = { path = "../../crates/ratatui" }
|
||||||
doux = { git = "https://github.com/sova-org/doux", tag = "v0.0.18", features = ["native", "soundfont"] }
|
doux = { git = "https://github.com/sova-org/doux", tag = "v0.0.19", features = ["native", "soundfont"] }
|
||||||
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug", features = ["standalone"] }
|
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug", features = ["standalone"] }
|
||||||
nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug" }
|
nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug" }
|
||||||
egui_ratatui = "2.1"
|
egui_ratatui = "2.1"
|
||||||
|
|||||||
100
scripts/build.py
100
scripts/build.py
@@ -3,7 +3,7 @@
|
|||||||
# requires-python = ">=3.11"
|
# requires-python = ">=3.11"
|
||||||
# dependencies = ["rich>=13.0", "questionary>=2.0"]
|
# dependencies = ["rich>=13.0", "questionary>=2.0"]
|
||||||
# ///
|
# ///
|
||||||
"""Cagire release builder — replaces build-all.sh, make-dmg.sh, make-appimage.sh."""
|
"""Cagire release builder."""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
@@ -150,6 +150,8 @@ def get_version(root: Path) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def builder_for(p: Platform) -> str:
|
def builder_for(p: Platform) -> str:
|
||||||
|
if p.os == "windows" and p.cross:
|
||||||
|
return "cargo-xwin"
|
||||||
return "cross" if p.cross else "cargo"
|
return "cross" if p.cross else "cargo"
|
||||||
|
|
||||||
|
|
||||||
@@ -195,12 +197,31 @@ def run_cmd(
|
|||||||
# Build functions
|
# Build functions
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _macos_env(p: Platform) -> dict[str, str] | None:
|
def _find_llvm_prefix() -> str | None:
|
||||||
if p.os == "macos":
|
"""Find Homebrew LLVM installation path."""
|
||||||
return {"MACOSX_DEPLOYMENT_TARGET": "12.0"}
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["brew", "--prefix", "llvm"], capture_output=True, text=True,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return result.stdout.strip()
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _cross_env(p: Platform) -> dict[str, str] | None:
|
||||||
|
env = {}
|
||||||
|
if p.os == "macos":
|
||||||
|
env["MACOSX_DEPLOYMENT_TARGET"] = "12.0"
|
||||||
|
if p.os == "windows" and p.cross:
|
||||||
|
env["VCINSTALLDIR"] = "/dummy"
|
||||||
|
llvm_prefix = _find_llvm_prefix()
|
||||||
|
if llvm_prefix:
|
||||||
|
env["LIBCLANG_PATH"] = f"{llvm_prefix}/lib"
|
||||||
|
return env or None
|
||||||
|
|
||||||
|
|
||||||
def _platform_features(p: Platform) -> list[str]:
|
def _platform_features(p: Platform) -> list[str]:
|
||||||
if p.os == "windows":
|
if p.os == "windows":
|
||||||
return ["--features", "asio"]
|
return ["--features", "asio"]
|
||||||
@@ -211,7 +232,7 @@ def build_binary(root: Path, p: Platform, log: list[str], extra_args: list[str]
|
|||||||
features = _platform_features(p) if platform_features else []
|
features = _platform_features(p) if platform_features else []
|
||||||
cmd = [builder_for(p), "build", "--release", *target_flags(p), *features, *(extra_args or [])]
|
cmd = [builder_for(p), "build", "--release", *target_flags(p), *features, *(extra_args or [])]
|
||||||
log.append(f" Building: {' '.join(extra_args or ['default'])}")
|
log.append(f" Building: {' '.join(extra_args or ['default'])}")
|
||||||
run_cmd(cmd, log, env=_macos_env(p), cwd=root)
|
run_cmd(cmd, log, env=_cross_env(p), cwd=root)
|
||||||
|
|
||||||
|
|
||||||
def bundle_plugins(root: Path, p: Platform, log: list[str]) -> None:
|
def bundle_plugins(root: Path, p: Platform, log: list[str]) -> None:
|
||||||
@@ -224,7 +245,7 @@ def bundle_plugins(root: Path, p: Platform, log: list[str]) -> None:
|
|||||||
def _bundle_plugins_native(root: Path, p: Platform, log: list[str]) -> None:
|
def _bundle_plugins_native(root: Path, p: Platform, log: list[str]) -> None:
|
||||||
log.append(" Bundling plugins (native xtask)")
|
log.append(" Bundling plugins (native xtask)")
|
||||||
cmd = ["cargo", "xtask", "bundle", PLUGIN_NAME, "--release", *target_flags(p)]
|
cmd = ["cargo", "xtask", "bundle", PLUGIN_NAME, "--release", *target_flags(p)]
|
||||||
run_cmd(cmd, log, env=_macos_env(p), cwd=root)
|
run_cmd(cmd, log, env=_cross_env(p), cwd=root)
|
||||||
|
|
||||||
|
|
||||||
def _bundle_plugins_cross(root: Path, p: Platform, log: list[str]) -> None:
|
def _bundle_plugins_cross(root: Path, p: Platform, log: list[str]) -> None:
|
||||||
@@ -267,7 +288,7 @@ def bundle_desktop_app(root: Path, p: Platform, log: list[str]) -> None:
|
|||||||
return
|
return
|
||||||
log.append(" Bundling desktop .app")
|
log.append(" Bundling desktop .app")
|
||||||
cmd = ["cargo", "bundle", "--release", "--features", "desktop", "--bin", "cagire-desktop", *target_flags(p)]
|
cmd = ["cargo", "bundle", "--release", "--features", "desktop", "--bin", "cagire-desktop", *target_flags(p)]
|
||||||
run_cmd(cmd, log, env=_macos_env(p), cwd=root)
|
run_cmd(cmd, log, env=_cross_env(p), cwd=root)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -444,36 +465,6 @@ def make_appimage(root: Path, binary: Path, arch: str, output_dir: Path, log: li
|
|||||||
return _make_appimage_docker(root, binary, arch, output_dir, log)
|
return _make_appimage_docker(root, binary, arch, output_dir, log)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Packaging: NSIS
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def make_nsis(root: Path, rd: Path, version: str, output_dir: Path, config: BuildConfig, log: list[str]) -> str | None:
|
|
||||||
if not shutil.which("makensis"):
|
|
||||||
log.append(" makensis not found, skipping NSIS installer")
|
|
||||||
return None
|
|
||||||
|
|
||||||
log.append(" Building NSIS installer")
|
|
||||||
abs_root = str(root.resolve())
|
|
||||||
cmd = [
|
|
||||||
"makensis",
|
|
||||||
f"-DVERSION={version}",
|
|
||||||
f"-DICON={abs_root}/assets/Cagire.ico",
|
|
||||||
f"-DOUTDIR={abs_root}/{OUT}",
|
|
||||||
]
|
|
||||||
if config.cli:
|
|
||||||
cmd.append(f"-DCLI_EXE={abs_root}/{rd.relative_to(root)}/cagire.exe")
|
|
||||||
if config.desktop:
|
|
||||||
cmd.append(f"-DDESKTOP_EXE={abs_root}/{rd.relative_to(root)}/cagire-desktop.exe")
|
|
||||||
cmd.append(str(root / "nsis" / "cagire.nsi"))
|
|
||||||
run_cmd(cmd, log)
|
|
||||||
|
|
||||||
installer = f"cagire-{version}-windows-x86_64-setup.exe"
|
|
||||||
log.append(f" Installer -> {output_dir / installer}")
|
|
||||||
return str(output_dir / installer)
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Artifact copying & packaging dispatch
|
# Artifact copying & packaging dispatch
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -483,7 +474,6 @@ def copy_artifacts(root: Path, p: Platform, config: BuildConfig, log: list[str])
|
|||||||
rd = release_dir(root, p)
|
rd = release_dir(root, p)
|
||||||
out = root / OUT
|
out = root / OUT
|
||||||
sx = suffix_for(p)
|
sx = suffix_for(p)
|
||||||
version = get_version(root)
|
|
||||||
artifacts: list[str] = []
|
artifacts: list[str] = []
|
||||||
|
|
||||||
if config.cli:
|
if config.cli:
|
||||||
@@ -515,11 +505,6 @@ def copy_artifacts(root: Path, p: Platform, config: BuildConfig, log: list[str])
|
|||||||
if dmg:
|
if dmg:
|
||||||
artifacts.append(dmg)
|
artifacts.append(dmg)
|
||||||
|
|
||||||
if p.os == "windows":
|
|
||||||
nsis = make_nsis(root, rd, version, out, config, log)
|
|
||||||
if nsis:
|
|
||||||
artifacts.append(nsis)
|
|
||||||
|
|
||||||
if p.os == "linux":
|
if p.os == "linux":
|
||||||
if config.cli:
|
if config.cli:
|
||||||
ai = make_appimage(root, rd / "cagire", p.arch, out, log)
|
ai = make_appimage(root, rd / "cagire", p.arch, out, log)
|
||||||
@@ -725,9 +710,10 @@ def run_builds(
|
|||||||
for p in platforms:
|
for p in platforms:
|
||||||
_update_phase(p.alias, "waiting", 0)
|
_update_phase(p.alias, "waiting", 0)
|
||||||
|
|
||||||
# Split into native (share cargo lock) and cross (independent Docker builds)
|
# Docker-isolated cross builds (Linux only — each in its own container)
|
||||||
native_platforms = [p for p in platforms if not p.cross]
|
docker_cross = [p for p in platforms if p.cross and p.os != "windows"]
|
||||||
cross_platforms = [p for p in platforms if p.cross]
|
# Local builds share cargo lock — run sequentially
|
||||||
|
local_builds = [p for p in platforms if not p.cross or p.os == "windows"]
|
||||||
|
|
||||||
results: list[PlatformResult] = []
|
results: list[PlatformResult] = []
|
||||||
completed: dict[str, PlatformResult] = {}
|
completed: dict[str, PlatformResult] = {}
|
||||||
@@ -740,19 +726,19 @@ def run_builds(
|
|||||||
return _build_display(platforms, config, completed, start_times, log_max_lines)
|
return _build_display(platforms, config, completed, start_times, log_max_lines)
|
||||||
|
|
||||||
with Live(make_display(), console=console, refresh_per_second=4) as live:
|
with Live(make_display(), console=console, refresh_per_second=4) as live:
|
||||||
# Native builds run sequentially in one thread (they contend on cargo lock).
|
# Local builds run sequentially (they contend on cargo lock).
|
||||||
# Cross builds run in parallel (each in its own Docker container).
|
# Docker cross builds run in parallel (each in its own container).
|
||||||
with ThreadPoolExecutor(max_workers=max(len(cross_platforms) + 1, 1)) as pool:
|
with ThreadPoolExecutor(max_workers=max(len(docker_cross) + 1, 1)) as pool:
|
||||||
futures = {}
|
futures = {}
|
||||||
|
|
||||||
if native_platforms:
|
if local_builds:
|
||||||
f = pool.submit(
|
f = pool.submit(
|
||||||
_build_native_sequential, root, native_platforms, config,
|
_build_native_sequential, root, local_builds, config,
|
||||||
completed, start_times,
|
completed, start_times,
|
||||||
)
|
)
|
||||||
futures[f] = "native"
|
futures[f] = "native"
|
||||||
|
|
||||||
for p in cross_platforms:
|
for p in docker_cross:
|
||||||
f = pool.submit(build_platform, root, p, config)
|
f = pool.submit(build_platform, root, p, config)
|
||||||
futures[f] = "cross"
|
futures[f] = "cross"
|
||||||
|
|
||||||
@@ -928,20 +914,22 @@ def check_git_clean(root: Path) -> tuple[str, bool]:
|
|||||||
|
|
||||||
def check_prerequisites(platforms: list[Platform], config: BuildConfig) -> None:
|
def check_prerequisites(platforms: list[Platform], config: BuildConfig) -> None:
|
||||||
"""Verify required tools are available, fail fast if not."""
|
"""Verify required tools are available, fail fast if not."""
|
||||||
need_cross = any(p.cross for p in platforms)
|
need_xwin = any(p.os == "windows" and p.cross for p in platforms)
|
||||||
|
need_cross = any(p.cross and p.os != "windows" for p in platforms)
|
||||||
need_docker = any(p.cross and p.os == "linux" for p in platforms)
|
need_docker = any(p.cross and p.os == "linux" for p in platforms)
|
||||||
need_bundle = config.desktop and any(not p.cross and p.os == "macos" for p in platforms)
|
need_bundle = config.desktop and any(not p.cross and p.os == "macos" for p in platforms)
|
||||||
need_nsis = any(p.os == "windows" for p in platforms)
|
|
||||||
|
|
||||||
checks: list[tuple[str, bool]] = [("cargo", True)]
|
checks: list[tuple[str, bool]] = [("cargo", True)]
|
||||||
|
if need_xwin:
|
||||||
|
checks.append(("cargo-xwin", True))
|
||||||
|
checks.append(("clang", True))
|
||||||
|
checks.append(("cmake", True))
|
||||||
if need_cross:
|
if need_cross:
|
||||||
checks.append(("cross", True))
|
checks.append(("cross", True))
|
||||||
if need_docker:
|
if need_docker:
|
||||||
checks.append(("docker", True))
|
checks.append(("docker", True))
|
||||||
if need_bundle:
|
if need_bundle:
|
||||||
checks.append(("cargo-bundle", True))
|
checks.append(("cargo-bundle", True))
|
||||||
if need_nsis:
|
|
||||||
checks.append(("makensis", False))
|
|
||||||
|
|
||||||
console.print("[bold]Prerequisites:[/]")
|
console.print("[bold]Prerequisites:[/]")
|
||||||
missing_critical: list[str] = []
|
missing_critical: list[str] = []
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
FROM ghcr.io/cross-rs/x86_64-pc-windows-gnu:main
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y --no-install-recommends \
|
|
||||||
cmake \
|
|
||||||
clang \
|
|
||||||
libclang-dev \
|
|
||||||
mingw-w64-tools \
|
|
||||||
mingw-w64-x86-64-dev \
|
|
||||||
g++-mingw-w64-x86-64 \
|
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
|
||||||
&& ln -sf windows.h /usr/x86_64-w64-mingw32/include/Windows.h \
|
|
||||||
&& ln -sf winsock2.h /usr/x86_64-w64-mingw32/include/WinSock2.h \
|
|
||||||
&& ln -sf ws2tcpip.h /usr/x86_64-w64-mingw32/include/WS2tcpip.h \
|
|
||||||
&& GCCDIR=$(ls -d /usr/lib/gcc/x86_64-w64-mingw32/*-posix 2>/dev/null | head -1) \
|
|
||||||
&& ln -sf "$GCCDIR/libstdc++.a" /usr/x86_64-w64-mingw32/lib/libstdc++.a \
|
|
||||||
&& ln -sf "$GCCDIR/libgcc.a" /usr/x86_64-w64-mingw32/lib/libgcc.a \
|
|
||||||
&& rm -f /usr/x86_64-w64-mingw32/lib/libstdc++.dll.a \
|
|
||||||
&& rm -f /usr/lib/gcc/x86_64-w64-mingw32/*/libstdc++.dll.a
|
|
||||||
@@ -5,5 +5,5 @@ triples = [
|
|||||||
"x86_64-apple-darwin",
|
"x86_64-apple-darwin",
|
||||||
"x86_64-unknown-linux-gnu",
|
"x86_64-unknown-linux-gnu",
|
||||||
"aarch64-unknown-linux-gnu",
|
"aarch64-unknown-linux-gnu",
|
||||||
"x86_64-pc-windows-gnu",
|
"x86_64-pc-windows-msvc",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -267,6 +267,7 @@ pub fn preload_sample_heads(
|
|||||||
|
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
use cpal::traits::{DeviceTrait, StreamTrait};
|
use cpal::traits::{DeviceTrait, StreamTrait};
|
||||||
|
use cpal::FromSample;
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
use cpal::Stream;
|
use cpal::Stream;
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
@@ -421,29 +422,46 @@ pub fn build_stream(
|
|||||||
input_cfg.channels(),
|
input_cfg.channels(),
|
||||||
input_cfg.sample_rate()
|
input_cfg.sample_rate()
|
||||||
);
|
);
|
||||||
|
let input_format = input_cfg.sample_format();
|
||||||
let mut input_producer = input_producer;
|
let mut input_producer = input_producer;
|
||||||
let stream = dev
|
|
||||||
.build_input_stream(
|
macro_rules! build_input {
|
||||||
&input_cfg.into(),
|
($T:ty) => {{
|
||||||
move |data: &[f32], _| {
|
let mut scratch: Vec<f32> = Vec::new();
|
||||||
input_producer.push_slice(data);
|
dev.build_input_stream(
|
||||||
},
|
&input_cfg.into(),
|
||||||
{
|
move |data: &[$T], _| {
|
||||||
let device_lost = Arc::clone(&device_lost);
|
scratch.resize(data.len(), 0.0);
|
||||||
move |err: cpal::StreamError| {
|
for (dst, &src) in scratch.iter_mut().zip(data.iter()) {
|
||||||
eprintln!("input stream error: {err}");
|
*dst = <f32 as FromSample<$T>>::from_sample_(src);
|
||||||
match err {
|
|
||||||
cpal::StreamError::DeviceNotAvailable
|
|
||||||
| cpal::StreamError::StreamInvalidated => {
|
|
||||||
device_lost.store(true, Ordering::Release);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
input_producer.push_slice(&scratch);
|
||||||
},
|
},
|
||||||
None,
|
{
|
||||||
)
|
let device_lost = Arc::clone(&device_lost);
|
||||||
.ok()?;
|
move |err: cpal::StreamError| {
|
||||||
|
eprintln!("input stream error: {err}");
|
||||||
|
match err {
|
||||||
|
cpal::StreamError::DeviceNotAvailable
|
||||||
|
| cpal::StreamError::StreamInvalidated => {
|
||||||
|
device_lost.store(true, Ordering::Release);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
let stream = match input_format {
|
||||||
|
cpal::SampleFormat::F32 => build_input!(f32),
|
||||||
|
cpal::SampleFormat::I32 => build_input!(i32),
|
||||||
|
cpal::SampleFormat::I16 => build_input!(i16),
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
.ok()?;
|
||||||
stream.play().ok()?;
|
stream.play().ok()?;
|
||||||
Some(stream)
|
Some(stream)
|
||||||
});
|
});
|
||||||
@@ -455,94 +473,109 @@ pub fn build_stream(
|
|||||||
let mut live_scratch = vec![0.0f32; 4096];
|
let mut live_scratch = vec![0.0f32; 4096];
|
||||||
let mut input_consumer = input_consumer;
|
let mut input_consumer = input_consumer;
|
||||||
let mut current_pos: u64 = 0;
|
let mut current_pos: u64 = 0;
|
||||||
|
let output_format = default_config.sample_format();
|
||||||
|
|
||||||
let stream = device
|
macro_rules! build_output {
|
||||||
.build_output_stream(
|
($T:ty) => {{
|
||||||
&stream_config,
|
let mut conv_buf: Vec<f32> = Vec::new();
|
||||||
move |data: &mut [f32], _| {
|
device.build_output_stream(
|
||||||
if !rt_set {
|
&stream_config,
|
||||||
let ok = super::realtime::set_realtime_priority();
|
move |data: &mut [$T], _| {
|
||||||
rt_set = true;
|
conv_buf.resize(data.len(), 0.0f32);
|
||||||
if !ok {
|
|
||||||
super::realtime::warn_no_rt("audio");
|
if !rt_set {
|
||||||
|
let ok = super::realtime::set_realtime_priority();
|
||||||
|
rt_set = true;
|
||||||
|
if !ok {
|
||||||
|
super::realtime::warn_no_rt("audio");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let buffer_samples = data.len() / channels;
|
let buffer_samples = conv_buf.len() / channels;
|
||||||
let buffer_time_ns = (buffer_samples as f64 / sr as f64 * 1e9) as u64;
|
let buffer_time_ns = (buffer_samples as f64 / sr as f64 * 1e9) as u64;
|
||||||
|
|
||||||
while let Ok(cmd) = audio_rx.try_recv() {
|
while let Ok(cmd) = audio_rx.try_recv() {
|
||||||
match cmd {
|
match cmd {
|
||||||
AudioCommand::Evaluate { cmd, tick } => {
|
AudioCommand::Evaluate { cmd, tick } => {
|
||||||
let cmd_ref = match tick {
|
let cmd_ref = match tick {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
cmd_buffer.clear();
|
cmd_buffer.clear();
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
let _ = write!(&mut cmd_buffer, "{cmd}/tick/{t}");
|
let _ = write!(&mut cmd_buffer, "{cmd}/tick/{t}");
|
||||||
cmd_buffer.as_str()
|
cmd_buffer.as_str()
|
||||||
|
}
|
||||||
|
None => &cmd,
|
||||||
|
};
|
||||||
|
engine.evaluate(cmd_ref);
|
||||||
|
}
|
||||||
|
AudioCommand::Hush => {
|
||||||
|
engine.hush();
|
||||||
|
}
|
||||||
|
AudioCommand::Panic => {
|
||||||
|
engine.panic();
|
||||||
|
}
|
||||||
|
AudioCommand::LoadSamples(samples) => {
|
||||||
|
engine.sample_index.extend(samples);
|
||||||
|
}
|
||||||
|
AudioCommand::LoadSoundfont(path) => {
|
||||||
|
if let Err(e) = engine.load_soundfont(&path) {
|
||||||
|
eprintln!("Failed to load soundfont: {e}");
|
||||||
}
|
}
|
||||||
None => &cmd,
|
|
||||||
};
|
|
||||||
engine.evaluate(cmd_ref);
|
|
||||||
}
|
|
||||||
AudioCommand::Hush => {
|
|
||||||
engine.hush();
|
|
||||||
}
|
|
||||||
AudioCommand::Panic => {
|
|
||||||
engine.panic();
|
|
||||||
}
|
|
||||||
AudioCommand::LoadSamples(samples) => {
|
|
||||||
engine.sample_index.extend(samples);
|
|
||||||
}
|
|
||||||
AudioCommand::LoadSoundfont(path) => {
|
|
||||||
if let Err(e) = engine.load_soundfont(&path) {
|
|
||||||
eprintln!("Failed to load soundfont: {e}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let nch_in = input_channels.max(1);
|
let nch_in = input_channels.max(1);
|
||||||
let raw_len = buffer_samples * nch_in;
|
let raw_len = buffer_samples * nch_in;
|
||||||
if live_scratch.len() < raw_len {
|
if live_scratch.len() < raw_len {
|
||||||
live_scratch.resize(raw_len, 0.0);
|
live_scratch.resize(raw_len, 0.0);
|
||||||
}
|
|
||||||
live_scratch[..raw_len].fill(0.0);
|
|
||||||
input_consumer.pop_slice(&mut live_scratch[..raw_len]);
|
|
||||||
|
|
||||||
engine.metrics.load.set_buffer_time(buffer_time_ns);
|
|
||||||
engine.process_block(data, &[], &live_scratch[..raw_len]);
|
|
||||||
|
|
||||||
// Publish accurate audio reference AFTER process_block
|
|
||||||
// so sample_pos matches doux's internal tick exactly.
|
|
||||||
current_pos += buffer_samples as u64;
|
|
||||||
audio_ref.store(Arc::new(AudioRef {
|
|
||||||
sample_pos: current_pos,
|
|
||||||
timestamp: Instant::now(),
|
|
||||||
sample_rate: sr as f64,
|
|
||||||
}));
|
|
||||||
|
|
||||||
scope_buffer.write(data);
|
|
||||||
|
|
||||||
// Feed mono mix to analysis thread via ring buffer (non-blocking)
|
|
||||||
for chunk in data.chunks(channels) {
|
|
||||||
let mono = chunk.iter().sum::<f32>() / channels as f32;
|
|
||||||
let _ = fft_producer.try_push(mono);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
move |err: cpal::StreamError| {
|
|
||||||
let _ = error_tx.try_send(format!("stream error: {err}"));
|
|
||||||
match err {
|
|
||||||
cpal::StreamError::DeviceNotAvailable
|
|
||||||
| cpal::StreamError::StreamInvalidated => {
|
|
||||||
device_lost.store(true, Ordering::Release);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
live_scratch[..raw_len].fill(0.0);
|
||||||
}
|
input_consumer.pop_slice(&mut live_scratch[..raw_len]);
|
||||||
},
|
|
||||||
None,
|
engine.metrics.load.set_buffer_time(buffer_time_ns);
|
||||||
)
|
engine.process_block(&mut conv_buf, &[], &live_scratch[..raw_len]);
|
||||||
.map_err(|e| format!("Failed to build stream: {e}"))?;
|
|
||||||
|
current_pos += buffer_samples as u64;
|
||||||
|
audio_ref.store(Arc::new(AudioRef {
|
||||||
|
sample_pos: current_pos,
|
||||||
|
timestamp: Instant::now(),
|
||||||
|
sample_rate: sr as f64,
|
||||||
|
}));
|
||||||
|
|
||||||
|
scope_buffer.write(&conv_buf);
|
||||||
|
|
||||||
|
for chunk in conv_buf.chunks(channels) {
|
||||||
|
let mono = chunk.iter().sum::<f32>() / channels as f32;
|
||||||
|
let _ = fft_producer.try_push(mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (out, &src) in data.iter_mut().zip(conv_buf.iter()) {
|
||||||
|
*out = <$T as FromSample<f32>>::from_sample_(src);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
move |err: cpal::StreamError| {
|
||||||
|
let _ = error_tx.try_send(format!("stream error: {err}"));
|
||||||
|
match err {
|
||||||
|
cpal::StreamError::DeviceNotAvailable
|
||||||
|
| cpal::StreamError::StreamInvalidated => {
|
||||||
|
device_lost.store(true, Ordering::Release);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
let stream = match output_format {
|
||||||
|
cpal::SampleFormat::F32 => build_output!(f32),
|
||||||
|
cpal::SampleFormat::I32 => build_output!(i32),
|
||||||
|
cpal::SampleFormat::I16 => build_output!(i16),
|
||||||
|
format => return Err(format!("unsupported output sample format: {format:?}")),
|
||||||
|
}
|
||||||
|
.map_err(|e| format!("Failed to build stream: {e}"))?;
|
||||||
|
|
||||||
stream
|
stream
|
||||||
.play()
|
.play()
|
||||||
|
|||||||
Reference in New Issue
Block a user