ym2149

Crates.ioym2149
lib.rsym2149
version0.9.0
created_at2025-10-28 17:17:44.495822+00
updated_at2026-01-15 17:17:23.340914+00
descriptionCycle-accurate YM2149 PSG emulator
homepagehttps://ym2149-rs.org
repositoryhttps://github.com/slippyex/ym2149-rs
max_upload_size
id1905249
size100,239
slippyvex (slippyex)

documentation

https://docs.rs/ym2149

README

ym2149 – Cycle-Accurate YM2149 PSG Emulator

Crates.io Docs.rs License: MIT

Hardware-accurate emulation of the Yamaha YM2149 Programmable Sound Generator (PSG) chip, as used in the Atari ST, Amstrad CPC, and ZX Spectrum 128. The core runs an internal clk/8 loop (~250 kHz @ 2 MHz) with hardware envelope/volume tables, DC adjust, and buzzer/digidrum correctness.

Overview

This crate provides pure chip emulation only with cycle-accurate behavior. For file playback and audio output, see the companion crates:

Feature Highlights

Area Details
Emulation Integer/lookup pipeline with clk/8 substep, hardware envelope/volume tables
Effects SID voice, Sync Buzzer, Mad Max digi-drums, DC filter
Control Per-channel mute, color filter, register dump/load
Backend Trait Ym2149Backend for interchangeable implementations
Utilities Register math helpers in ym2149-common crate

Install

[dependencies]
ym2149 = "0.9"

For YM file playback with real-time audio, add the CLI:

ym2149-replayer-cli = "0.9"

Quick Start

Core Emulation Only

use ym2149::{Ym2149, Ym2149Backend};

let mut chip = Ym2149::new();
chip.write_register(0x00, 0xF0); // Channel A period low
chip.write_register(0x01, 0x01); // Channel A period high
chip.write_register(0x08, 0x0F); // Channel A volume
chip.write_register(0x07, 0x3E); // Mixer: enable tone A

chip.clock();
let sample = chip.get_sample();

YM File Playback

For playing YM music files, use the ym2149-ym-replayer crate:

use ym2149_ym_replayer::{load_song, PlaybackController};

let data = std::fs::read("song.ym")?;
let (mut player, summary) = load_song(&data)?;

player.play()?;
let samples = player.generate_samples(summary.samples_per_frame as usize);

Real-Time Audio Playback

For real-time audio output, use the CLI:

cargo run -p ym2149-replayer-cli -- path/to/song.ym

Backend Trait

The Ym2149Backend trait allows alternative implementations:

use ym2149::Ym2149Backend;

fn play_note<B: Ym2149Backend>(chip: &mut B) {
    chip.write_register(0x00, 0xF0);
    chip.write_register(0x08, 0x0F);
    chip.clock();
}

Modules

Module Description
ym2149 Core chip implementation
backend Ym2149Backend trait for alternative implementations

Note: Utility types like ChannelStates and register math helpers (channel_period, period_to_frequency) are in the ym2149-common crate.

Migration from < 0.7

Version 0.7 reorganized the crate structure for better separation of concerns:

  • Streaming audio moved to ym2149-replayer-cli
  • Visualization moved to ym2149-replayer-cli
  • YM file parsing in ym2149-ym-replayer (since 0.6)

The ym2149 crate now focuses exclusively on pure chip emulation.

// Old (< 0.7)
use ym2149::streaming::AudioDevice;
use ym2149::visualization::create_volume_bar;

// New (>= 0.7)
// Use ym2149-replayer-cli for audio output and visualization

Architecture

The YM2149 emulator implements:

  • 3 tone generators: 12-bit period counters
  • 1 noise generator: 17-bit LFSR
  • 1 envelope generator: Hardware-accurate shapes (10 patterns)
  • Mixer: Configurable tone/noise routing
  • Volume control: 32-step logarithmic + envelope
  • Effects support: DigiDrum, SID voice, Sync Buzzer

See ARCHITECTURE.md for implementation details.

Performance

  • Sample generation: ~0.5–1 ms per 50 Hz frame (44.1 kHz output)
  • Memory: ~1 KB per chip instance
  • Zero allocations in sample generation hot path

Documentation

Related Crates

Contributing

Run cargo fmt, cargo clippy, and cargo test -p ym2149 before submitting changes.

License

MIT License – see LICENSE.

Commit count: 0

cargo fmt