Mp3 works on pc but not on my iPad Starling

I have been using Flash Builder and Starling 1.3 to create some iPad apps and recently ran into an issue that was making me want to pull out my hair. Luckily for me I don’t have any hair. The latest version of Starling (1.3) has a new AssetManager class in the starling.utils package. It’s pretty cool, it handles the loading and accessing of all of the assets for your apps. In the app that I’m working on I’m using it to load the graphic assets and the audio assets. Sounds simple enough right? That’s what I thought too, but then I ran into a little problem. When I ran the app on my PC using the AIR simulator the audio played fine, but when I ran it on my iPad I couldn’t hear any audio. It wasn’t throwing any errors, I just couldn’t hear anything. After trying everything I could think of, one of the guys that I work with told me to send him the audio files I was using and he would try them in his app. That got me thinking and so asked him to send me some of his audio files as well because they were working. So he did and they worked in my app. To make this long story short, the problem was with the particular MP3 files. I opened them up in Audition and saved them at a different bitrate and that did it. Not sure how many people will run into this, but if you do, try saving the mp3 file differently and see if that fixes it.

SoundChannel position doesn’t = Sound length

So I recently made an AIR app at work that we use for finding cue points in an mp3 file. It loads an mp3 file, creates the sound wave spectrum for said file and then allows the user to target different locations in the file and output them as cue points. While working on this project I noticed that I was getting weird results on the the location of the play head in the audio file. It was really noticeable at the end of the file. The position property of the SoundChannel object at the end of the file didn’t equal the length property of the Sound object. It was a variable amount of milliseconds behind it. After a beating my head for a while and doing some searching online I realized what the problem was. It was all due to the bit rate at which the mp3 was saved. Anything below 128 was causing it to be off and the amount that it was off varied depending on the bit rate. If it was saved above 128 it was fine, but below caused problems. So if you are playing mp3 files in the Flash Player the ideal settings are 44100 Hz with a bit rate of 128 Kbps or higher. Also just as a side note if you don’t sample it at 44100 Hz the audio actually sounds bad as well. Hope this helps. Flash Player is still the best way to play audio files on the web.

Flash Player Garbage Collection.

So the more you work with ActionScript 3 and especially when it comes to building RIA’s (Rich Internet Applications) or games, the more garbage collection will become really important. When I first started down the road of memory management and garbage collection there were a lot of things that were very confusing. This post is to share the things that I’ve learned and hopefully help others avoid much of the confusion. The first thing to know is as of right now there is no real way of triggering a garbage collection pass on demand, but there are some good practices to follow that will ensure that objects are flagged to be collected. The first thing to be aware of is that if you are not using the Premium version of Flash Builder to profile your swf file you are going to have a difficult time knowing if it’s cleaning itself up properly. There are some other tools out there to help with this, but as off the time I wrote this Flash Builder Premium is by far the best. One tool to keep in eye on though that looks very promising is called project monocle. Do a Google search for it. Covering how to profile a swf is a little beyond the scope of this post, but when you’re writing your code here are the things I’ve found that you want to look for.

  1. Remove all event listeners.
    It’s good practice to use weak referencing when adding listeners. To do this set the last parameter in the addEventListener function to true. Doing that is not a guarantee though so remember to always remove listeners.
  2. Set all complex data types and any other object that contains a reference to another object such as Arrays and vectors to null.
    Although you can’t call the garbage collector on demand, this is the best way to ensure that an object is marked for collection on the next pass(as long as listeners are remove prior).
  3. Stop and nullify all timer and loader variables.
    Timers and loaders are notorious for hanging out in memory so make sure you watch them carefully.
  4. Ensure that all display objects are off of the display list before trying to destroy them.
    It’s rare, but there have been times when I’ve had to manually remove children from a parent before destroying the parent.
  5. Start a habit of good coding practices that works for you.
    So after you know what types of things to look for in your code that can lead to memory leaks, start making some habits to help you avoid those things. One thing that I’ve found helpful is to create a “destroy” or “cleanup” function for every class. Another thing that I’ve started doing that is very helpful is to make “create” and “destroy” functions for every complex object that I instantiate. So for example say that you were making a game that had a hero class, the two methods would be “createHero” and “destroyHero”. In those functions is where the object is created/destroyed(null) and where listeners are added and removed. Then you would have one public function that when it comes time to do the overall cleanup would call all of the destroy functions for the different objects. You can download a sample AS file that illustrates how to do this.

Memory management is very important in polishing any game or project. I hope this helps.

Is Flash a Dying Technology

So no surprise I’m a big Fan of pretty much everything Flash. Because of this people will ask me things like “Flash you’re still doing that?” and “Isn’t that a dying technology?” and my response is “NO!”. I’ve blogged about this before, but let me just state again that I personally feel that the technology behind the Flash Player was, and still is ahead of its time as far as delivering rich content on the web is concerned. You create something once and you can deliver it everywhere that the Flash Player is installed. And that is pretty much everywhere. Except on iOS devices. iOS is a different story and I’ll come back to that. Leaving Flash in favor of HTML 5 is a step backwards as far as I’m concerned. Don’t get me wrong, I think that HTML 5 is great, it’s just inferior to Flash and it’s not as ready as everyone who supports it would have you think. When I say inferior I am referring to using it as a tool to create rich internet applications and games, the two areas where I feel Flash is the better choice. If you just want to make a sweet website with a cool little jQuery navigation then by all means use HTML 5. The other thing that I feel is disappointing is how everyone is deciding to leave Flash right when it is getting good. Flash player now supports processing on the GPU and multi-threading, things that I never thought I’d see. ActionScript has come a long way and in my opinion is a very powerful and robust object-oriented programming language. So with that said let me address the iOS thing. Now before you get all upset and run off telling everyone that I hate Apple, I want to make it clear that I like Apple products and own three iPods and love them. Apple makes great (expensive) stuff, and they are brilliant marketers and innovators. With that said I strongly feel that they, like any other company do what’s in the best interest of themselves, and that’s fine. The part that rubs me the wrong way is that that’s not what they say. Let’s take the now famous stance from Steve Jobs himself against the Flash Player (again don’t get me wrong, Steve Jobs did a lot of good for the world of computing). So he said that it wasn’t secure and that it didn’t perform very well both of which I think are bunk. Then he went on to say that HTML 5 was the way of the future. So here’s my question: If HTML 5 is the way of the future, why does Apple not use it on their own website to display video content instead of Quicktime? Isn’t Quicktime all of a sudden a dying technology as well? It seems a little one-sided, just saying. I recently purchased an Android tablet and wanted to go watch some movie trailers on Apple’s website, but what do you know I couldn’t because I needed Quicktime and at the time of this post I couldn’t get it for my Android device. I’m not trying to bash, I just wish those to whom a majority of people look up to in the computer world would be a little more honest and not just say things that will benefit their personal interest. Right now is a great time to be in the computer world. There are new technologies coming out all the time that are revolutionizing things. Let’s embrace those and use them, but in doing so let’s not attempt to kill others that are also great.

AS3 Random Class

So just recently I did a major overhaul to the random class that I use for my projects. I implemented Grant Skinner‘s (thanks Grant!) random class and made some modifications. If you’re looking for a sweet little ActionScript 3 random class you need to check it out. You can download it here and you can read the documentation for it here. It works great for games. Enjoy!

FPS and Memory Profiler

With Flash shifting more of it’s focus to games it is becoming more and more important to optimize and ensure good performance. A great way to gauge performance is by the frame rate that your game can maintain on the desired device. I recently made a simply little tool that can be used to test the frame rate of your game or app. It is really easy to use, it only requires one line of code. Here is what it looks like:

as3 fps profiler

Here is all the code that is needed:

FpsProfiler.profile(this.stage);

I hope this can be useful to some of you looking to optimize your Flash games. Please feel free to give me some feedback. To download the source files click on the link in the bottom right hand corner. Enjoy!

 

Download Source Files

The Future of Flash

So I recently read an article that I like to call The Future of Flex and a couple of days ago I read The Future of Flash. We’ve known for a while now that Adobe is shifting their focus for Flash to online gaming and high end video online. In this article there are some new insights however the biggest in my opinion being ActionScript 4.0. They don’t come right out and say that, but an overhaul of ActionScript = new version in my mind. It’s a great article worth reading. Go check it out here: http://www.adobe.com/devnet/flashplatform/whitepapers/roadmap.html

Remove Duplicates from an Array AS3

I recently needed function that would remove duplicate values from an array. After looking around online and modifying what I found to fit my needs I came up with the following:

var arr:Array = ["a", "b", "c", "a", "d", "a", "a"];

removeDuplicates(arr);

trace(arr);

function removeDuplicates(target:Array):void
{
	for(var i:uint=target.length; i>0; i--)
	{
		if(target.indexOf(target[i-1]) != i-1)
		{
			target.splice(i-1, 1);
		}
	}
}

If you are searching for a way to do this, I hope this helps!

Random Vector and Random Array Functions

I’ve been working on a Blackjack game and have needed to do a lot of shuffling, cards that is. I’ve seen quite a few shuffling functions over the years. Here is the one I like, partly because I wrote it. Well okay I took what I liked in the others and modified them to come up with these:

public static function randomArray(src:Array):void
{
    var len:uint = src.length;
    for(var i:int=len-1; i>=0; i--)
    {
        var randIndex:uint = randomUint(0, len-1);
        var temp:* = src[randIndex];
        src[randIndex] = src[i];
        src[i] = temp;
    }
}

Vector version looks like this:

public static function randomVector(src:*):void
{
    var len:uint = src.length;
    for(var i:int=len-1; i>=0; i--)
    {
        var randIndex:uint = randomUint(0, len-1);
        var temp:* = src[randIndex];
        src[randIndex] = src[i];
        src[i] = temp;
    }
}

Here is a sample of how the vector version is used:

Randomize.randomVector(cards as Vector.<Card>);

Here is the randomUint function that it uses:

public static function randomUint(min:uint, max:uint):uint
{
    return Math.random()*((max+1)-min)+min;
}

I like to call these functions a random number of times so that the deck of cards is nice and shuffled. Enjoy!

How do I change the retry time in SmartFTP

So if you do much with ftp you have probably heard of SmartFTP. If not I would highly recommend them. I have used a variety of ftp programs and theirs is by far the best that I have used up to now. It has a lot of great features and is reasonably priced. If you have used it then you have also most likely ran into the issue that arrives if you attempt to upload a file and it fails causing it to state that it will retry at (time stamp) future. The default is 30 seconds from the time that it attempted to upload the file. Well for me the problem is 30 seconds is much more than I care to wait. I do a lot in Adobe Flash and I have SmartFTP set to monitor the .swf file for the .fla file that I am working on. This way every time I publish the file it will automatically upload it for me. The problem is that SmartFTP recognizes the file having been changed right as Flash begins to compile the swf not when it is actually finished. This means that every time I would have to wait 30 seconds. Well there is a solution and here it is. To change the retry default time value go to Favorites > Edit Favorites. In the Favorites window, go to Tools > Edit Default Favorite. In the Properties window, select the “Connection” menu, and there you will see a setting “Retry Delay” it is set to 30 seconds by default. There you can type in whatever time you want. For most small swf files 1 second has worked for me.