# PianoRT Debian packages — initial build

Version 0.1.0~alpha3 targets Debian 13 amd64. These are installation candidates,
not a validated appliance image. This source tree is deliberately assembled
from an explicit file list; it contains no personal machine backup or test run.

## Packages

- `pianort-config`: PipeWire64/48kHz/RT94 and JACK settings, player permissions,
  user service, single-instance check and compiled memory-lock helper.
- `pianort-g3-audio`: G3/Noibat RT5682 headphone hardware timing and period/headroom
  rules, the generated no-HDMI topology and its module options.
- `pianort-g3-tuning` (optional): the CPU profile, IRQ placement, Pianoteq thread
  placement and audio DSP power settings from the reference G3, as systemd
  services that are installed but not enabled. Settings are in
  `/etc/pianort/tuning.conf`.

No Pianoteq executable, activation, preset, MIDI, recording, SSH/VPN/Wi-Fi data,
serial number, machine ID, recovery snapshot, benchmark or stress harness is
included. No kernel or firmware ROM is included. The generated ALSA topology is
included with its upstream notices; the DSP firmware comes separately from Debian.

These packages do not start/stop services, alter CPU/power settings (until you
enable the pianort-g3-tuning services yourself), set volume,
flash firmware or change boot arguments. They stage configuration that becomes
effective at the next relevant restart. Install during setup with playback
stopped. Do not install them remotely onto a live instrument merely to inspect
them. Existing administrator fragments can override these settings; merge them
deliberately. An old `/etc/systemd/user/pianoteq.service` overrides the packaged
unit and needs explicit migration with a private backup.

## Build on Debian13 amd64

Install `python3 gcc libc6-dev dpkg-dev xz-utils` and `firmware-sof-signed`.
The first qualified topology input is from version2025.01-1, SHA256
`a4c5ae2c4c15926f2871fc5d6858385a9c5e8df0a2f526e4466818f7944143fb`.
Different input hashes are rejected even if the package name is identical.

```sh
python3 build.py --topology /usr/lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg --output ./dist
```

The build generates both debs, validates their extracted content against the
staged payload, records hashes, and retains this source. It does not install
them. No prior user state is read by the builder. The modified topology output
must hash to `a12f980db0c3d3dddcb2512942518def975b357d6c0be7e86dbc303cead5e363`.
Its original input remains the separately installed upstream file.

## Set up a new player

1. Preserve an administrative login, console access and the existing working
   kernel. Install the selected custom kernel through a separate validated boot
   path. A deb on disk does not update a coreboot-embedded Linux payload.
2. Install the Debian graphics/audio stack appropriate to your hardware.
   A kiosk normally needs `weston xwayland`, suitable fonts, and Pianoteq's
   X11/GL/ALSA/Fontconfig/FreeType libraries. This initial pair does not assemble
   or enable a Weston kiosk, configure networking, or supply a kernel.
3. Install the candidates and separately obtain and activate your own Pianoteq.
   Set `/etc/pianort/player.conf` to the executable's actual path, or create the
   documented stable symlink. Retain all user-owned preferences and licenses.
4. Create the `pianort` group with `groupadd -f pianort`; add the selected player
   with `usermod -aG pianort,audio PLAYER`. In a planned new session verify RT
   and memory-lock permissions. If needed configure the selected user's systemd
   manager hard limits explicitly: LimitRTPRIO95 and LimitMEMLOCK=infinity in
   `/etc/systemd/system/user@UID.service.d/90-pianort.conf`. Do not copy another
   user's UID. Restarting that manager interrupts its session; plan this setup.
5. In the player's graphical session, import the display environment into the
   user manager and verify PipeWire/WirePlumber. Once manual startup works,
   enable `pianoteq.service` for a session that activates
   `graphical-session.target`. A minimal Weston kiosk needs its own qualified
   seat/session startup; linger alone is insufficient. No launch changes volume.
6. Select the intended preset/sample rate and keep CPU overload protection
   enabled. This package does not set polyphony or modify a preset file.
7. On the G3 verify the custom topology was loaded, `snd_sof` reads its custom
   filename, `snd_sof_intel_hda` reads codec_mask0, and the headphone sink reads
   `api.alsa.disable-tsched=true`, period64/headroom256. Reference readbacks are
   ALSA48kHz/period64/buffer1024/avail_min704; another device may allocate differently.
8. Validate listening, physical MIDI/pedal operation, offline/cold startup,
   workload capacity and package removal/recovery on a clean machine.

## Optional tuning (pianort-g3-tuning)

Check what would be applied, without changing anything:

```sh
sudo /usr/libexec/pianort/g3-tuning plan
```

Then enable the parts you want and reboot:

```sh
sudo systemctl disable --now irqbalance.service power-profiles-daemon.service
sudo systemctl enable pianort-g3-cpu-profile.service pianort-g3-irq.service \
  pianort-g3-placement.service pianort-g3-audio-power.service
```

- `pianort-g3-cpu-profile`: SMT off on 4-core models, CPUs locked to
  `PIANORT_CPU_KHZ` (default 3 GHz, capped at the CPU's maximum), and the
  sustained package power limit set to `PIANORT_PACKAGE_POWER_W` (default
  20 W, tested on the reference i7-10610U; more heat and fan noise). Leave a
  value empty to keep the firmware's setting. It conflicts with
  power-profiles-daemon and tuned.
- `pianort-g3-irq`: Wi-Fi and USB interrupts on the housekeeping CPU, audio DSP
  interrupts on the audio CPUs, audio DSP IRQ thread at FIFO 99, Wi-Fi IRQ
  threads at SCHED_IDLE, NVMe IRQ threads at FIFO 55. It conflicts with
  irqbalance, which would undo the placement.
- `pianort-g3-placement`: keeps Pianoteq's `data-loop.0` on the housekeeping
  CPU and its `fasthp-N` workers on separate audio CPUs, and pins the desktop
  processes listed in `PIANORT_PIN_PROCESSES` to the housekeeping CPU. It's
  tested on 4-core models only and does nothing on others.
- `pianort-g3-audio-power`: stops the SOF audio DSP from runtime-suspending, to
  avoid a wake-up delay on the first note after idle.

The housekeeping and audio CPUs come from the `isolcpus=` list on the kernel
command line, which the PianoRT firmware flasher sets. Without
it, the last CPU does housekeeping and the rest do audio, as on the reference
unit. To undo, disable the services and reboot.

## Services and maintenance

`/usr/share/pianort/service-policy.json` lists conditional choices. Under
PipeWire, prevent the standalone PulseAudio daemon and socket from competing;
`pipewire-pulse` is a different, optional compatibility server. Omit printing,
scanning, Bluetooth or discovery only when the product does not offer them.
Account for socket/D-Bus activation, not just enabled service symlinks.

Select one network/power manager, preserve security and thermal protections,
and arrange updates/trim/heavy maintenance outside playing. Audio must not wait
for Internet access or NTP synchronization. Do not bulk-disable all timers or
copy every mask from an experimental installation.

## Removal and remaining work

Back up the previous unit/configuration states before activation. Remove only
PianoRT's package files and restore the captured prior states. Removing a
fragment does not reverse a running graph until a planned session restart.
Debian retains edited conffiles on ordinary removal; purge is a separate choice.

Next layers are explicit activation/rollback tooling, an optional tested CPU
profile, kiosk assembly, kernel source/rebuild provenance and clean-install
qualification. None of those are implied complete by these two debs. Publishing
an APT repository or website release is a separate step.

Original helpers/configuration/docs use the included MIT license. The SOF
topology retains the upstream terms in `licenses/SOF-Debian-copyright`; it is
not relicensed MIT. See `debian-copyright` for package attribution.
