A configurable, multi-threaded, real-time chord detector for musicians and audio nerds.
chordy-cpp
re-implements its ancestor chordy-py
for performance (~2.53x faster) in C++, maintaining a three thread structure to prevent audio buffer starvation and UI lag.
- Audio Callback Thread: Uses PortAudio to stream input buffers into a single producer, single consumer, thread-safe, lock-free circular queue (ring buffer).
- Main Thread: Collects frames from the audio ring buffer, dispatching compute jobs via ring buffer and displaying waveform data / compute results via ImGui (OpenGL3 + GLFW3).
- Compute Thread: Uses KissFFT to compute the Fast-Fourier Transform of the real signal. Computing the pitch chroma, we use chord templates to estimate chord probabilities, and we also provide the Harmonic Product Spectrum for display.
Unlike chordy-py
, chordy-cpp
supports real-time settings modification. In Release mode, the gui of chordy-cpp
ticks at ~60fps (16.7ms/f), while the compute thread processes jobs at ~0.06ms/job. Memory consumption is ~230 MB on default settings.
chordy-cpp
is distributed as a single executable for MacOS. Download and unzip /cpp/dist.zip
then run ./chordy
. While this binary works out of the box, chordy-cpp
relies on dist/res/
for font assets. If your binary is moved from its original dist folder, chordy-cpp
will simply fallback to the default ImGui font. For a MacOS .dmg
, see dist/Chordy.dmg
. However, this does not have font support and is signifantly slower (Debug build only).
For a source build using CMake, run ./build.sh Release && ./dist.sh
in /cpp
to generate ./dist
and follow the above instructions. This is required for Windows/Linux users.
chordy-py
maintains three threads to isolate audio streaming, chord recognition, and GUI rendering, with dequeues for data management.
chordy-py
usespyaudio
to stream microphone audio into a queue of chunks.chordy-py
uses interpretable, analytic techniques instead of machine learning, building on Alexander Lerch'spyACA
package. Seecompute_chords
inchord.py
for the implementation.chordy-py
uses Python's defaulttkinter
package for GUI rendering, as well asscipy
for timeseries resampling.
The GUI application ticks at ~23.7fps (42.1 ms/f), while the chord detection itself takes ~6.7ms (~149 per sec).
chordy-py
admits a MacOS binary at /py/release/chordy
. Add to PATH if needed. Please refer to the following usage guidelines:
usage: chordy [options] [audio] [gui] [algo]
A configurable, multi-threaded, real-time chord detector!
options:
-h, --help show this help message and exit
audio:
--sample-rate FS, -fs FS
Audio sample rate in frames per second (default: 44100)
--chunk-size CHUNK_SIZE, -cs CHUNK_SIZE
Number of samples per streamed chunk (default: 1024)
gui:
--display-chunks DISPLAY_CHUNKS, -d DISPLAY_CHUNKS
Number of chunks to display in viewer waveform (default: 200)
algo:
--chord-chunks CHORD_CHUNKS, -cc CHORD_CHUNKS
Number of chunks to send to chord recognition algorithm (default: 8)
--hop-chunks HOP_CHUNKS, -hc HOP_CHUNKS
Number of chunks to hop (default: 2)
--block-chunks BLOCK_CHUNKS, -bc BLOCK_CHUNKS
Number of chunks per block (default: 2)
--algorithm {RAW,VITERBI}, -a {RAW,VITERBI}
Choice of recognition algorithm (default: RAW)
--raw Use raw chords and probabilities (default: None)
--viterbi Use Markov Chains / Viterbi Algorithm to process raw chord probabilities (default: None)
--threshold THRESHOLD, -t THRESHOLD
Minimum probability for a detected chord (default: 0.07)
For a MacOS .dmg
, see /py/release/Chordy.dmg
. Some users may experience a malicious software warning when running the application. To avoid this, choose Open in Finder
. Right click on Chordy
and choose Open
from the dropdown. Then, click Open
again. Chordy
will request permission to access your microphone and start running. After doing this once, the application can be opened directly from Launchpad.
For Windows / Linux users, a source build is mandatory for chordy-py
.
- Begin by cloning the repository.
$: git clone https://github.com/arulandu/chordy.git && cd chordy/py
- Use your python package manager to install the dependencies.
$: pip install -r requirements.txt
- Run
main.py
to start the application!
$: python src/main.py
This project is open to contribution! Feel free to open a PR / GitHub issue!
@book{lerch2012introduction,
title={An introduction to audio content analysis: Applications in signal processing and music informatics},
author={Lerch, Alexander},
year={2012},
publisher={Wiley-IEEE Press}
}