summarylogtreecommitdiffstats
path: root/PKGBUILD
blob: b04fff0eab15cfc9993bc7a43000305e94b5c591 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# Maintainer: loteran <https://github.com/loteran>
pkgname=arctis-sound-manager
pkgver=1.4.26
pkgrel=1
pkgdesc="Linux GUI for SteelSeries Arctis headsets — all GG/Sonar features: mixer, EQ, ANC, mic processing, surround"
arch=('any')
url="https://github.com/loteran/Arctis-Sound-Manager"
license=('GPL-3.0-or-later')
depends=(
    'python>=3.10'
    'pyside6'
    'qt6-svg'
    'python-babel'
    'python-pillow'
    'python-pyudev'
    'python-pyusb'
    'python-ruamel-yaml'
    'pipewire'
    'pipewire-pulse'
    'wireplumber'
    'libusb'
    'libpulse'
    # D-Bus service backend (dbus_service.py) — in official Arch repos (extra/).
    'python-dbus-next'
    # PulseAudio/PipeWire control bindings — not in official Arch repos, but
    # available in the AUR (same situation as noise-suppression-for-voice
    # below: pacman prompts paru/yay to build it as part of the transaction).
    'python-pulsectl'
    # Used by asm-setup to download HRIR (~/.local/share/pipewire/
    # hrir_hesuvi/EAC_Default.wav) on first run — Spatial Audio is
    # silent without it. asm-setup falls back to wget but a default
    # Arch base install ships curl, not wget.
    'curl'
    # LADSPA Steve Harris pack — provides plate_1423 used by the HeSuVi
    # 7.1 surround filter-chain (issue #23). In the official 'extra' repo,
    # so pacman satisfies it directly.
    'swh-plugins'
)
optdepends=(
    # rnnoise LADSPA plugin for the ClearCast / mic noise-suppression toggle.
    # AUR-only, so it CANNOT be a hard depend: pacman can't satisfy it from the
    # official repos, and `pacman -S arctis-sound-manager` from the signed repo
    # would abort on an unresolvable dependency (#175, and the #96 rule that this
    # must never be a Depends). It stays optional — the mic noise-cancel toggle
    # degrades gracefully when it's missing (and DeepFilterNet is an alternative
    # engine). The signed pacman repo ships a build of it under that exact name,
    # so from there it is one `pacman -S noise-suppression-for-voice` away.
    #
    # Both names are listed on purpose (issue #229): on the AUR the only package
    # that exists is the -git one, so naming just the plain package pointed users
    # of this very PKGBUILD at something they could not install. Listing both is
    # harmless, since pacman only ever suggests an optdepend and never resolves
    # it — and either one provides the same LADSPA plugin.
    'noise-suppression-for-voice: RNNoise mic noise cancellation (ClearCast), from the signed pacman repo'
    'noise-suppression-for-voice-git: RNNoise mic noise cancellation (ClearCast), from the AUR'
    # ── Clips (opt-in) ───────────────────────────────────────────────────
    # Deliberately not in depends(), unlike swh-plugins above. Clips ships
    # off, and the toggle that turns it on (Settings → Clips) installs these
    # through pkexec with the same package names — so an install that only
    # wants the mixer and the EQ never pulls a screen recorder's encoders,
    # and one that wants Clips is one dialog away from having them.
    'python-gobject: clip capture (Gst/Gio bindings)'
    'gstreamer: clip capture'
    'gst-plugin-pipewire: clip capture — pipewiresrc, the portal screen stream'
    'gst-plugins-base: clip capture — appsrc, audioconvert/audioresample, opusenc'
    'gst-plugins-good: clip capture — pulsesrc, matroskamux'
    'gst-plugins-ugly: clip capture — x264enc, the software encoder fallback'
    'ffmpeg: clip thumbnails, track levels and export'
    # Hardware H.264 encoders. Purely a performance choice on top of that: the
    # capture probes for these and falls back to x264enc, so their absence
    # costs CPU, not the feature.
    'gst-plugin-va: hardware H.264 encoding on Intel/AMD GPUs'
    'gst-plugins-bad: hardware H.264 encoding on NVIDIA GPUs (nvcodec)'
)
makedepends=('python-installer' 'uv')
install=arctis-sound-manager.install
source=("$pkgname-$pkgver.tar.gz::https://github.com/loteran/Arctis-Sound-Manager/releases/download/v$pkgver/$pkgname-$pkgver.tar.gz")
sha256sums=('8ba97663e5a43be929b08d01f2540d51b2f3382ebb2834dd48ac4b82ab38dd80')

build() {
    cd "Arctis-Sound-Manager-$pkgver"

    # Never let uv download or select a Python interpreter other than the
    # system one — the produced wheel is pure-Python (py3-none-any) so the
    # interpreter used to build it doesn't matter for content, but a
    # mismatched interpreter here can still lead uv to create a venv keyed
    # to a different Python version than what's actually installed.
    export UV_PYTHON_DOWNLOADS=never
    export UV_SYSTEM_PYTHON=1
    uv build --wheel --python /usr/bin/python
}

package() {
    cd "Arctis-Sound-Manager-$pkgver"

    # Install Python package
    python -m installer --destdir="$pkgdir" dist/*.whl

    # udev rules (generated from device YAMLs — never hardcode PIDs here).
    # Run with the system python3 directly (no uv/venv involved): the script
    # only needs the stdlib plus the local arctis_sound_manager.udev_rules
    # module and inserts src/ onto sys.path itself when run from the repo.
    python3 scripts/generate_udev_rules.py \
        | install -Dm644 /dev/stdin "$pkgdir/usr/lib/udev/rules.d/91-steelseries-arctis.rules"

    # Desktop entry
    install -Dm644 src/arctis_sound_manager/desktop/ArctisManager.desktop \
        "$pkgdir/usr/share/applications/ArctisManager.desktop"

    # Icon
    install -Dm644 src/arctis_sound_manager/gui/images/steelseries_logo.svg \
        "$pkgdir/usr/share/icons/hicolor/scalable/apps/arctis-manager.svg"

    # Systemd user services (single source of truth in systemd/, not heredocs)
    install -Dm644 systemd/arctis-manager.service \
        "$pkgdir/usr/lib/systemd/user/arctis-manager.service"
    install -Dm644 systemd/arctis-video-router.service \
        "$pkgdir/usr/lib/systemd/user/arctis-video-router.service"
    install -Dm644 systemd/arctis-stream-guard.service \
        "$pkgdir/usr/lib/systemd/user/arctis-stream-guard.service"
    # The tray unit is named for the desktop entry, not the project — that is
    # what gives the process a portal app id and lets the clip shortcut bind.
    # The old arctis-gui.service is not shipped any more; the .install script
    # disables and removes what earlier versions left enabled.
    install -Dm644 systemd/app-ArctisManager.service \
        "$pkgdir/usr/lib/systemd/user/app-ArctisManager.service"

    # dinit user service templates (Artix Linux / dinit init systems)
    install -Dm644 dinit/arctis-manager \
        "$pkgdir/usr/share/$pkgname/dinit/arctis-manager"
    install -Dm644 dinit/arctis-video-router \
        "$pkgdir/usr/share/$pkgname/dinit/arctis-video-router"
    install -Dm644 dinit/arctis-stream-guard \
        "$pkgdir/usr/share/$pkgname/dinit/arctis-stream-guard"
    install -Dm644 dinit/arctis-gui \
        "$pkgdir/usr/share/$pkgname/dinit/arctis-gui"
    install -Dm644 dinit/pipewire-filter-chain \
        "$pkgdir/usr/share/$pkgname/dinit/pipewire-filter-chain"

    # dinit diagnostic script
    install -Dm755 scripts/asm-diag-dinit.py \
        "$pkgdir/usr/bin/asm-diag-dinit"

    # Post-upgrade helper: restarts the user services so the new code is the
    # code that runs. Not in /usr/bin — it is packaging machinery, not a
    # command users are meant to invoke.
    install -Dm755 scripts/restart-user-services.sh \
        "$pkgdir/usr/lib/$pkgname/restart-user-services.sh"

    # PipeWire configs (shared, copied to user dir on first run by asm-setup)
    install -Dm644 scripts/pipewire/10-arctis-virtual-sinks.conf \
        "$pkgdir/usr/share/$pkgname/pipewire/10-arctis-virtual-sinks.conf"
    install -Dm644 scripts/pipewire/sink-virtual-surround-7.1-hesuvi.conf \
        "$pkgdir/usr/share/$pkgname/pipewire/sink-virtual-surround-7.1-hesuvi.conf"

    # filter-chain.service (for distros that don't ship one; Arch ships it via pipewire-audio)
    install -Dm644 scripts/filter-chain.service \
        "$pkgdir/usr/share/$pkgname/filter-chain.service"

    # Device configs
    install -Dm644 src/arctis_sound_manager/devices/*.yaml \
        -t "$pkgdir/usr/share/$pkgname/devices/"

    # AppStream metainfo (releases injected from CHANGELOG.md — never hardcode).
    # Stdlib-only script, no uv/venv needed.
    python3 scripts/generate_metainfo_releases.py --in-place
    install -Dm644 src/arctis_sound_manager/desktop/com.github.loteran.arctis-sound-manager.metainfo.xml \
        "$pkgdir/usr/share/metainfo/com.github.loteran.arctis-sound-manager.metainfo.xml"

    # AppStream catalog entry. The metainfo above describes the app; only this
    # ties it to a package name, which is what a software centre needs to show
    # it at all. Arch's archlinux-appstream-data covers the official repos only,
    # so a package from anywhere else is invisible in Discover without it.
    python3 scripts/generate_appstream_catalog.py \
        --output "$pkgdir/usr/share/swcatalog/xml/$pkgname.xml.gz"
    chmod 644 "$pkgdir/usr/share/swcatalog/xml/$pkgname.xml.gz"

    # First-run autostart (triggers asm-setup on first graphical login)
    install -Dm644 debian/asm-first-run.desktop \
        "$pkgdir/etc/xdg/autostart/asm-first-run.desktop"
}