Page 1 of 2

Android Audio

Posted: Sat Oct 14, 2017 2:19 am
by LunaRebirth
I was trying to use SFML for audio, which works great on PC. But when it comes to Android, it's been a major disaster for me so far.

Does anyone have any experience with an audio library that's cross-compatible with Android?

I'm looking for a free-for-commercial-use audio library.

Re: Android Audio

Posted: Sat Oct 14, 2017 8:24 am
by hendu
OpenAL.

Re: Android Audio

Posted: Sat Oct 14, 2017 12:47 pm
by CuteAlien
Yeah I also use OpenAL (this one: https://github.com/apportable/openal-soft) in combination with Tremor (https://wiki.xiph.org/Tremor) for ogg-vorbis (other ogg-vorbis implementation back then didn't work for me, but this might have changed in the meantime).

Re: Android Audio

Posted: Mon Oct 16, 2017 4:44 pm
by LunaRebirth
Great, thanks.
I'm having a bit of troubles compiling Irrlicht with OpenAL on Android. Perhaps you could help me :D

I took the source online which plays audio files, using the OpenAL binaries (I had troubles building it myself):

Code: Select all

    ALboolean enumeration;
    const ALCchar *devices;
    const ALCchar *defaultDeviceName = argc1;
    int ret;
    char *bufferData;
    ALCdevice *device;
    ALvoid *data;
    ALCcontext *context;
    ALsizei size, freq;
    ALenum format;
    ALuint buffer, source;
    ALfloat listenerOri[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f };
    ALboolean loop = AL_FALSE;
    ALCenum error;
    ALint source_state;
 
    //fprintf(stdout, "Using " BACKEND " as audio backend\n");
 
    enumeration = alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT");
    if (enumeration == AL_FALSE)
        fprintf(stderr, "enumeration extension not available\n");
 
    if (!defaultDeviceName)
        defaultDeviceName = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
 
    device = alcOpenDevice(defaultDeviceName);
    if (!device) {
        fprintf(stderr, "unable to open default device\n");
        return -1;
    }
 
    fprintf(stdout, "Device: %s\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
 
    alGetError();
 
    context = alcCreateContext(device, NULL);
    if (!alcMakeContextCurrent(context)) {
        fprintf(stderr, "failed to make default context\n");
        return -1;
    }
    TEST_ERROR("make default context");
 
    /* set orientation */
    alListener3f(AL_POSITION, 0, 0, 1.0f);
    TEST_ERROR("listener position");
        alListener3f(AL_VELOCITY, 0, 0, 0);
    TEST_ERROR("listener velocity");
    alListenerfv(AL_ORIENTATION, listenerOri);
    TEST_ERROR("listener orientation");
 
    alGenSources((ALuint)1, &source);
    TEST_ERROR("source generation");
 
    alSourcef(source, AL_PITCH, 1);
    TEST_ERROR("source pitch");
    alSourcef(source, AL_GAIN, 1);
    TEST_ERROR("source gain");
    alSource3f(source, AL_POSITION, 0, 0, 0);
    TEST_ERROR("source position");
    alSource3f(source, AL_VELOCITY, 0, 0, 0);
    TEST_ERROR("source velocity");
    alSourcei(source, AL_LOOPING, AL_FALSE);
    TEST_ERROR("source looping");
 
    alGenBuffers(1, &buffer);
    TEST_ERROR("buffer generation");
 
    alutLoadWAVFile((ALbyte*)"Worlds/global/Sounds/Beginning.wav", &format, &data, &size, &freq, &loop);
    TEST_ERROR("loading wav file");
 
    alBufferData(buffer, format, data, size, freq);
    TEST_ERROR("buffer copy");
 
    alSourcei(source, AL_BUFFER, buffer);
    TEST_ERROR("buffer binding");
 
    alSourcePlay(source);
    TEST_ERROR("source playing");
 
    alGetSourcei(source, AL_SOURCE_STATE, &source_state);
    TEST_ERROR("source state get");
With the binary files, this works great.

On Android, I downloaded OpenAL-soft as provided (https://github.com/apportable/openal-soft) but I get errors when using ndk-build, including:

Code: Select all

In file included from jni/../../openal-soft-android/jni/OpenAL/Alc/ALc.c:36:0:
jni/../../openal-soft-android/jni/OpenAL/OpenAL32/Include/alAuxEffectSlot.h:45:1: warning: no semicolon at end of struct or union
 };
 ^
In file included from jni/../../openal-soft-android/jni/OpenAL/Alc/ALc.c:38:0:
jni/../../openal-soft-android/jni/OpenAL/OpenAL32/Include/bs2b.h:105:41: error: unknown type name 'ALfp'
 void bs2b_cross_feed(struct bs2b *bs2b, ALfp *sample);
                                         ^
make: *** [obj/local/armeabi/objs/Project/__/openal-soft-android/jni/OpenAL/Alc/ALc.o] Error 1
Here is my Android.mk file:

Code: Select all

LOCAL_PATH := $(call my-dir)/..
IRRLICHT_PROJECT_PATH := $(LOCAL_PATH)
 
include $(CLEAR_VARS)
LOCAL_MODULE := Irrlicht
LOCAL_SRC_FILES := ../irrlicht-code-5543-branches-ogl-es/lib/Android/libIrrlicht.a
LOCAL_STATIC_LIBRARIES := src/liblua.a
include $(PREBUILT_STATIC_LIBRARY)
 
include $(CLEAR_VARS)
 
LOCAL_MODULE := Project
APP_ALLOW_MISSING_DEPS := true
 
LOCAL_CFLAGS := -D_IRR_ANDROID_PLATFORM_ -pipe -fexceptions -fno-exceptions -fno-rtti -fstrict-aliasing -DLUA_ANSI -DLUA_USE_APICHECK
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../openal-soft-android/jni/OpenAL \
        -I$(LOCAL_PATH)/../openal-soft-android/jni/OpenAL/include \
        -I$(LOCAL_PATH)/../openal-soft-android/jni/OpenAL/include/AL \
        -I$(LOCAL_PATH)/../openal-soft-android/jni/OpenAL/OpenAL32/Include \
        -DAL_ALEXT_PROTOTYPES \
                -DANDROID \
                -fpic \
                -ffunction-sections \
                -funwind-tables \
                -fstack-protector \
                -fno-short-enums \
                -DHAVE_GCC_VISIBILITY \
                -O3 \
                -g \
 
ifndef NDEBUG
LOCAL_CFLAGS += -g -D_DEBUG
else
LOCAL_CFLAGS += -fexpensive-optimizations -O3
endif
 
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_CFLAGS += -fno-stack-protector
endif
 
LOCAL_C_INCLUDES := include ../irrlicht-code-5543-branches-ogl-es/include src/Lua ../freealut-master/include
 
FILE_LIST := $(wildcard $(LOCAL_PATH)/src/*.cpp)
LUA_FILE_LIST := $(wildcard $(LOCAL_PATH)/include/Lua/*.c*)
OPENAL_FILE_LIST_1 := $(wildcard $(LOCAL_PATH)/../openal-soft-android/jni/OpenAL/Alc/*.c*)
OPENAL_FILE_LIST_2 := $(wildcard $(LOCAL_PATH)/../openal-soft-android/jni/OpenAL/OpenAL32/*.c*)
LOCAL_SRC_FILES := main.cpp $(FILE_LIST:$(LOCAL_PATH)/%=%) $(LUA_FILE_LIST:$(LOCAL_PATH)/%=%) $(OPENAL_FILE_LIST_1:$(LOCAL_PATH)/%=%) $(OPENAL_FILE_LIST_2:$(LOCAL_PATH)/%=%)
 
LOCAL_LDLIBS := -lEGL -llog -lGLESv1_CM -lGLESv2 -lz -landroid -lm
LOCAL_LDLIBS    += -Wl,--build-id -Bsymbolic -shared
 
LOCAL_STATIC_LIBRARIES := Irrlicht android_native_app_glue
LOCAL_SHARED_LIBRARIES += libandroid 
include $(BUILD_SHARED_LIBRARY)
 
$(call import-module,android/native_app_glue)
 
# copy Irrlicht data to assets
 
$(shell mkdir -p $(IRRLICHT_PROJECT_PATH)/assets)
$(shell mkdir -p $(IRRLICHT_PROJECT_PATH)/assets/media)
$(shell mkdir -p $(IRRLICHT_PROJECT_PATH)/assets/media/Shaders)
$(shell cp $(IRRLICHT_PROJECT_PATH)/media/Shaders/*.* $(IRRLICHT_PROJECT_PATH)/assets/media/Shaders/)
Appreciate any help

Re: Android Audio

Posted: Mon Oct 16, 2017 8:55 pm
by CuteAlien
Strange error - saying there is no semicolon while pointing to the semicolon?

Unfortunately figuring out build-errors on another system is hard. And I rememer getting OpenAL + FreeAlut working together (you likely need both) was some work back then, just not remembering what was hard.

So I can only tell you what I did. If you check https://bitbucket.org/mzeilfelder/trunk_hc1/src there are my build-file for Android and OpenAL in libs/openal/openal-soft-apportable/jni. Thought it's probably not changed much from the original one.

And in folder build (same repository) there is a script called make-openal-android.sh which I used to build OpenAL and FreeAlut. So in that script are the exact ndk-build commands which I used to build those libs. I seem to have build them as shared libs.

And when using those libs in my Application - that build-file is in build/android/jni/Android.mk. In there search for "openal".

Re: Android Audio

Posted: Thu Oct 19, 2017 11:22 pm
by LunaRebirth
It's great to see your open-source project. Lots of cool things I can learn from it.

Unfortunately after following doc/build.txt for Windows, the exe comes out, but does nothing after starting (opens a console only, must use task manager to close the program, even when running as a GUI) so I can't really test it.

Nonetheless, I think it would be really helpful if someone could make an OpenAL + freealut for Android tutorial. I'm having way more issues with it than I should, and there isn't one site within 5 pages of Google that I haven't clicked trying to figure out how to set this up.

OpenAL-Soft compiles fine now, but there is no documentation on freealut that includes it's mobile ability.
I follow https://wiki.haskell.org/ALUT for building freealut, then get stuck on an error produced from mingw's math.h file

Code: Select all

c:\mingw\bin\../lib/gcc/mingw32/4.7.2/../../../../include/math.h:379:20: error: expected identifier or '(' before numeric constant
src\CMakeFiles\alut.dir\build.make:287: recipe for target 'src/CMakeFiles/alut.dir/alutWaveform.c.obj' failed
I'm failing embarrassingly bad at adding audio to my android project. I haven't had this much trouble with something that should be so simple in a long time.

Re: Android Audio

Posted: Fri Oct 20, 2017 12:17 am
by CuteAlien
Hm, aside from the build-script I mentioned above I can't help much. And yeah - that stuff can be hard to build. It also took my quite a while to get those working - and after updating my project a few years later I spend again a lot of time. Which is why I wrote the scripts which kinda document each step so I'll have it easier next time. Actually haven't tried to build it in a while... just noticed that I already got newer libs installed again (gcc 6.30 headers now it seems in my case). Unfortunately those headers changed too much - my math.h doesn't even have 379 lines but got a lot shorter, so not sure what your error is about.

Is that error the only one you get? Maybe post the line with the error and the few lines before it in case it gives some hint.

Re: Android Audio

Posted: Fri Oct 20, 2017 1:00 am
by LunaRebirth
I ended up directly taking your hcraft freealut folder.
Everything seems to build fine with it, no errors.
Now I'm just trying to build the Irrlicht Android Example with sound.

I'm getting a crash as soon as the OpenAL device is started:

Code: Select all

10-19 19:35:18.782 29102 29102 F DEBUG   : backtrace:
10-19 19:35:18.782 29102 29102 F DEBUG   :     #00 pc 000cd948  /data/app/com.irrlicht.example-1/lib/arm/libopenal.so
10-19 19:35:18.782 29102 29102 F DEBUG   :     #01 pc 00013bd8  /data/app/com.irrlicht.example-1/lib/arm/libopenal.so (alcOpenDevice+1120)
10-19 19:35:18.782 29102 29102 F DEBUG   :     #02 pc 0011f36f  /data/app/com.irrlicht.example-1/lib/arm/libHelloWorldMobile.so (_Z9InitSoundv+106)
10-19 19:35:18.782 29102 29102 F DEBUG   :     #03 pc 0011fff1  /data/app/com.irrlicht.example-1/lib/arm/libHelloWorldMobile.so (android_main+1936)
10-19 19:35:18.782 29102 29102 F DEBUG   :     #04 pc 0027dd55  /data/app/com.irrlicht.example-1/lib/arm/libHelloWorldMobile.so
10-19 19:35:18.782 29102 29102 F DEBUG   :     #05 pc 00046eb3  /system/lib/libc.so (_ZL15__pthread_startPv+22)
10-19 19:35:18.782 29102 29102 F DEBUG   :     #06 pc 00019acd  /system/lib/libc.so (__start_thread+6)
I assume this might be because I don't have a .java file with the System.loadLibrary. I don't see any documentation on how to load the .java file, though it's likely from the android manifest.

Code: Select all

bool InitSound()
{
    ALboolean enumeration;
    const ALCchar *devices;
    const ALCchar *defaultDeviceName;
    int ret;
    char *bufferData;
    ALCdevice *device;
    ALvoid *data;
    ALCcontext *context;
    ALsizei size, freq;
    ALenum format;
    ALuint buffer, source;
    ALfloat listenerOri[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f };
    ALboolean loop = AL_FALSE;
    ALCenum error;
    ALint source_state;
 
    //fprintf(stdout, "Using " BACKEND " as audio backend\n");
 
    enumeration = alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT");
    if (enumeration == AL_FALSE)
        fprintf(stderr, "enumeration extension not available\n");
 
    //if (!defaultDeviceName)
        defaultDeviceName = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
 
    device = alcOpenDevice(defaultDeviceName);
    if (!device) {
        fprintf(stderr, "unable to open default device\n");
        return -1;
    }
 
    fprintf(stdout, "Device: %s\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
 
    alGetError();
 
    context = alcCreateContext(device, NULL);
    if (!alcMakeContextCurrent(context)) {
        fprintf(stderr, "failed to make default context\n");
        return -1;
    }
    TEST_ERROR("make default context");
 
    /* set orientation */
    alListener3f(AL_POSITION, 0, 0, 1.0f);
    TEST_ERROR("listener position");
        alListener3f(AL_VELOCITY, 0, 0, 0);
    TEST_ERROR("listener velocity");
    alListenerfv(AL_ORIENTATION, listenerOri);
    TEST_ERROR("listener orientation");
 
    alGenSources((ALuint)1, &source);
    TEST_ERROR("source generation");
 
    alSourcef(source, AL_PITCH, 1);
    TEST_ERROR("source pitch");
    alSourcef(source, AL_GAIN, 1);
    TEST_ERROR("source gain");
    alSource3f(source, AL_POSITION, 0, 0, 0);
    TEST_ERROR("source position");
    alSource3f(source, AL_VELOCITY, 0, 0, 0);
    TEST_ERROR("source velocity");
    alSourcei(source, AL_LOOPING, AL_FALSE);
    TEST_ERROR("source looping");
 
    alGenBuffers(1, &buffer);
    TEST_ERROR("buffer generation");
 
    alutLoadWAVFile((ALbyte*)"media/Beginning.wav", &format, &data, &size, &freq, &loop);
    TEST_ERROR("loading wav file");
 
    alBufferData(buffer, format, data, size, freq);
    TEST_ERROR("buffer copy");
 
    alSourcei(source, AL_BUFFER, buffer);
    TEST_ERROR("buffer binding");
 
    alSourcePlay(source);
    TEST_ERROR("source playing");
 
    alGetSourcei(source, AL_SOURCE_STATE, &source_state);
    TEST_ERROR("source state get");
 
       // play forever -- just until it actually works
    while (true)
       {
        alGetSourcei(source, AL_SOURCE_STATE, &source_state);
        if (source_state != AL_PLAYING)
            alSourcePlay(source);
       }
 
    /* exit context */
    alDeleteSources(1, &source);
    alDeleteBuffers(1, &buffer);
    device = alcGetContextsDevice(context);
    alcMakeContextCurrent(NULL);
    alcDestroyContext(context);
    alcCloseDevice(device);
 
    return 1;
}
(From https://github.com/ffainelli/openal-exa ... -example.c, works fine on Windows)

EDIT:
Seems I was naïve on how the .java file got compiled. I simply added a file src/com/Irrlicht/example.java with the source:

Code: Select all

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
 
public class example extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        System.loadLibrary("openal");
        System.loadLibrary("freealut");
    }
}
which seems to compile just fine.
The crash remains at the same location.

By changing device = alcOpenDevice(defaultDeviceName) to device = alcOpenDevice(0), there was no change in behavior as expected. Crash remains.

Re: Android Audio

Posted: Fri Oct 20, 2017 1:47 am
by CuteAlien
Right, the stupid System.loadLibrary stuff which was needed because those libs could only be compiled as shared-libs and Android doesn't allow linking any shared c++ libs which are not already part of the Android system! I completely forgot about that ****

So...yeah - you have to load those libs from Java - no way around it I think (at least I didn't find a way around it back then). Which means you need one Java-class. In hcraft it's the file build/android/src/com/irrgheist/HC1NativeActivity.java
And you have to register that class somehow, can't remember details - but I think I added it in AndroidManifest.xml as application class.
You can remove all the AdHelper and BillingHelper parts in that class (that was about online payment stuff).

I also notice that you are working with OpenAL directly. In that case you probably don't need FreeAlut (that has utility functions which make stuff like OpenAL setup easier).

If you use alut you might start by using their hello-world first: http://distro.ibiblio.org/rootlinux/roo ... /alut.html

Re: Android Audio

Posted: Fri Oct 20, 2017 2:23 am
by LunaRebirth
CuteAlien wrote:In hcraft it's the file build/android/src/com/irrgheist/HC1NativeActivity.java
And you have to register that class somehow, can't remember details - but I think I added it in AndroidManifest.xml as application class.
You can remove all the AdHelper and BillingHelper parts in that class (that was about online payment stuff).

I also notice that you are working with OpenAL directly. In that case you probably don't need FreeAlut (that has utility functions which make stuff like OpenAL setup easier).
Yeah I took what I needed out of HC1NativeActivity.java, and the crash didn't change.
I also copied the source from hcraft's src/sound_openal.cpp, and this time the crash occurred at alutInit which contains alcOpenDevice

Code: Select all

10-19 21:12:01.775 10277 10277 F DEBUG   : backtrace:
10-19 21:12:01.775 10277 10277 F DEBUG   :     #00 pc 000cd9bc  /data/app/com.irrlicht.example-1/lib/arm/libopenal.so
10-19 21:12:01.775 10277 10277 F DEBUG   :     #01 pc 00013bbc  /data/app/com.irrlicht.example-1/lib/arm/libopenal.so (alcOpenDevice+1120)
10-19 21:12:01.775 10277 10277 F DEBUG   :     #02 pc 0000397f  /data/app/com.irrlicht.example-1/lib/arm/libfreealut.so (alutInit+38)
10-19 21:12:01.775 10277 10277 F DEBUG   :     #03 pc 0011f3af  /data/app/com.irrlicht.example-1/lib/arm/libHelloWorldMobile.so (_Z9InitSoundv+106)
10-19 21:12:01.775 10277 10277 F DEBUG   :     #04 pc 00120039  /data/app/com.irrlicht.example-1/lib/arm/libHelloWorldMobile.so (android_main+1936)
10-19 21:12:01.775 10277 10277 F DEBUG   :     #05 pc 0027dd9d  /data/app/com.irrlicht.example-1/lib/arm/libHelloWorldMobile.so
10-19 21:12:01.775 10277 10277 F DEBUG   :     #06 pc 00046eb3  /system/lib/libc.so (_ZL15__pthread_startPv+22)
10-19 21:12:01.775 10277 10277 F DEBUG   :     #07 pc 00019acd  /system/lib/libc.so (__start_thread+6)
I'm really not sure what I'm missing here ...

Re: Android Audio

Posted: Fri Oct 20, 2017 9:52 am
by CuteAlien
Difficult :-( Maybe reduce your application first. Backup your old main and create a new one which does nothing but sound at all. And same for Android.mk - only use a single file for your main with sound. Then you know at least nothing else is getting in the way.
The callstack looks to me like it has the libopenal.so
You might try to test if sound in my game works by installing it from GooglePlay (no worries it's free), so you know at least that code will work in theory (I haven't updated it in a long time and not tested with newer Android versions...).

edit: Sorry, I forgot another thing (it was late last night...). I worked on Linux when developing for Android. I only compiled Windows version of H-Craft on MinGW. So I guess I should try on compiling for Android on MinGW first myself *sigh*

Re: Android Audio

Posted: Fri Oct 20, 2017 2:19 pm
by LunaRebirth
CuteAlien wrote:Backup your old main and create a new one which does nothing but sound at all. And same for Android.mk - only use a single file for your main with sound. Then you know at least nothing else is getting in the way.
The callstack looks to me like it has the libopenal.so
I downloaded the example program from http://pielot.org/wp-content/uploads/20 ... OpenAL.zip and after building it, it ran fine and played sound.
Sadly it looks like it plays from the .java file and doesn't seem to have an android_main, so I'm having trouble learning how to merge it with the Irrlicht Android example.
CuteAlien wrote:You might try to test if sound in my game works by installing it from GooglePlay (no worries it's free), so you know at least that code will work in theory (I haven't updated it in a long time and not tested with newer Android versions...).
Yep, sounded great.
Honestly, I'm a little surprised it has only a thousand downloads. One of the smoothest running racers on my phone I've played by far.

Re: Android Audio

Posted: Fri Oct 20, 2017 3:29 pm
by CuteAlien
Yeah, everything easier from Java on Android ... NDK is badly supported by google. I'm a little stumped myself right now. It just shouldn't crash there :-( Maybe you will have to look for another OpenAL version?

And thanks for comments about racer :-) But well - I know many problems with it - like on most new system you can't even enter the name easily on start-screen right now (and having to enter name as first thing might already be annoying anyway). And everyone complains about missing input controls with gyroscope. Maybe I'll improve it again some day - but currently too much other stuff to do. Also I kinda would prefer working on a new game instead :-)

Re: Android Audio

Posted: Fri Oct 20, 2017 3:56 pm
by LunaRebirth
According to http://pielot.org/2010/12/14/openal-on- ... mment-1160, this is a fix for the crash.
Don't really see how it will help me with the snippet I posted above, though.

Re: Android Audio

Posted: Fri Oct 20, 2017 7:06 pm
by CuteAlien
Did you try printing defaultDeviceName to see which value it has?