Playing sound files in p5.js

Hi!
I’m working through the p5.js course in Kadenze and I’m trying to play an audio sample while my mouse hovers over a section of my sketch:

if (mouseX > 600 && mouseX <700){
sound_out.play();
} else {
sound_out.stop();
}

this block of code is inside the draw function. When it is triggered, it sounds horrible. In all the examples I have found, the playback is triggered within a mousePressed or canvasPressed function, but I don’t want to do that. Is there a different function I should use, or change playback rate somehow?

Many thanks,
Anna

I think the problem is that play function is triggered every frame while your cursor is in the area. When you ask questions, I suggest sharing your sketch on web editor so we can look into it further :slight_smile:

Hi! Thanks for your suggestions. That does make sense, but I’m not sure how to fix the problem or go about it a different way. Here is my code:

//strobe variable
var strobe = 10;

//image variables
var img_out;
var img_dan;
var img_east;
var img_po;
var img_path;

//sound variables
var sound_po;
var sound_out;

function preload() {
img_out = loadImage(“outkast.jpeg”);
img_dan = loadImage(“danger.jpeg”);
img_east = loadImage(“east_point.png”);
img_po = loadImage(“police.jpeg”);
img_path = loadImage(“path.jpeg”);
sound_po = loadSound(“police_siren.mp3”);
sound_out = loadSound(“outkast_short.mp3”);

}

function setup() {
createCanvas(700, 600);

}

function draw() {
noFill();
strokeWeight(4);

var c = (‘rgba(255, 255, 0, 255)’);

background©;

//police siren
if (mouseX > 50 && mouseX <300){
sound_po.play();
} else {
sound_po.stop();
}

//outkast
if (mouseX > 600 && mouseX <700){
sound_out.play();
} else {
sound_out.stop();
}

//background color change near police car
if (mouseX > 50 && mouseX <250) {
c = (‘rgba(255, 0, 0, 100)’);
background©;
}

//police car
var expandX = map(pmouseX, 0, 322, 280, 360 );
var expandY = map(mouseY, 0, 156, 130, 180);

if (mouseY <300 && mouseX < 400) {
image(img_po, 10, 10, expandX, expandY);
} else {
image(img_po, 10, 10, 322, 156);
}

//strobing circles
strobe = strobe + 10;

if (mouseX > 50 && mouseX <300) {
ellipse(width/2, height/2, strobe, strobe);
}

if (strobe > height&&width ) {
strobe = 10;
}

image(img_out, 390, 10);
image(img_dan, 400, 400);
image(img_east, 250, 200);

image(img_path, 10, 330);

}

Now that I understand the issue, I will try different things.
Thanks again.

Hi! Glad it helped a bit. When I say posting the code, I recommend you to use the web editor with necessary assets (images and sound files) so we can try it easily (we are volunteers so you would have a better chance of getting answers by doing so).

Given that, I haven’t tried the code, but I would suggest two things. One is to play the sound only if the file is not playing or paused. If you look at the reference, you can find isPlaying, which tells you if the playback is finished or not. Also you can note the time when you started playing the file as a variable (probably getting from millis) and don’t play the file till the duration of the file has passed.

Another approach is totally different one, to loop the sound all the time and set the volume to 100% only when the cursor is inside the area. This is actually super easy because you can keep setting volume every frame without conditions, but two things to note: one is that on a browser you always need “user interaction” for example a mouse click to start playing the sound. Another problem is that since it’s always looping, the sound may start in the middle of the loop when the volume is turned on.

2 Likes

https://editor.p5js.org/saveryanna/sketches/0CU7eZMtk

Hi Really appreciate your time and your comments! I’m new to this, so hoping I shared the code correctly this time round.

Looking forward to working through your suggestions.

thanks! that definitely helps. But have you tried running the sketch by yourself? It won’t run because of the following reasons:

  • you declared the sound as sound_po but you typed sound when you trigger play
  • sound file name is wrong when you loadSound
  • you declared preload twice which is problematic because basically the first one will be completely replaced by the second one so the sound won’t be loaded

and do you have any ideas how to implement what I suggested above? I’d love to help but we are not here to do your homework - of course if you tried something and didn’t work, I’m happy to help but first I want to see what you have tried :slight_smile:

Hi! I’m sorry, that is embarrassing. I sent the wrong sketch code as I was trying to figure out how to share it. I’ve been making copies as I go. This one runs.

https://editor.p5js.org/saveryanna/sketches/DTHP-PMSn

I don’t know how to implement your suggestions, although I have seen examples of isPlaying on the p5.js examples page. If I can’t figure out how to change the sketch in the way I want, I will just use the tools I have already learnt in the course and move on to the next session. This is pretty early on, so hopefully I will have a much deeper understanding of everything by the end. I just wanted to see if it is a quick fix, but clearly I lack some basic knowledge here, so I think it’s best to keep working through the course.

Thanks again for your time and help!! I really appreciate it.

oh thanks! before looking at it in detail I want to comment that for those who want to help, don’t run the sketch as it is because the repeated play can actually crash the browser :frowning:

ok here’s what I meant with the second option:
https://editor.p5js.org/micuat/sketches/Ab1M7Tc5t

basically it doesn’t change the logic, but sets the volume depending on the mouse position. The sounds are looped all the time but as I wrote they need mouse click to start playing (this is because of the browsers preventing from sound to play automatically). It kind of works because the sound is repetitive, but if you want to play the sound from the top every time the cursor enters the region, you need to add a bit more logic as I wrote as the first option.

Thank you! That’s really super helpful.

Use an if statement as a super lazy fix:

if (mouseX > 600 && mouseX <700){
   if(!sound_out.playing){
//I can’t remember if it’s a built in Boolean if it’s sound.isPlaying(); try both 

     sound_out.play(); 
   }
} else {
sound_out.stop();
}