Reputation: 65
I'm new to tone.js and I just want a simple pause button. I know that there is a stop() and start() but it's not a pause and when to start again the music just go to the beginning of the song.
I use tone.js because I want to manipulate the music and do some synthesizing sound. I also use p5.js but somehow the pause dose not work. It throws an error saying "Cannot read property 'length' of undefined. So I want to use tone.js but just have to figure out how to pause the music. Thanks.
Here's the code
var player = new Tone.Player("data/audio/singingbird_audio.mp3").toMaster();
var whale = new Tone.Player("data/audio/whale.mp3").toMaster();
whale.autostart = false;
whale.volume.value = -10;
player.autostart = false;
player.volume.value = 5;
player.stop();
button = createButton('Play Bird');
button.position(20, 200);
button.mousePressed(birdSwitch);
function birdSwitch() {
if (player.state == "started") {
player.stop();
whale.stop();
} else if (player.state == "stopped") {
player.start();
whale.start();
}
}
Upvotes: 0
Views: 3178
Reputation: 51
Not sure why Johannes is being such a buzz kill. There's absolutely no reason NOT to use Tone.js. It's a really cool library.
Besides, the ACTUAL solution is easier than the solution Johaness so unhelpfully came up with.
SOLUTION
Literally all you need to do is sync the Player objects to the Tone.Transport and then you can play/pause/stop all day long by controlling the Transport instead of the players
Try modifying your code to look like this
var player = new Tone.Player("data/audio/singingbird_audio.mp3").toMaster();
var whale = new Tone.Player("data/audio/whale.mp3").toMaster();
// sync the Players to the Transport like this
player.sync().start(0);
whale.sync().start(0);
whale.volume.value = -10;
player.volume.value = 5;
button = createButton('Play Bird');
button.position(20, 200);
button.mousePressed(birdSwitch);
function birdSwitch() {
if (player.state == "started") {
// Use the Tone.Transport to pause audio
Tone.Transport.pause();
} else if (player.state == "stopped") {
// Use the Tone.Transport to start again
Tone.Transport.start();
}
}
ADDITIONAL IDEAS
If you want to make the UI for your program even easier, you may also want to consider using the "tonejs-ui.js" library, which has a great Play/Pause/Stop button in it.
Just include the link to the "tonejs-ui.js" library in your <head>
and then you can use the <tone-play-toggle>
element in your HTML and add an event listener to it that triggers the Transport start/pause.
Here's an example of the code you'd need to add to your HTML file and the event listener to add to your javascript instead of the logic you're using for your own button. Hopefully this makes sense.
<head>
<!-- The tonejs-ui.js CDN link -->
<script type="text/javascript" src="https://unpkg.com/@tonejs/[email protected]/build/tonejs-ui.js"></script>
</head>
<body>
<tone-content>
<tone-play-toggle></tone-play-toggle>
</tone-content>
<script type="text/javascript">
document.querySelector("tone-play-toggle").addEventListener("play", (e) => {
const playing = e.detail;
if (playing){
Tone.Transport.start();
} else {
Tone.Transport.pause();
}
});
</script>
</body>
Upvotes: 5
Reputation: 11020
Tone.js is a bit of a overkill to just play an mp3 file.
Why not just using the <audio>
-Tag?
That way you can directly play and pause it.
<button id="pause">Play/Pause</button>
<audio
id="audioNode"
src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-7.mp3"
controls
></audio>
const audio = document.getElementById("audioNode");
document.getElementById("pause").addEventListener("click", () => {
if (audio.paused) {
audio.play();
} else {
audio.pause();
}
});
Codesandbox: https://codesandbox.io/s/charming-wiles-ehy8y
In Tonejs a player is just a wrapper around an audio buffer. Play, pausing, etc. is done by syncing the players to the Transport class and use Transports play, pause, stop functionalities. Which then propagates to the players. But since the Transport has an internal timeline I don't think that this is what you need, since you would have to reset the Transport to the correct position, etc.
I guess in the end it's way more convenient for you to just fall back to the simpler solution.
Upvotes: -2