Olaf
Overly Lightweight Acoustic Fingerprinting
Loading...
Searching...
No Matches
Overly Lightweight Acoustic Fingerprinting (Olaf)

Introduction

Olaf is a C application / library for landmark based acoustic fingerprinting. Olaf is able to extract fingerprints from an audio stream, and either store those fingerprints in a database, or find a match between extracted fingerprints and stored fingerprints. Olaf does this efficiently in order to be used on embedded platforms, traditional computers or in web browsers via WASM.

Please be aware of the patents US7627477 B2 and US6990453 and perhaps others. They describe techniques used in algorithms implemented within Olaf. These patents limit the use of Olaf under various conditions and for several regions. Please make sure to consult your intellectual property rights specialist if you are in doubt about these restrictions. If these restrictions apply, please respect the patent holders rights. The main aim of Olaf is to serve as a learning platform on efficient (embedded) acoustic fingerprinting algorithms.

Why Olaf?

Olaf stands out for three reasons.

  1. Olaf runs on embedded devices.
  2. Olaf is fast on traditional computers.
  3. Olaf runs in the browsers.

There seem to be no lightweight acoustic fingerprinting libraries that are straightforward to run on embedded platforms. On embedded platforms memory and computational resources are severely limited. Olaf is written in portable C with these restrictions in mind. Olaf mainly targets 32-bit ARM devices such as some Teensy’s, some Arduino’s and the ESP32. Other modern embedded platforms with similar specifications and might work as well.

Olaf, being written in portable C, operates also on traditional computers. There, the efficiency of Olaf makes it run fast. On embedded devices reference fingerprints are stored in memory. On traditional computers fingerprints are stored in a high-performance key-value-store: LMDB. LMDB offers an a B+-tree based persistent storage ideal for small keys and values with low storage overhead.

Olaf works in the browser. Via Emscripten Olaf can be compiled to WASM. This makes it relatively straightforward to combine the capabilities of the Web Audio API and Olaf to create browser based audio fingerprinting applications.

Olaf's design

The core of Olaf is kept as small as possible and is shared between the ESP32, WebAssembly and traditional version. The only difference is how audio enters the system. The default configuration expects monophonic, 32bit float audio sampled at 16kHz. Transcoding and resampling is different for each environment.

For traditional computers file handling and transcoding is governed by a Ruby script. This script expands lists of incoming audio files, transcodes audio files, checks incoming audio, checks for duplicate material, validates arguments and input,... The Ruby script, essentially, makes Olaf an easy to use CLI application and keeps the C parts of Olaf simple. The C core it is not concerned with e.g. transcoding. Crucially, the C core trusts input and does not do much input validation and does not provide much guardrails. Since the interface is the Ruby script this seems warranted.

For the ESP32 version, only a small part of the core is used. To create a new ESP32 Arduino project, there is a small script which links to the core. The default Arduino setup uses C++ extensions so olaf_config.h remains olaf_config.h but olaf_config.c becomes olaf_config.cpp. Perhaps other environments (PlatformIO) do not need this name change.

The WebAssembly version also uses a similarly small part of the core and some bridge code is available.

To verify both the ESP32 and WebAssembly versions, the Olaf C core can be compiled with the 'memory' database to mimic the ESP32/WebAssembly versions. In the compilation step the implementation for the olaf_db.h header is done by olaf_db_mem.c in stead of the standard olaf_db.c implementation. This paradigm of several implementations for a single header file is done a few times in Olaf. Olaf ships with several max-filter implementations.

Olaf's configuration

The configuration of Olaf is set at compile time, since it is expected to not change in between runs. The default configuration is defined in the function olaf_config_default() in olaf_config.h. A different set of default configuration parameters is available for the memory version, ESP32 version (e.g. olaf_config_esp_32()) and the WebAssembly version.