Ellington is an experimental project to automate the calculation of beats-per-minute (BPM) information for swing jazz music, such as the works of Duke Ellington - the project's namesake. BPM information for swing jazz music is notoriously hard to calculate automatically, as the shuffle of the rhythm section, the soft/loud chunking guitar, and overall swing feel mean that standard algorithms (which are often optimised for four-on-the-floor feel music) report inaccurate times. As such, this project has two main goals:
-
Provide a platform for experimenting with various BPM algorithms and tools (machine learning anyone?) in order to find high quality (at least >90% accuracy, 99% of the time) solutions.
-
Provide a tool, or set of tools, for automatically processing libraries of swing jazz music, and reporting BPM information.
Ellington is based around the idea of a 'library' of audio files, that you might wish to process. This is similar to an iTunes library - you must explicitly add audio files to the library, and where possible metadata is written to the library, not the audio file.
An example ellington usage flow might be:
ellington init library.json -d ~/Music/
ellington bpm library.json
ellington write library.json
The above commands, in order:
- Initialise a new ellington library
library.json
- Calculate bpm information for each audio file in the library, storing the information in
library.json
- Write the bpm information to the audio file comment - where requested (more on this later).
NOTE: ELLINGTON IS PRE-ALPHA, AND VERY BUGGY. BACK UP YOUR MUSIC LIBRARY BEFORE USING IT TO WRITE METADATA TO AUDIO FILES!!
Most Ellington dependencies are expressed using the rust package manager, cargo, and so will be automatically installed when Ellington is built. However, Ellington makes use of a number of external programs for tasks such as parsing mp3 audio data, or writing id3v2 tags. These are:
- ffmpeg
- id3v2
- mp4info
- mp4tags
External programs are listed in src/shelltools
, in case any are missing here.
Ellington currently supports four different operations (see ellington --help
for more information):
- Library initialisation:
ellington init
- BPM calculation:
ellington bpm
- Writing ellington metadata to audio files:
ellington write
- Clearing ellington metadata from audio files:
ellington clear
Ellington library files can be initialised as follows:
ellington init <library_file> -d <directory>
ellington init <library_file> -i <itunes_xml_library>
ellington init <library_file>
This will write a json-based library to the file given in <library_file
. Audio discovery is currently possible with three different methodologies. Ellington can:
- Recursively explore a directory tree to find music files --
-d <directory>
- Read individual audio file names from stdin --
-i <itunes_xml_library>
- Read an iTunes XML library to discover music files (but not other metadata) -- no further parameters.
Ellington can, given a library file, calculate the bpm of each track in the library using a "pipeline". A pipeline is a combination of an audio decoder (e.g ffmpeg
), and a bpm algorithm (e.g. naive
). The results of the bpm calculations are written in place to the library file. This stage can be invoked as follows:
ellington bpm <library_file>
Ellington files, themselves, are not that useful for the casual DJ. It takes a while to find each song in the JSON, and JSON itself can be a bit tricky to read. In order to remedy this, Ellington can write the data that it has calculated to the audio file itself, as follows:
ellington write <library_file>
NOTE: This will modify metadata of the audio files listed in library_file
. Run this command at your own risk - it may damage your audio library!
As the bpms calculated with Ellington are not yet high quality, Ellington avoids writing to an audio file's bpm
tag, but instead writes a specially formed piece of text to the comment field of the audio data. Ellington is (by default) very polite - it only writes to the comment when requested.
Comments with Ellington metadata contain a valid Ellington data string of the form:
[ed#<data>#de]
Where <data>
is a JSON string, with :
replaced with #
, representing some Ellington data (see src/library/ellingtondata.rs
).
A good default Ellington data string is:
[ed#{"algs"#{}}#de]
In order to persuade Ellington to write to an audio file, edit the 'comment' metadata tag of it to include the above data string, using your tag editor of choice. Alternatively, Ellington can be made more aggressive, by passing the --append
flag to the write
command. This will append the ellington data to an existing comment even if it does not yet contain comment data.
By default, Ellington is quite conservative in what it prints. In order to get it to log more, export the following environment variable as follows:
RUST_LOG=ellington,libellington
0.1.0: (current master)
- Audio file discovery through iTunes based libraries
- Audio file discovery through recursive directory enumeration
- Audio file discovery through
stdin
- Support for generic audio decoding using
ffmpeg
- Support for mp3 tagging using
id3v2
- Support for mp4 metadata parsing using
mp4info
- Support for mp4 metadata writing using
mp4tags
- Naive BPM calculation algorithm acting on raw audio data
- Draft json-based ellington-data format for ephemeral bpm information
- Comment appending (i.e. programmatically marking tracks as wanting to have bpm information written to them)
0.1.1:
- Updated/better ellington-data metadata format for audio data tags.
0.1.2:
- Support for FLAC metadata
0.1.3:
- Integration tests for tag reading/writing of mp3,mp4,FLAC files
0.1.4:
- Unit tests for library components
0.2.0:
- Replace
id3v2
program invocation with library calls. - Replace
mp4tags
andmp4info
program invocations with library calls.
0.3.0:
- Stream output/input for libraries (i.e. writing a library to stdout, reading one from stdin - this should allow us to pipe libraries between ellington commands)
0.4.0:
- Integration of static
ffmpeg
libraries instead of system calls - Integration of all dependencies in
cargo.toml
- Standalone binary, without dynamic dependencies (including external programs)
0.5.0
- Parallel bpm analysis
1.0.0:
- Stable release of Ellington.
- Windows support
2.0.0:
- Neural network based bpm classifier