Add asymmetry parameter

This commit is contained in:
Geraint 2025-08-11 17:30:09 +01:00
parent 90d6c686eb
commit 103513b186
4 changed files with 20 additions and 18 deletions

View File

@ -7,7 +7,7 @@ include(FetchContent)
FetchContent_Declare( FetchContent_Declare(
signalsmith-linear signalsmith-linear
GIT_REPOSITORY https://github.com/Signalsmith-Audio/linear.git GIT_REPOSITORY https://github.com/Signalsmith-Audio/linear.git
GIT_TAG 0.2.3 GIT_TAG 0.2.4
GIT_SHALLOW ON GIT_SHALLOW ON
) )
FetchContent_MakeAvailable(signalsmith-linear) FetchContent_MakeAvailable(signalsmith-linear)

View File

@ -11,19 +11,19 @@ out/stretch: main.cpp ../signalsmith-stretch.h util/*.h util/*.hxx
# Uses input files from: https://signalsmith-audio.co.uk/code/stretch/inputs.zip # Uses input files from: https://signalsmith-audio.co.uk/code/stretch/inputs.zip
examples: out/stretch examples: out/stretch
mkdir -p out/examples mkdir -p out/examples
inputs/run-all.sh out/examples/u2- out/stretch --semitones=2 inputs/run-all.sh out/examples/u2- out/stretch --semitones=2 --asymmetry=0.5
inputs/run-all.sh out/examples/d2- out/stretch --semitones=-2 inputs/run-all.sh out/examples/d2- out/stretch --semitones=-2 --asymmetry=0.5
inputs/run-all.sh out/examples/u4- out/stretch --semitones=4 inputs/run-all.sh out/examples/u4- out/stretch --semitones=4 --asymmetry=0.5
inputs/run-all.sh out/examples/d4- out/stretch --semitones=-4 inputs/run-all.sh out/examples/d4- out/stretch --semitones=-4 --asymmetry=0.5
inputs/run-all.sh out/examples/u8- out/stretch --semitones=8 inputs/run-all.sh out/examples/u8- out/stretch --semitones=8 --asymmetry=0.5
inputs/run-all.sh out/examples/d8- out/stretch --semitones=-8 inputs/run-all.sh out/examples/d8- out/stretch --semitones=-8 --asymmetry=0.5
inputs/run-all.sh out/examples/u16- out/stretch --semitones=16 inputs/run-all.sh out/examples/u16- out/stretch --semitones=16 --asymmetry=0.5
inputs/run-all.sh out/examples/d16- out/stretch --semitones=-16 inputs/run-all.sh out/examples/d16- out/stretch --semitones=-16 --asymmetry=0.5
inputs/run-all.sh out/examples/t_8- out/stretch --time=0.8 inputs/run-all.sh out/examples/t_8- out/stretch --time=0.8 --asymmetry=0.5
inputs/run-all.sh out/examples/t1_2- out/stretch --time=1.2 inputs/run-all.sh out/examples/t1_2- out/stretch --time=1.2 --asymmetry=0.5
inputs/run-all.sh out/examples/t1_5- out/stretch --time=1.5 inputs/run-all.sh out/examples/t1_5- out/stretch --time=1.5 --asymmetry=0.5
inputs/run-all.sh out/examples/t2- out/stretch --time=2 inputs/run-all.sh out/examples/t2- out/stretch --time=2 --asymmetry=0.5
inputs/run-all.sh out/examples/t4- out/stretch --time=4 inputs/run-all.sh out/examples/t4- out/stretch --time=4 --asymmetry=0.5
TEST_WAV ?= "inputs/voice.wav" TEST_WAV ?= "inputs/voice.wav"

View File

@ -19,12 +19,13 @@ int main(int argc, char* argv[]) {
std::string inputWav = args.arg<std::string>("input.wav", "16-bit WAV file"); std::string inputWav = args.arg<std::string>("input.wav", "16-bit WAV file");
std::string outputWav = args.arg<std::string>("output.wav", "output WAV file"); std::string outputWav = args.arg<std::string>("output.wav", "output WAV file");
double time = args.flag<double>("time", "time-stretch factor", 1);
double semitones = args.flag<double>("semitones", "pitch-shift amount", 0); double semitones = args.flag<double>("semitones", "pitch-shift amount", 0);
double formants = args.flag<double>("formant", "formant-shift amount (semitones)", 0); double formants = args.flag<double>("formant", "formant-shift amount (semitones)", 0);
bool formantComp = args.hasFlag("formant-comp", "formant compensation"); bool formantComp = args.hasFlag("formant-comp", "formant compensation");
double formantBase = args.flag<double>("formant-base", "formant base frequency (Hz, 0=auto)", 100); double formantBase = args.flag<double>("formant-base", "formant base frequency (Hz, 0=auto)", 100);
double tonality = args.flag<double>("tonality", "tonality limit (Hz)", 8000); double tonality = args.flag<double>("tonality", "tonality limit (Hz)", 8000);
double time = args.flag<double>("time", "time-stretch factor", 1); double asymmetry = args.flag<double>("asymmetry", "asymmetrical STFT analysis (0-1)", 0);
bool splitComputation = args.hasFlag("split-computation", "distributes the computation more evenly (but higher latency)"); bool splitComputation = args.hasFlag("split-computation", "distributes the computation more evenly (but higher latency)");
args.errorExit(); // exits on error, or with `--help` args.errorExit(); // exits on error, or with `--help`
@ -42,7 +43,7 @@ int main(int argc, char* argv[]) {
outWav.resize(outputLength); outWav.resize(outputLength);
SignalsmithStretch stretch; SignalsmithStretch stretch;
stretch.presetDefault(int(inWav.channels), inWav.sampleRate, splitComputation); stretch.configure(int(inWav.channels), inWav.sampleRate*0.12, inWav.sampleRate*0.03, splitComputation, asymmetry);
stretch.setTransposeSemitones(semitones, tonality/inWav.sampleRate); stretch.setTransposeSemitones(semitones, tonality/inWav.sampleRate);
stretch.setFormantSemitones(formants, formantComp); stretch.setFormantSemitones(formants, formantComp);
stretch.setFormantBase(formantBase/inWav.sampleRate); stretch.setFormantBase(formantBase/inWav.sampleRate);

View File

@ -68,11 +68,12 @@ struct SignalsmithStretch {
} }
// Manual setup // Manual setup
void configure(int nChannels, int blockSamples, int intervalSamples, bool splitComputation=false) { void configure(int nChannels, int blockSamples, int intervalSamples, bool splitComputation=false, Sample asymmetry=0) {
_splitComputation = splitComputation; _splitComputation = splitComputation;
channels = nChannels; channels = nChannels;
asymmetry *= 1 - 2.0*intervalSamples/blockSamples; // maximum asymmetry gives latency of two intervals
stft.configure(channels, channels, blockSamples, intervalSamples + 1); stft.configure(channels, channels, blockSamples, intervalSamples + 1);
stft.setInterval(intervalSamples, stft.kaiser); stft.setInterval(intervalSamples, stft.kaiser, asymmetry);
stft.reset(0.1); stft.reset(0.1);
stashedInput = stft.input; stashedInput = stft.input;
stashedOutput = stft.output; stashedOutput = stft.output;