Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon

How-To Tutorials - Android Programming

62 Articles
article-image-flash-development-android-audio-input-microphone
Packt
22 Jun 2011
4 min read
Save for later

Flash Development for Android: Audio Input via Microphone

Packt
22 Jun 2011
4 min read
  Flash Development for Android Cookbook Introduction Camera and microphone are standard accessories on most mobile devices and Android devices are no exception to this. In the previous article we dealt with Visual Input via Camera. The present article will cover encoding raw audio captured from the device microphone and encoding it to WAV or MP3 for use on other platforms and systems. All of the recipes in this article are represented as pure ActionScript 3 classes and are not dependent upon external libraries or the Flex framework. Therefore, we will be able to use these examples in any IDE we wish. The reader is advised to refer to the first recipe of Flash Development for Android: Visual Input via Camera for detecting microphone support. Using the device microphone to monitor audio sample data By monitoring the sample data being returned from the Android device microphone through the ActionScript Microphone API, we can gather much information about the sound being captured, and perform responses within our application. Such input can be used in utility applications, learning modules, and even games. How to do it... We will set up an event listener to respond to sample data reported through the Microphone API: First, import the following classes into your project: import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.SampleDataEvent; import flash.media.Microphone; import flash.text.TextField; import flash.text.TextFormat; Declare a TextField and TextFormat object pair to allow visible output upon the device. A Microphone object must also be declared for this example: private var mic:Microphone; private var traceField:TextField; private var traceFormat:TextFormat; We will now set up our TextField, apply a TextFormat, and add the TextField to the DisplayList. Here, we create a method to perform all of these actions for us: protected function setupTextField():void { traceFormat = new TextFormat(); traceFormat.bold = true; traceFormat.font = "_sans"; traceFormat.size = 44; traceFormat.align = "center"; traceFormat.color = 0x333333; traceField = new TextField(); traceField.defaultTextFormat = traceFormat; traceField.selectable = false; traceField.mouseEnabled = false; traceField.width = stage.stageWidth; traceField.height = stage.stageHeight; addChild(traceField); } Now, we must instantiate our Microphone object and set it up according to our needs and preferences with adjustments to codec, rate, silenceLevel, and so forth. Here we use setSilenceLevel() to determine what the minimum input level our application should consider to be "sound" and the rate property is set to 44, indicating that we will capture audio data at a rate of 44kHz. Setting the setLoopBack () property to false will keep the captured audio from being routed through the device speaker: protected function setupMic():void { mic = Microphone.getMicrophone(); mic.setSilenceLevel(0); mic.rate = 44; mic.setLoopBack(false); } Once we have instantiated our Microphone object, we can then register a variety of event listeners. In this example, we'll be monitoring audio sample data from the device microphone, so we will need to register our listener for the SampleDataEvent.SAMPLE_DATA constant: protected function registerListeners():void { mic.addEventListener(SampleDataEvent.SAMPLE_DATA, onMicData); } As the Microphone API generates sample data from the Android device input, we can now respond to this in a number of ways, as we have access to information about the Microphone object itself, and more importantly, we have access to the sample bytes with which we can perform a number of advanced operations: public function onMicData(e:SampleDataEvent):void { traceField.text = ""; traceField.appendText("activityLevel: " + e.target.activityLevel + "n"); traceField.appendText("codec: " + e.target.codec + "n"); traceField.appendText("gain: " + e.target.gain + "n"); traceField.appendText("bytesAvailable: " + e.data.bytesAvailable + "n"); traceField.appendText("length: " + e.data.length + "n"); traceField.appendText("position: " + e.data.position + "n"); } The output will look something like this. The first three values are taken from the Microphone itself, the second three from Microphone sample data: How it works... When we instantiate a Microphone object and register a SampleDataEvent.SAMPLE_DATA event listener, we can easily monitor various properties of our Android device microphone and the associated sample data being gathered. We can then respond to that data in many ways. One example would be to move objects across the Stage based upon the Microphone.activityLevel property. Another example would be to write the sample data to a ByteArray for later analysis. What do all these properties mean? activityLevel: This is a measurement indicating the amount of sound being received codec: This indicates the codec being used: Nellymoser or Speex gain: This is an amount of boosting provided by the microphone to the sound signal bytesAvailable: This reveals the number of bytes from the present position until the end of our sample data byteArray length: Lets us know the total length of our sample data byteArray position: This is the current position, in bytes, within our sample data byteArray  
Read more
  • 0
  • 0
  • 2198

article-image-flash-development-android-visual-input-camera
Packt
21 Jun 2011
7 min read
Save for later

Flash Development for Android: Visual Input via Camera

Packt
21 Jun 2011
7 min read
Camera and microphone are standard accessories on most mobile devices and Android devices are no exception to this. The present article will cover everything from accessing the camera and taking photos to recording video data. All of the recipes in this article are represented as pure ActionScript 3 classes and are not dependent upon external libraries or the Flex framework. Therefore, we will be able to use these examples in any IDE we wish. Detecting camera and microphone support in Android Nearly all Android devices come equipped with camera hardware for capturing still images and video. Many devices now have both front and rear-facing cameras. It is important to know whether the default device camera is usable through our application. We should never assume the availability of certain hardware items, no matter how prevalent across devices. Similarly, we will want to be sure to have access to the device microphone as well, when capturing video or audio data. How to do it... We will determine which audio and video APIs are available to us on our Android device: First, import the following classes into your project: import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.media.Camera; import flash.media.CameraUI; import flash.media.Microphone; import flash.text.TextField; import flash.text.TextFormat; Declare a TextField and TextFormat object pair to allow visible output upon the device: private var traceField:TextField; private var traceFormat:TextFormat; We will now set up our TextField, apply a TextFormat, and add the TextField to the DisplayList. Here, we create a method to perform all of these actions for us: protected function setupTextField():void { traceFormat = new TextFormat(); traceFormat.bold = true; traceFormat.font = "_sans"; traceFormat.size = 44; traceFormat.align = "center"; traceFormat.color = 0x333333; traceField = new TextField(); traceField.defaultTextFormat = traceFormat; traceField.selectable = false; traceField.mouseEnabled = false; traceField.width = stage.stageWidth; traceField.height = stage.stageHeight; addChild(traceField); } Now, we must check the isSupported property of each of these objects. We create a method here to perform this across all three and write results to a TextField: protected function checkCamera():void { traceField.appendText("Camera: " + Camera.isSupported + "n"); traceField.appendText("CameraUI: " + CameraUI.isSupported + "n"); traceField.appendText("Microphone: " + Microphone.isSupported + "n"); } We now know the capabilities of video and audio input for a particular device and can react accordingly: How it works... Each of these three classes has a property isSupported, which we may invoke at any time to verify support on a particular Android device. The traditional Camera and mobile-specific CameraUI both refer to the same hardware camera, but are entirely different classes for dealing with the interaction between Flash and the camera itself, as CameraUI relies upon the default device camera applications to do all the capturing, and Camera works exclusively within the Flash environment. The traditional Microphone object is also supported in this manner. There's more... It is important to note that even though many Android devices come equipped with more than one camera, only the primary camera (and microphone) will be exposed to our application. Support for multiple cameras and other sensors will likely be added to the platform as Android evolves. Using the traditional camera API to save a captured image When writing applications for the web through Flash player, or for a desktop with AIR, we have had access to the Camera class through ActionScript. This allows us to access different cameras attached to whatever machine we are using. On Android, we can still use the Camera class to access the default camera on the device and access the video stream it provides for all sorts of things. In this example, we will simply grab a still image from the Camera feed and save it to the Android CameraRoll. How to do it... We will construct a Video object to bind the Camera stream to, and use BitmapData methods to capture and then save our rendered image using the mobile CameraRoll API: At a minimum, we need to import the following classes into our project: import flash.display.BitmapData; import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.TouchEvent; import flash.media.Camera; import flash.media.CameraRoll; import flash.media.Video; import flash.ui.Multitouch; import flash.ui.MultitouchInputMode; Now we must declare the object instances necessary for camera access and file reference: private var video:Video; private var camera:Camera; private var capture:BitmapData; private var cameraRoll:CameraRoll; private var videoHolder:Sprite; Initialize a Video object, passing in the desired width and height, and add it to the DisplayList: protected function setupVideo():void { videoHolder = new Sprite(); videoHolder.x = stage.stageWidth/2; videoHolder.y = stage.stageHeight/2; video = new Video(360, 480); videoHolder.addChild(video); video.x = -180; video.y = -240; videoHolder.rotation = 90; addChild(videoHolder); } Initialize a Camera object and employ setMode to specify width, height, and frames per second before attaching the Camera to our Video on the DisplayList: protected function setupCamera():void { camera = Camera.getCamera(); camera.setMode(480, 360, 24); video.attachCamera(camera); } We will now register a TouchEvent listener of type TOUCH_TAP to the Stage. This will enable the user to take a snapshot of the camera display by tapping the device screen: protected function registerListeners():void { Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; stage.addEventListener(TouchEvent.TOUCH_TAP, saveImage); } To capture an image from the camera feed, we will initialize our BitmapData object, matching the width and height of our Video object, and employ the draw method to translate the Video pixels to BitmapData. To save our acquired image to the device, we must initialize a CameraRoll object and invoke addBitmapData(), passing in the BitmapData object we have created using Video object pixels. We will also determine whether or not this device supports the addBitmapData() method by verifying CameraRoll. supportsAddBitmapData is equal to true: protected function saveImage(e:TouchEvent):void { capture = new BitmapData(360, 480); capture.draw(video); cameraRoll = new CameraRoll(); if(CameraRoll.supportsAddBitmapData){ cameraRoll.addBitmapData(capture); } } If we now check our Android Gallery, we will find the saved image: How it works... Most of this is performed exactly as it would be with normal Flash Platform development on the desktop. Attach a Camera to a Video, add the Video to the DisplayList, and then do whatever you need for your particular application. In this case, we simply capture what is displayed as BitmapData. The CameraRoll class, however, is specific to mobile application development as it will always refer to the directory upon which the device camera stores the photographs it produces. If you want to save these images within a different directory, we could use a File or FileReference object to do so, but this involves more steps for the user. Note that while using the Camera class, the hardware orientation of the camera is landscape. We can deal with this by either restricting the application to landscape mode, or through rotations and additional manipulation as we've performed in our example class. We've applied a 90 degree rotation to the image in this case using videoHolder.rotation to account for this shift when reading in the BitmapData. Depending on how any specific application handles this, it may not be necessary to do so. There's more... Other use cases for the traditional Camera object are things such as sending a video stream to Flash Media Server for live broadcast, augmented reality applications, or real-time peer to peer chat.
Read more
  • 0
  • 0
  • 2271
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime