A port of the excellent MeltySynth by Sinshu to Common Lisp. This provides MIDI music playback for Common Lisp projects without a lot of dependencies.
Also included is midi123, a command line MIDI player that serves as a non-trivial example program.
Example videos:
How do I get set up?
This has only been tested with SBCL (specifically 2.2.2, 2.2.3, and the currently in-dev 2.2.4). Other Lisps may work, but are unsupported.
- Setup SBCL and Quicklisp
- Clone CL-SDM locally somewhere that ASDF can find it. This isn't installable with Quicklisp. You will need version 0.99.1 or later.
- Install CL-PortAudio (for the example program), and Babel and Trival-Indent (for CL-SDM).
- Clone this repo where ASDF can find it.
To build the example program, midi123, run rake. The binary will be in the bin/ directory. You can disable
executable compression if you'd like by running rake midi123[1] instead.
You can also play around with CL-MeltySynth or midi123 from a REPL. To load just the library, do
(asdf:load-system :cl-meltysynth) from within the REPL. Or do (asdf:load-system :midi123) if you want to load
the library and example program. You can then run (midi123:main "-h") to see how to run the program. The
&REST arguments to MIDI123:MAIN should all be strings and are just the standard command line options:
(midi123:main "-f" "/path/to/midi-file.mid" "-s" "/path/to/soundfont.sf2")
Building The midi123 Program
midi123 is a command line player for MIDI files. It's code is short and documented to show a few basic ways to
use CL-MeltySynth without being a trivial program.
- Install cl-portaudio library via Quicklisp.
- Run
rake(orrake midi123[1]if you don't want SBCL to produce a compressed binary). - The program will be in the
bin/directory. You can usemidi123 --helpto see a list of command line options.
Some example usages:
$ midi123 -s sc-55.sf2 -f "11 - Goin' Down the Fast Way.mid"
$ midi123 -s "Arachno SoundFont.sf2" -f "15 - Spray.mid" --outfile spray.wav
$ midi123 -s TimGM6mb.sf2 -f "24 - I Choose the Stairs.mid" --no-loop
Additional example programs can be found in the examples directory.
Development
Debug Builds
A debug build of CL-MeltySynth can be made like this:
- Put :MELTYSYNTH-DEBUG into FEATURES before loading the library:
(push :meltysynth-debug *features*) - Load CL-MeltySynth, forcing recompilation:
(asdf:load-system :cl-meltysynth :force t)
Debug builds set (DEBUG 3) on most functions, and does less inlining. This is useful to pinpoint performance
issues. There are also a few debugging messages that get printed while using the library.
Style info
I use a slightly different style for my code.
- Keep lines 118 characters or shorter. Obviously sometimes you can't, but please try. Use 115 characters for Markdown files, though.
- New type declarations should have their names prefixed with T/, for example,
t/uint32-vector. This is only for DEFTYPEs and DEFINE-PSEUDO-ENUMs. - Try not to go below
(DEBUG 1)when optimizing unless it's an internal function that's been tested and is known to work well. Slime has issues showing signatures and such when you do.
Running Tests
You will need the FiveAM and Bordeaux-FFT libraries (both installable via Quicklisp) to run the tests. You will
also need to place the following SoundFonts into the t directory with these exact filenames:
- TimGM6mb (already included in this repo in the
tdirectory) - Arachno SoundFont v1.0 (
Arachno SoundFont - Version 1.0.sf2) - The GeneralUser GS MuseScore SoundFont v1.442 (
GeneralUser GS MuseScore v1.442.sf2) - Shan's GM SoundFont v2.01 (
SGM-V2.01.sf2)
Some tests will take a few seconds to compile and it may look like the whole process froze. Just give it a few moments. There are also a LOT of checks in the tests, so you may not want to run them from within SLIME unless you want Emacs to slow down dramatically with output.
Tests can be run with rake test.
Todo
- Wave synthesis and Sound
- [x] SoundFont reader
- [x] Waveform generator
- [x] Envelope generator
- [x] Low-pass filter
- [x] Vibrato LFO
- [x] Modulation LFO
- [x] Cubic interpolation
- MIDI message processing
- [x] Note on/off
- [x] Bank selection
- [x] Bank/Patch remapping (remaps unknown presets to bank 0/128)
- [x] Modulation
- [x] Volume control
- [x] Pan
- [x] Expression
- [x] Hold pedal
- [x] Program change
- [x] Pitch bend
- [x] Tuning
- Effects
- [x] Reverb
- [x] Chorus
- Examples
- [x] midi123 can play MIDIs
- [x] midi123 can render to WAV files
- Other things
- [x] Standard MIDI file support
- [x] Loop extension support
- [x] Performance optimization
- [/] Unit tests ported (only some are currently ported)
- [x] Document public API
- [x] Non-looping MIDIs
How do I contribute?
- Go to https://chiselapp.com/user/MistressRemilia/repository/CL-MeltySynth/ and clone the Fossil repository.
- Create a new branch for your feature.
- Push locally to the new branch.
- Create a bundle with Fossil that contains your changes.
- Get in contact with me.
Contributors
- Remilia Scarlet - creator and maintainer
Links and Licenses
- MeltySynth by Sinshu (MIT License)
- TimGM6mb.sf2 by Tim Brechbill (GPLv2 License)
CL-MeltySynth itself is under the GNU Affero General Public License version 3.