justinfrankel / WDL

WDL (by Cockos) mirror
http://www.cockos.com/wdl
418 stars 57 forks source link

Resampling from 22050Hz to 44100Hz bug #11

Closed Youlean closed 3 years ago

Youlean commented 4 years ago

Using the current settings:

      resampler.SetMode(true, 4, false);
      resampler.SetFilterParms();
      resampler.SetFeedMode(true);
      resampler.SetRates(22050, 44100);

I am getting huge CPU usage in memmove here: https://github.com/justinfrankel/WDL/blob/f6033fe4590e7b130cc439075658d93ca53dc601/WDL/resample.cpp#L1568

It seems that m_samples_in_rsinbuf always grows and doesn't shrink at all.

Youlean commented 4 years ago

Here is the full test code:

        WDL_Resampler resampler;

    resampler.SetMode(true, 4, false);
    resampler.SetFilterParms();
    resampler.SetFeedMode(true);
    resampler.SetRates(22050, 44100);
    resampler.Reset();

    for (size_t i = 0; i < 44100 * 10; i++)
    {
        double* resamplerInput = NULL;
        int numSamples = resampler.ResamplePrepare(1, 1, &resamplerInput);

        // Set everything to 0
        for (int i = 0; i < numSamples; i++)
        {
            resamplerInput[i] = 0;
        }

        std::vector<double> resamplerOutput(numSamples);

        int outputedSamples = resampler.ResampleOut(&resamplerOutput[0], numSamples, 1, 1);
    }
justinfrankel commented 3 years ago

Hi,

(sorry for the delay) -- the issue here is that you are upsampling by 2:1, so for ever sample you add, you need to get 2 back. Here's what you should be doing:

    WDL_Resampler resampler;

    resampler.SetMode(true, 4, false);
    resampler.SetFilterParms();
    resampler.SetFeedMode(true);
    double src_sr = 22050, dest_sr = 44100;
    resampler.SetRates(src_sr,dest_sr);
    resampler.Reset();

    for (size_t i = 0; i < 44100 * 10; i++)
    {
            double* resamplerInput = NULL;
            int numSamples = resampler.ResamplePrepare(1, 1, &resamplerInput);

            // Set everything to 0
            for (int i = 0; i < numSamples; i++)
            {
                    resamplerInput[i] = 0;
            }

            int max_ret = (int) (numSamples * dest_sr / src_sr + 0.5) + 1;
            std::vector<double> resamplerOutput(max_ret); 

            int outputedSamples = resampler.ResampleOut(&resamplerOutput[0], numSamples, max_ret, 1);
    }      

(obviously, processing in blocks of larger than 1 sample at a time is preferable!).