AS3 - Working with Sound.

Posted by admin on May 9th, 2008 filed in AIR, Actonscript 3, Flash, Flex
3 Comments »

The other day I was writing a small AIR mp3 player for myself that I could use for simply putting on shuffle and letting play all day. All that I wanted was to create a small AIR app that I could load my mp3 library into, read the ID3 tags, and implement my own custom search function. Once I had it all running I opened it up and let it scan my Music folder for mp3’s. Of course, loading the ID3 info for 3000+ mp3 files took a little while so I just left my computer and came back a little while later. When I came back my computer had been rendered almost useless! When I looked at the Activity Monitor it was showing that “adl” was using almost 1.5GB of my ram!

So naturally I thought to myself, “Geesh, stupid me. I must of left my event listeners on the Sound class”, which would mean that the Flash Player would not garbage collect them properly, thus leaving all the sound data in memory. After fixing this issue I let app scan my library again. Once again, rendering my computer useless.

After a long time searhing the internet for blog posts, documentation etc on this issue I came across nothing that showed me how to “unload” a sound from memory. Once the sound was loaded, it seemed that it was in memory until you closed your application. After finding nothing to help me out, I started to change my code around, trying different methods of loading / reading the ID3 info. Then I stumbled upon this, the delete keyword deletes the actual variable definition, not just the variable’s value. This of course frees any reference it was holding, potentially freeing that object for garbage collection”

So, I created a class that dynamically created properties to hold loaded Sound classes, and used the delete keyword to remove or “unload” the sounds. Bingo! The sounds were now unloading properly and my app then only started to consume 30 - 40 MB of ram while scanning my library.

Here is the key to the solution:


private var dynamicProps:Array = [null, null];

private function get sound():Sound {
	return dynamicProps[0];
}

private function set sound(value:Sound):void {
	destroySoundChannel();
	destroySound();

	System.gc(); //force garbage collection

	dynamicProps[0] = value;

	addSoundListeners();

	dispatchEvent(new Event("soundChanged"));
}

private function destroySound():void {
	if ( dynamicProps[0] != null ) {
		//cancel any remaining downloading
		try {
			Sound(dynamicProps[0]).close();
		} catch ( e:Error ) {}

		removeSoundListeners();

		delete dynamicProps[0];
		dynamicProps[0] = null;
	}
}

private function destroySoundChannel():void {
	if ( dynamicProps[1] != null ) {
		SoundChannel(dynamicProps[1]).stop();
		removeSoundChannelListeners();
		delete dynamicProps[1];
		dynamicProps[1] = null;
	}
}

Here is an example, of reading the ID3 tags of 100 mp3 files:

Not Using Sound Manager
Not using “SoundManager” to load mp3’s

Using Sound Manager
Using the “SoundManager” class for loading mp3’s

Here is an example usage of SoundManager.as


var manager:SoundManager = new SoundManager();

private function loadSound(url:String):void {
	manager.addEventListener(Event.COMPLETE, soundLoaded);

	//we can call loadSound as many times as we like
	//everytime we call it the old sound is replaced by the
	//new loading sound.
	manager.loadSound(new URLRequest(url));
}

private function soundLoaded(e:Event):void {
	manager.play();
}

private function soundComplete(e:Event):void {
	loadSound("anotherSound.mp3");
}

Files:

SoundManager.as


AlertBox With No Buttons! (HACK)

Posted by admin on January 10th, 2008 filed in AIR, Actonscript 3, Flex
4 Comments »

Browsing around EE today, I found an interesting question. This person wanted an AlertBox that had no buttons at all. The goal was to have the identical functionality / look as an alert, but to only display a message such as “Saving Changes…”. This is something that I do all over the place, and have written custom components specifically for locking the UI until an operation is complete.

However, if you don’t mind using some nasty hacks, this functionality can be accomplished in only a couple lines of code.

private var theAlert:Alert;

public function showAlert():void
{
  theAlert = Alert.show("Saving Changes...", "", Alert.OK);
  theAlert.mx_internal::alertForm.removeChild(
    theAlert.mx_internal::alertForm.mx_internal::buttons[0]);
}

public function hideAlert():void
{
  PopUpManager.removePopUp(theAlert);
}

It’s a hack, but it works really good!


Keyboard Text Navigation in OSX.

Posted by admin on December 16th, 2007 filed in OS X
3 Comments »

Having recently switched to a MacBook from Windows. I was becoming continually frustrated navigating text with the keyboard. I really missed my “DELETE” button from my old Acer. Finally I browsed around and found a bunch of useful keyboard shortcuts for OSX that make navigating text much easier.

- Func + Delete(Backspace): Deletes characters in front of the cursor. (Like the Windows Delete Key)

- Cmd + (Left | Right): Move to the beginning or end of the current line.

- Cmd + (Up | Down): Move to the beginning or end of the document.

- Opt + (Left | Right): Move the cursor to the beginning or end of the current word

- Opt + (Up | Down): Move the cursor to the beginning or end of the current paragraph.

- Opt + Delete: Delete to the beginning of the word.

Use shift with any of these combinations to select text.

Any others?