FM1 Betis Mode
Unofficial Betis-themed firmware for M-VAVE FM1, built from the official FM1 Open V13 source + binary SDK. The hardware package and browser emulator use the same application sources.
- Online emulator and firmware workbench
- Download flashable firmware
- Matching source + SDK archive
- Firmware validation report
- Run browser acceptance tests
Build-verified does not mean hardware-tested. The package is generated by the official packager with its boot/update resources, flash layout, build identity and recovery image. No physical FM1 has been flashed or tested. Back up projects and samples before installing. This is a community modification, not an M-VAVE-endorsed release.
Betis controls
The 240x240 RGB565 TFT starts at the Manque Pierda dashboard, with a green theme, the supplied shield/Palmerin artwork, a tempo animation and MIDI-activity jump/flash. Press HOME+FX to return to it from another page.
| Control | Dashboard action |
|---|---|
| SELECT | Select one of the eight tracks |
| Parameter knob 1: PASION | DX7 FM feedback (0-7), not available on non-FM tracks |
| Parameter knob 2: OLE REV | Selected track's reverb send |
| Parameter knob 3: DUENDE | Selected track's delay send |
| Parameter knob 4: BPM | Internal tempo, clamped to 60-180 |
| SCL | Toggle E Phrygian-dominant tuning / equal temperament |
| ARP | Toggle the selected track's official arpeggiator; hold for settings |
| PLAY | Play/stop the sequencer, including the crowd percussion on track 8 |
| SAVE | Open the official project save UI; no automatic persistent writes |
| HOME | Original eight-track overview |
The scale is E F G# A B C D, implemented with the official per-track whole-cent tuning API. Original MIDI note identities remain independent, so neighboring keys that quantize to the same pitch do not share note-off state. Alt tuning is left unchanged. The default project enables track 1's arpeggiator and includes an original synthesized 16-step 808 kick/clap/hat crowd rhythm. Loading a saved project restores its own tuning, sounds, patterns and arp.
Mas grada: guasa, goles y memoria betica
From the Betis studio, FX cycles through six shared hardware/browser views: studio, La Grada, Once 25/26, Memoria Betica, Himno / Aprender, and Penaltis. HOME+FX returns to the studio; HOME still opens the original overview.
- La Grada: K1 selects one of four original synthesized percussion patterns: Palmas del Heliopolis, Bombo de las 13 barras, Gol del Panda, Manque pierda. EDIT explicitly replaces the first 16 steps of track 8, which must still be an 808 instrument. Merely browsing never changes the project or source. Hidden steps beyond 16 are retained. PLAY starts/stops the normal sequencer; SAVE persists the pattern using the official project flow.
- Matchday: K2/K3 adjust Betis/opponent scores from 0 to 99; increasing the Betis score triggers a four-second goal message. Corrections are allowed. This is a manual toy scoreboard, not a live score service; it resets at boot. K4 retains the 60-180 BPM control. Thirteen green/white bars crown the display.
- Once 25/26: K1 browses a representative 2025/26 project selection, not an official fixed starting XI. List numbers are not shirt numbers. Valles; Bellerin, Natan, Bartra, Ricardo Rodriguez; Amrabat, Fornals; Isco, Antony, Abde; Cucho Hernandez. Player descriptions are original fan-written flavor, not quotations or claims of official nicknames.
- Memory: 1907 roots, the 1935 Liga, Cups in 1977/2005/2022, thirteen bars, Palmerin, and Manque pierda.
The web-only hymn corner has separate traditional / centenary local-audio players. Supply your own authorized files (up to 32 MiB each). Files are not uploaded, stored, bundled, synchronized to transport, or copied into firmware. No hymn lyrics or recordings are distributed; the two integrated teaching melodies are redistributed with the user's confirmed authorization. The four crowd patterns are original percussion, not versions of those hymns. For device samples use the existing sample editor and its supported limits.
The MIDI arranger/player also accepts user-supplied type-0/1 PPQN MIDI files (up to 2 MiB, two hours, 256 tracks). It flattens the tempo map to millisecond timing, merges melodic channels to channel 1 (eight FM voices) and retains percussion on channel 10. Sustain becomes note duration; overlapping pitches keep independent ownership. Voice stealing is reported. Original GM instruments, pitch bends, and other automation are deliberately not retained: this is a new monotimbral FM arrangement, not an exact orchestral render. The exported type-0 MIDI can be played into the hardware using an external MIDI sequencer with track 1 FM/12-TET/ARP off and track 8 808.
Web playback uses the real AudioWorklet synth. It stops transport, temporarily
disables track 1's scale/ARP, and restores both at stop/end. Stop it before
editing or saving a project. Hiding the tab stops playback to prevent
background timer drift and stuck notes. Supplied originals and full eight-voice
MIDI exports remain local under ignored himnos/; those files are not redistributed.
Only the two authorized melody-only teaching tables described below are bundled
in Git, corresponding source, firmware and the deployed emulator.
References checked for this implementation: Betisweb's 2025/26 squad listing for season membership (the XI itself is our selection), and the club's account of the 1935 championship. The season is explicitly 2025/26, as requested, regardless of the current date.
Integrated songs and Aprender
Both authorized monophonic teaching arrangements are included in the published firmware and Wasm; no external sequencer or MIDI upload is needed:
| K2 | Song | Steps | Playable MIDI range | Length |
|---|---|---|---|---|
| 1 | Centenario | 193 | 59-73 | 55.749 s |
| 2 | No puedo vivir sin ti | 355 | 54-78 | 180.691 s |
The centenary lead is isolated from track 1's upper register (source pitches 84 and above), excluding eight accompaniment-only onsets that were previously mistaken for melody. For the merged charanga FM1 MIDI, the original multitrack score's first track identifies the lead; every selected onset/pitch is checked against the supplied FM1 arrangement within 1 ms. Its accompaniment-only intro is omitted. At simultaneous lead onsets, the highest pitch is selected.
Each complete melody receives one constant transposition, centered on the 27-key keyboard: -29 semitones for Centenario, -22 for the charanga. This changes the key but preserves every melodic interval and its direction; individual notes are never octave-folded. Note lengths, rests and tempo changes are retained. These are melody-only teaching reductions, not the earlier eight-voice arrangements.
On Himno / Aprender, PLAY listens, EDIT starts the step-by-step lesson, SCL stops, and HOME exits. The next note's physical key LED lights; a correct new key press advances once, errors do not advance, and holding a key does not auto-repeat. No rhythmic scoring is claimed. K1 seeks, REC repeats an eight-note phrase. K2 selects the song, stopping playback and resetting lesson progress/errors. Track 1 must be FM; it uses a fixed octave, temporarily disables its scale/ARP and restores those settings at stop/exit. Follow input is the FM1 panel or on-screen keyboard; external MIDI input is not evaluated. Do not load/save projects or change patches during a lesson.
python .\tools\Compile-Hymn.py .\himnos\himno-centenario-del-betis.mid --track 1 --min-note 84 --charanga .\himnos\no-puedo-vivir-sin-ti-charanga-fm1.mid --charanga-melody .\himnos\no-puedo-vivir-sin-ti-charanga.mid --output .\vendor\fm1_open\app\betis_song_data.h
python -m unittest discover -s tests -p "test_*.py" -v
powershell -NoProfile -ExecutionPolicy Bypass -File .\Build.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\Verify.ps1
The generated compact melody header is tracked and included in the matching
source ZIP, so public builds do not need the original MIDI files. The user
confirmed authorization for distribution of both arrangements on 2026-10-18;
see THIRD_PARTY.md. Original MIDI files remain ignored.
Build.ps1 -LocalHymn / Verify.ps1 -LocalHymn remain optional output-directory
aliases for local/docs/, with the same authorized content as the public build.
Penaltis
K1 selects Tirador (shooter) or Portero (goalkeeper); changing role starts a fresh game. K2 chooses left, center or right, always relative to the screen. PLAY resolves one attempt against the computer's hidden direction: matching directions mean a save, otherwise a goal. A five-attempt game counts goals in shooter mode and saves in goalkeeper mode. EDIT starts another game; HOME exits. The goal, keeper, ball and result are drawn on the real shared TFT framebuffer. This is a direction-guessing minigame, not a football physics simulation. It never edits projects or writes flash, and piano keys are muted in this view.
Original pixel artwork
The shield, mascot and eleven stylized fan portraits are original 32x40,
16-color illustrations rendered at 2x on the TFT. They use lossless run-length
compression with a shared row dictionary to preserve the official
flash/VM/user-storage reservation without changing a single sprite pixel.
Isco, Antony, Cucho and the other selected players have separate portraits.
They are interpretive cartoons, not official photos or photorealistic likenesses.
Regenerate with python .\tools\Generate-Betis-Art.py; inspect the contact sheet
in web/betis-sprites.svg.
Preserved official features
The six-operator FM, 303, 808, PSG, pluck and sampler engines, eight tracks, USB/BLE/TRS MIDI, Bluetooth and USB audio, project/sample storage, and recovery workbench are retained. The browser uses the upstream portable synth kernels and an AudioWorklet, not the earlier two-operator demo. Radio discovery, board timing, actual Flash writes, analog output and battery behavior still need device validation.
Native sound-control adaptation: the early project draft requested standalone drive/chorus DSP. This release deliberately uses the official FM feedback and reverb/delay sends rather than replacing the native audio engine with an unverified demo. These dashboard controls do not pretend to be a new saturation or chorus implementation.
Reproduce the build (Windows x64)
Requires PowerShell 5.1+, Git, curl.exe, and tar.exe; no system-wide compiler
installation or administrator rights are needed:
git clone https://github.com/cotrino/fm1-betis-mode.git
Set-Location fm1-betis-mode
powershell -NoProfile -ExecutionPolicy Bypass -File .\Build.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\Verify.ps1
The bootstrap downloads and checksum-verifies JieLi 2.5.2 and WASI SDK
27 into .tools/. JieLi 2.5.3 does not match this SDK's compiler hashes.
Existing compatible installations can be reused with FM1_PI32_TOOLCHAIN and
FM1_WASI_SDK. The vendor SDK itself is not modified; its integrity checks,
linker/ABI/SRAM checks and source packager all run normally.
Outputs in docs/:
FM1_BETIS_MODE.fwsc: flashable package.index.html: self-contained emulator, updater and stock V15 recovery UI.simulator.wasm: independently testable browser module.source.zip: exact corresponding sources, SDK and build/install scripts.- reports, notices and
SHA256SUMS.txt.
The upstream commit and changed vendor files are recorded in upstream.json.
The generated workbench adds branding/navigation to the upstream HTML;
the packaged firmware and Wasm payloads remain unchanged and are checked
against the downloadable files.
Browser verification
Serve the repository locally:
python -m http.server 8080 --bind 127.0.0.1
Open http://localhost:8080/docs/ for the workbench or
http://localhost:8080/tests/verify-emulator.html for executable acceptance
tests. Tests boot the real Wasm application and check tuning, TFT pixels, BPM
bounds, ARP, finite bounded FM audio, independent note release, silence after
release, project/tuning round-trips, and sequenced percussion.
Click the workbench's audio control before playing. Web MIDI requires a compatible browser on HTTPS or localhost and explicit permission. Device firmware updates are a separate explicit action in the workbench: none are performed during builds or emulator tests. Keep the device powered throughout an update; use the included original V15 recovery option if needed, following the official recovery instructions.
GitHub Pages serves the committed docs/ directory from main. The Windows
CI workflow rebuilds and verifies packages and uploads them as an artifact;
publishing a changed build requires committing its refreshed docs/.
License and earlier prototype
Application changes are GPL-3.0-only with the FM1 SDK linking exception. The proprietary SDK is redistributable for FM1 devices under its separate terms. Retain LICENSE.md and THIRD_PARTY.md. Artwork was supplied in the project reference; this project claims no club endorsement or ownership of Real Betis trademarks.
The original independent two-operator/monochrome prototype remains in src/
and web/, with its native smoke test and Emscripten make wasm target.
It is not linked into the flashable firmware or deployed workbench.
