soxr icon indicating copy to clipboard operation
soxr copied to clipboard

Non-deterministic output

Open AllianceDarkSylinc opened this issue 2 years ago • 2 comments

Each run of soxr will produce different results.

In certain contexts this can be undesirable.

We stumbled on this problem today.

As far as I could research on the Internet, this problem has been brought up at least twice:

The Stack Overflow narrowed down the problem to the SOXR_NO_DITHER flag, as it indeed uses a seed that depends on time() and the random address of a variable:

p->seed = (unsigned long)time(0) ^ (unsigned long)(size_t)p;

The solution is obvious & straightforward: Allow to provide the seed externally, instead of setting it to a different value on each run:

void soxr_setseed(soxr_t resampler, soxr_seed_t new_seed)
{  
    resampler->seed = new_seed;
}

soxr_seed_t soxr_getseed(soxr_t resampler)
{  
    return resampler->seed;
}

AllianceDarkSylinc avatar Oct 21 '22 20:10 AllianceDarkSylinc

If anyone arrives here, as a quick hack I've forked the project so that ffmpeg can generate deterministic outputs.

Works on macOS & Linux

AllianceDarkSylinc avatar Oct 22 '22 00:10 AllianceDarkSylinc

The seed value is only used if the soxr output is 16 samples. In that case, some dithering process is applied. This means some noise is added to the signal to somehow mask quantization errors. Hence this is not a bug but a feature.

This being said, using a fixed seed to produce a deterministic result won't harm the result. What is essential is the apparent randomization from sample to sample.

Philippe91 avatar Oct 22 '22 06:10 Philippe91