Skip to main content

Python implementation of the defMON C64 tracker's file format and register-level player.

Project description

pydefmon

test PyPI

Read, write and play defMON C64 tracker tunes from Python. The player emits the same per-frame SID register writes as the real defMON binary — verified byte-for-byte by a live-VICE integration test that compares pydefmon's per-frame output against the actual defMON binary running in anarkiwi/headlessvice.

Install

pip install pydefmon          # core
pip install pydefmon[wav]     # adds pyresidfp + numpy for WAV render

Quick start

from pydefmon import DefmonSong, DefmonPlayer, PatternEvent

# Read / edit / write tunes
song = DefmonSong.from_file("tune.prg")
print(song.pattern_events(0)[:4])
print(song.sidtab_row(0))
song.set_step(0, v1=1, v2=2, v3=3)        # arranger row 0 plays patterns 1/2/3
song.to_file("out.prg")

# Render per-frame SID writes
player = DefmonPlayer(song)
for _ in range(600):
    writes = player.play_frame()           # list of (reg, value) for one main-tick NMI
    for reg, value in writes:
        # reg is an absolute SID register address $D400..$D418
        ...

Render to WAV (requires the [wav] extra):

pydefmon-player path/to/tune.prg /tmp/tune.wav

Dump per-frame SID writes as JSONL without rendering audio:

pydefmon-player --dump-writes /tmp/tune.jsonl path/to/tune.prg

What's in the package

  • DefmonSong — the 22887-byte runtime RAM image at $1800..$7166, parsed from a .prg file. Region accessors for arrangers, sidTAB rows + DL bytes, pattern bodies; structured edit API (set_step, set_jump, set_dl, set_jp, set_pattern_events). Round-trips through the $D6C9 LOAD codec.
  • PatternEvent — one 4-byte pattern step (flag, slot_a, slot_b, note) with flag-bit constants and factories (note_on, delay, alt_end).
  • SidtabRow — one 15-byte sidTAB row decoded to named column attributes (WGh / WGl / AD / SR / TR / AF / PW low half; PS / RE / FV / CP / ACID high half) plus its companion jp and dl bytes.
  • SidcallFrame — one frame of a cascade walk via DefmonSong.sidcall_frames(start_row).
  • DefmonPlayer — frame-accurate per-NMI player IRQ model. play_frame() returns the 24 SID register writes that defMON's $1022 body would emit for one main player tick. import_runtime_state() lets you bridge from a live VICE / hardware RAM capture for byte-faithful continuation of a running tune.

See docs/SPEC.md for the canonical reference of the file format, the runtime RAM layout, and what every cell of every region means.

Tests

pip install -e .[dev]
python -m tools.fetch_fixtures        # one-time: populate build/fixtures/
python -m unittest discover -s tests -t .

The unit tests under tests/ pin every subsystem of the player and codec against synthetic .prg fixtures and against the .GLOW WORM fixture (Tomek Grynfelder, in the upstream defMON release). tools/fetch_fixtures.py downloads the upstream csdb.dk archive, extracts the .d64, and writes per-PRG files under build/fixtures/ (override with the PYDEFMON_FIXTURES_DIR env var). Tunes are not redistributed; tests that need a fixture skipTest when it is missing.

The live-VICE integration test under tests/integration/ boots the real defMON binary inside anarkiwi/headlessvice, captures its SID write stream, and asserts pydefmon's DefmonPlayer matches byte-for-byte. Run with:

pip install -e .[dev,integration]
PYDEFMON_INTEGRATION=1 python -m unittest tests.integration.test_player_vs_real

CI runs all three (test, lint, build, integration) on push and PR. Python 3.10 through 3.13.

License

GPL-3.0-or-later. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydefmon-0.4.0.tar.gz (78.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydefmon-0.4.0-py3-none-any.whl (53.4 kB view details)

Uploaded Python 3

File details

Details for the file pydefmon-0.4.0.tar.gz.

File metadata

  • Download URL: pydefmon-0.4.0.tar.gz
  • Upload date:
  • Size: 78.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pydefmon-0.4.0.tar.gz
Algorithm Hash digest
SHA256 64e6922221f294c87abb771d405d5629b933ad1a57f5e24513d67ae24a080d5b
MD5 625846856b77497009059170312fa00a
BLAKE2b-256 30b73016a4344264f87b63feeae12b8e96e0083c44e43207defb8f4a385f5811

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydefmon-0.4.0.tar.gz:

Publisher: release.yml on anarkiwi/pydefmon

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydefmon-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: pydefmon-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 53.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pydefmon-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f50c0a220ed09d17c90f094751ca9bc1780c6afc499f4f8e6dfd6ed84bd2ab38
MD5 ccca8e5b842397d1429a53d2ebd70cfb
BLAKE2b-256 c01b6a49c95052dbd62a73257918e82be2f27c94dd8249f54a687c3cb320d8fc

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydefmon-0.4.0-py3-none-any.whl:

Publisher: release.yml on anarkiwi/pydefmon

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page