我已经成功实现了统一分区的卷积算法,现在我正在寻找实现非统一分区的版本。我在 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;
}