ym2149 – Cycle-Accurate YM2149 PSG Emulator
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 the core YM2149 chip emulation with cycle-accurate behavior. For YM file parsing and playback, see the companion crates:
- ym2149 (this crate): Pure chip emulation
- ym2149-ym-replayer: YM file parsing and music playback
- ym2149-softsynth: Experimental synthesizer backend
- bevy_ym2149: Bevy game engine integration
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 |
| Audio Output | Optional real-time streaming via rodio/cpal (feature: streaming) |
| Visualization | Optional terminal UI helpers (feature: visualization) |
Install
[]
= { = "0.6.1", = ["emulator"] }
For YM file playback, add:
= "0.6.1"
Quick Start
Core Emulation Only
use Ym2149;
let mut chip = new;
chip.write_register; // Channel A period low
chip.write_register; // Channel A period high
chip.write_register; // Channel A volume
chip.write_register; // 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 ;
let data = read?;
let = load_song?;
player.play?;
let samples = player.generate_samples;
Interactive Chip Demo
Try the interactive chip demo with real-time audio output:
The demo showcases 7 different sound demonstrations:
- Simple tone (440 Hz A4)
- Musical scale (C4-C5)
- Three-channel chord (C Major)
- Envelope generators (Attack-Decay, Sawtooth)
- Noise generator
- Tone + Noise (snare-like sound)
Press SPACE to advance between demos, Q to quit.
Backend Trait
The Ym2149Backend trait allows alternative implementations:
use Ym2149Backend;
Feature Flags
| Feature | Description |
|---|---|
emulator (default) |
Core chip implementation |
streaming |
Real-time audio output (rodio) |
visualization |
Terminal UI helpers |
Migration from < 0.6.1
Version 0.6.1 reorganized the crate structure for better separation of concerns.
All YM file parsing and playback functionality has been moved to the ym2149-ym-replayer crate:
// Old (< 0.6)
use Ym6Player;
use ym_loader;
// New (>= 0.6)
use Ym6Player;
use loader;
The ym2149 crate now focuses exclusively on chip emulation, streaming, 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 ADSR
- Mixer: Configurable tone/noise routing
- Volume control: 16-level logarithmic + envelope
- Effects support: Special registers for Mad Max effects
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
- API reference: docs.rs/ym2149
- Emulator internals:
ARCHITECTURE.md - Streaming guide:
STREAMING_GUIDE.md
Related Crates
- ym2149-ym-replayer: YM file parsing and playback
- ym2149-softsynth: Experimental synthesizer backend
- bevy_ym2149: Bevy game engine plugin
Contributing
Run cargo fmt, cargo clippy, and cargo test -p ym2149 --all-features before submitting changes.
License
MIT License – see LICENSE.