libsoxr确定性抖动

问题描述

我对某些单元测试代码有疑问,每次执行都会给它们不同的结果。 我将其追溯到libsoxr(0.1.3),发现其取决于抖动选项:

也就是说,如果使用以下命令调用soxr_create()

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

soxr_process()的输出是确定性的。 但是,如果不添加SOXR_NO_DITHER标志,则每次执行的输出都会略有不同。

关于图书馆的另一件事使我感到惊讶。 soxr_oneshot()不受此问题(不确定性)的困扰。

这是怎么回事?

解决方法

查看代码,我发现在soxr.c中,抖动使用了伪随机数生成器 但是种子是从以下时间生成的实现细节:

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

该库似乎没有公开它,因此可以防止您设置特定的种子,否则每次运行测试都可以获得相同的结果。

我建议对API进行一些次要的改进,如下所示, 尽管对图书馆有更多了解的人也许可以提出更好的方法。

Soxr.h中添加:

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

Soxr.c中添加:

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

关于图书馆的一件事仍然令我惊讶的是 soxr_oneshot()不受此问题(非确定性)的困扰。 我看不到种子如何固定或通过内部调用SOXR_NO_DITHER设置的soxr_create()

我显然在这里错过了一些对图书馆有更多了解的人可以解释的东西。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...