#shazam #audio #audio-fingerprinting

app songrec

An open-source Shazam client for Linux, written in Rust

8 releases

0.1.8 Jun 1, 2021
0.1.7 Apr 9, 2021
0.1.6 Mar 30, 2021
0.1.4 Feb 23, 2021
0.1.0 Oct 7, 2020

#30 in Audio

Download history 18/week @ 2021-02-25 14/week @ 2021-03-04 4/week @ 2021-03-11 8/week @ 2021-03-18 68/week @ 2021-03-25 24/week @ 2021-04-01 38/week @ 2021-04-08 52/week @ 2021-04-15 17/week @ 2021-04-22 20/week @ 2021-04-29 8/week @ 2021-05-06 26/week @ 2021-05-13 22/week @ 2021-05-20 25/week @ 2021-05-27 17/week @ 2021-06-03 19/week @ 2021-06-10

103 downloads per month

GPL-3.0+

705KB
4.5K SLoC

Rust 3.5K SLoC // 0.0% comments Python 612 SLoC // 0.1% comments Shell 79 SLoC // 0.2% comments

SongRec

SongRec is an open-source Shazam client for Linux, written in Rust.

Screenshot

Features:

  • Recognize audio from an arbitrary audio file.
  • Recognize audio from the microphone.
  • Usage from both GUI and command line (for the file recognition part).
  • Provide an history of the recognized songs on the GUI, exportable to CSV.
  • Continuous song detection from the microphone, with the ability to choose your input device.
  • Ability to recognize songs from your speakers rather than your microphone (on compatible PulseAudio setups).
  • Generate a lure from a song that, when played, will fool Shazam into thinking that it is the concerned song.

A (command-line only) Python version, which I made before rewriting in Rust for performance, is also available for demonstration purposes. It supports file recognition only.

How it works

For useful information about how audio fingerprinting works, you may want to read this article. To be put simply, Shazam generates a spectrogram (a time/frequency 2D graph of the sound, with amplitude at intersections) of the sound, and maps out the frequency peaks from it (which should match key points of the harmonics of voice or of certains instruments).

Shazam also downsamples the sound at 16 KHz before processing, and cuts the sound in four bands of 250-520 Hz, 520-1450 Hz, 1450-3500 Hz, 3500-5500 Hz (so that if a band is too much scrambled by noise, recognition from other bands may apply). The frequency peaks are then sent to the servers, which subsequently look up the strongest peaks in a database, in order look for the simultaneous presence of neighboring peaks both in the associated reference fingerprints and in the fingerprint we sent.

Hence, the Shazam fingerprinting algorithm, as implemented by the client, is fairly simple, as much of the processing is done server-side. The general functionment of Shazam has been documented in public research papers and patents.

Installation

Here are a few ways to install and run the application:

Using AUR (Archlinux):

yay -S songrec
songrec

Using apt with PPA (Ubuntu, supported 18.04, 20.04, 20.10, 21.04):

sudo apt-add-repository ppa:marin-m/songrec -y -u
sudo apt install songrec -y
songrec

Using Flatpak (all distributions) (NOTE: with Flatpak, the GUI should work fine but some of the CLI features may not be usable due to filesystem sandboxing restrictions):

sudo apt install flatpak -y
flatpak remote-add --user flathub https://flathub.org/repo/flathub.flatpakrepo --if-not-exists
flatpak install --user flathub com.github.marinm.songrec -y
flatpak run com.github.marinm.songrec

Using Cargo (all distributions, dependencies given for Ubuntu/Debian, if your rustc version is not recent enough please refer to the instructions below):

sudo apt install cargo rustc -y
echo 'export PATH="$HOME/.cargo/bin:$PATH"' | tee -a ~/.profile ~/.bashrc
source ~/.bashrc

sudo apt install build-essential libasound2-dev libgtk-3-dev libssl-dev -y
cargo install songrec
songrec

Note: It is not mandatory, but if you want to be able to recognize more formats than WAV, OGG, FLAC and MP3, you should ensure that you have the ffmpeg package installed.

Compilation

(WARNING: Remind to compile the code in "--release" mode for correct performance.)

Installing Rust

First, you need to install the Rust compiler and package manager. It has been observed to work with rustc 1.43.0 to the current rust 1.47.0.

Install Rust and put it in path, for all distributions:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Type "1"
# Login and reconnect to add Rust to the $PATH, or run:
source $HOME/.cargo/env

# If you already installed Rust, then update it:
rustup update

Install dependent libraries (nothing exotic):

sudo apt install build-essential libasound2-dev libgtk-3-dev libssl-dev

Compiling the project

This will compile and run the projet:

# For the stable release:
cargo install songrec
songrec

# For the Github tree:
git clone git@github.com:marin-m/songrec.git
cd songrec
cargo run --release

For the latter, you will then find the project's binary (that you will be able to move or execute directly) at target/release/songrec.

Sample usage

Passing no arguments or using the gui subcommand will launch the GUI, and try to recognize audio real-time as soon as the application is launched:

./songrec
./songrec gui

Using the gui-norecording subcommand will launch the GUI without recognizing audio as soon as the software is started (you will need to click the "Turn on microphone recognition" button to do so):

./songrec gui-norecording

The GUI allows you to recognize songs either from your microphone, speakers (on compatible PulseAudio setups), or from an audio file. The MP3, FLAC, WAV and OGG formats should be accepted for audio files if FFMpeg is not installed, and any audio or video formats supported by FFMpeg should be accepted if FFMpeg is installed.

The following subcommand will try to recognize audio from the middle of an audio file, and print the JSON response from Shazam servers:

./songrec audio-file-to-recognized-song sound_file.mp3

The following subcommands will do the same with an intermediary step, manipulating data-URI audio fingerprints as used by Shazam internally:

./songrec audio-file-to-fingerprint sound_file.mp3
./songrec fingerprint-to-recognized-song 'data:audio/vnd.shazam.sig;base64,...'

The following will produce back hearable tones from a given fingerprint, that should be able to fool Shazam into thinking that this is the original song (either to the default audio output device, or to a .WAV file):

./songrec fingerprint-to-lure 'data:audio/vnd.shazam.sig;base64,...'
./songrec fingerprint-to-lure 'data:audio/vnd.shazam.sig;base64,...' /tmp/output.wav

When using the application, you may notice that certain information will be saved to ~/.local/share/SongRec (or an equivalent directory depending on your operating system), including the CSV-format list of the last recognized songs and the last selected microphone input device (so that it is chosen back when restarting the app). You may want to delete this directory in case of persistent issues.

Privacy

SongRec collects no data and contacts no other servers than Shazam's. SongRec does not upload raw audio data anywhere: only fingerprints of the audio are uploaded, which means sequences of frequency peaks encoded in the form of "(frequency, amplitude, time)" tuples.

This does not suffice to represent anything hearable alone (use the "Play a Shazam lure" button to see how much this is different from full sound); that means that no actually hearable sound (e.g voice fragments) is sent to servers, only metadata derived on the characteristics of the sound that may only suffice to recognize a song already known by Shazam is being sent.

Legal

This software is released under the GNU GPL v3 license. It was created with the intent of providing interoperability between the remote Shazam services and Linux-based deskop systems.

Please note that in certain countries located outside of the European Union, especially the United States, software patents may apply.

Dependencies

~34MB
~616K SLoC