Author Topic: OpenAL for Android  (Read 19615 times)

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3473
  • Developer
    • View Profile
    • PaulsCode.Com
OpenAL for Android
« on: August 09, 2011, 07:15:56 PM »
I decided to take a short breather from my N64 emulator project and finish another project I've been sitting on for a while.  This is my port of native OpenAL to Android with a simple Java interface.  It will basically allow you to add OpenAL to your Android projects without having to play around with c/c++ and JNI.  It should work on all versions of Android back to 1.5.

The Java interface for this port is probably closer to JOAL rather than LWJGL's interface.  There are a few differences from JOAL, however (mainly in the methods that take array/ buffer parameters, the way the context is created and destroyed, and the lack of a direct interface to ALC with device and context objects Java-side).  That being said, code written for JOAL or LWJGL is pretty simple to make work with my interface (it's all OpenAL when you get right down to the nuts and bolts, after all).

Everything is accessed statically through the class paulscode.android.sound.ALAN.  Before creating any sources and what-not, first connect with the Android audio device and create an AL context by calling:
Code: [Select]
ALAN.create();
From there, you can access whatever AL functions you need through ALAN.  For example:
Code: [Select]
        int[] ALBufferIDs = new int[BUFFER_COUNT];
        int[] source = new int[1];
        int[] state = new int[1];
        ALAN.alGenSources( 1, source );
        ALAN.alGenBuffers( BUFFER_COUNT, ALBufferIDs );
        ALAN.alBufferData( ALBufferIDs[i], format, buffer, buffer.length, rate );
        ALAN.alSourceQueueBuffers( source[0], c, ALBufferIDs );
        ALAN.alSourceQueueBuffers( source[0], c, ALBufferIDs );
        ALAN.alSourcePlay( source[0] );
        ALAN.alGetSourcei( source[0], ALAN.AL_SOURCE_STATE, state );
        if( state[0] != ALAN.AL_PLAYING )
            whatever();

And when you're finished, destroy the AL context and disconnect from the Android audio device by calling:
Code: [Select]
ALAN.destroy();
In case you haven't caught on, ALAN isn't a personal name like some AI alias - it's just an abbreviated form of  "OpenAL for Android" (fewer keystrokes than OpenALAndroid).  On a humorous note, I was actually forced to rename a hundred or so references to my project's original title "Android OpenAL", which I was horrified to realize became "ANAL" when abbreviated.  THAT was a real pain in the butt ;D

Anyway, here is a very basic app to demonstrate streaming an .ogg file:
ALAN Demo    (source code)

I normally drop in the source code to my projects, but you should be able to just unzip the above APK file, grab the contents of the "lib" folder, and paste them into your own project's "lib" folder.  If you prefer to compile the source code yourself, you can unzip the source code archive above and either run the following commands from the terminal/command prompt:
Code: [Select]
ndk-build
ant debug
ant install
Or you can "create a new project from source" in Eclipse (requires the Android SDK and NDK to be installed, as well as the ADT plug-in and Sequoyah Android Native Code plugin from the update site plug-ins).  Once you've created the Eclipse project, just right-click on it in the left panel and navigate to "Android Tools->Add Native Support".

The above demo utilizes the Tremolo library for decoding the .ogg file.  It is a popular library for use on Android because it is extra light-weight and optimized for the ARM archetecture, but there are plenty of other decoder libraries out there you could use if you have problems with that one.  In theory, you could even use any of a number of pure-Java audio decoders as well, including the ones included with my SoundSystem library.  I do not recommend copying the code from this demo - it very inefficient and meant only as a proof of concept.

One final note: OpenAL Android is licensed by the LGPL (since that is what OpenAL and Tremolo are licensed under).  While I normally shy away from this license, it actually meshes really well with Android apps, because the end user can use any of a number of free backup programs (such as ASTRO) to create a backup APK of your app.  From there, he can plug in a different version of the library into the APK, and simply reinstall it.  All you have to do is mention somewhere in your documentation where they can acquire the sourcecode for OpenAL Android (feel free to mention my website if you don't want to host the files yourself).  Please let me know if you encounter any bugs (logcat output is always helpful).
« Last Edit: August 10, 2011, 07:52:27 PM by Paul »
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Melinda

  • Global Moderator
  • bit
  • *****
  • Posts: 5
    • View Profile
Re: OpenAL for Android
« Reply #1 on: August 10, 2011, 11:13:42 AM »
ANdroid OpenAL, ROFL!  :o

hehe guess I should say LMFAO
One hot mamma!

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3473
  • Developer
    • View Profile
    • PaulsCode.Com
Re: OpenAL for Android
« Reply #2 on: August 10, 2011, 02:43:29 PM »
Ha!  Nice.
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3473
  • Developer
    • View Profile
    • PaulsCode.Com
Re: OpenAL for Android
« Reply #3 on: August 10, 2011, 07:31:31 PM »
A couple folks have asked me why they can't change the volume on the ALAN Demo app.  That's because I threw everything into the activity's onCreate method, and the thread blocks there in the stream loop until playback finishes.  This was just for demonstration purposes - you wouldn't normally write an app that way.  You'll also notice that the make-shift ogg decoder I threw together is really inefficient (takes encoded buffers from Java, decode them in native, sends then back to Java, then Java sends them back to native to be played).  I wouldn't recommend copying any part of that demo in a real-world app - it is entirely a proof of concept.
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline gouessej

  • byte
  • *
  • Posts: 17
    • View Profile
    • TUER (first person shooter written in Java by Julien Gouesse)
Re: OpenAL for Android
« Reply #4 on: August 29, 2011, 09:12:45 AM »
What is the minimal Android version supported? JOGL 2.0 supports Android whereas JOAL 2.0 doesn't, such a binding is going to be useful.

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3473
  • Developer
    • View Profile
    • PaulsCode.Com
Re: OpenAL for Android
« Reply #5 on: August 29, 2011, 12:16:07 PM »
It should be compatible back to Android 1.5.  It currently supports ARM chips back to v5, plus an optimized version for v7a and later.  I'm planning to post an update in a couple weeks that also has a version for x86 chips.  That should cover more than 95% of android devices out there (anything older probably wouldn't be able to run at an acceptable speed anyway).
« Last Edit: August 29, 2011, 12:26:54 PM by Paul »
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline gouessej

  • byte
  • *
  • Posts: 17
    • View Profile
    • TUER (first person shooter written in Java by Julien Gouesse)
Re: OpenAL for Android
« Reply #6 on: August 29, 2011, 12:24:45 PM »
Good job (JOGL 2.0 is only compatible with Android 2.3).

Offline cyclonmaster

  • bit
  • Posts: 2
    • View Profile
Re: OpenAL for Android
« Reply #7 on: November 23, 2011, 10:39:42 PM »
With this, is it possible to port jpcsp for android. Hope to see something soon. PSP on android WTF ;)

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3473
  • Developer
    • View Profile
    • PaulsCode.Com
Re: OpenAL for Android
« Reply #8 on: November 24, 2011, 10:49:06 AM »
With this, is it possible to port jpcsp for android. Hope to see something soon. PSP on android WTF ;)
In theory, yes.  My "ALAN" port is very similar to JOAL, and would only take a few minor adjustments.  I have no idea on any other requirements the code needs (javax.swing and javex.sound, for example, are not part of Android's Dalvik vm, and would have to be ported to the Android API if it's used).  Additionally, Dalvik is nowhere near as efficient as Sun/Oracle Java and their HotSpot technology, so it may not run very fast once ported  ;)
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Pesegato

  • bit
  • Posts: 5
    • View Profile
Re: OpenAL for Android
« Reply #9 on: April 24, 2012, 04:56:20 AM »

Great project!

Is it possible to use sound from R.raw (for MP3, WAV or AMR)? How can I load these files?

Thanks!

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3473
  • Developer
    • View Profile
    • PaulsCode.Com
Re: OpenAL for Android
« Reply #10 on: April 24, 2012, 02:38:28 PM »
Is it possible to use sound from R.raw (for MP3, WAV or AMR)? How can I load these files?

To be honest, I haven't done an Android project yet that uses audio files in R.raw, so I don't really know the answer to your question.  I assume you need to figure out how to get the header (rate, channels, etc) and PCM data from these files, right?  I recommend searching on stackoverflow.com (you can post a new question there if someone hasn't already asked it yet).  If you can figure out how to do this part, then playing the audio is pretty simple.  Once you have the header and PCM data, I can show you how to play it on ALAN, and doing effects like 3D stuff, Doppler effect, etc. if you need help with any of that.
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Pesegato

  • bit
  • Posts: 5
    • View Profile
Re: OpenAL for Android
« Reply #11 on: April 26, 2012, 02:45:59 AM »
OK!

What are the sound format supported by ALAN? Ogg is included and therefore is supported; how about the other codecs/container?

I have modified your example by adding this line:

        ALAN.alSourcefv (source[0], ALAN.AL_POSITION, new float[]{x,y,z});

But even after changing the x,y,z the sound doesn't have a convincing 3d position effect. Am I missing something?
(I'm using earbuds)

Many thanks!

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3473
  • Developer
    • View Profile
    • PaulsCode.Com
Re: OpenAL for Android
« Reply #12 on: April 26, 2012, 05:00:04 AM »
ALAN is just an interface to OpenAL, so it doesn't support any particular format (you must have a decoder/codec to get the PCM data and format).  The example app comes with an OGG decoder for demonstration purposes, but generally you would acquire one for whatever format you plan to use.  There are some various Java-based codecs I wrote for my SoundSystem library that might be portable to Android (I haven't tried yet), and of course there are a lot of open-source native decoders around the internet that you could use.

In OpenAL, 3D effects only work on mono files, not stereo, so I'd check that first (use a converter like Audacity or something to make your file mono if it isn't).  Stereo files are used for ambient sounds (like background music, ets).  If that's not the problem, then you can play around with the attenuation (could just be the scale you are using is not large enough to have a noticeable effect).  And of course you will need some stereo headphones or something to hear the 3D effect if you are playing this on a phone.
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Pesegato

  • bit
  • Posts: 5
    • View Profile
Re: OpenAL for Android
« Reply #13 on: April 27, 2012, 02:31:40 AM »
OK, I have converted my audio file to mono and .ogg format. Now I get the "x" effect (I hear the sound left/right, or better, the left/right volume is balanced according to the position and the absolute distance).

But I don't get a noticeable effect from y and z (they sound practically all the same regardless of direction).

What should I do with "attenuation"? Could you please post some source?


Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3473
  • Developer
    • View Profile
    • PaulsCode.Com
Re: OpenAL for Android
« Reply #14 on: April 27, 2012, 12:37:58 PM »
Attenuation is set by changing the rolloff factor.  Something like this (should only need to do it once):

Code: [Select]
ALAN.alSourcef( source[0], ALAN.AL_ROLLOFF_FACTOR, 0.03f );  // play around with the 3rd parameter to change sensitivity
This is going to sound crazy, but I don't think I've actually ever tested this, come to think of it.  If it doesn't work, let me know, and I'll try to debug it (I probably won't have time to look at it for a few days though).
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted