breakfastquay / rubberband

Official mirror of Rubber Band Library, an audio time-stretching and pitch-shifting library.
http://breakfastquay.com/rubberband/
GNU General Public License v2.0
566 stars 91 forks source link

ticks while changing pitch scale constantly #35

Closed hagay321 closed 3 years ago

hagay321 commented 3 years ago

Hi to you all, I'm really appreciate your help with this issue, I'm not sure if I doing all as I should cause I saw this issue already solved in, https://github.com/breakfastquay/rubberband/issues/30 https://todo.sr.ht/~breakfastquay/rubberband/6

Vary thanks for your time..

When I'm trying to change the pitchshift (dynamically) constantly there is a lot of ticking along the all output.

What have I done:

  1. downloaded the repo from git.

  2. opened it in visual studio 2015

  3. added libsamplerate from https://github.com/libsndfile/libsamplerate.

    • I took the relevant source files from the repo and added them to the project.
  4. than, in the main.cpp and Resampler.cpp I add

    define HAVE_LIBSAMPLERATE"

    define DUSE_SPEEX

  5. run main.cpp in debug mode with the flags -t 1 -p 5 -R

  6. In the RT loop I change the pitchshift scale in each iteration like you can see in the script below,

Maybe I didn't add libsamplerate properly or I need to configure something else? Please tell me if you need anything to help you help me..

while (frame < sfinfo.frames) {

    int count = -1;

if ((count = sf_readf_float(sndfile, fbuf, ibs)) < 0) break;

    countIn += count;

    for (size_t c = 0; c < channels; ++c) {
        for (int i = 0; i < count; ++i) {
            float value = fbuf[i * channels + c];
            ibuf[c][i] = value;
        }
    }

    // ****************   SET NEW PITCH SCALE - the only change
    new_pitch_scale = ...
    rb.setPitchScale(new_pitch_scale);
    // ****************

    bool final = (frame + ibs >= sfinfo.frames);

    if (debug > 2) {
        cerr << "count = " << count << ", ibs = " << ibs << ", frame = " << frame << ", frames = " << sfinfo.frames << ", final = " << final << endl;
    }

    ts.process(ibuf, count, final);

    int avail = ts.available();
    if (debug > 1) cerr << "available = " << avail << endl;

    if (avail > 0) {
        float **obf = new float *[channels];
        for (size_t i = 0; i < channels; ++i) {
            obf[i] = new float[avail];
        }
        ts.retrieve(obf, avail);
        countOut += avail;
        float *fobf = new float[channels * avail];
        for (size_t c = 0; c < channels; ++c) {
            for (int i = 0; i < avail; ++i) {
                float value = obf[c][i];
                if (value > 1.f) value = 1.f;
                if (value < -1.f) value = -1.f;
                fobf[i * channels + c] = value;
            }
        }

        sf_writef_float(sndfileOut, fobf, avail);
        delete[] fobf;
        for (size_t i = 0; i < channels; ++i) {
            delete[] obf[i];
        }
        delete[] obf;
    }

    if (frame == 0 && !realtime && !quiet) {
        cerr << "Pass 2: Processing..." << endl;
    }

int p = int((double(frame) * 100.0) / sfinfo.frames);
if (p > percent || frame == 0) {
    percent = p;
        if (!quiet) {
            cerr << "\r" << percent << "% ";
        }
}

    frame += ibs;
}

Thank you ! Hagay

cannam commented 3 years ago

One way to tell whether you have successfully defined HAVE_LIBSAMPLERATE is to observe whether the program links successfully without the samplerate library listed in the link libraries. If you define HAVE_LIBSAMPLERATE but don't add samplerate to the set of libraries used when linking, then the compile should succeed but the link should fail. If the link succeeds without this library, then something went wrong!

Once you have the rubberband command line executable built, if you run it with debug enabled (-d 1 flag) it will print out which resampler it's using at the start.

The expected behaviour of the current default branch of Rubber Band when changing pitch during processing is:

The rest assumes realtime mode:

hagay321 commented 3 years ago

Thank you for the answer !! Really appreciate :) !

It took me a while but I realized it in the end. The ticks indeed occurred only in transitions from high pitch to low and vice versa. I truly ended up using libsamplerate and raising the OptionPitchHighConsistency flag and no more tics.

Thank you again.

I have another question if it's ok, I noticed that when I change RubberBandStretcher::Impl::m_defaultFftSize to 8192 (from default 2048) the sound sounds cleaner but accompanied with an echo. Is there another specific variable that I can might change to avoid this echo?

thanks, Hagay

cannam commented 3 years ago

Is there another specific variable that I can might change to avoid this echo?

Not that I can think of offhand.

Longer windows will tend to have this effect - even the OptionWindowLong setting, which creates a smoother mushier sound, only doubles the default fft size to 4096, not 8192. Generally speaking, if I know a combination of parameters works well for something, then it will likely be exposed as an option already - although of course you might still get interesting effects from other changes.