| Crates.io | ym2149-sndh-replayer |
| lib.rs | ym2149-sndh-replayer |
| version | 0.9.0 |
| created_at | 2025-12-03 15:01:07.13501+00 |
| updated_at | 2026-01-15 17:20:50.162244+00 |
| description | SNDH file parser and Atari ST machine emulation for YM2149 chiptune playback |
| homepage | https://ym2149-rs.org |
| repository | https://github.com/slippyex/ym2149-rs |
| max_upload_size | |
| id | 1964180 |
| size | 165,472 |
SNDH file parser and Atari ST machine emulation for YM2149 chiptune playback.
This crate provides playback support for SNDH files, a popular format for Atari ST chiptune music. SNDH files contain native Motorola 68000 machine code that must be executed on an emulated Atari ST to produce audio.
m68000 crateym2149 crate for cycle-accurate emulation[dependencies]
ym2149-sndh-replayer = "0.9"
use ym2149_sndh_replayer::{SndhPlayer, load_sndh, PlaybackMetadata, ChiptunePlayer};
// Load SNDH file
let data = std::fs::read("music.sndh")?;
let mut player = load_sndh(&data, 44100)?;
println!("Title: {}", player.metadata().title());
println!("Author: {}", player.metadata().author());
println!("Subsongs: {}", player.subsong_count());
// Initialize first subsong
player.init_subsong(1)?;
player.play();
// Generate audio samples
let mut buffer = vec![0.0f32; 882]; // ~20ms at 44100Hz
player.generate_samples_into(&mut buffer);
For direct audio output, use render_i16:
let mut buffer = vec![0i16; 882];
let loop_count = player.render_i16(&mut buffer);
SNDH is a standard format for Atari ST music that embeds original 68000 replay code:
| Offset | Description |
|---|---|
| +0 | BRA instruction (jump over header) |
| +12 | "SNDH" magic |
| +16 | Tag-based metadata (TITL, COMM, YEAR, ##, etc.) |
| Entry+0 | Init routine (D0 = subsong number) |
| Entry+4 | Exit/cleanup routine |
| Entry+8 | Play routine (called at player rate) |
TITL - Song titleCOMM - Composer/authorYEAR - Year of creation##nn - Number of subsongs!#nn - Default subsongTA/TB/TC/TD - Timer and replay rateTIME - Duration per subsong (in seconds)HDNS - End of header marker┌─────────────────────────────────────────┐
│ SndhPlayer │
├─────────────────────────────────────────┤
│ ┌─────────────────────────────────────┐ │
│ │ AtariMachine │ │
│ │ ┌───────────┐ ┌─────────────────┐ │ │
│ │ │ M68000 │ │ AtariMemory │ │ │
│ │ │ CPU │ │ ┌─────────────┐ │ │ │
│ │ │ (m68000) │ │ │ YM2149 │ │ │ │
│ │ └───────────┘ │ │ (ym2149) │ │ │ │
│ │ │ ├─────────────┤ │ │ │
│ │ │ │ MFP68901 │ │ │ │
│ │ │ │ (timers) │ │ │ │
│ │ │ ├─────────────┤ │ │ │
│ │ │ │ 4MB RAM │ │ │ │
│ │ │ └─────────────┘ │ │ │
│ │ └─────────────────┘ │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘
The Atari ST machine emulation provides:
Timer interrupts (used by SID voice effects) are handled by executing the interrupt handler code at audio sample rate.
Based on the sndh-player C++ implementation by Arnaud Carré (Leonard/Oxygene).
ICE! 2.4 depacker based on the public domain C implementation by Hans Wessels.
68000 emulation via the m68000 crate by Stovent.
MIT License - see LICENSE.