OscillatorNode
        
        
          
                Baseline
                
                  Widely available
                
                
              
        
        
        
          
                
              
                
              
                
              
        
        
      
      This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The OscillatorNode interface represents a periodic waveform, such as a sine wave. It is an AudioScheduledSourceNode audio-processing module that causes a specified frequency of a given wave to be created—in effect, a constant tone.
| Number of inputs | 0 | 
    
|---|---|
| Number of outputs | 1 | 
    
| Channel count mode | max | 
    
| Channel count | 2 (not used in the default count mode) | 
    
| Channel interpretation | speakers | 
    
Constructor
OscillatorNode()- 
Creates a new instance of an
OscillatorNodeobject, optionally providing an object specifying default values for the node's properties. As an alternative, you can use theBaseAudioContext.createOscillator()factory method; see Creating an AudioNode. 
Instance properties
Also inherits properties from its parent, AudioScheduledSourceNode.
OscillatorNode.frequency- 
An a-rate
AudioParamrepresenting the frequency of oscillation in hertz (though theAudioParamreturned is read-only, the value it represents is not). The default value is 440 Hz (a standard middle-A note). OscillatorNode.detune- 
An a-rate
AudioParamrepresenting detuning of oscillation in cents (though theAudioParamreturned is read-only, the value it represents is not). The default value is 0. OscillatorNode.type- 
A string which specifies the shape of waveform to play; this can be one of a number of standard values, or
customto use aPeriodicWaveto describe a custom waveform. Different waves will produce different tones. Standard values are"sine","square","sawtooth","triangle"and"custom". The default is"sine". 
Instance methods
Also inherits methods from its parent, AudioScheduledSourceNode.
OscillatorNode.setPeriodicWave()- 
Sets a
PeriodicWavewhich describes a periodic waveform to be used instead of one of the standard waveforms; calling this sets thetypetocustom. AudioScheduledSourceNode.start()- 
Specifies the exact time to start playing the tone.
 AudioScheduledSourceNode.stop()- 
Specifies the time to stop playing the tone.
 
Events
Also inherits events from its parent, AudioScheduledSourceNode.
Examples
>Using an OscillatorNode
The following example shows basic usage of an AudioContext to create an oscillator node and to start playing a tone on it. For an applied example, check out our Violent Theremin demo (see app.js for relevant code).
// create web audio api context
const audioCtx = new AudioContext();
// create Oscillator node
const oscillator = audioCtx.createOscillator();
oscillator.type = "square";
oscillator.frequency.setValueAtTime(440, audioCtx.currentTime); // value in hertz
oscillator.connect(audioCtx.destination);
oscillator.start();
Different oscillator node types
The four built-in oscillator types are sine, square, triangle and sawtooth. They are the shape of the waveform generated by an oscillator. Fun fact: These are the defaults for most synths because they are waveforms which are easy to generate electronically. This example visualizes the waveforms for the different types at different frequencies.
<div class="controls">
  <label for="type-select">
    Oscillator type
    <select id="type-select">
      <option>sine</option>
      <option>square</option>
      <option>triangle</option>
      <option>sawtooth</option>
    </select>
  </label>
  <label for="freq-range">
    Frequency
    <input
      type="range"
      min="100"
      max="800"
      step="10"
      value="250"
      id="freq-range" />
  </label>
  <button data-playing="init" id="play-button">Play</button>
</div>
<canvas id="wave-graph"></canvas>
The code is in two parts: in the first part, we set up the sound stuff.
const typeSelect = document.getElementById("type-select");
const frequencyControl = document.getElementById("freq-range");
const playButton = document.getElementById("play-button");
const audioCtx = new AudioContext();
const osc = new OscillatorNode(audioCtx, {
  type: typeSelect.value,
  frequency: frequencyControl.valueAsNumber,
});
// Rather than creating a new oscillator for every start and stop
// which you would do in an audio application, we are just going
// to mute/un-mute for demo purposes - this means we need a gain node
const gain = new GainNode(audioCtx);
const analyser = new AnalyserNode(audioCtx, {
  fftSize: 1024,
  smoothingTimeConstant: 0.8,
});
osc.connect(gain).connect(analyser).connect(audioCtx.destination);
typeSelect.addEventListener("change", () => {
  osc.type = typeSelect.value;
});
frequencyControl.addEventListener("input", () => {
  osc.frequency.value = frequencyControl.valueAsNumber;
});
playButton.addEventListener("click", () => {
  if (audioCtx.state === "suspended") {
    audioCtx.resume();
  }
  if (playButton.dataset.playing === "init") {
    osc.start(audioCtx.currentTime);
    playButton.dataset.playing = "true";
    playButton.innerText = "Pause";
  } else if (playButton.dataset.playing === "false") {
    gain.gain.linearRampToValueAtTime(1, audioCtx.currentTime + 0.2);
    playButton.dataset.playing = "true";
    playButton.innerText = "Pause";
  } else if (playButton.dataset.playing === "true") {
    gain.gain.linearRampToValueAtTime(0.0001, audioCtx.currentTime + 0.2);
    playButton.dataset.playing = "false";
    playButton.innerText = "Play";
  }
});
As for the second part, we draw the waveform on a canvas using the AnalyserNode we created above.
const dpr = window.devicePixelRatio;
const w = 500 * dpr;
const h = 300 * dpr;
const canvasEl = document.getElementById("wave-graph");
canvasEl.width = w;
canvasEl.height = h;
const canvasCtx = canvasEl.getContext("2d");
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
analyser.getByteTimeDomainData(dataArray);
// draw an oscilloscope of the current oscillator
function draw() {
  analyser.getByteTimeDomainData(dataArray);
  canvasCtx.fillStyle = "white";
  canvasCtx.fillRect(0, 0, w, h);
  canvasCtx.lineWidth = 4.0;
  canvasCtx.strokeStyle = "black";
  canvasCtx.beginPath();
  const sliceWidth = (w * 1.0) / bufferLength;
  let x = 0;
  for (let i = 0; i < bufferLength; i++) {
    const v = dataArray[i] / 128.0;
    const y = (v * h) / 2;
    if (i === 0) {
      canvasCtx.moveTo(x, y);
    } else {
      canvasCtx.lineTo(x, y);
    }
    x += sliceWidth;
  }
  canvasCtx.lineTo(w, h / 2);
  canvasCtx.stroke();
  requestAnimationFrame(draw);
}
draw();
Warning: This example makes a noise!
Specifications
| Specification | 
|---|
| Web Audio API> # OscillatorNode>  | 
            
Browser compatibility
Loading…