-
Notifications
You must be signed in to change notification settings - Fork 433
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 2 new examples for looping and playbackrate * Rename decode-audio-data * Separate files for scripts * Use fetch() in decodeaudiodata/callback * Use fetch() in script-processor-node * Use fetch() in voice-change-o-matic * Delete unused polyfill respond.js * Apply suggestions from code review Co-authored-by: Jean-Yves Perrier <[email protected]> * Review comments * Apply suggestions from code review Co-authored-by: Jean-Yves Perrier <[email protected]> * Init audio context on play --------- Co-authored-by: Jean-Yves Perrier <[email protected]>
- Loading branch information
Showing
21 changed files
with
610 additions
and
532 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width" /> | ||
|
||
<title>Web Audio API examples: looping a track</title> | ||
|
||
<script src="script.js" defer></script> | ||
</head> | ||
|
||
<body> | ||
<h1>Web Audio API examples: looping a track</h1> | ||
|
||
<button id="play">Play</button> | ||
<button id="stop" disabled>Stop</button> | ||
|
||
<h2>Set loop start and loop end</h2> | ||
<input | ||
id="loopstart-control" | ||
type="range" | ||
min="0" | ||
max="20" | ||
step="1" | ||
value="0" | ||
disabled /> | ||
Starts at <span id="loopstart-value">0</span> s. | ||
<br /> | ||
<input | ||
id="loopend-control" | ||
type="range" | ||
min="0" | ||
max="20" | ||
step="1" | ||
value="0" | ||
disabled /> | ||
Stops at <span id="loopend-value">0</span> s. | ||
<p> | ||
If the stop time is lower or equal to the start time, it'll loop over the | ||
whole track. | ||
</p> | ||
</body> | ||
</html> |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
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}`); | ||
} | ||
} | ||
|
||
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; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width" /> | ||
|
||
<title>Web Audio API examples: setting playback rate</title> | ||
|
||
<script src="script.js" defer></script> | ||
</head> | ||
|
||
<body> | ||
<h1>Web Audio API examples: setting playback rate</h1> | ||
|
||
<button id="play">Play</button> | ||
<button id="stop" disabled>Stop</button> | ||
|
||
<h2>Set playback rate</h2> | ||
<input | ||
id="playback-rate-control" | ||
type="range" | ||
min="0.25" | ||
max="3" | ||
step="0.05" | ||
value="1" | ||
disabled /> | ||
<span id="playback-rate-value">1.0</span> × the original rate. | ||
</body> | ||
</html> |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
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}`); | ||
} | ||
} | ||
|
||
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.textContent = playbackControl.value; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width" /> | ||
<title>Web Audio API examples: decodeAudioData() with callback</title> | ||
<script src="script.js" defer></script> | ||
</head> | ||
|
||
<body> | ||
<h1>Web Audio API examples: decodeAudioData() with callback</h1> | ||
|
||
<button id="play">Play</button> | ||
<button id="stop" disabled>Stop</button> | ||
|
||
<h2>Set playback rate</h2> | ||
<input | ||
id="playback-rate-control" | ||
type="range" | ||
min="0.25" | ||
max="3" | ||
step="0.05" | ||
value="1" | ||
disabled /> | ||
<span id="playback-rate-value">1.0</span> | ||
|
||
<h2>Set loop start and loop end</h2> | ||
<input | ||
id="loopstart-control" | ||
type="range" | ||
min="0" | ||
max="20" | ||
step="1" | ||
value="0" | ||
disabled /> | ||
<span id="loopstart-value">0</span> | ||
|
||
<input | ||
id="loopend-control" | ||
type="range" | ||
min="0" | ||
max="20" | ||
step="1" | ||
value="0" | ||
disabled /> | ||
<span id="loopend-value">0</span> | ||
|
||
<p> | ||
If the stop time is lower or equal to the start time, it'll loop over the | ||
whole track. | ||
</p> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
let audioCtx; | ||
let buffer; | ||
let source; | ||
|
||
// Get UI elements | ||
const play = document.getElementById("play"); | ||
const stop = document.getElementById("stop"); | ||
|
||
const playbackControl = document.getElementById("playback-rate-control"); | ||
const playbackValue = document.getElementById("playback-rate-value"); | ||
|
||
const loopstartControl = document.getElementById("loopstart-control"); | ||
const loopstartValue = document.getElementById("loopstart-value"); | ||
|
||
const loopendControl = document.getElementById("loopend-control"); | ||
const loopendValue = document.getElementById("loopend-value"); | ||
|
||
function playBuffer() { | ||
source = audioCtx.createBufferSource(); | ||
source.buffer = buffer; | ||
source.playbackRate.value = playbackControl.value; | ||
source.connect(audioCtx.destination); | ||
source.loop = true; | ||
source.loopStart = loopstartControl.value; | ||
source.loopEnd = loopendControl.value; | ||
source.start(); | ||
play.disabled = true; | ||
stop.disabled = false; | ||
playbackControl.disabled = false; | ||
loopstartControl.disabled = false; | ||
loopendControl.disabled = false; | ||
} | ||
|
||
async function loadAudio() { | ||
try { | ||
const response = await fetch("viper.mp3"); | ||
audioCtx.decodeAudioData(await response.arrayBuffer(), (buf) => { | ||
// executes when buffer has been decoded | ||
buffer = buf; | ||
const max = Math.floor(buf.duration); | ||
loopstartControl.max = max; | ||
loopendControl.max = max; | ||
play.disabled = false; // buffer loaded, enable play button | ||
playBuffer(); | ||
}); | ||
} catch (err) { | ||
console.error(`Unable to fetch the audio file. Error: ${err.message}`); | ||
} | ||
} | ||
|
||
play.addEventListener("click", async () => { | ||
if (!audioCtx) { | ||
audioCtx = new AudioContext(); | ||
await loadAudio(); | ||
} else { | ||
playBuffer(); | ||
} | ||
}); | ||
|
||
stop.addEventListener("click", () => { | ||
source.stop(); | ||
play.disabled = false; | ||
playbackControl.disabled = true; | ||
loopstartControl.disabled = true; | ||
loopendControl.disabled = true; | ||
}); | ||
|
||
playbackControl.addEventListener("input", () => { | ||
source.playbackRate.value = playbackControl.value; | ||
playbackValue.textContent = playbackControl.value; | ||
}); | ||
|
||
loopstartControl.addEventListener("input", () => { | ||
source.loopStart = loopstartControl.value; | ||
loopstartValue.textContent = loopstartControl.value; | ||
}); | ||
|
||
loopendControl.oninput = () => { | ||
source.loopEnd = loopendControl.value; | ||
loopendValue.textContent = loopendControl.value; | ||
}; |
File renamed without changes.
File renamed without changes.
Oops, something went wrong.