非均匀分区卷积实现

信息处理 声音的 卷积 音频处理 即时的 C
2022-02-14 15:46:31

我已经成功实现了统一分区的卷积算法,现在我正在寻找实现非统一分区的版本。我在 JACK 音频连接套件上运行并行线程没有运气,所以我现在正在尝试单线程实现。比较明显的解决方案是创建两个输入缓冲区以在不同频率下工作(例如,一个每 128 个样本运行一次,另一个每 1024 个样本运行一次),但这意味着当两个缓冲区都运行时,处理器负载将达到峰值。填补了。此处描述了此问题(第 162 页)。

我们将如何在单线程进程中调度子卷积以使 DSP 负载保持恒定?这是我用于 UPOL 卷积的起始代码。它为我提供了大约 10% 的 DSP 负载,2048 个采样长的 IR 以 48000hz 的采样率,所以我无法用它运行 2 秒长的 IR。任何帮助(即使它只是优化 UPOL 代码)将不胜感激。

int jack_callback (jack_nframes_t nframes, void *arg){
jack_default_audio_sample_t *in, *out;
int i, j, k;

in = (jack_default_audio_sample_t *)jack_port_get_buffer (input_port, nframes);
out = (jack_default_audio_sample_t *)jack_port_get_buffer (output_port, nframes);

for (i = 0; i < nframes; i++){
        // nframes come in and are then saved in the right part of the input buffer
        buffer[nframes + i] = in[i];
        i_time[i] = buffer[i];
        i_time[nframes+i] = buffer[nframes+i];
}

// take the FFT of the input:
fftw_execute(i_forward);

// circular shift of the frequency delay line:
for (i = 0; i < two_nframes; i++){
        for (k = partitions - 1; k > 0; k--){
                fdl[k][i] = fdl[k-1][i];
        }
}

// write the most recent FFT to the first slot of the FDL,
// reset o_fft to zero to erase the previous calculations
for (i = 0; i < two_nframes; i++){
        fdl[0][i] = i_fft[i];
        o_fft[i] = 0.0 + I*0.0;
}

// multiply-add the frequency domain line (fdl) with
// the frequency domain ir partitions (fir)
for (i = 0; i < two_nframes; i++){
        for (k = 0; k < partitions; k++){
                o_fft[i] += fdl[k][i] * fir[k][i];
        }
}

// take the ifft.
fftw_execute(o_inverse);

// output the right half of the ifft, discard the rest.
for (i = 0; i < nframes; i++){
        out[i] = vol*creal(o_time[nframes+i])/two_nframes;

        // shift the input buffer to the left.
        buffer[i] = in[i];
}
return 0;

}

2个回答

对于非均匀分区卷积,我认为不可能使 CPU 负载保持恒定,但可以实现更有利的时序依赖性。

Wefers的第 6.5 节演示了一种优化方法来找到最佳过滤器分区。它基于最小负载分区并引入了一些限制以平滑 CPU 负载分布。本质上,这是为了避免分区彼此时间对齐。

与最小负载分区相比,最优分区的每个样本成本略高,但负载分布更实际。

最优滤波器分区与脉冲响应的长度、块大小和每个操作的计算成本有关。因此,您需要测试 FFT、IFFT、复数和实数乘法的每个样本的计算成本,并添加到您的目标平台上,您可能会从作者那里得到不同的结果。

这真是一个难以破解的难题。如果是单线程,则对于每个输出样本,您将添加多个并行运行的 FIR 滤波器的结果。一些 FIR 滤波器用于较短的脉冲响应和较短的缓冲区。输出样本时,您必须检查每个过滤器以查看它是否有工作要做。你先做较短的 FIR。完成较短的 FIR 后,您必须检查下一个长度的 FIR 是否有工作要做。