Menu

Glitch at start of each upsample buffer when streaming

2020-12-14
2020-12-16
  • Glenn Newell

    Glenn Newell - 2020-12-14

    I'm getting a little "glitch" or "pop" at the start of each buffer when upsampling and streaming, using code similar to example 2.

    https://drive.google.com/file/d/1DhNIO6c50qhG-cEYvRGFjrpojy9iJsx3/view?usp=sharing

    https://drive.google.com/file/d/12GyS9hpyTjeTK5wmc9x7drNds4avFSTH/view?usp=sharing

    How can I avoid this?

    void sox_upsample(float * input_sample_buff, float * upsample_buff,sf_count_t insize) {
    
    
        size_t ilen = (size_t)(insize / 2); // insize is the interleaved stereo count of samples read
    
        size_t olen = (size_t)(insize / 2 * (double)process_srate / (double)input_srate + .5);
        size_t odone;
        unsigned long const q_recipe = SOXR_VHQ;
        unsigned long const q_flags = SOXR_LINEAR_PHASE;
        soxr_quality_spec_t       q_spec = soxr_quality_spec(q_recipe, q_flags);
        soxr_error_t error = soxr_oneshot(input_srate, process_srate, 1, /* Rates and # of chans. */
            input_sample_buff, ilen, NULL,                              /* Input. */
            upsample_buff, olen, &odone,                             /* Output. */
            NULL, &q_spec, NULL);
        printf("\n\t\t\t\tUpSample by %ldx to %ld SRate Status: %s Samples In: %lu Samples Out: %lu", oversample, process_srate, soxr_strerror(error), ilen, olen); /* and reported result. */
    
    }
    

    I have tried all the different qualities/recipes.

     
  • Glenn Newell

    Glenn Newell - 2020-12-16

    Well for those that come after...

    I believe this occurs because the resampler sees the buffer edges as discontinuities in the audio data. E.g. the first sample in the buffer is seen as having an infinite rise time from the "previous" sample, which causes and overshoot and high frequency ringing in the upsampled audio.

    So, I fixed the problem by making the buffer 100 samples larger than needed, and filling the first 50 buffer locations with a copy of the first sample, and the last 50 locations with a copy of the last sample.

    Then I loaded the audio data into the buffer with a 50 sample offset.

    When consuming the up sampled result, I used a 50 * oversampleratio offset, and the length of the original audio in samples * oversampleratio.

     

Log in to post a comment.