From c6db62ca6ef5b7e65b5e9702b0b47e4333bbd364 Mon Sep 17 00:00:00 2001 From: Geraint Date: Fri, 25 Nov 2022 14:17:40 +0000 Subject: [PATCH] Add license/readme --- LICENSE.txt | 21 +++++++++++ README.md | 86 +++++++++++++++++++++++++++++++++++++++++++ signalsmith-stretch.h | 4 +- 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 LICENSE.txt create mode 100644 README.md diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..889031e --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Geraint Luff / Signalsmith Audio Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ec84bd --- /dev/null +++ b/README.md @@ -0,0 +1,86 @@ +# Signalsmith Stretch: pitch/time library + +This is a C++11 library for pitch and time stretching, using the final approach from the ADC22 presentation _Four Ways To Write A Pitch-Shifter_. + +## How to use it + + +```cpp +#include "signalsmith-stretch.h" + +signalsmith::stretch::SignalsmithStretch stretch; +``` + +### Configuring + +The easiest way to configure is `.presetDefault()`: + +```cpp +stretch.presetDefault(channels, sampleRate); +``` + +If you want to test out different block-sizes etc. then you can use `.configure()` manually, and even change `.freqWeight`/`.timeWeight`/`.channelWeight`. + +### Processing (and resetting) + +```cpp +// Clears internal buffers +stretch.reset(); + +float **inputBuffers, **outputBuffers; +int inputSamples, outputSamples; +stretch.process(inputBuffers, inputSamples, outputBuffers, outputSamples); + +// Inspect latency +int totalLatency = stretch.inputLatency() + stretch.outputLatency(); +``` + +The `.process()` method takes anything where `buffer[channel][index]` gives you a sample. This could be a `float **` or a `double **` or some custom object. + +To get a time-stretch, just hand it differently-sized input/output buffers. + +### Pitch-shifting + +```cpp +stretch.setTransposeFactor(2); // up one octave + +stretch.setTransposeSemitones(12); // also one octave +``` + +You can set a "tonality limit", which uses a non-linear frequency map to preserve a bit more of the timbre: + +```cpp +stretch.setTransposeSemitones(4, 8000/sampleRate); +``` + +### Custom pitch map + +This stretcher does (fairly rough) peak-detection, and creates a non-linear frequency map based on that. + +You can hook into this to define your own pitch-map, by providing a callback which is called once per channel, for every FFT block: + +```cpp +stretch.setMap([&](int channel) { + for (auto &peak : stretch.peaks) { + peak.output = peak.input*2; // up one octave + } +}); +``` + +The input/output frequencies are relative to Nyquist. It's not currently-tested what happens if your map is non-monotonic. + +## Compiling + +Just include `signalsmith-stretch.h` in your build. + +It's pretty slow if optimisation is disabled though, so you might want to enable optimisation just where it's used. + +### DSP Library + +This uses the Signalsmith DSP library for FFTs and other bits and bobs. + +For convenience, a copy of the license is included (with its own `LICENSE.txt`) in `dsp/`, but if you're already using this elsewhere then you should remove this copy to avoid versioning issues. + +## License + +[MIT License](LICENSE.txt) for now - get in touch if you need anything else. diff --git a/signalsmith-stretch.h b/signalsmith-stretch.h index 6f4b3f1..12242a7 100644 --- a/signalsmith-stretch.h +++ b/signalsmith-stretch.h @@ -19,10 +19,10 @@ struct SignalsmithStretch { int intervalSamples() const { return stft.interval(); } - int inputLatencySamples() const { + int inputLatency() const { return stft.windowSize()/2; } - int outputLatencySamples() const { + int outputLatency() const { return stft.windowSize() - inputLatencySamples(); }