mackron / miniaudio

Audio playback and capture library written in C, in a single source file.
https://miniaud.io
Other
4.07k stars 361 forks source link

Emscripten crash in _ma_device__on_notification_unlocked #781

Closed tapio closed 11 months ago

tapio commented 11 months ago

With Emscripten build / WebAudio backend I got a crash/exception about null function with the line Module._ma_device__on_notification_unlocked(device.pDevice); inside ma_context_init__webaudio -> miniaudio.unlock -> device.webaudio.resume().then(

I commented out the line, and everything seems to work fine then. It seems that is the only line anywhere in the miniaudio.h referencing _ma_device__on_notification_unlocked, so perhaps it's some left-over thing that's forgotten to delete?

mackron commented 11 months ago

Thanks. This is new functionality. Are you compiling as C++? I noticed that miniaudio is not doing the extern "C" thing. I wonder if it's getting name mangled? In any case, I've pushed a potential fix to the dev branch. Are you able to give that a try?

(CC @mlabbe in case you're curious.)

mlabbe commented 11 months ago

@tapio Can you make sure this function is being compiled in?

#if defined(MA_EMSCRIPTEN)
EMSCRIPTEN_KEEPALIVE
void ma_device__on_notification_unlocked(ma_device* pDevice)
{
    ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_unlocked));
}
#endif

If it isn't, that's your problem. If it is, can you give us a dump of the symbols in Module right before it throws an exception, and the compile and link arguments you're using with emscripten?

I would not rule out extern "C". You may be our first c++ tester of this code.

mackron commented 11 months ago

Does it matter where the EMSCRIPTEN_KEEPALIVE token is specified relative to the return type? I just mention it because it my code I put it after the return type, and I also noticed that's how the Emscripten docs specify it as well. https://emscripten.org/docs/api_reference/emscripten.h.html#c.EMSCRIPTEN_KEEPALIVE. My patch in the dev branch moves it to after the return type just for consistency with some other functions in miniaudio. No idea if this actually matters or not, but just an observation I noticed.

tapio commented 11 months ago

I am indeed compiling as c++ (including miniaudio.h implementation into a .cpp file that has a bunch of other code too). I could put it into a separate .c file (seems like I've done that in another project) but this c++ way has served me fine like this also.

This is my first time trying Emscripten with anything and I did not think to search for the symbol without leading underscore to find that function (hence why I assumed it was a left-over).

Anyway, I applied d070909 and it works now. (I also tested adding an abort() call to that function to verify it is called, and it was hit successfully.)

Thanks for quick responses and patch!

mackron commented 11 months ago

Compiling as C++ is fully supported by miniaudio so this was a good report. This will be released shortly.