Unity audio import settings for android - android

I'm creating simple game in unity and recently I bought some audio clips on assetstore. Some of them are quite big so i searched about import settings for audio and found this. My problem is that I'm building game for android and I don't know which things(like CPU or RAM) are more important for optimization (for android). Do you have any Idea what should I do?

There is no universal rule for choosing Load Type. The catch is that all the sounds need to get decompressed at some point to get played. Compressed 3 megabyte .mp3 file can become 32mb or more. Set Compression Format on PCM and you'll see how much space will it take when decompressed. See Imported Size on this image:
On this image I'm working with .mp3 file which grows from 0.6mb to 7mb on decompression.
Note: this was just a showcase. In fact if you set your Compression Format to PCM the sound will get decompressed on compile-time and Load Type is useless in this case (Unity really should gray it out in this case). But decompressed audio will make the game size bigger.
So, in absolute majority of cases Compression Format is applied (currently only option is Vorbis, Unity may add some more though). Assuming you use compression you should consider if you are willing to sacrifice RAM to get better performance or other way around.
Back to Load Type: For example, if I was to ship my 0.6mb mp3 file to iOS/Android game I would probably set it on Decompress On Load because frame-rate is #1 priority on mobile. I'd need to save CPU cycles during gameplay so I'd try to load sound in menu. But if this was a PC game I'd probably use Compressed In Memory so that it gets decompressed chunk by chunk while playing.
So basically this setting is really for a post-production/optimization. If you're getting Did Receive Memory Warning's a lot than you'd go for Compressed In Memory. But if you're struggling for maintaining a decent FPS than you'd rather set it on Decompress On Load.

Related

Huge difference in performance when using .OGG/.MP3 vs .WAV, explanations?

I'm making a really small game for android, and trying to add sounds to the game
I'm using the MediaPlayer class to load the audio file (.ogg or .wav)
I want to use .ogg (or .mp3) to shrink the size of the apk, rather than using .wav files.
I understand why loading (i.e. creating the MediaPlayer from a .ogg would take longer than .wav) (compression)
BUT the problem is that when I put the audio on loop by audio.setLooping(true) each time the audio starts again, it lags the game significantly
Why ? does the audio gets decoded each time it's going to start ? even on a loop ?
Also, on the CPU usage, I see spikes marking the beginning of the audio in the loop. so I'm pretty sure that the loop is really causing the lag..
any explanations/solutions?
(P.s. I'm testing on a really low-end physical phone, but for the game it's fairly enough, the sudden spikes are what's causing the problem not the actual usage)

Image Conversions in Android?

I want to build an app which converts image formats. I was trying
convert an JPG image to BMP, while doing so i get OOM, cause app
memory is limited that its unable to use the array to store the image
for conversion. If this is the case, how there are apps which does the
same??
I don't know how the actual conversion has to look like, but in every case you will need a buffer or something like that, to consume the jpg. Because Android memory heap is between 24-48mb (one memory block) you run out of memory while trying to convert.
Memory of Android app is limited. The amount of available memory varies by device. So editing big images on an older device might be really a problem.
Solution to this is to use NDK. In NDK you can allocated much more memory than Java apps could have.

How does android deal with playing video given its memory constraints?

I'm curious if someone can point me to (or just describe) how, given that an Android application has an extremely limited memory space to play with (I think it's around 20 megs), a video player can load and play videos that are an order of magnitude or more larger in size. Is the app loading the video in some sort of chunks?
I ask because I have an app that has some video assets embedded and the app has grown to be about 80 megs and is just a total monster for compiling and debugging (without the assets the app would only be about 2 megs), and I was thinking that I should just remove the assets and have them download on the side and sit on the sdcard, rather than within the apk, but I'm worried that loading them and playing them at run time will bust through the app's memory allotment, and was hoping someone can shed some light on what my options are.
TIA
They buffer the video in manageable chunks, yes. Even if your videos are GBs in size, you won't hit a memory wall using standard video playing APIs. You can use the standard calls to setVideoURI or setVideoPath to point to the file and it will handle it from there. The same works for MediaPlayer in general if you're not using a VideoView
Downloading the videos outside the apk is still a good idea, though. If I had to download a new 80MB file for each incremental upgrade, I'd probably just uninstall instead. If you don't want to host them yourself, look into the supplemental apk option.
You can take your game into the native layer where you can bypass this limit. Take a look at a blog I wrote http://jnispot.blogspot.com/2012/10/jnindk-arrays-bitmaps-and-games-oh-my.html
I have no idea if this is what video apps do, but you can actually increase the memory beyond the normal limit by using malloc statements in native code. This bypasses the normal max of around 20 MB.
I have only used this for encryption on android devices where AES encryption needs rather karger amounts of memory when dealing with large encrypted files (even around 10MB files).

Is it better to .zip the data before downloading?

I have A LOT of (optional) audio files.. I have 6400 audio files, with average size ~40 kb each, and total size ~400 mb..
I was wondering how will I download the files, Is it better to:
download a .zip file and then extract .. less bandwidth , more sdcard space requireed , more cpu to unzip..
download all the files (no .zip file)... more bandwidth , less sdcard and less cpu..
What is more reasonable?
Do a little test first...
Most audio files are already compressed, and Zipping them does not always reduce the size.
And if you can get only a small reduction with a high compression (= high CPU demand) setting then zipping will not be worth it.
You will have to measure to see on what side of the tipping point your files are.
Zipping should you give you a much faster download, as a single connection for download will be faster than openning 6400 HTTP request. (for small files, the time it takes to download is lower than the time it takes to open the connection. But the connection opening is constant, so for a large file you'll have much less time spend on opening connections.)
However, and that's the big point, most users won't be able to download 400MB easily without the network connection dropping. I'd suggest a middle way. Package the audio files into chunks or say 64 files each, (best in directories for faster access and reference) and download 64 files in a single zip or tar for that matter. I'd go with a non-compressing format, as the zipping won't give you much size reduction.
That way, you won't have to worry much about the download failing, and you'll have easy progress tracking.
However, i'd think about if you really need that many files in the first place.
Look if you either just have one biger mp3 file in which you can just play certain areas (just skipping inside the file) when you need it.
I'd also give a thought to lazy loading, just load the files when you need them
There's no need to compress etc .mp3 .flac .ogg but if it's for example a wave file you can compress the size pretty much.

and again about memory issues with SoundPool

I am aware that SoundPool was intended to handle small fx like sounds and I made sure my 4 sound clips which I want to play one by one in some sequence are small enough.
I used ogg quality 0 and clips are 35kb, 14kb, 21kb and 23kb totaling 92kb of compressed audio. I have no idea how to estimate what the uncompressed size would be, but it should not be a lot, right?
So when I play 4 sounds in sequence, it works well for first 9 times (9 sequences x 4 sounds) but starts to cause memory issues on the nines sequence for one of the sounds. It is always sequence 9 when I start to see error.
What is the best way to handle that? I have a few ideas:
1) compress sounds even more (ogg quality -1 and mono instead of stereo)
2) unload and load sounds constantly using SoundPool.load and SoundPool.unload
3) release and recreate soundPool instance time from time
Is there anything else I can do? It is embarrassing that android api cannot handle so small clips. I wonder how people create games with a lot of sound effects...
Errors look like that:
ERROR/AudioFlinger(35): not enough memory for AudioTrack size=1048640
DEBUG/MemoryDealer(35): AudioTrack (0x25018,size=1048576)
It seems I was able to resolve my issue after:
1) downsampled my sound clips from 44 to 22khz. Uncompressed size was cut in half (I figured how to estimate uncompressed sound size - export your clip to uncompressed wav). I used nice open source tool Audacity
2) trim the sounds more to reduce duration
3) put try/catch around play() just in case (it does catch errors when it try to play the sound but cannot)
That seems odd. SoundPool should be expanding your audio clips into memory when it loads them, and once loaded I wouldn't expect you to run into memory issues later. When I've run into memory issues it was right at the beginning, not later on. You sure you're not loading more sounds later on?
To answer your other question, some games use JET Player and MIDI sounds instead of SoundPool. The JetBoy sample program that comes in the Android SDK is a great example of how to do this type of sound work in an app.

Categories

Resources