Stop a looping sound with play only

In the game loop there are several places where sounds are started for game entities. I start these with the usual play/release combination. That works fine for one shots but how about looping sounds?

My idea is to stop these, if they are no longer requested to play. Eg a breathing sound is called at several places and is stopped when no longer called. So no active stop command since different conditions for play can exist.

How do I implement this? Keep some sort of list with sounds playing, reset their counter to 0 each loop and stop them when not incremented by a play call? But how do I distinguish between looped and non looped sounds?

Could I get a more straightforward description of how these looping sounds are being implemented? I’m having trouble understanding exactly what you’re going for.

Also, just to clarify, are you working with the Core API, or the Studio API? Sounds and channels are Core API, while events and event instances are Studio API - while the Studio API is built on top of the Core API, they’re fundamentally different entities. There’s ways to check and handle looping for each:

Sorry, I was maybe a bit sparse. I’m using the Studio API and I’m wondering how to handle entity looped sounds. Eg this can be part of the gameloop for an entity

if (CertainCondition()){
    sound_engine_.PlaySound(my_sound);
}

If my_sound is looped, PlaySound() shall check if the sound is already playing and then do nothing. Eg by checking an std::map where all playing instances are stored. During the gameloop update-call, non playing instances are removed from that map.

But what about stopping? I could add an else block with StopSound() which would then go to the same map and stops the instance. But what if the entity is destroyed? Then the destructor should have some sort of stop all sounds for this entity? And what if someone forgets to add a stop-call?

Another option would be to let PlaySound() set a flag for that instance (yes, in that map) and then in the general update-call check if the flag is set, if not, stop the sound and remove it, if it is set, reset the flag and wait for the next update-call.

But maybe there are other design options. So is there a standard or preferred way to tackle this issue?

It’s difficult to make recommendations on the preferred or standard ways of handling event instance lifecycles, since it depends on the needs of your game and the specifics of your own code. In general, I would say to try implementing something, and then see what issues arise and address them as needed.

Both of your proposed solutions sound viable though - in the case of the first, ensuring all instances are stopped is something you’d need to note as a requirement of the system to address the case where someone forgets to add a stop-call.

1 Like

Thanks, I went for the latter. Works ok, only downside is that having an std::map in the entity object, makes play calls no longer thread safe.