Search code examples
haxe

How can I play Sound more than once in Haxe/Heaps?


I'm using Heaps.io Game Engine for Haxe and currently trying to play sound WAV file from my resources every time a specific event happens. But it always plays only first time, then nothing. Code example:

import hxd.Event;
import hxd.System;
import hxd.Window;
import hxd.res.Sound;

class Main extends hxd.App {
    var sound: Sound = null;
    var window: Window;

    function onEvent(event: Event) {
        if (event.kind == EKeyDown) {
            if (event.keyCode == hxd.Key.P) {
                playSound();
            }
            if (event.keyCode == hxd.Key.Q) {
                System.exit();    
            }
        }
    }

    function playSound() {
        trace(sound);
        if (sound != null) {
            sound.play();
        }
    }

    override function init() {
        hxd.Res.initEmbed();

        window = Window.getInstance();
        window.addEventTarget(onEvent);

        if (Sound.supportedFormat(Wav)) {
            sound = hxd.Res.pong;
        }
    }
    
    override function update(dt: Float) {
        
    }

    public static function main() {
        new Main();
    }
}

After pressing 'P' for 7 times, pong.wav would play only once. After quitting by pressing 'Q', debug console shows this:

(7) src/Main.hx:22: pong.wav
AL lib: (EE) alc_cleanup: 1 device not closed

So it does see my sound file but can't play it for whatever reason. I've tried to write sound.stop(); before sound.play();, but to no avail. Could it be something about the last debug message?

Edit1: I've tried to use Channels, but result was still the same. And in the code above it seems like no other sound file could be played after the first one as well.

P.S. There's even no such tag as "Heaps" on Stack Overflow.


Solution

  • Found solution: https://github.com/HeapsIO/heaps/issues/1100, and seems like it is a bug!

    A simple fix is to put this line in your App.init

    @:privateAccess haxe.MainLoop.add(() -> {});
    

    E.g.

    override function init() {
        hxd.Res.initEmbed();
        @:privateAccess haxe.MainLoop.add(() -> {});
    
        window = Window.getInstance();
        window.addEventTarget(onEvent);
    
        if (Sound.supportedFormat(Wav)) {
            sound = hxd.Res.pong;
        }
    }
    

    Now sound is always working properly and problem solved.

    As a side note, I still don't know what to think about the last waning message, it still occures but does nothing.