Hi Guys,
I have a big showstopper issue with my app performance caused by playing multiple sounds for a period of time.
My app has a lot of collisions, explosions, braking bodies etc. and those have sounds.
When you start to play the game everything is very fast, then little by little it slows down until it is extremely slow (even on the main menu page with 3 buttons to render and no physics engine or anything, not even sound).
Each sound I play on collisions, breakages, explosions, etc. is just some sound:play()
The issue gets worst when the game progresses and you can't recover without restarting the app:
- If stand alone app - kill and restart.
- If playing on the Gideros player on iOS device - stop and start (no need to kill the player).
I can't reproduce the issue on Windows and Android player (or app).
The issue is very easy to reproduce with Gideros Audio Example with a little modification.
I monitored the iPhone 5 CPU usage and after some game play it reaches 100%
If the games sounds are disabled - there is no issue .
How to reproduce:
1. Start XCode and open the GiderosPlayer project
2. Attach an iOS device and start the player trough XCode so that you can monitor CPU and threads
3. Open your "Audio Example"(Shipped with Gideros) in Gideros studio
4. Modify a little soundbutton.lua to play multiple sounds (attached is the modified version of soundbutton.lua)
5. Start the app on the iOS player running through XCode
6. Press each button(1,2,3) twice and wait for about a minute (this emulates extensive game play with sounds). E.g. 1,2,3,1,2,3
Reducing the volume is a good idea because it is annoying :-)
7. Montior the CPU usage and especially THERAD 1 - the main app thread. After about a minute all sounds stop, but the main thread keeps using tons of CPU while the app is doing absolutely nothing. On my system the main thread is using ALL of the CPU after certain amount of play with sounds.
While the app is doing nothing the main thread loops like crazy doing this:
GGSampleOpenALManager::tick... (SEE THE ATACHED SCREENSHOT)
Guys, please help, because this is a major showstopper for us. The app becomes unusable after some time unless the sound option is off.
Thanks
Vlad
-------------------------
P.S. Modified soundbutton.lua below (it is also attached)
FYI: My app code is nothing like that, but this reproduces the issue just fine.
SoundButton = Core.class(Sprite)
function SoundButton:init(upimage, downimage, soundfile)
local up = Bitmap.new(Texture.new(upimage))
local down = Bitmap.new(Texture.new(downimage))
local button = Button.new(up, down)
self:addChild(button)
local sound = Sound.new(soundfile)
button:addEventListener("click", function () self:play200(sound,1) end)
end
function SoundButton:play200(snd,cnt)
cnt = cnt + 1
if cnt <= 200 then
snd:play()
Timer.delayedCall(100 + (500)*math.random(), function() self:play200(snd,cnt) end)
end
end |
Comments
What version of Gideros are you using exactly and what kind of device?
I don't have a Mac to test with xCode, but I've used Gideros Player 2013.09.1 on iPad 4 with your modified Audio Example and put additional draggable physics on it,
let my kid punch sound buttons for a while and then I was dragging/throwing the physics object all the time, and have not noticed a single delay.
So it could be either some Gideros version specific or something device specific, I guess.
Gideros: 2013.09.1
Device: iPhone 5
OS: iOS v.7.0.3
The example was meant to be monitored in XCode. You will not see the slowness immediately. It takes time until the sound thing kills the app. The main thread needs to kill the CPU first. You will notice slowness only after it reaches 100%. Otherwise it just eats battery.
If you do not have mac with XCode - I see two options:
1. I write a new example that kills my iPad Gideros Player (but I do not want to spend time on it since the problem is clearly reproducible and visible with the example I already have).
2. Use the email support with Atilim that comes with the Gideros Pro License. I am sure Atilim has a Mac with xcode since he ships Gideros for Mac and iOS
In the meantime I will run the simulation on my iPad and monitor via XCode... in case the issue does not happen on iPad (but I am 99% sure it will).
By the way: Is there a way to detect and print the real FPS?
When I monitor it via XCode - it starts with 60 and then goes below 30 when the main thread reaches 100% (The main thread uses about 5% CPU when I don't use sounds)
Vlad
Interesting - this is harder to reproduce on iPad. I guess its hardware is faster or something. I think I have the same iPad as you - the Retina iPad.
So in order to reproduce on iPad with XCode - change step 6 to:
6. Press each button(1,2,3) 8 times and wait for about 1.5 minutes (until the sound stops)
In order to reproduce on iPad without XCode AND IF you want to SEE actual slowness do:
6. Press each button(1,2,3) 10 times and wait for about 1.5 minutes (until the sound stops)
6a. Repeat step 6 two more times
See the attached screenshot.
The app was doing absolutely nothing on my iPad (no sound) when the screenshot was taken.
- Notice Thread 1
- Notice the CPU usage 99-101% vs 9% prior to repeating step 6 3 times
- Note: Thread 9 is the renderLoop() - it is always almost constant
--------------
Android and Windows note:
It works just fine on Android and Windows.
I even tried step 6 with pressing each button 30 times on Android and Windows. Gideros handled it well - no issues.
Likes: Yan
When the sound STOPS and the app is doing absolutely nothing it still uses 100% of the CPU.
High CPU during so much sounds is just fine and actually it is much less than 100% and does not cause slowness.
However it just grows and grows after each retry and then never stops using the CPU.
As if all those sound channels do not get cleared after they stop playing (even though they are not even assigned to a variable) and something is keeping them alive and waiting for them to do something...
BTW: On a relatively old Android tablet playing 30x3x200 sounds for 1.5 minutes uses only about 12% of the CPU.
On Windows (quad core i7 3.5GHz) the same (30x3x200) uses 1.2% CPU
This looks like some kind of timing issue.
The simulation just renders 3 buttons.
The app does not play that many sounds as the simulation, but the problem is much easier to reproduce with the app even on iPad, because the app does tons of other things like: calculating and moving around many physics objects, animations, scrolling, tracking collisions, doing ray casting from time to time, etc.
Those seem to be done also by the main thread 1. It looks like when it gets busy it does not have time to clear something - making the issue much easier to reproduce with less number of sounds. I just played a level on an iPad(with sounds) and went back to the main page. Main page CPU before: 9%, after 24%.
If I do the same with sound off - CPU before and after is 9%
And one last note: All my sounds are wav. No mp3s.
when you play lots of sounds that OpenAL cannot handle (>=32), Gideros cannot detect sound is played/ended therefore Gideros' sound channel queue grows.
Now trying to find a solution
Likes: kussakov
After limiting the maximum number of channels to 32, everything works fine. I just need to test if playing mp3s decreases the number of available channels.
You can expect a new release that fixes this problem in a couple of days.
Likes: Platypus, kussakov
This issue must be a leftover from iPhone 2 / iOS 1 implementation of OpenAL :-)
Seems to me that Apple forgot to remove it :-)
Thanks a lot guys! This was a big showstopper...
When will the next release be available?
Thanks
so sorry, release was supposed to be earlier, but "someone" decided to incorporate more features
Thanks for the update!
report:
Date/Time: 2014-01-29 18:44:05.073 -0200
OS Version: Mac OS X 10.7.4 (11E53)
Report Version: 9
Interval Since Last Report: 3457042 sec
Crashes Since Last Report: 77
Per-App Interval Since Last Report: 501154 sec
Per-App Crashes Since Last Report: 52
Anonymous UUID: B22E6FE5-C82E-41F4-81A5-3D45066DC20F
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000000cebb000
VM Regions Near 0xcebb000:
IOKit 000000000ca40000-000000000cebb000 [ 4588K] rw-/rw- SM=SHM
-->
IOKit 000000000cec1000-000000000cf31000 [ 448K] rw-/rw- SM=SHM
Application Specific Information:
objc[47018]: garbage collection is OFF
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_c.dylib 0x00007fff8e02b7e5 memset_pattern4 + 337
1 libsystem_c.dylib 0x00007fff8e02b67b memset + 155
2 com.yourcompany.Gideros Player 0x0000000100060094 unsigned char* std::fill_n(unsigned char*, unsigned long, unsigned char const&) + 52
...
Binary Images:
0x10000 - 0x3bfff com.apple.audio.OpenAL (1.5.1 - 1.5.1) <5B954EC6-08B6-3255-932C-DDAB908E72F4> /System/Library/Frameworks/OpenAL.framework/Versions/A/OpenAL
VM Region Summary:
ReadOnly portion of Libraries: Total=188.8M resident=80.1M(42%) swapped_out_or_unallocated=108.6M(58%)
Writable regions: Total=147.8M written=33.1M(22%) resident=110.4M(75%) swapped_out=1904K(1%) unallocated=37.4M(25%)
...
Model: MacBook6,1, BootROM MB61.00C8.B00, 2 processors, Intel Core 2 Duo, 2.26 GHz, 2 GB, SMC 1.51f53
Graphics: NVIDIA GeForce 9400M, NVIDIA GeForce 9400M, PCI, 256 MB
Memory Module: BANK 0/DIMM0, 1 GB, DDR3, 1067 MHz, 0x80CE, 0x4D34373142323837334548312D4346382020
Memory Module: BANK 1/DIMM0, 1 GB, DDR3, 1067 MHz, 0x80CE, 0x4D34373142323837334548312D4346382020
is there any specific code that causes it?
changed all sfx mp3 to wav and am using a singleton class to play the sounds, so no need to worry about many instances Sound.new (), only the channels.
I'll do some more tests and inform any news