diff --git a/files/en-us/web/api/audiobuffersourcenode/loop/index.md b/files/en-us/web/api/audiobuffersourcenode/loop/index.md
index 40197bf111b0513..a26e3db9ff21396 100644
--- a/files/en-us/web/api/audiobuffersourcenode/loop/index.md
+++ b/files/en-us/web/api/audiobuffersourcenode/loop/index.md
@@ -27,51 +27,79 @@ is reached, playback continues at the time specified by
## Examples
-In this example, the {{domxref("BaseAudioContext/decodeAudioData", "AudioContext.decodeAudioData()")}} function is used to
-decode an audio track and put it into an {{domxref("AudioBufferSourceNode")}}. Buttons
-are provided to play and stop the audio playback, and a slider control is used to change
-the `playbackRate` property value on the fly. When the audio is played, it
-loops.
+### Setting `loop`
-> **Note:** You can [run the full example live](https://mdn.github.io/webaudio-examples/decode-audio-data/) (or [view the source](https://github.com/mdn/webaudio-examples/blob/master/decode-audio-data/index.html).)
+In this example, when the user presses "Play", we load an audio track, decode it, and put it into an {{domxref("AudioBufferSourceNode")}}.
-```js
-function getData() {
- source = audioCtx.createBufferSource();
- request = new XMLHttpRequest();
-
- request.open("GET", "viper.ogg", true);
-
- request.responseType = "arraybuffer";
+The example then sets the `loop` property to `true`, so the track loops, and plays the track.
- request.onload = () => {
- const audioData = request.response;
+The user can set the `loopStart` and and `loopEnd` properties using [range controls](/en-US/docs/Web/HTML/Element/input/range).
- audioCtx.decodeAudioData(
- audioData,
- (buffer) => {
- myBuffer = buffer;
- source.buffer = myBuffer;
- source.playbackRate.value = playbackControl.value;
- source.connect(audioCtx.destination);
- source.loop = true;
- },
+> **Note:** You can [run the full example live](https://mdn.github.io/webaudio-examples/audio-buffer-source-node/loop/) (or [view the source](https://github.com/mdn/webaudio-examples/tree/main/audio-buffer-source-node/loop).)
- (e) => console.error(`Error with decoding audio data: ${e.err}`),
- );
- };
-
- request.send();
+```js
+let audioCtx;
+let buffer;
+let source;
+
+const play = document.getElementById("play");
+const stop = document.getElementById("stop");
+
+const loopstartControl = document.getElementById("loopstart-control");
+const loopstartValue = document.getElementById("loopstart-value");
+
+const loopendControl = document.getElementById("loopend-control");
+const loopendValue = document.getElementById("loopend-value");
+
+async function loadAudio() {
+ try {
+ // Load an audio file
+ const response = await fetch("rnb-lofi-melody-loop.wav");
+ // Decode it
+ buffer = await audioCtx.decodeAudioData(await response.arrayBuffer());
+ const max = Math.floor(buffer.duration);
+ loopstartControl.setAttribute("max", max);
+ loopendControl.setAttribute("max", max);
+ } catch (err) {
+ console.error(`Unable to fetch the audio file. Error: ${err.message}`);
+ }
}
-// wire up buttons to stop and play audio, and range slider control
-
-play.onclick = () => {
- getData();
- source.start(0);
- play.setAttribute("disabled", "disabled");
- playbackControl.removeAttribute("disabled");
-};
+play.addEventListener("click", async () => {
+ if (!audioCtx) {
+ audioCtx = new AudioContext();
+ await loadAudio();
+ }
+ source = audioCtx.createBufferSource();
+ source.buffer = buffer;
+ source.connect(audioCtx.destination);
+ source.loop = true;
+ source.loopStart = loopstartControl.value;
+ source.loopEnd = loopendControl.value;
+ source.start();
+ play.disabled = true;
+ stop.disabled = false;
+ loopstartControl.disabled = false;
+ loopendControl.disabled = false;
+});
+
+stop.addEventListener("click", () => {
+ source.stop();
+ play.disabled = false;
+ stop.disabled = true;
+ loopstartControl.disabled = true;
+ loopendControl.disabled = true;
+});
+
+loopstartControl.addEventListener("input", () => {
+ source.loopStart = loopstartControl.value;
+ loopstartValue.textContent = loopstartControl.value;
+});
+
+loopendControl.addEventListener("input", () => {
+ source.loopEnd = loopendControl.value;
+ loopendValue.textContent = loopendControl.value;
+});
```
## Specifications
diff --git a/files/en-us/web/api/audiobuffersourcenode/loopend/index.md b/files/en-us/web/api/audiobuffersourcenode/loopend/index.md
index 4ad2071341271b6..16cd9d37404236d 100644
--- a/files/en-us/web/api/audiobuffersourcenode/loopend/index.md
+++ b/files/en-us/web/api/audiobuffersourcenode/loopend/index.md
@@ -27,65 +27,79 @@ The default value is 0.
## Examples
-In this example, the {{domxref("BaseAudioContext/decodeAudioData", "AudioContext.decodeAudioData()")}} function is used to
-decode an audio track and put it into an {{domxref("AudioBufferSourceNode")}}. Buttons
-are provided to play and stop the audio playback, and slider controls are used to change
-the `playbackRate`, `loopStart` and `loopEnd`
-properties on the fly.
+### Setting `loopEnd`
-When the audio is played to the end, it loops, but you can control how long the loops
-last by altering `loopStart` and `loopEnd`. For example, if you
-set their values to 20 and 25, respectively, then begin playback, the sound will play
-normally until it reaches the 25 second mark. Then the current play position will loop
-back to the 20 second mark and continue playing until the 25 second mark, ad infinitum
-(or at least until {{domxref("AudioScheduledSourceNode/stop", "stop()")}} is called).
+In this example, when the user presses "Play", we load an audio track, decode it, and put it into an {{domxref("AudioBufferSourceNode")}}.
-> **Note:** For a full working example, see [this code running live](https://mdn.github.io/webaudio-examples/decode-audio-data/), or [view the source](https://github.com/mdn/webaudio-examples/tree/master/decode-audio-data).
+The example then sets the `loop` property to `true`, so the track loops, and plays the track.
-```js
-function getData() {
- source = audioCtx.createBufferSource();
- request = new XMLHttpRequest();
-
- request.open("GET", "viper.ogg", true);
-
- request.responseType = "arraybuffer";
-
- request.onload = () => {
- const audioData = request.response;
-
- audioCtx.decodeAudioData(
- audioData,
- (buffer) => {
- myBuffer = buffer;
- songLength = buffer.duration;
- source.buffer = myBuffer;
- source.playbackRate.value = playbackControl.value;
- source.connect(audioCtx.destination);
- source.loop = true;
+The user can set the `loopStart` and and `loopEnd` properties using [range controls](/en-US/docs/Web/HTML/Element/input/range).
- loopstartControl.setAttribute("max", Math.floor(songLength));
- loopendControl.setAttribute("max", Math.floor(songLength));
- },
+> **Note:** You can [run the full example live](https://mdn.github.io/webaudio-examples/audio-buffer-source-node/loop/) (or [view the source](https://github.com/mdn/webaudio-examples/tree/main/audio-buffer-source-node/loop).)
- (e) => console.error(`Error with decoding audio data: ${e.err}`),
- );
- };
-
- request.send();
+```js
+let audioCtx;
+let buffer;
+let source;
+
+const play = document.getElementById("play");
+const stop = document.getElementById("stop");
+
+const loopstartControl = document.getElementById("loopstart-control");
+const loopstartValue = document.getElementById("loopstart-value");
+
+const loopendControl = document.getElementById("loopend-control");
+const loopendValue = document.getElementById("loopend-value");
+
+async function loadAudio() {
+ try {
+ // Load an audio file
+ const response = await fetch("rnb-lofi-melody-loop.wav");
+ // Decode it
+ buffer = await audioCtx.decodeAudioData(await response.arrayBuffer());
+ const max = Math.floor(buffer.duration);
+ loopstartControl.setAttribute("max", max);
+ loopendControl.setAttribute("max", max);
+ } catch (err) {
+ console.error(`Unable to fetch the audio file. Error: ${err.message}`);
+ }
}
-// …
-
-loopstartControl.oninput = () => {
+play.addEventListener("click", async () => {
+ if (!audioCtx) {
+ audioCtx = new AudioContext();
+ await loadAudio();
+ }
+ source = audioCtx.createBufferSource();
+ source.buffer = buffer;
+ source.connect(audioCtx.destination);
+ source.loop = true;
+ source.loopStart = loopstartControl.value;
+ source.loopEnd = loopendControl.value;
+ source.start();
+ play.disabled = true;
+ stop.disabled = false;
+ loopstartControl.disabled = false;
+ loopendControl.disabled = false;
+});
+
+stop.addEventListener("click", () => {
+ source.stop();
+ play.disabled = false;
+ stop.disabled = true;
+ loopstartControl.disabled = true;
+ loopendControl.disabled = true;
+});
+
+loopstartControl.addEventListener("input", () => {
source.loopStart = loopstartControl.value;
- loopstartValue.innerHTML = loopstartControl.value;
-};
+ loopstartValue.textContent = loopstartControl.value;
+});
-loopendControl.oninput = () => {
+loopendControl.addEventListener("input", () => {
source.loopEnd = loopendControl.value;
- loopendValue.innerHTML = loopendControl.value;
-};
+ loopendValue.textContent = loopendControl.value;
+});
```
## Specifications
diff --git a/files/en-us/web/api/audiobuffersourcenode/loopstart/index.md b/files/en-us/web/api/audiobuffersourcenode/loopstart/index.md
index 71b4a8677ff781d..4a43b516cc81c4d 100644
--- a/files/en-us/web/api/audiobuffersourcenode/loopstart/index.md
+++ b/files/en-us/web/api/audiobuffersourcenode/loopstart/index.md
@@ -22,62 +22,79 @@ which each loop should begin during playback. This value is only used when the
## Examples
-In this example, the {{domxref("BaseAudioContext/decodeAudioData", "AudioContext.decodeAudioData()")}} function is used to
-decode an audio track and put it into an {{domxref("AudioBufferSourceNode")}}. Buttons
-are provided to play and stop the audio playback, and slider controls are used to change
-the `playbackRate`, `loopStart`, and `loopEnd`
-properties on the fly.
+### Setting `loopStart`
-When the audio is played to the end, it loops, but you can control how long the loops
-last by altering `loopStart` and `loopEnd`. For example, if you
-set their values to 20 and 25, respectively, the audio will start to loop between 20 and
-25 seconds in to the track.
+In this example, when the user presses "Play", we load an audio track, decode it, and put it into an {{domxref("AudioBufferSourceNode")}}.
-> **Note:** For a full working example, see [this code running live](https://mdn.github.io/webaudio-examples/decode-audio-data/), or [view the source](https://github.com/mdn/webaudio-examples/tree/master/decode-audio-data).
+The example then sets the `loop` property to `true`, so the track loops, and plays the track.
-```js
-function getData() {
- source = audioCtx.createBufferSource();
- request = new XMLHttpRequest();
-
- request.open("GET", "viper.ogg", true);
- request.responseType = "arraybuffer";
-
- request.onload = () => {
- const audioData = request.response;
-
- audioCtx.decodeAudioData(
- audioData,
- (buffer) => {
- myBuffer = buffer;
- songLength = buffer.duration;
- source.buffer = myBuffer;
- source.playbackRate.value = playbackControl.value;
- source.connect(audioCtx.destination);
- source.loop = true;
-
- loopstartControl.setAttribute("max", Math.floor(songLength));
- loopendControl.setAttribute("max", Math.floor(songLength));
- },
+The user can set the `loopStart` and and `loopEnd` properties using [range controls](/en-US/docs/Web/HTML/Element/input/range).
- (e) => console.error(`Error with decoding audio data: ${e.err}`),
- );
- };
+> **Note:** You can [run the full example live](https://mdn.github.io/webaudio-examples/audio-buffer-source-node/loop/) (or [view the source](https://github.com/mdn/webaudio-examples/tree/main/audio-buffer-source-node/loop).)
- request.send();
+```js
+let audioCtx;
+let buffer;
+let source;
+
+const play = document.getElementById("play");
+const stop = document.getElementById("stop");
+
+const loopstartControl = document.getElementById("loopstart-control");
+const loopstartValue = document.getElementById("loopstart-value");
+
+const loopendControl = document.getElementById("loopend-control");
+const loopendValue = document.getElementById("loopend-value");
+
+async function loadAudio() {
+ try {
+ // Load an audio file
+ const response = await fetch("rnb-lofi-melody-loop.wav");
+ // Decode it
+ buffer = await audioCtx.decodeAudioData(await response.arrayBuffer());
+ const max = Math.floor(buffer.duration);
+ loopstartControl.setAttribute("max", max);
+ loopendControl.setAttribute("max", max);
+ } catch (err) {
+ console.error(`Unable to fetch the audio file. Error: ${err.message}`);
+ }
}
-// …
-
-loopstartControl.oninput = () => {
+play.addEventListener("click", async () => {
+ if (!audioCtx) {
+ audioCtx = new AudioContext();
+ await loadAudio();
+ }
+ source = audioCtx.createBufferSource();
+ source.buffer = buffer;
+ source.connect(audioCtx.destination);
+ source.loop = true;
+ source.loopStart = loopstartControl.value;
+ source.loopEnd = loopendControl.value;
+ source.start();
+ play.disabled = true;
+ stop.disabled = false;
+ loopstartControl.disabled = false;
+ loopendControl.disabled = false;
+});
+
+stop.addEventListener("click", () => {
+ source.stop();
+ play.disabled = false;
+ stop.disabled = true;
+ loopstartControl.disabled = true;
+ loopendControl.disabled = true;
+});
+
+loopstartControl.addEventListener("input", () => {
source.loopStart = loopstartControl.value;
- loopstartValue.innerHTML = loopstartControl.value;
-};
+ loopstartValue.textContent = loopstartControl.value;
+});
-loopendControl.oninput = () => {
+loopendControl.addEventListener("input", () => {
source.loopEnd = loopendControl.value;
- loopendValue.innerHTML = loopendControl.value;
-};
+ loopendValue.textContent = loopendControl.value;
+});
```
## Specifications
diff --git a/files/en-us/web/api/audiobuffersourcenode/playbackrate/index.md b/files/en-us/web/api/audiobuffersourcenode/playbackrate/index.md
index 92cc72ba1751194..645aa97232e8c57 100644
--- a/files/en-us/web/api/audiobuffersourcenode/playbackrate/index.md
+++ b/files/en-us/web/api/audiobuffersourcenode/playbackrate/index.md
@@ -33,71 +33,64 @@ second). Let's see what a few values of `playbackRate` do:
## Examples
-In this example, the {{domxref("BaseAudioContext/decodeAudioData", "AudioContext.decodeAudioData()")}} function is used to
-decode an audio track, and put it into an {{domxref("AudioBufferSourceNode")}}. Buttons
-are provided to play and stop the audio playback, and a slider control is used to change
-the `playbackRate` property value on the fly.
-
-> **Note:** You can [run the example live](https://mdn.github.io/webaudio-examples/decode-audio-data/) (or [view the source](https://github.com/mdn/webaudio-examples/tree/master/decode-audio-data)). Play the song and alter the playback rate for some fun results.
-
-```html
-
-1.0
-```
-
-```js
-function getData() {
- source = audioCtx.createBufferSource();
- request = new XMLHttpRequest();
-
- request.open("GET", "viper.ogg", true);
+### Setting `playbackRate`
- request.responseType = "arraybuffer";
+In this example, when the user presses "Play", we load an audio track, decode it, and put it into an {{domxref("AudioBufferSourceNode")}}.
- request.onload = () => {
- const audioData = request.response;
+The example then sets the `loop` property to `true`, so the track loops, and plays the track.
- audioCtx.decodeAudioData(
- audioData,
- (buffer) => {
- myBuffer = buffer;
- source.buffer = myBuffer;
- source.playbackRate.value = playbackControl.value;
- source.connect(audioCtx.destination);
- source.loop = true;
- },
+The user can set the `playbackRate` property using a [range control](/en-US/docs/Web/HTML/Element/input/range).
- (e) => console.error(`Error with decoding audio data: ${e.err}`),
- );
- };
+> **Note:** You can [run the full example live](https://mdn.github.io/webaudio-examples/audio-buffer-source-node/playbackrate/) (or [view the source](https://github.com/mdn/webaudio-examples/tree/main/audio-buffer-source-node/playbackrate).)
- request.send();
+```js
+let audioCtx;
+let buffer;
+let source;
+
+const play = document.getElementById("play");
+const stop = document.getElementById("stop");
+
+const playbackControl = document.getElementById("playback-rate-control");
+const playbackValue = document.getElementById("playback-rate-value");
+
+async function loadAudio() {
+ try {
+ // Load an audio file
+ const response = await fetch("rnb-lofi-melody-loop.wav");
+ // Decode it
+ buffer = await audioCtx.decodeAudioData(await response.arrayBuffer());
+ } catch (err) {
+ console.error(`Unable to fetch the audio file. Error: ${err.message}`);
+ }
}
-// wire up buttons to stop and play audio, and range slider control
-
-play.onclick = () => {
- getData();
- source.start(0);
- play.setAttribute("disabled", "disabled");
- playbackControl.removeAttribute("disabled");
-};
-
-stop.onclick = () => {
- source.stop(0);
- play.removeAttribute("disabled");
- playbackControl.setAttribute("disabled", "disabled");
-};
+play.addEventListener("click", async () => {
+ if (!audioCtx) {
+ audioCtx = new AudioContext();
+ await loadAudio();
+ }
+ source = audioCtx.createBufferSource();
+ source.buffer = buffer;
+ source.connect(audioCtx.destination);
+ source.loop = true;
+ source.playbackRate.value = playbackControl.value;
+ source.start();
+ play.disabled = true;
+ stop.disabled = false;
+ playbackControl.disabled = false;
+});
+
+stop.addEventListener("click", () => {
+ source.stop();
+ play.disabled = false;
+ stop.disabled = true;
+ playbackControl.disabled = true;
+});
playbackControl.oninput = () => {
source.playbackRate.value = playbackControl.value;
- playbackValue.innerHTML = playbackControl.value;
+ playbackValue.textContent = playbackControl.value;
};
```