A Libretro core for playing video game music in RetroArch, with a built-in graphical interface: a browsable track list, audio meters and playback.
-
Massive Format Coverage
Extensive format compatibility: Over 50 supported formats, from classic chip-based console and arcade soundtracks to CD-quality streams. It is also compatible with tracker modules. -
Zero-Friction Album Playback
Drop a.zipcontaining an entire soundtrack, and AOLIB plays it in order immediately. No external cue sheets or playlist files are ever required. -
Optimized Memory Management
Handles albums up to 1.7 GB effortlessly — lazy-loads ZIP entries (first 64 KB per track) and never materializes a CD track, keeping RAM available during playback on any system. -
CHD support and CD playback
Open a PS1 disc image and AOLIB finds its music: Red Book CD-DA tracks and the CD-XA audio buried in the data track, without extracting anything to disk. AOLIB also supports CHD files as audio containers just like .zip files. Take advantage of its compression and block access to efficiently play any compatible format (.spc, .vgm, .psf or streaming audio, etc).
| Backend | Formats |
|---|---|
| libgme | .spc .nsf .nsfe .gbs .hes .kss .sap .ay .gym |
| libvgm | .vgm .vgz (30+ chips, including many arcade ones) |
| libxmp-lite | .mod .s3m .xm .it (tracker modules) |
| aosdk | .psf .minipsf .psf2 .minipsf2 .ssf .minissf |
| vgmstream | .xa .str .pxa .xai .vag .psh .npsf .adx .dsp .brstm .genh |
The breakdown of which chip or format covers which system or arcade board is in SUPPORTED_SYSTEMS
The core opens the archive itself: it enumerates the entries, sorts them in natural order (9 Theme before 10 Theme), and plays them as an album. Shared library files (.psflib, .psf2lib, .ssflib) are resolved across entries in the same archive, but never show up as tracks.
Two things worth knowing about how playback behaves:
Track changes don't interrupt the audio. The next entry is decompressed ahead of time, a slice per frame, while the current track plays. By the time the track ends, the next one is already in memory.
Track durations fill in as you listen. They're probed in the background instead of up front, so loading an album is immediate no matter how large it is. Until a track has been probed its length shows as --:--.
Point the core at a PS1 disc image and it plays the music on it. There is nothing to rip and nothing to extract: the CHD hunk map gives random access, so tracks are read as they play.
.chd isn't limited to real PlayStation discs. AOLIB reads whatever an ISO 9660 filesystem lists inside the CHD, so a .chd built from an ordinary folder of AOLIB-supported files -- .spc, .vgm, .psf, streamed formats, anything the core already opens from a .zip -- works the same way as a .zip album. CHD's compression and hunk-based random access make it a usable container for a regular library, not just for disc rips.
A disc can carry its music two ways, and AOLIB lists both as one album:
CD-DA tracks — Red Book audio, the whole track never held in RAM (a four-minute track is 42 MB, a disc easily 500 MB).
CD-XA audio — the compressed audio interleaved into the data track, which on many discs is where all the music lives. AOLIB finds it through the CD-XA attributes in the ISO 9660 directory rather than by file extension, because these files are often named without one. Files that turn out to hold no audio are dropped from the list instead of sitting there as unplayable entries.
| Button | Action |
|---|---|
| Up / Down | Move the cursor through the list (repeats on hold) |
| Left / Right | Move focus across the deck |
| B | Plays the track under the cursor |
| A | Activates the focused deck button |
| L / R | Volume down / up |
| Start | Pause / resume |
The deck has eight buttons: stop, previous track, play/pause, fast forward (hold to use), next track, volume, reverb, and repeat mode. Volume, reverb, and repeat stay lit, with an orange border, until toggled again.
| Option | Values | Effect |
|---|---|---|
| Loop forever at end of album | disabled / enabled | Restarts from the beginning once the last track ends |
| Fade duration (s) | 8, 0, 1, 2, 3, 5, 10 | Length of the final fade-out |
| SPU Reverb (PSF2 only) | enabled / disabled | Reverb of the emulated PlayStation SPU |
| Player Reverb Amount | 1, 2, 3 | Level (35%, 50%, 65%) of the player's own reverb |
The player's reverb is turned on and off only with the REB button on the deck; the menu just sets the level it'll play at. These are two different things: the SPU reverb is part of how the console actually sounded, so it ships enabled; the player's reverb is an effect added on top, and ships disabled.
Requires GNU Make and a C++17 compiler. All dependencies are vendored
under deps/; nothing else needs to be installed.
make all USE_PSF_ENGINE=1 USE_VGMSTREAM=1 # Linux -> aolib_libretro.so
make all USE_PSF_ENGINE=1 USE_VGMSTREAM=1 PLATFORM=windows # Windows -> aolib_libretro.dllCross-compiling for Windows requires x86_64-w64-mingw32-g++.
On Windows, run these commands from Git Bash/MSYS, not from PowerShell:
PowerShell resolves find to its own find.exe, so the vgmstream source
list silently comes back empty and the core gets built without that
backend (USE_VGMSTREAM=1 then does nothing).
Run make clean when switching platforms: object files are named the
same on both, and Make has no way of knowing the compiler changed.
Without USE_PSF_ENGINE=1 the core builds without the aosdk engines, and
the PSF and SSF formats are left out. The same applies to USE_VGMSTREAM=1
and the streamed formats (XA, VAG, ADX, DSP, BRSTM...).
For releases, always use the packaging targets instead of copying binaries by hand:
make dist USE_VGMSTREAM=1 # builds from scratch and updates dist-linux/
make dist-windows USE_VGMSTREAM=1 # same, for dist-windows/ (~2.6 MB stripped dll)
make dist-all USE_VGMSTREAM=1 # both platformsOnly the dist* targets strip the binary (strip --strip-all, using
x86_64-w64-mingw32-strip on Windows). make all binary deliberately keeps
its debug symbols and is several MB larger.
info lives at the repo root (aolib_libretro.info, single source of
truth) and is copied into dist-linux//dist-windows/ by the packaging
targets. Edit the root copy, not the ones under dist/..
Three distinct lifetime layers: CoreContext is rebuilt on every
retro_load_game(), while UiModel, AudioAnalyzer, and dsp::Reverb
live for the whole RetroArch session. All file I/O goes through
IVFSBridge, without exception. The three aosdk engines (PSF1, PSF2, SSF)
share a single process-wide state guard, because the vendored R3000A and
M68000 cores don't support two live instances at once. The audio pipeline
applies reverb BEFORE the gain stage — so the tail rises with the overall
volume — and analyzes the signal AFTER.
You can see the complete System Architecture Diagram and pipiline at.
architecture.ascii.
The project's own code belongs to Ckines, under GPL-2.0-or-later. The compiled binary also links against third-party code under other licenses (BSD, LGPL-2.1, GPL, and non-commercial licenses from MAME and Musashi).
This is third-party work AOLIB depends on to function: the player itself doesn't emulate anything on its own — it's an interface and a Libretro bridge over what follows.
Format. Neill Corlett designed the PSF format itself (2003) and its successor PSF2, the basis SSF and the rest of the "Portable Sound Format" family also derive from. None of his code is vendored directly, but without his format there would be no PSF1, PSF2, or SSF.
libgme (SPC, NSF/NSFE, GBS, HES, KSS, SAP, AY, GYM) — Shay Green. The YM2612 emulator (Sega Genesis/Mega Drive) is by Stéphane Dallongeville.
libvgm (VGM/VGZ) — ValleyBell. The chip cores this core enables come from MAME and from independent projects: Nicola Salmoria (SN76496), Jarek Burczynski and Ernesto Corvi (YM2413, YM3812), Mirko Buffoni, Aaron Giles, and Andrew Gardner (OKIM6295 and the shared ADPCM decoder), Mitsutaka Okazaki (AY8910/emu2149), superctr (Ian Karlsson) with Valley Bell (QSound), R. Belmont, superctr, and Valley Bell (C219/C352), Olivier Galibert and Aaron Giles (RF5C68), and Stéphane Dallongeville, Stéphane Akhoun, and David Korth (PWM and RF5C164, from the Gens project lineage).
libxmp-lite (MOD, S3M, XM, IT) — Claudio Matsuoka and Hipolito Carraro Jr, with Alice Rowan and Ozkan Sezer maintaining it today.
vgmstream (all the streamed formats in the table above: CD-XA, Sony VAG, CRI ADX/AHX, Nintendo GC/Wii DSP and BRSTM, FMOD FSB, EA SCHl, Ubisoft Jade, and the rest) — bnnm, kode54, Fastelbja, Ricardo Bravo and contributors, under an ISC-style license. Only the parsers this core can actually reach are vendored.
aosdk (PSF1, PSF2, SSF/Saturn) — R. Belmont and Richard Bannister created the SDK; nmlgc maintains it today. Within aosdk:
- PlayStation R3000A core (
psx.c) — "smf", from the MAME project, with thanks to Farfetch'd for the delay-slot bug documentation used in its emulation. - PSF1's SPU and PSF2's SPU2 (
peops/peops2) — Pete Bernert. - Saturn's SCSP (
scsp.c) — ElSemi, with the MAME conversion and cleanup by R. Belmont, and additional fixes by kingshriek. - Saturn's M68000 core ("Musashi") — Karl Stenerud.
- The PS1/PS2 engine itself (
psx.c,cpuintrf.h, and related files) is distributed under the MAME license, copyright Nicola Salmoria and the MAME team.
zlib & minizip (.zip reading) — Jean-loup Gailly, Mark Adler, Gilles Vollant & Info-ZIP.
libchdr (.chd disc images) — Aaron Giles & contributors (BSD-3-Clause), with dr_flac by David Reid.
LZMA SDK (CHD lzma/cdlz hunks) — Igor Pavlov (Public Domain).

