创建具有长周期波的定制振荡器

时间:2017-09-20 10:03:57

标签: javascript web-audio waveform

我试图长时间创造复杂的周期性声音。我想尽可能准确地定义频率,所以我使用步骤sampleRate*0.5/tableLen。但是我对大型波表有一些问题。声音失真并失去高频。

以下是~440 Hz正弦波的最小示例。当我使用长度为8192的表时,产生的正弦波非常容易识别:

https://jsfiddle.net/zxqzntf0/

var gAudioCtx = new AudioContext();
var osc = gAudioCtx.createOscillator();
var tableSize = 8192;
var real = new Float32Array(tableSize);
var imag = new Float32Array(tableSize);
var freq = 440;
var step = gAudioCtx.sampleRate*0.5/tableSize;
real[Math.floor(freq/step)] = 1;
var wave = gAudioCtx.createPeriodicWave(real, imag, {disableNormalization: true});
osc.frequency.value = step;
osc.setPeriodicWave(wave);
osc.connect(gAudioCtx.destination);
osc.start();

但是当我增加桌子大小时,我会发现一些奇怪的东西。结果根本不是正弦波!

https://jsfiddle.net/0cc75nnm/

此问题在所有浏览器(Chrome,Firefox,Edge)中都会重现,因此它似乎不是一个浏览器错误。但我在文档中没有发现任何相关内容。

我发现如果振荡器频率是一个整数> = 2 Hz,我在表格大小为16384的声音中没有任何伪影。我认为现在我的需求是完全可以接受的。但是有一天我可能想要创造更长的时期。如果有人解释我为什么当步长小于2赫兹时会出现声音伪影,我会接受他的回答。

我在JavaScript中生成了一个复杂的声音旋律示例: https://jsfiddle.net/h9rfzrnL/1/

1 个答案:

答案 0 :(得分:2)

您错误地创建了周期性波浪。在填充周期波的阵列时,假设采样率为1.然后,如果您想要一个频率为440 Hz的振荡器,请将振荡器频率设置为440 Hz。

因此,对于正弦波,实数组应为全零,虚数组为[0,1]。 (你实际上正在创造一个余弦波,但这并不重要。)