SoLoud audio plugin

Quoting the intro page: “SoLoud is an easy to use, free, portable c/c++ audio engine for games.”

This is a binding for that engine, and aims to be a faithful one, with only a few changes here and there to sand down the C++ edges into a more friendly Lua form.

If you scroll down on that page, the “How powerful?” section will give you a general overview of what’s available. From there, you can explore many of the side links to dig deeper.

Among other things: you get a bunch of formats (on all platforms); several built-in filters; properties like panning, play speed, 3D position; faders and oscillators on those properties; busses and queues; SFXR and speech synthesizers.

I’ve re-implemented SoLoud’s many examples and demos as a way to flush out the kinks in my binding. These are available here and can be used as a guide to get started; in particular, see its build.settings.

@BK_PANARA and @Siu have been doing some testing. For any interested Windows users, Siu has also adapted and built one of the samples: (3.2 MB)

(This uses an interesting project of his own.)

The “Latest Stable Release” (~47 MB) here has the assets needed by most samples: the audio and graphics directories (in bin) should be copied to the sample. If you’re on Windows, bin also contains the original samples, if you want to compare.

I DO NOT claim to have gotten everything faithfully ported; any major substantive discrepancies are probably things I need to fix. :grinning_face_with_smiling_eyes:

The welcome and space samples use the Openmpt audio source. Currently that only has Windows support. This just means those samples do a little less, and that you can’t yet use its capabilities on other platforms in your own projects.

At the moment the samples are the documentation, although of course I mean to address that.

I’ve tried to hew pretty close to what you see on the SoLoud page. Major differences include using strings instead of enums, and tables where there are multiple default values, the idea in both cases being to avoid seemingly “magic” numbers as input.

Yet to do / ideas:

There is support for custom audio sources, used in particular by the piano sample. (This was an utter beast to implement! :smiley:) The groundwork for that should mean custom filters are also possible, but I didn’t have an example to port and so haven’t done it yet. Ditto colliders and attenuators, and maybe file ops. I figured these wouldn’t be urgent.

As mentioned above, Openmpt needs porting. I figure this shouldn’t be too bad, especially on Mac, but just have to work out how to make it optional in each case, as it comes down to bundling another library.

I had the same thought as fungos here, and for plugin purposes am not so worried about the attribution issue, so might add TinySoundFont support.

I haven’t yet done the Ay and TedSid samples because I don’t have any handy audio files. :smiley: The ones listed in the original source are either missing or in a no-longer-supported .dump form. (This has conversion utilities but I haven’t mustered the will to try it.)

A sample or two use some audio source member values, e.g. sample rate and such, without going through any getters. I only exposed the ones that were needed for those purposes, but there might be others that are useful. Similarly, I added a few methods to float buffers to make certain operations in the piano sample quicker; there might be other useful ones too.

There might be a few naming inconsistencies left in the API, like optional buffersize in one place but then sampleRate in others. I think these are mostly in corner cases, in which case I might still amend them before I write up the normative docs.

Linux, web, and Switch implementations still to do.

I left in a few print statements. There was an occasional issue when you quit, related to the audio thread. I might have fixed it, though I’m bewildered that the circumstance in question never even seems to happen now. :smiley: If anybody sees something about “mutex = no”, I would like to know. :slightly_smiling_face: Anyhow, those are otherwise harmless and I expect to remove them in not too long.

The Henley sample is the only “original” one (actually adapted from something in Paul Graham’s Common Lisp). It seems to just stop at some point—maybe when too many short words get queued up?—but I imagine that’s my own fault. :smiley:

Some of the samples start with a little sound before the timer fixes it up, so I’ll need to fix that. Also, in general they should probably use scenes and allow going back to the menu, but that concern was out-of-sight, out-of-mind when porting them. :smiley:


This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.

If anyone is interested in using this SoLoud plugin while keeping the same functionality as the current audio API, you can try this SoLoud Module that does precisely that.

The module currently doesn’t flex any of the additional SoLoud features than what the standard audio API offers, but I think it’ll be added in the future.

For now, just wanted to put this out there since it can be used together to bundle audio files using Binary Archive.

A side note: I do plan on creating a single Asset Bundle module where graphics, audio, and fonts will be accessible. Binary Archive will be stripped of Solar2D related code as it serves as an all purpose Lua module.


Thank you very much. We will try out this plugin in our project later.

After replacing the audio library with the soloud plugin, some crashes llike “Rtt_PlatformOpenALPlayer.cpp - Rtt::ALmixerSoundCompletionEvent::~ALmixerSoundCompletionEvent()” disappeared, but some new crashes appeared. The number seems to be small for now. I will continue to observe the situation of the crashes.

#00 pc 0x000000000000ade0 /system/lib/ (android::RefBase::decStrong(void const*) const+11)
#01 pc 0x00000000000488b9 /system/lib/ (android::IPCThreadState::processPendingDerefs()+80)
#02 pc 0x00000000000488f1 /system/lib/ (android::IPCThreadState::joinThreadPool(bool)+32)
#03 pc 0x000000000005ef35 /system/lib/ (android::PoolThread::threadLoop()+12)
#04 pc 0x000000000000d479 /system/lib/ (android::thread::_threadLoop(void*)+144)
#05 pc 0x00000000000a15a9 /system/lib/ (android::AndroidRuntime::javaThreadShell(void*)+80)
#06 pc 0x0000000000048a5f /system/lib/ (__pthread_start(void*)+22)
#07 pc 0x000000000001b333 /system/lib/ (__start_thread+32)

#00 pc 0x0000000000011f8c /system/lib/ (aaudio::AudioStream::MyPlayerBase::playerSetVolume()+5)

#00 pc 0x000000000005f1c8 /system/lib64/ (android::AudioTrack::setVolume(float, float)+412)
#01 pc 0x000000000002c774 /system/lib64/ (aaudio::AudioStreamTrack::doSetVolume()+132)
#02 pc 0x000000000001c568 /system/lib64/ (aaudio::AudioStream::MyPlayerBase::playerSetVolume()+184)
#03 pc 0x000000000007d6e0 /system/lib64/ (android::PlayerBase::setVolume(float)+96)
#04 pc 0x0000000000044d24 /system/lib64/ (android::media::BnPlayer::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+252)
#05 pc 0x000000000004d678 /system/lib64/ (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+136)
#06 pc 0x000000000005a4d0 /system/lib64/ (android::IPCThreadState::executeCommand(int)+1008)
#07 pc 0x000000000005a02c /system/lib64/ (android::IPCThreadState::getAndExecuteCommand()+156)
#08 pc 0x000000000005a80c /system/lib64/ (android::IPCThreadState::joinThreadPool(bool)+220)
#09 pc 0x0000000000080898 /system/lib64/ (android::PoolThread::threadLoop()+24)
#10 pc 0x0000000000013654 /system/lib64/ (android::thread::_threadLoop(void*)+328)
#11 pc 0x00000000000c4ac0 /system/lib64/ (android::AndroidRuntime::javaThreadShell(void*)+140)
#12 pc 0x00000000000d96d0 /apex/ (__pthread_start(void*)+36)
#13 pc 0x0000000000075f2c /apex/ (__start_thread+64)

#00 pc 0x000000000005fcb2 /apex/ (abort+166)
#01 pc 0x000000000003606d /system/lib/ (abort_message+88)
#02 pc 0x0000000000045c7f /system/lib/ (__cxa_pure_virtual+6)
#03 pc 0x0000000000014f4d /system/lib/ (aaudio::AudioStreamLegacy::processCallbackCommon(int, void*)+404)
#04 pc 0x0000000000043b23 /system/lib/ (android::AudioTrack::processAudioBuffer()+1858)
#05 pc 0x0000000000045875 /system/lib/ (android::AudioTrack::AudioTrackThread::threadLoop()+104)
#06 pc 0x000000000000d941 /system/lib/ (android::thread::_threadLoop(void*)+320)
#07 pc 0x00000000000a5bc9 /system/lib/ (android::AndroidRuntime::javaThreadShell(void*)+84)
#08 pc 0x00000000000a8147 /apex/ (__pthread_start(void*)+20)
#09 pc 0x0000000000061467 /apex/ (__start_thread+30)


If you have any logs, do you see any of the error messages mentioned here?

My NDK slighly predates that patch, I think, so it would be one shot in the dark. (None of the stack traces above involve library code, unfortunately.)

From what we can see now, after introducing the Soloud plugin, “ android::RefBase::decStrong(void const*) const SIGSEGV” is a new crash that occurs frequently, and this crash only occurs on Android 8 devices.

#00 pc 0x000000000000adac /system/lib/ (android::RefBase::decStrong(void const*) const+11)
#01 pc 0x00000000000488bf /system/lib/ (android::IPCThreadState::processPendingDerefs()+86)
#02 pc 0x00000000000488f5 /system/lib/ (android::IPCThreadState::joinThreadPool(bool)+32)
#03 pc 0x000000000005eff9 /system/lib/ (android::PoolThread::threadLoop()+24)
#04 pc 0x000000000000d469 /system/lib/ (android::thread::_threadLoop(void*)+140)
#05 pc 0x0000000000079f69 /system/lib/ (android::AndroidRuntime::javaThreadShell(void*)+80)
#06 pc 0x0000000000047db7 /system/lib/ (__pthread_start(void*)+22)
#07 pc 0x000000000001b0a5 /system/lib/ (__start_thread+32)

Do you have any idea when these happen? Are headphones involved?

Could you try modifying this line to include backend = "OPENSLES" in the createCore() arguments? (Example) I don’t have any ideas really, but maybe that would point to whether it’s an AAudio issue.

I’m not sure what caused this crash. I will try your method(for android 8) and see if it can solve the problem. There are also 3 crashes related to Soloud here.

Sample attributes: OPPO OP4FA7L1 (OPPO Reno6 Z 5G) Android 13 (SDK 33)
#00 pc 0x0000000000034aa4 /system/lib64/ (aaudio::AudioStreamTrack::release_l()+116)
#01 pc 0x00000000000279d0 /system/lib64/ (aaudio::AudioStream::safeReleaseCloseInternal()+176)
#02 pc 0x00000000000278d8 /system/lib64/ (aaudio::AudioStream::safeReleaseClose()+184)
#03 pc 0x00000000000050d8 /system/lib64/ (AAudioStream_close.cfi+120)
#04 pc 0x0000000000121254 /data/app/~~Tg4Xavf4_25MygXGcIc1mA==/com.mycompanyapp.testapp-FrQW43uSLlcRRtZc5GpjRQ==/split_config.arm64_v8a.apk!
#05 pc 0x00000000000fe8e0 /data/app/~~Tg4Xavf4_25MygXGcIc1mA==/com.mycompanyapp.testapp-FrQW43uSLlcRRtZc5GpjRQ==/split_config.arm64_v8a.apk!
#06 pc 0x00000000000eb720 /apex/ (__pthread_start(void*)+208)
#07 pc 0x000000000007e2d0 /apex/ (__start_thread+64)

Sample attributes: vsmart jacaranda (Aris) Android 11 (SDK 30) Version: 445 (1.0.427)
[split_config.arm64_v8a.apk!] ma_device_stop
#00 pc 0x00000000000041ec /system/lib64/ (AAudioStream_getState.cfi+44)
#01 pc 0x00000000001222a8 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk!
#02 pc 0x0000000000100ffc /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (ma_device_stop+236)
#03 pc 0x00000000001004ac /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (ma_device_uninit+52)
#04 pc 0x00000000001270dc /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (SoLoud::Soloud::deinit()+100)
#05 pc 0x0000000000126eec /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (SoLoud::Soloud::~Soloud()+28)
#06 pc 0x00000000000b1254 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk!
#07 pc 0x000000000001388c /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (luaD_precall+340)
#08 pc 0x0000000000013e84 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (luaD_call+397)
#09 pc 0x00000000000151f4 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (GCTM+467)
#10 pc 0x0000000000015100 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (luaC_callGCTM+479)
#11 pc 0x00000000000131cc /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (luaD_rawrunprotected+135)
#12 pc 0x00000000000213e8 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (lua_close+209)
#13 pc 0x00000000000ee3ac /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk!
#14 pc 0x00000000000ede78 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk!
#15 pc 0x000000000011ff1c /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk!
#16 pc 0x0000000000120078 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk!
#17 pc 0x0000000000042578 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk!
#18 pc 0x0000000000047798 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/split_config.arm64_v8a.apk! (Java_com_ansca_corona_JavaToNativeShim_nativeDone+36)
#19 pc 0x00000000000100a8 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/oat/arm64/base.odex (art_jni_trampoline+152)
#20 pc 0x00000000001337e8 /apex/ (art_quick_invoke_static_stub+568)
#21 pc 0x00000000001a8a94 /apex/ (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228)
#22 pc 0x000000000031830c /apex/ (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376)
#23 pc 0x000000000030e638 /apex/ (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+996)
#24 pc 0x000000000067f428 /apex/ (MterpInvokeStatic+548)
#25 pc 0x000000000012d994 /apex/ (mterp_op_invoke_static+20)
#26 pc 0x0000000000108b82 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/oat/arm64/base.vdex (com.ansca.corona.JavaToNativeShim.destroy+14)
#27 pc 0x0000000000305c34 /apex/ (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.11487796752256266877)+268)
#28 pc 0x000000000030dc24 /apex/ (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+200)
#29 pc 0x000000000030f00c /apex/ (bool art::interpreter::DoCall<false, true>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+1772)
#30 pc 0x0000000000177f40 /apex/ (void art::interpreter::ExecuteSwitchImplCpp<true, false>(art::interpreter::SwitchImplContext*)+57848)
#31 pc 0x000000000013f7d8 /apex/ (ExecuteSwitchImplAsm+8)
#32 pc 0x00000000000fa008 /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/oat/arm64/base.vdex (com.ansca.corona.Controller.destroy)
#33 pc 0x0000000000305d3c /apex/ (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.11487796752256266877)+532)
#34 pc 0x000000000030dc24 /apex/ (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+200)
#35 pc 0x000000000030e61c /apex/ (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+968)
#36 pc 0x0000000000682f14 /apex/ (MterpInvokeVirtualQuick+672)
#37 pc 0x0000000000131594 /apex/ (mterp_op_invoke_virtual_quick+20)
#38 pc 0x0000000000102bee /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/oat/arm64/base.vdex (com.ansca.corona.CoronaRuntime.dispose+46)
#39 pc 0x00000000006831b4 /apex/ (MterpInvokeVirtualQuick+1344)
#40 pc 0x0000000000131594 /apex/ (mterp_op_invoke_virtual_quick+20)
#41 pc 0x00000000000fd95e /data/app/~~jf8SvZEKGQkLhqms5FTCNg==/com.mycompanyapp.testapp-LOS0COb9xp5N3ZGo_1gr2Q==/oat/arm64/base.vdex (com.ansca.corona.CoronaActivity.onDestroy+50)
#42 pc 0x0000000000305c34 /apex/ (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.11487796752256266877)+268)
#43 pc 0x000000000066b1d8 /apex/ (artQuickToInterpreterBridge+780)
#44 pc 0x000000000013cff8 /apex/ (art_quick_to_interpreter_bridge+88)
#45 pc 0x00000000005c00e0 /system/framework/arm64/boot-framework.oat (
#46 pc 0x000000000031f274 /system/framework/arm64/boot-framework.oat (
#47 pc 0x000000000040752c /system/framework/arm64/boot-framework.oat (
#48 pc 0x0000000000402ea8 /system/framework/arm64/boot-framework.oat (
#49 pc 0x00000000005e0c40 /system/framework/arm64/boot-framework.oat (
#50 pc 0x000000000034b034 /system/framework/arm64/boot-framework.oat (
#51 pc 0x000000000034b848 /system/framework/arm64/boot-framework.oat (
#52 pc 0x00000000003e9358 /system/framework/arm64/boot-framework.oat ($H.handleMessage+536)
#53 pc 0x000000000063fbe4 /system/framework/arm64/boot-framework.oat (android.os.Handler.dispatchMessage+180)
#54 pc 0x00000000006430dc /system/framework/arm64/boot-framework.oat (android.os.Looper.loop+1516)
#55 pc 0x00000000003fce40 /system/framework/arm64/boot-framework.oat (
#56 pc 0x00000000001337e8 /apex/ (art_quick_invoke_static_stub+568)
#57 pc 0x00000000001a8a94 /apex/ (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228)
#58 pc 0x00000000005556d4 /apex/ (art::InvokeMethod(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long)+1364)
#59 pc 0x00000000004d4ee0 /apex/ (art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*)+52)
#60 pc 0x000000000008b6f4 /apex/ (art_jni_trampoline+180)
#61 pc 0x0000000000884ee8 /system/framework/arm64/boot-framework.oat ($
#62 pc 0x000000000088d6a0 /system/framework/arm64/boot-framework.oat (
#63 pc 0x00000000001337e8 /apex/ (art_quick_invoke_static_stub+568)
#64 pc 0x00000000001a8a94 /apex/ (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228)
#65 pc 0x0000000000554110 /apex/ (art::JValue art::InvokeWithVarArgsart::ArtMethod*(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+448)
#66 pc 0x00000000005545c4 /apex/ (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92)
#67 pc 0x0000000000438af8 /apex/ (art::JNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+656)
#68 pc 0x000000000009a424 /system/lib64/ (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, …)+124)
#69 pc 0x00000000000a2260 /system/lib64/ (android::AndroidRuntime::start(char const*, android::Vectorandroid::String8 const&, bool)+836)
#70 pc 0x0000000000003674 /system/bin/app_process64 (main+1580)
#71 pc 0x00000000000499e4 /apex/ (__libc_init+108)

Sample attributes: lge judypn (V40 ThinQ) Android 9 (SDK 28) Version: 445 (1.0.427)
#00 pc 0x00000000000223bc /system/lib64/ (abort+116)
#01 pc 0x000000000002b2b0 /system/lib64/ (abort_message+248)
#02 pc 0x000000000002ae0c /system/lib64/ (__cxa_pure_virtual+16)
#03 pc 0x00000000000270b0 /system/lib64/ (aaudio::AudioStream::waitForStateChange(int, int*, long)+356)
#04 pc 0x0000000000121798 /data/app/com.laboladoapp.labo_tank-epq3E6MIPeBKWma_UUrtqg==/split_config.arm64_v8a.apk
#05 pc 0x00000000001214ac /data/app/com.laboladoapp.labo_tank-epq3E6MIPeBKWma_UUrtqg==/split_config.arm64_v8a.apk
#06 pc 0x00000000000fe8e0 /data/app/com.laboladoapp.labo_tank-epq3E6MIPeBKWma_UUrtqg==/split_config.arm64_v8a.apk
#07 pc 0x0000000000092f8c /system/lib64/ (__pthread_start(void*)+36)
#08 pc 0x0000000000023c78 /system/lib64/ (__start_thread+68)

Okay, that second one has stuff like ma_device_stop() and ~Soloud, so is obviously happening on shutdown. Seems like the issue mentioned here, and it mentions “some devices running Android 8.0” in the link.

(SoLoud is built on top of miniaudio. I did update its own code not so long ago for some headphone stuff, so will have to puzzle out if it somehow hasn’t picked up those fixes.)

EDIT: Looking over some DMs and the project history, looks like I grabbed the latest release at the time (from April '22, about 6 months old at the time)… and then literally days later the pace picked back up again. :smiley: I’ll try to do some rebuilds shortly.

EDIT #2: Uploaded new builds.

After doing this, my game crashes as soon as it starts. Now, all of my Android 8 (26) devices are using Solar2D’s built-in audio library, while Soloud plugin is used for others. The two crashes, “ android::RefBase::decStrong(void const*) const SIGSEGV” and “Rtt_PlatformOpenALPlayer.cpp - Rtt::ALmixerSoundCompletionEvent::~ALmixerSoundCompletionEvent()”, have not occurred so far.

There is a very small chance of a crash with “Rtt_PlatformOpenALPlayer.cpp - Rtt::PlatformALmixerPlaybackFinishedCallback::PlatformALmixerPlaybackFinishedCallback(Rtt::ResourceHandle<lua_State> const&)” occurs on Android 8 (26) system.

I will update to the latest build and then see if there are still any crashes.

Crashes after upgrading to the latest build.I think most of them are related to the Soloud plugin

[split_config.arm64_v8a.apk!] ldo.c - luaD_precall
pid: 0, tid: 3762 >>> com.testapp <<<

#00 pc 0x000000000009ebfc /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk!
#01 pc 0x000000000001388c /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk! (luaD_precall+340)
#02 pc 0x0000000000028ac0 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk! (luaV_execute+595)
#03 pc 0x0000000000013e94 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk! (luaD_call+398)
#04 pc 0x00000000000131cc /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk! (luaD_rawrunprotected+135)
#05 pc 0x00000000000141bc /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk! (luaD_pcall+484)
#06 pc 0x000000000000a424 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk! (lua_pcall+821)
#07 pc 0x00000000000edae8 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk!
#08 pc 0x00000000001219d8 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk!
#09 pc 0x0000000000121bc8 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk!
#10 pc 0x0000000000043718 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk!
#11 pc 0x0000000000047454 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/split_config.arm64_v8a.apk! (Java_com_ansca_corona_JavaToNativeShim_nativeResume+32)
#12 pc 0x00000000000110a8 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/oat/arm64/base.odex (art_jni_trampoline+152)
#13 pc 0x0000000002015ac8 /memfd:jit-cache (com.ansca.corona.Controller.updateRuntimeState+200)
#14 pc 0x0000000002001e28 /memfd:jit-cache ($GLThread.guardedRun+3032)
#15 pc 0x000000000013487c /apex/ (art_quick_osr_stub+60)
#16 pc 0x000000000033fff0 /apex/ (art::jit::Jit::MaybeDoOnStackReplacement(art::Thread*, art::ArtMethod*, unsigned int, int, art::JValue*)+344)
#17 pc 0x000000000068e234 /apex/ (MterpMaybeDoOnStackReplacement+208)
#18 pc 0x0000000000133350 /apex/ (MterpHelpers+240)
#19 pc 0x000000000016f6b2 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/oat/arm64/base.vdex ($GLThread.guardedRun+946)
#20 pc 0x00000000006821c0 /apex/ (MterpInvokeDirect+1248)
#21 pc 0x000000000012e914 /apex/ (mterp_op_invoke_direct+20)
#22 pc 0x000000000016fab4 /data/app/~~rigVAPcUyla5FW60d5uffA==/com.testapp-wecXXCClwZRvqDP2yjn2VA==/oat/arm64/base.vdex ($
#23 pc 0x0000000000308b40 /apex/ (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.9213191182998925907)+268)
#24 pc 0x000000000066e5ac /apex/ (artQuickToInterpreterBridge+780)
#25 pc 0x000000000013dff8 /apex/ (art_quick_to_interpreter_bridge+88)
#26 pc 0x0000000000134564 /apex/ (art_quick_invoke_stub+548)
#27 pc 0x00000000001a9a78 /apex/ (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
#28 pc 0x0000000000557d74 /apex/ (art::JValue art::InvokeVirtualOrInterfaceWithJValuesart::ArtMethod*(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+460)
#29 pc 0x00000000005a73b4 /apex/ (art::thread::CreateCallback(void*)+1308)
#30 pc 0x00000000000eb9ac /apex/ (__pthread_start(void*)+64)
#31 pc 0x000000000008bb88 /apex/ (__start_thread+64)

Is there a way to fix the crash of luaD-precall or output more detailed stack trace? Now the number of crashes of this one has exceeded “[] android::RefBase::decStrong(void const*) const”.

Thanks for the awesome module, that’s just what I need!

I’ve replace original audio by m_soloud_audio and found an issue that the channel seems to be not freed after
Tried it both on original one and soloud one by print("free chnl: "…audio.findFreeChannel( ) ) after each the soloud one just keep increasing the count of channel found while the original one just get the none playing ones.

Not sure the cause was from soloud or m_soloud_audio, do you have any idea?

Thank! :slight_smile:

1 Like

First question, are you using latest version? :slightly_smiling_face:

I tried to replicate the issue but seems to be reporting fine:

timer.performWithDelay(1000, function() 
print("findFreeChannel", AUDIO.findFreeChannel())
end, -1)

It returned channel 2 while playing an audio, once the audio finished it returned channel 1.

If you’re still having issues, do you think you can provide a sample project replicating the issue?


I grabbed it here: GitHub - siudesu/SoLoudModule: Solar2D Lua module to use with SoLoud plugin.
and using Solar2d 2023.3691 MacOS 11.7.7

here is my code:
audio = require"m_soloud_audio"
timer.performWithDelay(100, function()"sfx_bite1.mp3"
print(“findFreeChannel”, audio.findFreeChannel())
end, -1)

after the count reach 32, it start return 0. it just won’t count back. both sfx_bite1.mp3 and m_soloud_audio are at project root. I tried both replace audio and declare it as AUDIO, still no luck.
any other clue that might cause this?

@pickerel “or output more detailed stack trace?” I would like that myself! :slight_smile:

Unfortunately all I can tell is that a pcall is happening (the (lua_pcall+821) bit) and only on #00 is there any mention of SoLoud itself. Didn’t see any pcall()s in Siu’s module. Would it point to anything particular in your code? The only “ordinary” part of SoLoud that does a lua_pcall() is in the onComplete-ish logic, but I would expect to show up further in the call stack, in that case.

Could you send send the rest of the call stacks, including the ma_device_* ones? Preferably as a zip or something, so this isn’t full of walls of error text.

I saw you were looking at BugSnag. Please do let me know if you can narrow anything down. I’d gladly fix this, but don’t know where to look. :smiley:

Good. You can grab the new version now; it’s fixed. :slightly_smiling_face:

With the same code you provided I tested the new implementation and channel usage stayed under 5.

Results will vary depending on how short the audio is, but freeing channels internally should no longer be an issue under this circumstance.

Thanks for reporting and providing the sample code. :+1:t3:

Yeah~ that’s works fine! thanks for the quick fix! :grinning_face_with_smiling_eyes:

Btw, I found the result of setPitch() and setSpeed() are the same. I’m using this module for playing musical notes say play C4,D4,E4,F4,G4,A4,B4 by just load a single ‘pianoF4.mp3’ then tweak it’s pitch and speed.

the code here:
audio = require"m_soloud_audio"
local _chnl= “pianoF4.mp3”, {channel= audio.findFreeChannel()} )
audio.setPitch( _chnl, 2 )
audio.setSpeed( _chnl, 1/2 )

My desired result is the length of playing sound should be as close as origin one, and the pitch should be sound like ‘pianoF5.mp3’. Not sure if soloud able to achieve this, I know that is possible but not feasible due to it might require to reformat the audio file to prolong it.

Do you guys know how to do that? thanks a lot :blush: