# virittaa
[](https://builds.sr.ht/~mtmn/virittaa?)
A command-line tool that analyzes audio files to detect `BPM` and `Key` tags.
BPM and key detection are powered by [Essentia](https://github.com/MTG/essentia):
tempo comes from `RhythmExtractor2013` (multifeature method) and key from
`KeyExtractor` using the EDMA profile. The reported BPM is Essentia's true tempo
estimate — there is no octave-folding into a fixed range.
## Features
* Detect BPM and Key of audio files
* Write detected BPM and Key to metadata tags
* Save track metadata to a database (on by default)
* Query the database by artist, key, BPM range, or regex
* Import tracks from a Mixxx SQLite database
## Building
virittaa binds to Essentia through the [`essentia`](https://github.com/lagmoellertim/essentia-rs)
crate (essentia-rs), which links against a system-installed `libessentia` and
its dependencies via `pkg-config`. Before building, make sure all of the
following resolve (`pkg-config --exists <name>`):
`essentia`, `eigen3`, `yaml-0.1`, `fftw3f`, `taglib`, `samplerate`,
`libchromaprint`, `libavformat`, `libswresample`, `libavcodec`, `libavutil`
Essentia is not usually packaged as a library, so you will likely need to build
and install it from source (see `nix/essentia.nix` for a reference build). A
C++17 compiler is also required (the bindings are generated and compiled with
`cxx`).
essentia-rs links TensorFlow by default; virittaa doesn't need it and opts out
via `USE_TENSORFLOW=0`, which is set for you in `.cargo/config.toml`.
To build the project, run:
```sh
cargo build --release
```
## Usage
```sh
./target/release/virittaa [OPTIONS] [PATH]...
```
### Arguments
* `[PATH]...`: Files or directories to analyze. Not required when using database query flags.
### Options
* `-t`, `--write-tags`: Write detected BPM and Key to audio file metadata.
* `--no-store`: Skip saving track reports to the database.
* `-f`, `--force`: Re-analyze files that already have BPM/Key tags.
* `-j`, `--jobs <JOBS>`: Number of threads (0 = all cores).
* `-l`, `--list`: List track reports in the database.
* `--limit <N>`: Max entries to list (default: 1000, 0 = all).
* `--query <KEY>`: Look up a track by exact key.
* `-S`, `--search <PATTERN>`: Search track reports by regex.
* `-a`, `--artist <PREFIX>`: Find tracks by artist name prefix.
* `--key <PREFIX>`: Find tracks by key prefix (e.g. 'C Major', 'Am').
* `--bpm <MIN> <MAX>`: Find tracks with BPM in range MIN MAX.
* `--import-mixxx <PATH>`: Import tracks from a Mixxx SQLite database.
* `--db-path <PATH>`: Database directory (default: `~/.local/share/virittaa`).
* `-h`, `--help`: Print help information.
* `-V`, `--version`: Print version information.
### Examples
```sh
# Analyze a single file (saves to DB by default)
./target/release/virittaa /path/to/track.mp3
# Analyze a directory and write metadata tags
./target/release/virittaa --write-tags /path/to/music/
# Re-analyze files that already have tags
./target/release/virittaa --force --write-tags /path/to/music/
# Analyze without saving to the database
./target/release/virittaa --no-store /path/to/music/
# Limit to 4 threads
./target/release/virittaa -j 4 /path/to/music/
# Write tags and use a custom database path
./target/release/virittaa -t --db-path ~/my_library /path/to/music/
# List tracks in the database (default limit: 1000)
./target/release/virittaa --list
# List all tracks (no limit)
./target/release/virittaa --list --limit 0
# Look up a specific track
./target/release/virittaa --query "Aphex Twin - Xtal"
# Search by regex
./target/release/virittaa --search 'weed'
./target/release/virittaa --search '^Aphex'
# Find all tracks by an artist
./target/release/virittaa --artist 'Aphex Twin'
# Find all tracks in a key
./target/release/virittaa --key 'C Major'
# Find tracks with BPM between 120 and 140
./target/release/virittaa --bpm 120 140
# Import from a Mixxx database
./target/release/virittaa --import-mixxx ~/.mixxx/mixxxdb.sqlite
```