deterministic dithering with libsoxr

184 views Asked by At

I have an issue with some unit test code which is giving different results for every execution. I tracked it back to libsoxr (0.1.3) and discovered that is its down to the dithering option:

That is, if soxr_create() is invoked with:

 soxr_io_spec_t soxIoSpec = soxr_io_spec(SOXR_INT16_I, SOXR_INT16_I);
 sxIoSpec.flags |= SOXR_NO_DITHER;

The output of soxr_process() is deterministic. But without adding the SOXR_NO_DITHER flag the output is slightly different for each execution.

There is another thing about the library which surprises me here. soxr_oneshot() does not suffer from this problem (the non-determinism).

What is going on here?

1

There are 1 answers

0
Bruce Adams On

Looking into the code I see that in soxr.c the dither uses a pseudo random number generator but the seed is an implementation detail generated from the time by:

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

It does not seem to be exposed by the library thus preventing you from setting a particular seed which you could otherwise do tog et the same result each time the test is run.

I have suggested a minor enhanced to the API like the below to facilitate this, though someone with more knowledge of the library may be able to suggest a better way.

In Soxr.h add:

typedef unsigned long soxr_seed_t;

// set or retrieve the random seed used by the dithering function
void soxr_setseed(soxr_t resampler, soxr_seed_t new_seed);
soxr_seed_t soxr_getseed(soxr_t* resampler);

In Soxr.c add:

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;
}

One thing about the library which still surprises me here is that soxr_oneshot() does not suffer from this problem (the non-determinism). I can’t see how the seed is fixed or SOXR_NO_DITHER set by the internal call to soxr_create().

I have obviously missed something here which someone with more knowledge of the library may be able to explain.