Benben v0.5.0 is almost ready, now a general-purpose music player

YunoSynth is a high-performance VGM playback library written entirely in Crystal. VGM files are sample-accurate music files ripped from video games. Rather than containing audio data like an MP3 or WAV file, they contain a log of the instructions that are sent to sound chips in these old game consoles and machines. This makes them much smaller (38 KB for the song below, versus what would be a 5.3 MB 192kbit MP3). YunoSynth is made up of a playback core that sends VGM instructions to various sound chip emulators that then produce PCM output.

The initial 0.1.0 release supports a large number of chips, but it’s still lacking a few chips supported by the VGM specification. My plan is to continue adding additional chips as time goes on until they are all supported. If you download any VGM files, just check the YunoSynth page to see if its chips are supported. Currently, you can play music from many arcade games, the PC Engine/TurboGrafx-16, NeoGeo, GameBoy, PC-88 and PC-98 computers, MSX2 computer, and Sharp X68000 computer.

Benben, meanwhile, is a command line player that uses YunoSynth. The program itself is written entirely in Crystal as well, though it does use bindings to PulseAudio and PortAudio to connect to your audio system. It can be used as a standalone player, and has optional effects that you can enable at will, such as a parametric EQ with unlimited bands, a configurable reverb effect, and stereo enhancement (these are also all pure Crystal lol).

Aside from playback, it’s also capable of rendering VGM files to both WAV and Au format. This is done in parallel, so the more cores you have, the faster it’ll work.

Here’s an example video where Benben is playing a song from a game called Rusty. This game is from an old Japanese computer system called the PC-98, and uses a Yamaha YM2608 for FM synthesis and ADPCM sample playback. There are more sample videos listed in the readme.

A pre-compiled x86-64 Linux binary in the form of an AppImage is available in the repo: Download v0.1.0

EDIT: v0.4.0 released: Benben v0.5.0 is almost ready, now a general-purpose music player - #4 by MistressRemilia

EDIT: v0.5.0 release candidates are now available: Benben v0.5.0 is almost ready, now a general-purpose music player - #5 by MistressRemilia


Holy F**king ***t !

This is abslutely incredible work.

And not only that:

  • clean code with comments
  • project split in reasonable parts, usable seperately
  • with documentation and example usage code
  • links and explanations to everything neccessary.
  • even a precompiled appimage is available.

Absolutely wowed. Thank you!


That is absolutely remarkable! Stunning work. I downloaded the AppImage build and it works flawlessly right out of the box (using Pipewire’s PulseAudio interface). Tested a couple of Atari ST and arcade soundtracks using a range of synth chips. Just… wow. What an incredible showcase for Crystal – this thing just works, is easy to use, looks great and doesn’t crash (like some of the old C-based Winamp plugins I used to use for playback of PSF/miniPSF files etc).


Guess I forgot to post some updates here ^_^;

I’ve released v0.4.0 of Benben and YunoSynth today! They have had a TON of new stuff added since v0.1.0, so I’ll just summarize some of the cooler stuff here:

  • A bunch of new chip emulators: YM2612 (aka, Sega Genesis), SN764xx (also used in the Sega Genesis), YM3812, YMF262 (IBM PC), RF5C164, VSU-VUE (aka, Virtual Boy), ES5503, Y8950 (MSX), YM3526, NES, Famicom Disk System, X1-010, SAA1099, Sega 32x PWM, Wonderswan.
  • A new snazzy interface that uses my S-Lang bindings. It also shows the CPU usage now.
  • Improved performance throughout.
  • Redesigned to be more multi-threaded internally.
  • Support for libao output in addition to PulseAudio and PortAudio.
  • Optional automatic peak normalization when rendering to WAV or Au.
  • Generation of CUE files when rendering to WAV/Au.
  • The emulator/sound/player code is still 100% Crystal. The only bindings here are S-Lang, ZStandard, and the audio outputs (e.g. PortAudio).

A Linux x86-64 AppImage is available for download like usual.


Benben v0.5.0 is almost ready for release! The code is in a freeze right now, with only bug fixes going in. I’ve been releasing Linux x86-64 AppImages of each release candidate on the Releases page, or you can just build from source. There’s also a FAQ page now.

This is a huge update that introduces a bunch of new features.

  • Benben is now a general-purpose music player
    • VGM support is still in-place and is 100% native Crystal
    • MPEG-1 support (so .mp3, .mp2, and .mp1 files)
    • Module/tracker support (.s3m, .mod, .xm, etc.)
    • FLAC support (100% native Crystal)
    • Opus support
    • Ogg Vorbis support (demuxer is native Crystal)
    • MIDI support (native Crystal)
    • Playback of WAV and Au (native Crystal)
    • High quality resampling for MPEG-1/FLAC/Opus/WAV/Au/Ogg files via a native port of libsamplerate to Crystal
  • Theme support
  • More startup animations added
  • Seeking support for MP3, MP2, MP1, RIFF WAV, module files, and Au files added. Support for seeking in other formats will come in the future.
  • ReplayGain support for MPEG-1, Vorbis, Opus, and FLAC files
  • Improved metadata display (things scroll now)
  • Full changelog

Example video where it’s playing a tracker/module file (S3M) that I really like.

The finalized v0.5.0 release will come at the end of July. Enjoy :D


Sick !! Good music too!!

1 Like

Now it is time to find music from my fav games back in 80ies on Yamaha MSX/MSX2.

I loved Arkanoid, Wiz, Kings Valley, and music on them.


Good news!


Does Lemmings count?

1 Like

Take your pick lemmings • VGMRips

Just for mention, if built with -Dstrict_multi_assign -Dno_number_autocast, will failed with:

In lib/libremiliacr/src/remilib/compression/bzip/

 2245 | bucketB[DivSufSort.bucketBStar(@t[i], @t[i + 1])] += 1
Error: expected argument #1 to 'RemiLib::Compression::BZip2::DivSufSort.bucketBStar' to be Int32, not UInt8

Overloads are:
 - RemiLib::Compression::BZip2::DivSufSort.bucketBStar(c0 : Int32, c1 : Int32)


In src/players/

 71 | outputRateMul, outputRateDiv = Yuno::VgmPlayer.calcResampling(Benben.config.sampleRate, file.file)
Error: cannot assign Tuple(UInt32, UInt32, UInt32, UInt32) to 2 targets

Without set those option, built successful.

1 Like

Thanks for the report! I always forget about those flags ^_^; This has been fixed in the trunk code and the related libraries.

1 Like

Yesterday, I downloaded and ran the Benben binary. I found the BenBen logo flickering beautifully on the terminal.

1 Like