Developing Android Applications with Adobe AIR [68]
sound.addEventListener(Event.COMPLETE, onLoaded);
sound.load(new URLRequest("mySound.mp3"));
addChild(sprite);
function onLoaded(event:Event):void {
soundChannel = new SoundChannel();
soundChannel = event.target.play();
soundChannel.addEventListener(Event.SOUND_COMPLETE, onPlayComplete);
sprite.addEventListener(event.ENTER_FRAME, drawMusic);
}
function drawMusic(event:Event):void {
var value:Number;
var i:int;
SoundMixer.computeSpectrum(bytes, false, 0);
// erase the previous drawing
sprite.graphics.clear();
// move to the far left
sprite.graphics.moveTo(0, PEAK);
// left channel in red
sprite.graphics.lineStyle(0, 0xFF0000);
for (i = 0; i < CHANNEL_LENGTH; i++) {
value = bytes.readFloat()*PEAK;
// increase the x position by 2 pixels
sprite.graphics.lineTo(i*2, PEAK - value);
}
// move to the far right
sprite.graphics.lineTo(CHANNEL_LENGTH*2, PEAK);
// right channel in blue
sprite.graphics.lineStyle(0, 0x0000FF);
for (i = CHANNEL_LENGTH; i > 0; i--) {
sprite.graphics.lineTo(i*2, PEAK - bytes.readFloat()*PEAK);
}
}
function onPlayComplete(event:Event):void {
soundChannel. removeEventListener(Event.SOUND_COMPLETE, onPlayComplete);
sprite.removeEventListener(Event.ENTER_FRAME, drawMusic);
}
On most Android phones, which have a width of 480 pixels, the waveform will draw off-screen on the right to pixel 512 (256 * 2). Consider presenting your application in landscape mode and positioning the sprite container centered on the screen.
For better performance, let’s draw the vector into a bitmap. As a general rule, on mobile devices, you should avoid the drawingAPI, which is redrawn every frame and degrades performance.
The Sprite is not added to the display list, and therefore is not rendered to the screen. Instead, we create a BitmapData and draw the sprite inside its rectangle:
import flash.display.Bitmap;
import flash.display.BitmapData;
var sprite:Sprite;
var bitmap:Bitmap;
sprite = new Sprite();
// draw a BitmapData to draw the waveform
var bitmapData = new BitmapData(480, PEAK*2, true, 0x000000);
// store it in a Bitmap
bitmap = new Bitmap(bitmapData);
// position and add Bitmap to displayList
bitmap.y = 200;
addChild(bitmap);
function drawMusic(event:Event):void {
var value:Number;
var i:int;
SoundMixer.computeSpectrum(bytes, false, 0);
// use the sprite.graphics as before
// but does not render it to the screen
sprite.graphics.clear();
sprite.graphics.moveTo(0, PEAK);
sprite.graphics.lineStyle(0, 0xFF0000);
for (i = 0; i < CHANNEL_LENGTH; i++) {
value = bytes.readFloat()*PEAK;
sprite.graphics.lineTo(i*2, PEAK - value);
}
sprite.graphics.lineTo(CHANNEL_LENGTH*2, PEAK);
sprite.graphics.lineStyle(0, 0x0000FF);
for (var i:int = CHANNEL_LENGTH; i > 0; i--) {
value = bytes.readFloat()*PEAK;
sprite.graphics.lineTo(i*2, PEAK - value);
}
// instead draw it into a bitmap
// empty bitmap
bitmap.fillRect(bitmap.rect(sprite), 0);
// draw the sprite onto the bitmap image
bitmap.draw(sprite);
}
Audio and Application Activity
The Android Activity Manager controls applications moving to the foreground or the background based on the user’s decision, but doesn’t terminate them.
When your application goes to the background, most processes are paused, but audio and timers continue to run. Unless you want your audio to keep playing, you need to listen to two events to monitor a play and pause scenario:
import flash.desktop.NativeApplication;
import flash.events.Event;
NativeApplication.nativeApplication.addEventListener
(Event.ACTIVATE, onActivate);
NativeApplication.nativeApplication.addEventListener
(Event.DEACTIVATE, onDeactivate);
function onDeactivate(event:Event):void {
// pause or stop audio
}
function onActivate(event:Event):void {
// play audio
}
Please refer to Chapter 6 for more information.
Conclusion
Audio and music applications are as diverse as the imagination of their creators. Here are a few examples, ranging from applications for creating music with a visual component to saving audio notes: