mp3 takes forever to decode on Android

We are experiencing severe delays with our Corona app on Android while the splash screen is showing, evidently because all our sound files are converted.

Is there any format that works on both platforms without conversion? We have tried mp3, ogg and aac, and none of them give acceptable results:

MP3:
iPhone: Works
Android: 20 seconds delay (logcat output below)

I/SoundDecoder(10927): MPG123: Accepting data stream.  
I/SoundDecoder(10927): MPG123: Accepting data stream.  
I/SoundDecoder(10927): MPG123: Accepting data stream.  
etc.  

OGG:
iPhone: No sound
Android: 6 seconds delay (logcat output below)

I/SoundDecoder(10879): OGG: bitstream version == (0).  
I/SoundDecoder(10879): OGG: bitstream channels == (2).  
I/SoundDecoder(10879): OGG: bitstream sampling rate == (48000).  
I/SoundDecoder(10879): OGG: seekable == {TRUE}.  
I/SoundDecoder(10879): OGG: number of logical bitstreams == (1).  
I/SoundDecoder(10879): OGG: serial number == (2146820407).  
I/SoundDecoder(10879): OGG: total seconds of sample == (0.000000).  
etc.  

AAC:
iPhone: Works
Android: No sound

PS! I dread the possibility that we must use a different sound format on each platform, as we then will have to manually switch sound folders each time before building for the respective platforms to prevent both sets of files from being included on both platforms. (Any tips of automating this process will be greatly appreciated!)

[import]uid: 73434 topic_id: 35319 reply_id: 335319[/import]

Have you tried .wav or .m4a [import]uid: 199310 topic_id: 35319 reply_id: 140399[/import]

M4A (aac/mp4a):
iPhone: Works
Android: No sound

@Rob: Is there one sound format that works on both platforms with no conversion delay? Or are my tests right, that this is not possible?

(WAV is really not an option as it takes 10 times as much space as compressed formats.)

[import]uid: 73434 topic_id: 35319 reply_id: 140455[/import]

@Rob (or anyone): Still need an answer here. Hoping to find a single audio format that will work on all Androids and iPhones without a huge conversion penalty on startup.

(The SoundDecoder, is that an internal Android thing or a Corona thing? Do different Android phones have support for different audio codecs, so that this conversion process is an unavoidable thing?) [import]uid: 73434 topic_id: 35319 reply_id: 140722[/import]

I’ve never seen decode times like that in any of my apps. On the OOG, 48000 seems like an odd bit rate. 44Khz, should be around 45,000 and change. It also looks like these are stereo tracks.

What device are you running these tests on?
Have you tried running 11khz mono tracks to see if that’s a difference?
How long are the clips?
Are you using audio.loadSound() or audio.loadStream()?

SoundDecoder is probably part of the OS. Each media type has a CODEC (Coder-DeCoder) library that gets loaded to convert the file format into binary data that can actually be played. There is a world of difference in various CODEC’s from different vendors in how well they handle the various decoding of the data.

What I had to do for an app that was going to run both on iOS and on the Nook Color and the client was insistent on high quality sounds was to have two folders, one for android and one for iOS. I used code similar to what we blogged about on device detection a few weeks back and had a variable for the folder name:

 beep = audio.loadSound("audio/" .. folder .. "/beep.mp3")  

where folder was either “high” or “low” depending on which one I wanted for that device.
[import]uid: 199310 topic_id: 35319 reply_id: 140855[/import]

Have you tried .wav or .m4a [import]uid: 199310 topic_id: 35319 reply_id: 140399[/import]

M4A (aac/mp4a):
iPhone: Works
Android: No sound

@Rob: Is there one sound format that works on both platforms with no conversion delay? Or are my tests right, that this is not possible?

(WAV is really not an option as it takes 10 times as much space as compressed formats.)

[import]uid: 73434 topic_id: 35319 reply_id: 140455[/import]

Tried converting 48000 Hz to 44100 Hz, and still 20 second startup time on Android.

Device: Samsung GT-I9000
11Khz/Mono: Quality not unacceptable
Clip length: 1-3 seconds (60 effects total)
Loader: [lua]audio.loadSound()[/lua]

Another Android tester said she had quick startup (I need to confirm this), so maybe this only happens for some Android devices? [import]uid: 73434 topic_id: 35319 reply_id: 141106[/import]

Just with my limited testing on 6 Android devices… you will NEVER get consistent load times on sound or even the speed of sound playing. Too many variables in hardware in the Android market.

It’s like your making a game for cheap PCs in the early 1990’s. There is cheap cheap cheap hardware. There is mediocre hardware. Then there is the really good hardware. You either aim for the lowest common denominator or you live with the knowledge that somebody’s going to have issues with your app.

If you have 60 sound effects then yeah, wav is out. However it’s your only choice to avoid decompression of the sound files.

Though I have to ask. Are you loading 60 sound effects at the start of your app? If so, 6 seconds with OGG format is pretty good. Your best best is to do what Rob is describing. Two folders of compressed sound should still be considerably less space than uncompressed wav files. [import]uid: 56820 topic_id: 35319 reply_id: 141108[/import]

I’m not sure how you’re timing your load time, but if you could create a small sample project that has this code:

local startTime = system.getTimer()  
local sound = audio.loadSound("oneofthesounds.mp3")  
local endTime = system.getTimer()  
print(endTime-startTime)  
  
local startTime = system.getTimer()  
local sound = audio.loadStream("oneofthesounds.mp3")  
local endTime = system.getTimer()  
print(endTime-startTime)  

Then if you like, you can email me the sound at rob at coronalabs dot com and I can do a test on the Nexus 7, Kindle Fire 1st Ed. and Nook Color to get some comparison times to see if its hardware of software.
[import]uid: 199310 topic_id: 35319 reply_id: 141122[/import]

@Rob: Here are some test results for loading a sound effect:

MP3 on iPhone 5: 15 ms
OGG on GT-I9100: 30 ms
OGG on GT-I9000: 50 ms
MP3 on GT-I9000: 130 ms

GT = Samsung/Android

MP3 loading on the GT-I9000 is the big problem here. Why is OGG loading so much faster?

Also, the I9100 loads twice as fast as the I9000. Is this a simple question of CPU power?

Will OGG be faster on all Android phones, or could there be phones where MP3 is fast and OGG is slow?

I would prefer to have one audio format that works optimally on both platforms, if possible. Otherwise I have to hide the OGG files when compiling for iPhone and hide the MP3 files when compiling for Android. This must be done manually, since Corona has no way of excluding folders when building for different devices, and I’m not going to include a double set of audio files in both builds.

[import]uid: 73434 topic_id: 35319 reply_id: 141261[/import]

Well the first thing I see here is that your worst load time is 0.13 seconds. When you are talking 20 seconds, are you talking for all your sounds to load? The load times above seam to be reasonable.

There are several things that affect loading time. The app and OS has to open the file, load the proper CODEC (decoder library), run the data through the CODEC and then store the decoded data in memory. Therefore the CPU matters. The App matters. The OS matters. The CODEC matters. Your available memory matters, the bus speed between the CPU and memory and storage matter.

All of that adds up to the total load time for a given sound. If the only thing different between your I9000 and I9100 are CPU speed, then that’s the difference, but if they are running different versions of Android that could affect it too. Solid state memory have different speeds. I’m a photographer and there are a world of difference in CF card speeds, so its possible that your phones could have different performance as well.

You’re OS’s OOG codec could be much more efficient than it’s MP3 driver, and you could take the same setup and put it on a DroidX and find out that the MP3 driver is noticeably better than the OOG driver. There is no guarantee that you are going to have one format to rule them all. It’s the way the highly fragmented Android market.

Now if your 20 second delay is due to loading all your sounds at once, you might want to consider delay loading the ones you don’t need right away. You could do it with a timer or if you’re doing any scene management, don’t load those sounds until you need them.
[import]uid: 199310 topic_id: 35319 reply_id: 141271[/import]

@Rob (or anyone): Still need an answer here. Hoping to find a single audio format that will work on all Androids and iPhones without a huge conversion penalty on startup.

(The SoundDecoder, is that an internal Android thing or a Corona thing? Do different Android phones have support for different audio codecs, so that this conversion process is an unavoidable thing?) [import]uid: 73434 topic_id: 35319 reply_id: 140722[/import]

I’ve never seen decode times like that in any of my apps. On the OOG, 48000 seems like an odd bit rate. 44Khz, should be around 45,000 and change. It also looks like these are stereo tracks.

What device are you running these tests on?
Have you tried running 11khz mono tracks to see if that’s a difference?
How long are the clips?
Are you using audio.loadSound() or audio.loadStream()?

SoundDecoder is probably part of the OS. Each media type has a CODEC (Coder-DeCoder) library that gets loaded to convert the file format into binary data that can actually be played. There is a world of difference in various CODEC’s from different vendors in how well they handle the various decoding of the data.

What I had to do for an app that was going to run both on iOS and on the Nook Color and the client was insistent on high quality sounds was to have two folders, one for android and one for iOS. I used code similar to what we blogged about on device detection a few weeks back and had a variable for the folder name:

 beep = audio.loadSound("audio/" .. folder .. "/beep.mp3")  

where folder was either “high” or “low” depending on which one I wanted for that device.
[import]uid: 199310 topic_id: 35319 reply_id: 140855[/import]

Tried converting 48000 Hz to 44100 Hz, and still 20 second startup time on Android.

Device: Samsung GT-I9000
11Khz/Mono: Quality not unacceptable
Clip length: 1-3 seconds (60 effects total)
Loader: [lua]audio.loadSound()[/lua]

Another Android tester said she had quick startup (I need to confirm this), so maybe this only happens for some Android devices? [import]uid: 73434 topic_id: 35319 reply_id: 141106[/import]

Just with my limited testing on 6 Android devices… you will NEVER get consistent load times on sound or even the speed of sound playing. Too many variables in hardware in the Android market.

It’s like your making a game for cheap PCs in the early 1990’s. There is cheap cheap cheap hardware. There is mediocre hardware. Then there is the really good hardware. You either aim for the lowest common denominator or you live with the knowledge that somebody’s going to have issues with your app.

If you have 60 sound effects then yeah, wav is out. However it’s your only choice to avoid decompression of the sound files.

Though I have to ask. Are you loading 60 sound effects at the start of your app? If so, 6 seconds with OGG format is pretty good. Your best best is to do what Rob is describing. Two folders of compressed sound should still be considerably less space than uncompressed wav files. [import]uid: 56820 topic_id: 35319 reply_id: 141108[/import]

I’m not sure how you’re timing your load time, but if you could create a small sample project that has this code:

local startTime = system.getTimer()  
local sound = audio.loadSound("oneofthesounds.mp3")  
local endTime = system.getTimer()  
print(endTime-startTime)  
  
local startTime = system.getTimer()  
local sound = audio.loadStream("oneofthesounds.mp3")  
local endTime = system.getTimer()  
print(endTime-startTime)  

Then if you like, you can email me the sound at rob at coronalabs dot com and I can do a test on the Nexus 7, Kindle Fire 1st Ed. and Nook Color to get some comparison times to see if its hardware of software.
[import]uid: 199310 topic_id: 35319 reply_id: 141122[/import]

@Rob: Here are some test results for loading a sound effect:

MP3 on iPhone 5: 15 ms
OGG on GT-I9100: 30 ms
OGG on GT-I9000: 50 ms
MP3 on GT-I9000: 130 ms

GT = Samsung/Android

MP3 loading on the GT-I9000 is the big problem here. Why is OGG loading so much faster?

Also, the I9100 loads twice as fast as the I9000. Is this a simple question of CPU power?

Will OGG be faster on all Android phones, or could there be phones where MP3 is fast and OGG is slow?

I would prefer to have one audio format that works optimally on both platforms, if possible. Otherwise I have to hide the OGG files when compiling for iPhone and hide the MP3 files when compiling for Android. This must be done manually, since Corona has no way of excluding folders when building for different devices, and I’m not going to include a double set of audio files in both builds.

[import]uid: 73434 topic_id: 35319 reply_id: 141261[/import]

Well the first thing I see here is that your worst load time is 0.13 seconds. When you are talking 20 seconds, are you talking for all your sounds to load? The load times above seam to be reasonable.

There are several things that affect loading time. The app and OS has to open the file, load the proper CODEC (decoder library), run the data through the CODEC and then store the decoded data in memory. Therefore the CPU matters. The App matters. The OS matters. The CODEC matters. Your available memory matters, the bus speed between the CPU and memory and storage matter.

All of that adds up to the total load time for a given sound. If the only thing different between your I9000 and I9100 are CPU speed, then that’s the difference, but if they are running different versions of Android that could affect it too. Solid state memory have different speeds. I’m a photographer and there are a world of difference in CF card speeds, so its possible that your phones could have different performance as well.

You’re OS’s OOG codec could be much more efficient than it’s MP3 driver, and you could take the same setup and put it on a DroidX and find out that the MP3 driver is noticeably better than the OOG driver. There is no guarantee that you are going to have one format to rule them all. It’s the way the highly fragmented Android market.

Now if your 20 second delay is due to loading all your sounds at once, you might want to consider delay loading the ones you don’t need right away. You could do it with a timer or if you’re doing any scene management, don’t load those sounds until you need them.
[import]uid: 199310 topic_id: 35319 reply_id: 141271[/import]