编辑:稍微清理了代码和播放器(在 Github 上),以便更容易设置频率
我正在尝试使用Karplus Strong 字符串合成算法来合成字符串,但我无法正确调整字符串。有谁有想法吗?
如上链接,代码在 Github:https ://github.com/achalddave/Audio-API-Frequency-Generator (相关位在 中strings.js
)。
Wiki 有以下图表:
所以本质上,我产生了噪声,然后将其输出并同时发送到延迟滤波器。延迟滤波器连接到低通滤波器,然后与输出混合。根据维基百科,延迟应该是 N 个样本,其中 N 是采样频率除以基频 ( N = f_s/f_0
)。
我的代码摘录:
产生噪音(bufferSize
是 2048,但这不应该太重要)
var buffer = context.createBuffer(1, bufferSize, context.sampleRate);
var bufferSource = context.createBufferSource();
bufferSource.buffer = buffer;
var bufferData = buffer.getChannelData(0);
for (var i = 0; i < delaySamples+1; i++) {
bufferData[i] = 2*(Math.random()-0.5); // random noise from -1 to 1
}
创建延迟节点
var delayNode = context.createDelayNode();
我们需要延迟f_s/f_0
样品。但是,延迟节点以秒为单位获取延迟,因此我们需要将其除以每秒样本数,我们得到(f_s/f_0) / f_s
,即1/f_0
。
var delaySeconds = 1/(frequency);
delayNode.delayTime.value = delaySeconds;
创建低通滤波器(据我所知,截止频率不应该影响频率,更多的是字符串“听起来”是否自然):
var lowpassFilter = context.createBiquadFilter();
lowpassFilter.type = lowpassFilter.LOWPASS; // explicitly set type
lowpassFilter.frequency.value = 20000; // make things sound better
将噪声连接到输出和延迟节点(destination = context.destination
之前已定义):
bufferSource.connect(destination);
bufferSource.connect(delayNode);
将延迟连接到低通滤波器:
delayNode.connect(lowpassFilter);
将低通连接到输出并返回延迟*:
lowpassFilter.connect(destination);
lowpassFilter.connect(delayNode);
有没有人有任何想法?我不知道问题是我的代码、我对算法的解释、我对 API 的理解,还是(尽管这不太可能)是 API 本身的问题。
*请注意,在 Github 上,实际上在低通和输出之间有一个增益节点,但这对输出并没有太大的影响。