I use several Sound.loop , Sound.stop methods on one particular OGG file when I start and stop a level . It works fine for a while but as time advances it sometimes fails and I don't hear the sound anymore. LOGCAT:
AudioFlinger could not create track, status: -12
Error creating AudioTrack
It only happens on an older phone. How can I reset the sound memory system (sound pool) each time I restart the level so this doesn't happen?
I saved the ogg files to the minimum memory capacity in Audacity so I don't think this is the pb.
I had the exact same issue. My workaround was to use the Music class instead of Sound.
To initialize it:
Music note = Gdx.audio.newMusic(Gdx.files.internal("sounds/myfile.wav"));
note.setLooping(true);
Then just call .play() and .stop() as needed on the instance. Remember to call .dispose() when you no longer need it.
This worked for me and has the same practical effect than .loop() in a Sound instance.
Related
I'm working on a Flash game using Starling, and I have started coming across an issue where my render crashes immediately after I put my PC to sleep/lock it and then turn it back on. The error I'm getting is:
Error #3600: No valid program set
I was not able to find any advice online on how to prevent this/re-initialize everything appropriately. I'm assuming this is part of a wider issue with how Flash/Starling handles the computer being put to sleep/locked.
Things I have tried so far:
Catching the error and re-uploading the shader programs.
Setting Starling.handleLostContext to true
Has anyone come across this issue before? Any help/pointers would be greatly appreciated.
It sounds like your game is losing the GPU context.
On context loss, all GPU data is lost. You have to restore textures, vertex buffers, etc. Starling handles some of it for you when you set handleLostContext to true, but you still have to handle the textures.
If you use the AssetManager, it will handle re-uploading textures for you, which is clearly the easiest way to go. It automatically creates a texture.root.onRestore callback function which Starling calls after it re-creates the context, and it will attempt to re-load your textures from wherever you first loaded them from, whether from disk, an embedded asset, or a URL.
You can also manually define the function yourself, though that is more complicated and as the article mentions, some gotchas are involved.
More information: http://wiki.starling-framework.org/manual/context_loss
So I'm quite aware of flash/as3 garbage collecting causing memory leaks, and all the questions on the net.
Our software runs a swf, that loads in other swfs, videos, and images. It is expected to run a week without being restarted. generally, the player barely makes it a week without crashing from using too much memory. the swf will load in other assets based on the time of day, or if the schedule has changed. I wrote a simple resource manager so that it keeps track of what is used and what isn't, and will unload and set the unused assets to null. it does this unused check every hour, but it still seems that memory still doesn't go down after these assets are unloaded, and the memory leak continues to grow.
What I'm wondering, and can't seem to find, is can you expect flash to for SURE eventually release memory that is unused? or is there a possibility that flash may NEVER release unused memory?
It's really hard to find where memory-leaks come from without tools.
During game developpement I use Flash Builder Profiler, allow me to see if all my objects are destroyed when they are supposed to be.
In your case I would take a look at Adobe Scout :
http://gaming.adobe.com/technologies/scout/
Introduction to adobe scout: https://www.youtube.com/watch?v=yUHipsoGB2U
Using those tools during and after game developpement are the way to deal with memory-leaks.
Flash should be garbage collecting things that are no longer referenced. Is it possible that there are still references to whatever you're trying to garbage collect? You'll need to use removeEventListener() anytime that you've used addEventListener() to ensure that all of the references get deleted.
So, if you add an event listener to an object:
foo.addEventListener(Event, functionName)
Then you'll need to remove the reference when you're deleting the object:
foo.removeEventListener(Event, functionName)
It should be garbage collecting. Are you sure you're not inadvertently holding onto a reference to the unused objects? It's pretty easy to forget to remove an event listener, which will prevent an object from being collected when the GC runs.
Okay, basically we have the jRecorder implemented in our website which provides the ability for us to capture audio in WAV format.
Now, after the capture, we use the ShineMP3Encoder to convert that WAV to MP3 (to save on file size). This all works fine.
Numerous people have encountered an issue in that if the recorded audio levels are too high, MP3 encoding will completely stop and the file will become corrupt/short. When performing this with a WAV, it seems the WAV doesn't care how loud the recorded audio is and will happily play it back as is.
I appreciate my question is incredibly niche, but after banging my head against the wall for days, this is my only other option.
For what it's worth, this is the ActionScript that was use to record (it's bog standard ShineMP3 implementation):
//recorder.output is outputted from jRecorder
mp3Encoder = new ShineMP3Encoder(recorder.output);
mp3Encoder.addEventListener(Event.COMPLETE, mp3EncodeComplete);
mp3Encoder.start();
One possibility is that the encoding is running slower than the loop on those tracks, causing an error.
Try making the encoder run slower and see if that fixes the error.
In the start() method of ShineMP3Encoder.as replace
timer = new Timer(1000/30);
with
timer = new Timer(150);
That's line 37 in the current code base.
I have been creating a custom video player for the web. On some machines that I run this on it will start loading the .flv file then no progress will be made for 30 seconds to one minute then show that the video is completely loaded. I am checking how much has been loaded using a bytesLoaded / bytesTotal in an Event.ENTER_FRAME. When traced separately what seems to be happening when it shows fully loaded the bytesTotal value changes to the current bytesLoaded value causing my video player to register that my load percentage to be 1. I have traced out the NetStatus event.code value and there is no update to show that there has been any sort of error. All I get are a NetStream.Play.Start NetStream.Buffer.Full and then it will wait and reset the bytes total value.
So what I am asking is if there a way to handle this problem?
There doesn't seem to be a specific answer to this problem. I have since made another attempt at the problem and there are two lessons that I have learned.
1) You can code around most shortcomings in the netstream class by not allowing it to attempt to seek past the loaded point using the bytesLoaded, bytesTotal and the bufferTime properties. This can allow you to make sure that you never allow the seek to be attempted to a time that could cause a problem.
2) Always allow the previous seek attempt to finish and handle it properly before attempting to send another.
Are you playing an mp4 whose moov atom (e.g. metadata) is at the end of the file? If so, Flash cannot play the file until the entire file loads and is able to read the metadata.
This tool should fix your video file:
http://renaun.com/blog/code/qtindexswapper/
My website is entirely flash based, it moves around a 3D model which was given to me as chunks of video that I've converted to FLV files. I'm using the FLVPlayback component to control the video inside of my program. While running memory checks using System.totalMemory I've noticed that whenever a video is loaded, it will eat up a chunk of memory and even when I remove all the event listeners from it(they are all weakly referenced), remove the component from its parent, stop the video and null the component instance, it still will not give that memory back.
This has been bothering me since I started working on this project because of the huge amount of video a user can potentially instantiate and load. Currently every video is loaded into a new FLVPlayback instance whenever it is required, but I have read that perhaps the best way to go about this problem is to simply have a global FLVPlayback instance and just reload the new video into the old instance, that way there would only be one FLVPlayback component in the application's memory.
Has anyone else run into this problem as well? Have you found a better solution than using a global instance that you just re-use for every new video?
I've never really liked the components, they're a bit dodgy. This particular problem seems to be common, and the somewhat annoying solution is, as you're suggesting, to only have one FLVPlayback and reuse that.
Here's a blog post about it
You can't help the memory problems much until Flash adds destructors and explicit object deletion, unfortunately. See this thread:
Unloading a ByteArray in Actionscript 3
There's a limit to how much memory Flash applets can use; the GC seems to fire upon reaching that limit. I've seen my memory-easy applets use as much as ~200MB, just because they run for hours on end and the GC doesn't want to kick in.
Oh, and I don't think using a single instance is an elegant solution, either. Currently I just write a dispose() function for my custom classes, waiting for some day when it can be turned into a proper destructor.
From what I gather after a lot of testing is that flash dynamically loads in libraries and components as needed but never garbage collects that data. For instance, if I have a website or an Air app that uses the FLVPlayback component, the actual component and libraries associated with it aren't loaded until a new FLVPlayback() instance is created. It will then load in the library and component into memory but you will never get that space back until the program / website is closed. That specific instance with the video inside of it will get garbage collected and release some memory as long as you remove listeners from it, take it off the stage, and set it to null.
Also, if you are doing individual videos, the VideoPlayer is much lighter weight, and cleans up nicer.
Thanks for the responses, the links to the other blog questions were helpful as well, I had read all of Grant Skinner's info on garbage collection too, but searching through those links and going back and re-reading what he had originally said about GC helped refresh the old noggin. In addition to nulling and re-instantiating that single FLVPlayback component, I also realized that I wasn't correctly unloading and destroying my Loader instances either, so I got them cleaned up and now the program is running much more efficiently. I would say the memory usage has improved by around 90% for the site.
#aib I will admit the single instance solution isn't elegant, but because flash just won't let go of those FLV files, I'm kind of stuck with it.
#grapefrukt I detest the flash components, they typically cause more grief than time saved, however in this case I had a lot of cue points and navigation stuff going on with the video files and the FLVPlayback component was the best solution I found. Of course I'm still fairly new to the ActionScript world so perhaps I over-looked something.
Unfortuantely, thats just the way flash handles it. Not particularly smart, but it works for most people.