[英]Implementing a digital delay line in C
我正在尝试在 C 中实现数字延迟线,它将时间序列延迟 integer 数字。 背景是音频信号处理,当采样率为 44100 Hz 时,我想添加一些延迟,大约为 10 ms,即 441 个样本。 输入音频 stream 是逐块发送给我的,所以我希望 output 的信号大小相同。 块大小通常为 1024 个样本或类似的东西。
我有一个指针*data
,它是长度blockSize
的时间序列,以及一个长度为N
的指针*buffer
,用于保存延迟的N
个样本以供下一个块使用。 这里我们可以假设blockSize
> N
。
如果data
的长度为blockSize + N
,我知道如何实现它:首先将最后N
个样本复制到data
的开头,然后从data + N
写入样本:
memcpy(data, data + blockSize, N * sizeof(*data));
write_data(data + N, blockSize);
read_data(data + N, blockSize);
但我不知道如何处理data
和buffer
,两个没有连续 memory 地址的指针。
如果我有长度为blockSize
的data
和长度为2 * N
的buffer
,我可以写如下内容:
void delayline(int *data, int *buffer, unsigned blockSize, unsigned N)
{
memcpy(buffer + N, data + blockSize - N, N * sizeof(*data)); // copy the last N samples of data to the second half of buffer
memmove(data + N, data, (blockSize - N) * sizeof(*data)); // delay the remaining blockSize - N samples by N
memcpy(buffer, data, N * sizeof(*data)); // copy the first half of buffer to data, these samples are from the previous block
memcpy(buffer + N, buffer, N * sizeof(*data)); // copy the second half of buffer to the first half for the use of next block
}
但是如果buffer
只有N
的长度,我不知道该怎么做。 可能吗? 先感谢您!
这是我关于如何制作延迟线的初步想法。
#include <stdio.h>
#define DELAY_SIZE 5
int delay_data[DELAY_SIZE];
int delay_data_index = 0;
// The output of this function is equal to the input
// that was passed to it 5 iterations ago.
// (The first five outputs are fixed to 0.)
int delay(int x)
{
int r = delay_data[delay_data_index];
delay_data[delay_data_index] = x;
delay_data_index++;
if (delay_data_index >= DELAY_SIZE) { delay_data_index = 0; }
return r;
}
void out(int x) {
printf("%d\n", x);
}
int main() {
out(delay(1)); // 0
out(delay(2)); // 0
out(delay(3)); // 0
out(delay(4)); // 0
out(delay(5)); // 0
out(delay(6)); // 1
out(delay(7)); // 2
out(delay(8)); // 3
out(delay(9)); // 4
out(delay(10)); // 5
out(delay(11)); // 6
out(delay(12)); // 7
}
它肯定不会是最有效的事情,因为它一次移动一个int
,但您应该能够将其用作起点,然后在需要时对其进行优化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.