我正在尝试制作一个鼓声,当在不同的速度下循环时必须发出完全相同的声音。下面的实现在每秒重复一次时听起来完全一样,但是对我来说听起来像每隔一秒钟播放时其他每次踢球都有更高的音高。这就像有一个剪辑声音或其他东西。
var context = new AudioContext();
function playKick(when) {
var oscillator = context.createOscillator();
var gain = context.createGain();
oscillator.connect(gain);
gain.connect(context.destination);
oscillator.frequency.setValueAtTime(150, when);
gain.gain.setValueAtTime(1, when);
oscillator.frequency.exponentialRampToValueAtTime(0.001, when + 0.5);
gain.gain.exponentialRampToValueAtTime(0.001, when + 0.5);
oscillator.start(when);
oscillator.stop(when + 0.5);
}
for (var i = 0; i < 16; i++) {
playKick(i * 0.5); // Sounds fine with multiplier set to 1
}
这是JSFiddle上的相同代码:https://jsfiddle.net/1kLn26p4/3/
答案 0 :(得分:1)
不正确; oscillator.start将从0开始阶段。问题是你正在启动&#34;当&#34;参数为零;你应该在context.currentTime上启动它。
for (var i = 0; i < 16; i++) {
playKick(context.current time + i * 0.5); // Sounds fine with multiplier set to 1
}
答案 1 :(得分:0)
振荡器设置为从默认频率440 Hz更改为150 Hz的同时启动。有时这会导致故障,因为转换暂时可以听到。
可以通过在创建时将振荡器节点的频率设置为150 Hz来防止毛刺。所以添加:
oscillator.frequency.value = 150;
如果你想出于好奇而使故障更加明显,请尝试:
oscillator.frequency.value = 5000;
你应该能够听到正在发生的事情。
修改强>
此外,同样的问题是与斜坡的时间相互作用。您可以通过确保在播放开始后短时间内setValueAtTime
事件始终发生来进一步改善声音:
oscillator.frequency.setValueAtTime(3500, when + 0.001);
同样,在3500赫兹不完美,但这是一个改进,我不确定你会通过网络音频实现声音完美。您可以做的最好的事情是尝试掩盖这些故障,直到实现改进。在实际的底鼓频率(例如原始Q中的150 Hz)中,我无法分辨连续声音之间的任何差异。希望这很好。