Sound.is_phone_call_active

sound.is_phone_call_active
Checks if a phone call is active. If there is an active phone call all other sounds will be muted until the phone call is finished.

How does this work exactly? Does the function need to be there to detect if there is a phone call? Does it automatically mute audio if there is, or is that left up to the user and only returns true or false? What’s the best practice for it? The text is a little confusing because it implies it auto mutes, but then why return any value?

What’s the best practice for sound.is_music_playing() too? As in when to check it. Unlike sound.is_phone_call_active the documentation seems to say it’s up to the user to decide what to do with the true/false value it returns. Does the window listener for getting focus work on iOS/Android? If so I assume that’s kind of a good way to check if music is playing? Not constantly, but when app gets focus again / on inits?

Hello @Pkeod!

There has been some internal changes to the sound system recently, and I’m not sure the manuals reflect these changes, so thanks for bringing it up. I’ll ping in @sicher to this answer so we can improve on this.

Sound
The engine doesn’t respect other applications when a play_sound message is issued, with the exception of phone calls. This means that the engine will always attempt to play a sound when a message is issued, even if there is another application playing sounds/music and sound.is_playing_music() returns true. In other words, it is up to the developer to check if music is playing and make a decision on whether sounds should be played or not based on that.

We will however issue signals to other applications when a sound is starting to play telling them to be quiet, and we will issue a signal when the sounds stop telling them we’re done. If no sound is playing, or the volume is set to 0, we will not send any data to the sound component of the device. We’re basically telling others what to do, but not listening to their feedback.

sound.is_music_playing() is implemented on Android and iOS, on all other platforms the function will always return false. On Android, we are looking at audio focus to determine whether another application is playing sounds or not. As long as all other applications running on the device is respecting the audio focus system that is in place on Android, we will correctly detect whether music is playing or not. However, if an application ignores the audio focus system there is a case where we will be unable to detect that application. To trigger this case, follow the steps below.

  1. Play music on an application that is not respecting audio focus.
  2. (optional) check sound.is_music_playing(), it should return true.
  3. Start playing sounds using the defold sound system, the sounds of the two applications will be mixed.
  4. check sound.is_music_playing(), it will return false.

Phone call
Phone calls are different since they are always prioritised by the device. The engine will continuously check for phone calls and when a phone call is detected all sounds will be silenced for the duration of the phone call. When the phone call ends the sounds will continue to play as before the phone call. We will still advance the buffers but no data will be sent to the mixer, so any sounds that is played from start to finish during a phone call will be “lost” completely and never heard.

It will not be possible for the developer to force a sound to be played during a phone call, even if it’s possible to mix sounds with a phone call on Android. It is up to the developer to monitor sound.is_phone_call_active if sounds has to be in sync with the gameplay.

Best practise
I’m no game developer, but my recommendation would be to check sound.is_music_playing() before the first play_sound message is sent, and then continuously check for a change in state and handle it accordingly. Maybe you want to make a difference between music and transient sounds and silence the music but keep playing sounds whenever the hero collects a gold coin.

Both sound.is_music_playing() and sound.is_phone_call_active() should have a very low impact on performance.

Regards,
Jakob

4 Likes

Thank you for the detailed explanations, Jakob!

1 Like

Excellent answer! Thank you for clarifying the implementation.

One question: You say that “The engine will continuously check for phone calls and when a phone call is detected all sounds will be silenced for the duration of the phone call.” Is the sound playing with a volume of 0 or is it actually paused?

The volume will be unaffected, but the sounds will be completely silenced. We will advance the buffers but no buffers will be sent to the mixer. Sounds you’re playing during a phone call will be “lost”, and never heard, so to speak.

1 Like

I have a strange bug.
I try to listen music and play game. When sounds in game play, music turned off.
I tried to fix it using sound.is_music_playing and if music playing -I turned off sounds in my game. But on my phone (Xiomi redmi note 4 Android 6.0) this method all time return true.