Search code examples
variablesaudiorateresampling

Unwanted click when using SoXR Library to do variable rate resampling


I am using the SoXR library's variable rate feature to dynamically change the sampling rate of an audio stream in real time. Unfortunately I have have noticed that an unwanted clicking noise is present when changing the rate from 1.0 to a larger value (ex: 1.01) when testing with a sine wave. I have not noticed any unwanted artifacts when changing from a value larger than 1.0 to 1.0. I looked at the wave form it was producing and it appeared as if a few samples right at rate change are transposed incorrectly.

Here's a picture of an example of a stereo 440Hz sinewave stored using signed 16bit interleaved samples:

https://i.sstatic.net/WqJgd.png

I also was unable to find any documentation covering the variable rate feature beyond the fifth code example. Here's is my initialization code:

bool DynamicRateAudioFrameQueue::intialize(uint32_t sampleRate, uint32_t numChannels)
{
    mSampleRate = sampleRate;
    mNumChannels = numChannels;
    mRate = 1.0;
    mGlideTimeInMs = 0;

    // Intialize buffer
    size_t intialBufferSize = 100 * sampleRate * numChannels / 1000; // 100 ms
    pFifoSampleBuffer = new FiFoBuffer<int16_t>(intialBufferSize);

    soxr_error_t error;

    // Use signed int16 with interleaved channels
    soxr_io_spec_t ioSpec = soxr_io_spec(SOXR_INT16_I, SOXR_INT16_I);

    // "When creating a var-rate resampler, q_spec must be set as follows:" - example code
    // Using SOXR_VR makes sense, but I'm not sure if the quality can be altered when using var-rate
    soxr_quality_spec_t qualitySpec = soxr_quality_spec(SOXR_HQ, SOXR_VR);


    // Using the var-rate io-spec is undocumented beyond a single code example which states
    // "The ratio of the given input rate and ouput rates must equate to the
    // maximum I/O ratio that will be used: "
    // My tests show this is not true
    double inRate = 1.0;
    double outRate = 1.0;

    mSoxrHandle = soxr_create(inRate, outRate, mNumChannels, &error, &ioSpec, &qualitySpec, NULL);

    if (error == 0) // soxr_error_t == 0; no error
    {
        mIntialized = true;
        return true;
    }
    else 
    {
        return false;
    }

}

Any idea what may be causing this to happen? Or have a suggestion for an alternative library that is capable of variable rate audio resampling in real time?


Solution

  • After speaking with the developer of the SoXR library I was able to resolve this issue by adjusting the maximum ratio parameters in the soxr_create method call. The developer's response can be found here.