如何让 OscillatorNode 在 Web Audio 中在 0 和 1 之间振荡?
How do I make an OscillatorNode oscilate between 0 and 1 in Web Audio?
据我了解,振荡器发出的所有波都在 -1 到 1 之间振荡。
我想让它们从0到1振荡,仍然使用正弦波和方波。
为什么?例如,只提高音高的颤音(音高永远不会低于主音符,如吉他颤音)。
在抖音案例中。我最接近的是弹奏两个音符中间的音符并从那里振荡,但音调并不完全正确:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContext();
// notes are semitones from soundFreq
var soundFreq = 440; // a4
var mainNote = 0.0; // a4
var bendNote = 4.0; // c#4 (major third interval)
// nSoundSource is the sound we're playing, on the a4
var nSoundSource = audioContext.createOscillator();
nSoundSource.type = 'triangle';
nSoundSource.frequency.value = soundFreq; // a4
// at 1 second sound plays the note between a4 and c#4: b4
nSoundSource.frequency.setValueAtTime(
intervalToFrequency((mainNote + bendNote) / 2) * soundFreq,
audioContext.currentTime + 1.0
);
// at 3 seconds, sound returns to a4
nSoundSource.frequency.setValueAtTime(
soundFreq,
audioContext.currentTime + 3.0
);
// gain to change the detune of the played sound
var nGainSoundFreq = audioContext.createGain();
// if amplitude is the whole interval (400 cents), the value should be half of that, so in this case 200 cents
nGainSoundFreq.gain.value = ((mainNote + bendNote) / 2) * 100; // 200 cents up and down
// oscillator to make the vibrato on the gain
var nGainSoundFreqOsc = audioContext.createOscillator();
nGainSoundFreqOsc.type = 'square'; // try with sine too
nGainSoundFreqOsc.frequency.value = 3;
nGainSoundFreqOsc.start(audioContext.currentTime + 1.0);
nGainSoundFreqOsc.stop(audioContext.currentTime + 3.0);
// enable vibrato
nGainSoundFreqOsc.connect(nGainSoundFreq);
nGainSoundFreq.connect(nSoundSource.detune);
// play the sound
nSoundSource.connect(audioContext.destination);
nSoundSource.start(audioContext.currentTime);
nSoundSource.stop(audioContext.currentTime + 4.0);
// helper to convert semitones to frequency
function intervalToFrequency(interval) {
return Math.pow(2, interval / 12);
}
我知道我可以使用其他技术来实现颤音,这不是重点。我想知道是否可以让 NodeOscillator 在 0 和 1 之间振荡。
方波振荡器确实从 -1 变为 1,但与您预期的不同,因为它是标准化的。由于带宽限制,在不连续处有一些振铃,因此波的实际 "square" 顶部略低于 1。
您可以向输出添加增益以将其放大一点。最好的解决方案是使用 PeriodicWave 创建您自己的方波,但关闭此归一化。那么方顶会有振幅1,但是部分波浪会超过1。
据我了解,振荡器发出的所有波都在 -1 到 1 之间振荡。
我想让它们从0到1振荡,仍然使用正弦波和方波。
为什么?例如,只提高音高的颤音(音高永远不会低于主音符,如吉他颤音)。
在抖音案例中。我最接近的是弹奏两个音符中间的音符并从那里振荡,但音调并不完全正确:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContext();
// notes are semitones from soundFreq
var soundFreq = 440; // a4
var mainNote = 0.0; // a4
var bendNote = 4.0; // c#4 (major third interval)
// nSoundSource is the sound we're playing, on the a4
var nSoundSource = audioContext.createOscillator();
nSoundSource.type = 'triangle';
nSoundSource.frequency.value = soundFreq; // a4
// at 1 second sound plays the note between a4 and c#4: b4
nSoundSource.frequency.setValueAtTime(
intervalToFrequency((mainNote + bendNote) / 2) * soundFreq,
audioContext.currentTime + 1.0
);
// at 3 seconds, sound returns to a4
nSoundSource.frequency.setValueAtTime(
soundFreq,
audioContext.currentTime + 3.0
);
// gain to change the detune of the played sound
var nGainSoundFreq = audioContext.createGain();
// if amplitude is the whole interval (400 cents), the value should be half of that, so in this case 200 cents
nGainSoundFreq.gain.value = ((mainNote + bendNote) / 2) * 100; // 200 cents up and down
// oscillator to make the vibrato on the gain
var nGainSoundFreqOsc = audioContext.createOscillator();
nGainSoundFreqOsc.type = 'square'; // try with sine too
nGainSoundFreqOsc.frequency.value = 3;
nGainSoundFreqOsc.start(audioContext.currentTime + 1.0);
nGainSoundFreqOsc.stop(audioContext.currentTime + 3.0);
// enable vibrato
nGainSoundFreqOsc.connect(nGainSoundFreq);
nGainSoundFreq.connect(nSoundSource.detune);
// play the sound
nSoundSource.connect(audioContext.destination);
nSoundSource.start(audioContext.currentTime);
nSoundSource.stop(audioContext.currentTime + 4.0);
// helper to convert semitones to frequency
function intervalToFrequency(interval) {
return Math.pow(2, interval / 12);
}
我知道我可以使用其他技术来实现颤音,这不是重点。我想知道是否可以让 NodeOscillator 在 0 和 1 之间振荡。
方波振荡器确实从 -1 变为 1,但与您预期的不同,因为它是标准化的。由于带宽限制,在不连续处有一些振铃,因此波的实际 "square" 顶部略低于 1。
您可以向输出添加增益以将其放大一点。最好的解决方案是使用 PeriodicWave 创建您自己的方波,但关闭此归一化。那么方顶会有振幅1,但是部分波浪会超过1。