This repository contains a C++ library for computing harmonic-percussive source separation. The library intends to provide fast and high-quality separation, while also remaining suitable for real-time use-cases.
The library exports a single static library (hpss) as a CMake target.
add_subdirectory(hpss-cpp)
target_link_libraries(MyCoolProject PRIVATE hpss)After initializing a processor, you may process your signal
by repeatedly calling hpss::process_hop().
#include <hpss/hpss.cpp>
// Set up parameters
const hpss::Params params {
.window_size = 1 << 12,
.hop_factor = 2,
.zero_pad = 2,
.mask_power = 2,
};
// Initialize an HPSS processor
auto processor = hpss::init (params);
// Process one "hop" of audio data
const auto [harmonic_out, percussive_out] = hpss::process_hop (processor, hop);
// De-initialize the processor
hpss::deinit (processor);Most of the "intermediate" steps of the algorithm are exposed as their own standalone methods. These can be called independently, which is useful in some cases.
For example, in real-time processing, the audio device buffer size may be smaller than the hop size used by the HPSS algorithm. When using the Simple API, the user would have wait until enough buffers have accumulated to process a single "hop", at which point the entire algorithm would run. In this scenario, the entire algorithm would need to be fast enough to meet the real-time deadline determined by the device buffer size.
With the Complete API, the work being done by the algorithm can be split up into multiple steps. This allows an implementation where a little bit of work is done with each incoming buffer, while waiting for the next hop to accumulate, thereby reducing the worst-case computation time for any one buffer.
Please review the implementation of hpss::process_window() to
see how the individual methods of the Complete API should be used.
- Configure and compile the test program
$ cmake -Bbuild -G<generator> -DHPSS_BUILD_TESTS=ON
$ cmake --build build --target hpss_test --parallel- Run the test program
$ .build/.../hpss_test audio_file.wav <num_seconds> <start_trim_seconds>The test program will generate 4 files:
- ref.wav: A trimmed copy of the input file.
- harmonic.wav: Just the harmonic part of the signal.
- percussive.wav: Just the percussive part of the signal.
- sum.wav: The sum of the harmonic and percussive signals.
The main algorithm being implemented is based on Derry Fitzgerald's paper from DAFx10 "Harmonic/Percussive Separation Using Median Filtering".
The median filtering algorithm implemented in this library is inspired by https://ideone.com/8VVEa (MIT license).
The FFT is computed using chowdsp_fft.
- Currently the slowest part of the algorithm is the median computation. There's probably some ways that we can improve on it.
- It would be nice to either support more FFT backends (FFTW, Accelerate, etc), or allow the user to provide their own FFT backend.
- I've experimented with some SIMD optimizations, but have abandoned them for now, as I was not seeing a measurable performance improvement. However, it would be nice to take another shot at some point!
hpss-cpp is published under the BSD 3-clause license.