【发布时间】:2012-10-20 14:58:26
【问题描述】:
编辑:稍微清理了代码和播放器(在 Github 上),以便更容易设置频率
我是使用Karplus Strong string synthesis 算法的trying to synthesize 字符串,但我无法正确调整字符串。有人有什么主意吗?
如上链接,代码在 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 上,实际上在低通和输出之间有一个增益节点,但这并不会真正对输出产生太大影响。
【问题讨论】:
-
我只是在摆弄这个,我真的不知道我在做什么。但是尝试将频率设置为 241。在我的 Mac 上会产生一些奇怪的噪音。也许这告诉你一些事情?你似乎更精通数学和理论。 :)
-
嗯,这很有趣。老实说,除了一门EE课程外,我对理论也不太熟悉,大部分都是拼凑和四处询问。不过,感谢您的帮助,如果我再四处寻找,这可能会提供一些见解。
-
这可能不是问题,因为我认为 Lowpass 是默认设置,但您可能应该在代码中明确设置过滤器类型...类似于
lowpassFilter.type = lowpassFilter.LOWPASS。 -
这可能会使代码更加明确。我会更新的。 (不幸的是,它并没有解决问题......,谢谢)
-
这真是令人费解。起初我以为 Web Audio 延迟节点可能无法处理如此低的延迟时间,但如果是这样的话,应该有一个更高的水平,其中音高不再增加,但似乎并非如此。另一个奇怪的事情是音高在八度音阶上也不一致。 220、440 和 880 的音高在不同的八度音阶中不会产生相同的音符。这使我认为某处的计算可能有错误,但我看不到在哪里。
标签: javascript audio html5-audio web-audio-api