找到你要的答案

Q:How do I make an OscillatorNode oscilate between 0 and 1 in Web Audio?

Q:我如何使Web Audio 0和1之间的oscillatornode作振荡?

To my understanding, all waves from the oscillator oscillate from -1 to 1.

I want to make them oscillate from 0 to 1, still using sine and square waves.

Why? for example a vibrato that only pitches up (pitch never goes below the main note, like a guitar vibrato).

In the vibrato case. the closest thing I got to was to play the note in the middle of the two notes and oscillate from there, but the tones aren't exactly right:

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);
}

I know I can achieve the vibrato using other techniques, that's not the point. I want to know if it is possible to make a NodeOscillator oscilate between 0 and 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);
}

我知道我能达到的颤音使用其他技术,那不是重点。我想知道如果它是可能的0和1之间做出一个nodeoscillator作振荡。

answer1: 回答1:

The square wave oscillator does go from -1 to 1, but not quite the way you expect because it is normalized. Due to bandlimiting, there is some ringing which at the discontinuities, so the actual "square" top of the wave is slightly below 1.

You could add a gain to the output to scale it up a little. The best solution is to use PeriodicWave to create your own square wave but turn off this normalization. Then the square top will have amplitude 1, but some parts of the wave will exceed 1.

方波振荡器确实从1到1,但不是你所期望的那样,因为它是标准化的。由于带宽限制,有振铃,在不连续,因此波实际的“广场”上是略低于1。

您可以添加一个增益的输出,以扩大了一点。最好的解决办法是使用periodicwave创建自己的方波而关闭这种正常化。然后广场顶部将有振幅1,但部分波将超过1。

javascript  audio  web-audio