- Dart 59.4%
- C++ 34.8%
- BitBake 1.9%
- CMake 1.3%
- Shell 1.3%
- Other 1.3%
- Cables carry left and right. Stereo blocks process both sides; mono effects get a twin that follows their parameters for the right side, amps and NAM captures mix a stereo input to mono. - A stereo source on OUT 1 and OUT 2 splits left/right; a single output gets the mono sum. - Stereo: delay (new ping-pong type, width), reverb (width), chorus, flanger, phaser, vibe (width), tremolo (auto-pan mode), rotary (two mics), pitch (spread). The cab can put mic A left and mic B right. - USB interfaces behind the BCM2712's dwc2 controller keep at least 4 ms of playback buffer. - Selftests cover the routing, twins, cab stereo and every stereo effect (width, mono compatibility, ping-pong timing, auto-pan). - UI: cab stereo switch, output hint, labels for the new parameters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .devcontainer | ||
| amp-dsp | ||
| amp-ui | ||
| bitbake@51fd94a67f | ||
| build-cm4/conf | ||
| build-cm5/conf | ||
| build-pi4/conf | ||
| meta-amp | ||
| meta-flutter@7ccc272f7f | ||
| meta-openembedded@47d7dbdd10 | ||
| meta-raspberrypi@919588393f | ||
| meta-rauc@38da0e5866 | ||
| meta-yocto@7c25b11156 | ||
| openembedded-core@0f03c732a0 | ||
| tools | ||
| .gitignore | ||
| .gitmodules | ||
| Dockerfile.build-arm64 | ||
| oe-init-build-env | ||
| README.md | ||
ampOS
Yocto (6.0 "Wrynose") image for a NAM-based guitar amp on a Raspberry Pi CM4 or CM5 carrier board: PREEMPT_RT kernel, I2S ADC/DAC, NVMe, and a Flutter UI rendered by flutter-pi on DRM/KMS.
| Target | MACHINE | Build dir |
|---|---|---|
| CM4 | raspberrypi4-64 |
build-cm4 |
| CM5 | raspberrypi5 |
build-cm5 |
| Pi 4 B + USB interface (test rig) | raspberrypi4-64 |
build-pi4 |
Layout
meta-amp/– distroamp,amp-image, kernel fragments (preempt-rt.cfg,audio.cfg), flutter-pi/engine/SDK appends,amp-uirecipeamp-dsp/– the audio engine (C++). A 4 × 12 grid of blocks – inputs, amps (NAM capture + gate + tone stack), cabs (IR), NAM pedal captures, built-in effects (boost, overdrive, compressor, chorus, delay, reverb), outputs – joined by cables running left to right; several cables into a block are mixed. A2 captures run on TONE3000's A2-Full/A2-Lite engines (tone-3000/embedded, converted once withnam2namb), everything else on NeuralAmpModelerCore. ALSA full duplex on an isolated core, a YIN tuner, assignable footswitches (tap/hold), encoders and expression pedal. Controlled over/run/amp/control.sock(one JSON object per line).amp-ui/– the Flutter app: amp heads styled after the amp family, pedals, cab, swipe through a row's blocks, up/down between rows, pinch out for the grid editor, pull down for settings, tuner, TONE3000 browser.flutter run -d macosruns it against a demo engine on the Mac;flutter test test/shots --update-goldensrenders the views to PNGs.meta-rauc/– RAUC for the A/B updates (amp-bundle, see below)
Build (Apple Silicon)
git submodule update --init
tools/yocto-arm64.sh bitbake amp-image # CM4
BUILD=build-cm5 tools/yocto-arm64.sh bitbake amp-image # CM5
The image lands in the ampos-cm4-tmp volume under deploy/images/
(~/OrbStack/docker/volumes/). Flash the .wic.bz2 with bmaptool or
rpiboot + Raspberry Pi Imager for eMMC modules.
The CM4/CM5 images boot from the carrier's NVMe SSD (AMP_ROOT_DISK = "nvme0n1" in amp.conf; build-pi4 uses the SD card). Write the image to
the SSD in a USB adapter, or through the module with rpiboot and
usbboot's mass-storage-gadget64. A CM4 with eMMC tries the eMMC first:
flash tools/cm4-bootloader/boot.conf (NVMe first) once with usbboot's
recovery. A CM4 Lite without an SD card finds the SSD on its own.
FLUTTER_SDK_TAG in meta-amp/conf/distro/amp.conf must match the Flutter
SDK used for amp-ui.
Partitions and updates
The disk (amp-ab.wks.in) has two system slots and a data partition:
| # | Label | |
|---|---|---|
| 1 | autoboot | autoboot.txt: which boot partition the bootloader starts |
| 2, 3 | bootA, bootB | firmware, kernel, config.txt, cmdline.txt |
| 4, 5 | rootA, rootB | root filesystems, 2 GiB each |
| 6 | data | /data, grows to the end of the disk at first boot |
/data keeps what an update must not touch: /data/amp (bind-mounted on
/var/lib/amp: models, IRs, pedals, presets, settings, TONE3000 login),
WLAN connections (/data/nm), the SSH host keys (/data/ssh) and RAUC's
status (/data/rauc).
Updates are RAUC bundles that are written to the slot that isn't running.
The Raspberry Pi bootloader then starts that slot once (reboot "0 tryboot"). The new slot is kept only once amp-dsp and amp-ui have
been running steadily for about 10 s (amp-boot-check, then
rauc-mark-good). Otherwise it is rolled back, and so is a hang (watchdog),
a kernel panic or a missing root filesystem: the next boot is the old
system again. rauc status shows both slots.
The board's bootloader EEPROM has to be recent enough to know autoboot.txt
with tryboot_a_b. If the image boots but an update never switches over,
update the EEPROM with usbboot's recovery.
Build the image and the bundle:
tools/yocto-arm64.sh bitbake amp-image amp-bundle
Update a running amp. The script copies the bundle to /data, then runs
amp-update, which installs it and restarts:
tools/device-update.sh # newest build-cm4 bundle, root@ampos.local
tools/device-update.sh x.raucb root@192.168.178.52
Bundles are signed with the development key in
certs/rauc/openssl-ca/dev/ (not in git). Create it with
meta-rauc/scripts/openssl-ca.sh; the image only accepts bundles signed by
that CA. A new CA needs a fresh flash. Bundles only fit images built for
the same machine and system disk (AMP_RAUC_COMPATIBLE).
Before flashing a device that has data on it, back the data up and put it back afterwards:
tools/device-backup.sh # → ~/ampos-backup/amp-data-<date>.tgz
# flash, connect WLAN on the amp
tools/device-restore.sh # newest backup
TONE3000
Create a publishable key at tone3000.com/settings and set it in
build-*/conf/local.conf:
AMP_TONE3000_CLIENT_ID = "t3k_pub_..."
The amp signs in with the device flow: it shows a code and a QR code, the player confirms it at tone3000.com/activate on a phone.
Engine self test
amp-dsp --selftest /var/lib/amp/models/x.nam [ir.wav] [--size 0|1]
runs 2 s of a test tone through the chain without a sound card and prints the load per block.
Real-time audio
CPUs 2 and 3 are isolated (ISOLATED_CPUS, nohz_full, rcu_nocbs) for
the DSP: the audio thread runs on core 3 with SCHED_FIFO, a worker on
core 2 (--worker-cpu) takes the second chain when the grid has two that
only meet at the outputs (split, mix, dual). Check latency with
cyclictest -m -p 90 -a 2,3 -i 200.
TigerCM4 Display Carrier
build-cm4 loads tigercm4-carrier.dtbo
(meta-amp/recipes-kernel/linux/files/tigercm4-carrier-overlay.dts) and the
out-of-tree ES9290 driver (meta-amp/recipes-kernel/es9290).
The BCM2711 PCM block carries 2 channels per direction. Both ES9290 run TDM4 x 32 bit at 48 kHz (BCK 6.144 MHz, their APLL locks to it); the CM4 takes slots 0 and 2:
| ALSA | Capture | Playback |
|---|---|---|
| ch 0 | guitar (codec 1 ch1) | L → phones and XLR L |
| ch 1 | XLR in 1 (codec 2 ch1) | R → phones and XLR R |
Not yet covered: the DSI panel (ST7703 needs the vendor's init sequence) and the CM5, which needs its own overlay.