OscillatorNode
OscillatorNode 介面表示一個週期性波形,例如正弦波。它是一個 AudioScheduledSourceNode 音訊處理模組,用於建立給定波形的指定頻率——實際上是一個恆定的音調。
| 輸入數量 | 0 |
|---|---|
| 輸出數量 | 1 |
| 通道計數模式 | max |
| 聲道數 | 2 (在預設計數模式下未使用) |
| 通道解釋 | 揚聲器 |
建構函式
OscillatorNode()-
建立一個新的
OscillatorNode物件例項,可以選擇提供一個物件來指定節點的 屬性 的預設值。或者,您可以使用BaseAudioContext.createOscillator()工廠方法;請參閱 建立 AudioNode。
例項屬性
還繼承了其父類 AudioScheduledSourceNode 的屬性。
OscillatorNode.frequency-
一個 a-rate
AudioParam,表示振動的頻率(以赫茲為單位)(儘管返回的AudioParam是隻讀的,但它表示的值不是)。預設值為 440 Hz(標準的中央 A 音)。 OscillatorNode.detune-
一個 a-rate
AudioParam,表示振動的失諧(以音分為單位)(儘管返回的AudioParam是隻讀的,但它表示的值不是)。預設值為 0。 OscillatorNode.type-
一個字串,指定要播放的波形形狀;它可以是許多標準值之一,或者
custom,用於使用PeriodicWave來描述自定義波形。不同的波形會產生不同的音調。標準值是"sine"、"square"、"sawtooth"、"triangle"和"custom"。預設值為"sine"。
例項方法
還繼承了其父類 AudioScheduledSourceNode 的方法。
OscillatorNode.setPeriodicWave()-
設定一個
PeriodicWave,該波形描述了用於替代標準波形之一的週期性波形;呼叫此方法會將type設定為custom。 AudioScheduledSourceNode.start()-
指定開始播放音調的確切時間。
AudioScheduledSourceNode.stop()-
指定停止播放音調的時間。
事件
還繼承了其父類 AudioScheduledSourceNode 的事件。
示例
使用 OscillatorNode
以下示例展示瞭如何使用 AudioContext 建立一個振盪器節點並開始播放其音調。有關實際應用示例,請檢視我們的 Violent Theremin 演示(相關程式碼請參見 app.js)。
// 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();
不同的振盪器節點型別
四個內建的振盪器 型別 是 sine、square、triangle 和 sawtooth。它們是振盪器生成的波形的形狀。有趣的事實:這些是大多數合成器的預設設定,因為它們是易於電子生成的波形。此示例可視化了不同型別在不同頻率下的波形。
<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>
程式碼分為兩部分:第一部分,我們設定了聲音相關的部分。
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";
}
});
至於第二部分,我們使用上面建立的 AnalyserNode 將波形繪製在畫布上。
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();
警告:此示例會發出噪音!
規範
| 規範 |
|---|
| Web Audio API # OscillatorNode |
瀏覽器相容性
載入中…