Commodore-64-SID-Chiptune-Player als Single-File-HTML5-Version und native SwiftUI-macOS-App.
Ein eigenständiger Commodore-64-SID-Musikplayer in zwei Varianten:
- HTML5 (
vicious-sid-player.html) — Eine einzelne HTML-Datei (~50 KB), die ohne Webserver direkt per Doppelklick aus dem Dateisystem funktioniert. - Native macOS App (
Vicious SID Player.app) — SwiftUI-Desktop-Anwendung mitAVAudioEngineund Echtzeit-Oszilloskop.
Beide Varianten enthalten keine SID-Dateien. Musikstücke werden per Drag & Drop oder Datei-Dialog geladen.
Fertige Builds der macOS-App stehen als notarisierte DMGs auf der Releases-Seite bereit. DMG herunterladen, öffnen und die App in den Programme-Ordner ziehen.
Der HTML5-Player benötigt keinen Download über die Releases hinaus: Die Datei vicious-sid-player.html lässt sich direkt im Browser öffnen.
- Drag & Drop: Einzelne
.sid-Dateien oder ganze Ordner können auf den Player gezogen werden. Die Wiedergabe startet sofort. - Echtzeit-Oszilloskop: Zeigt die Wellenformen der drei SID-Stimmen (Dreieck, Sägezahn, Puls, Rauschen) samt Frequenzen, Gate-Status und ADSR-Hüllkurven.
- Dark / Light Mode: Automatische Erkennung der Systemeinstellung oder manuelles Umschalten.
- Playlist mit Duplikaterkennung: Bereits geladene Titel werden nicht doppelt aufgenommen. Die Playlist kann jederzeit geleert werden.
- Keine externen Assets: Die gesamte Oberfläche (inkl. macOS-Fensterdekorationen und Icons) ist rein prozedural in CSS bzw. SwiftUI Canvas gezeichnet.
Der Emulator für den MOS 6581/8580 SID-Chip und den 6502-CPU-Core basiert auf jsSID 0.9.1 von Hermit (Mihály Horváth, 2016, WTFPL-Lizenz).
Gegenüber dem Original wurden folgende Korrekturen vorgenommen:
- 6502-Opcode-Maske:
IR & 0xF0stattIR & 0xC0für implizierte Opcodes. Die fehlerhafte Maske führte dazu, dass Befehle wieINX,TAY,PHPundPLPnicht ausgeführt wurden — viele Songs blieben stumm oder froren ein. - AudioWorklet-Architektur: Die Engine wurde als eigenständige Klasse implementiert statt als Unterklasse von
AudioWorkletProcessor, was den Konstruktorfehler im Browser beseitigt. - Noise-Waveform und ENV3-Readback: An die korrekte jsSID-Referenz angeglichen.
- Swift-Port: Korrekte 24-Bit-XOR-Verschiebungen für kombinierte Wellenformen und Array-Schutzguards gegen Out-of-Bounds-Zugriffe.
| Schicht | HTML5 | macOS (Swift) |
|---|---|---|
| Parser | sidplayer.js |
SidParser.swift |
| DSP / Emulator | sid-player-worklet.js (AudioWorklet) |
ViciousProcessor.swift (AVAudioSourceNode) |
| UI | Vanilla JS + CSS Custom Properties | SwiftUI + Canvas |
python3 build.py # → vicious-sid-player.html (~50 KB)
python3 build.py --no-min # ohne Minifizierungbash build_app.sh # → "Vicious SID Player.app"Die App sucht beim Start nach einem audio/-Verzeichnis neben der Anwendung und lädt dort gefundene .sid-Dateien automatisch in die Playlist.
Für Release-Builds signiert build_app.sh automatisch mit der Developer-ID
Developer ID Application: Daniel Mueller (9QSWKSR4NQ), sofern sie im
Schlüsselbund verfügbar ist. Lokale unsignierte Builds sind mit
SIGN_APP=0 bash build_app.sh möglich.
bash build_dmg.sh # → build/Vicious SID Player.dmg
bash build_dmg.sh --notarize # DMG signieren, notarisieren und stapelnDas DMG enthält ein Retina-kompatibles Hintergrundbild (1x/2x TIFF via tiffutil).
Für die Notarisierung wird ein Keychain-Profil erwartet, standardmäßig
SavageProtrackerNotary. Es kann einmalig interaktiv angelegt werden:
xcrun notarytool store-credentials SavageProtrackerNotaryswift testbash publish_github.sh --dry-run --release
bash publish_github.sh --releaseDas Veröffentlichungsskript setzt origin auf
https://github.com/DanielMuellerIR/vicious-sidplayer.git, blockt versehentlich
getrackte Audio- und Release-Artefakte und erzeugt bei --release den passenden
GitHub-Release-Eintrag mit DMG-Asset.
Die SID- und CPU-Emulation wurde aus dem JavaScript-Projekt jsSID von Hermit portiert und um die oben genannten Bugfixes erweitert. Die native macOS-App ist eine vollständige Neuimplementierung in Swift.
WTFPL — siehe LICENSE.