Search code examples
androidpythonaudiokivybuildozer

Kivy: play sound on android without delay


I'm creating a metronome app with kivy. Since the ticks need to be exactly on point I ran in a lot of issues.

I sheduled the clock-events as "free" events:

Config.set('kivy', 'kivy_clock', 'free_all')
Config.write()

Clock.schedule_once_free(self.callback, self.delay)

If I trace the timings of the callbacks they are all great. The widgets are updated in these callbacks and they are just on point.

But if I play a sound on the start of the callback it gets executed with different delays every time. So the sound does not relate to the intented bpm.

Different Sound-loaders have different behavior: "SoundPygame" doesn't have a delay but can't be used for android (missing support for pygame) The non-kivy module "play sound" works great, but can't be used with a buildozer because of missing module "gi". "SoundSDL2" is used by default and does not work for this task.

sound_norm = SoundPygame(source='sounds/tick.wav')

def callback(self, dt):
    self.sound_norm.play()

Is there any way to play sound on android with kivy without event-based delays?

It's my first question here, so please excuse me if I asked something wrong or need to improve my question. Best regards!


Solution

  • Using Pyjnius soved the problem. I now have platform depandant code. For Android:

    from jnius import autoclass
    
    MediaPlayer = autoclass('android.media.MediaPlayer')
    mPlayer_norm = MediaPlayer()
    mPlayer_norm.setDataSource(SOUND_NORM)
    mPlayer_norm.prepare()
    

    later I can play the sound in the callback:

    self.sound_norm.play()
    

    This way there is no noticable delay so it works for me.