DroidCon UK – day 2

Another quick summary of the talks of the day.

9.45 The Fragment transition
Who: Corey Leigh Latislaw
What: Introduction on using Fragments.
Web:
Summary: Start using Fragments now. There is no need to convert a whole app at once, but you can start using Fragments with the new Activities you are building.

10.30 Writing games for an Android console.
Who: All Sutton – Ouya
What: Some considerations to keep in mind when developing for a console.
Web: www.funkyandroid.com
Summary: Developing for a console is wildly different from mobile.

11.30 Android reverse engineering
Who: David Tellebaum – apkudo
What: Reverse engineering Android applications.
Web: www.apkudo.com
Summary: Hacking Zynga’s “Words With Friends” using (bak)smali and ViewServer.

12.15 Interfacing hardware with Android and Arduino
Who: Fei Manheche – Robobo
What: Connecting Android apps to Arduino hardware.
Web: www.robobo.org
Summary: A brief introduction on how to make Android and Arduino talk to each other.

14.00 Memory Analyzer
Who: Felipe Ferraz – CESAR
What: Memory analyzing to resolve bugs and optimize performance.
Web:
Summary: Using a timeline of memory dumps and the MAT Eclipse plugin to resolve bugs and optimize performance.

14.45 Deep dive into Android custom components
Who: Chui-Ki Chan – Monkey Write
What: Creating your own custom components.
Web: www.sqisland.com
Summary: Easily create your own custom components by either encapsulating or extending existing widgets. Slides: www.bit.ly/DeepDiveComp

15.45 Optimized network communication
Who: Erik Hellman – Sony Mobile
What: How to optimize your networking logic to provide user-friendly and power-efficient experiences.
Web:
Summary: A set of tips and best practices to avoid annoying the user and not drain the battery with networking activities.

16.30 Dynamic Animations
Who: Anders Ericsson – jayway.com
What: Dynamic animations.
Web: www.jayway.com
Summary: By extending a View, adding a custom class to calculate position (using spring and damper physics) and using a Runnable you can quickly add animations to any View.

17.15 AndroVM
Who: Daniel Fages – Genymobile
What: An Android VM that runs on VirtualBox.
Web: www.androvm.com
Summary: An explanation about how AndroVM is built followed by a demo.

18.00 Developing accessible applications
Who: Gary Readfern-Gray – RNIB
What: Developing accessible applications for Android.
Web: www.rnib.org.uk
Summary: It takes very little effort to add basic accessibility optimizations by using content descriptions for widgets and making the app navigable by keyboard (or at least D-pad).

DroidCon UK – day 1

A quick summary of the talks of the day.

10.05 AllJoyn
Who: Mitch Williams – Qualcomm
What: AllJoyn P2P framework
Web: www.alljoyn.org, www.alljoynappchallenge.com
Summary: An ad-hoc and proximity based p2p framework.

10.40 Device fragmentation
Who: Robin Puthli – Itude Mobile
What: Mobile device fragmentation
Web: www.itude.com
Summary: Fragmentation is an old problem. “There is no silver bullet. You have to pick and mix [from the available solutions].”

11.15 Unify VoIP / MSG Core
Who: Martyn Davis – Voxygen
What: Unify VoIP / MSG Core
Web: www.voxygen.co.uk
Summary: A paid for VoIP library written in C, using JSON messaging. Available for Android and iOS.

11.50 Polaris
Who: Cyril Mottier – Prixing
What: An introduction to Polaris
Web: www.github.com/cyrilmottier/Polaris
Summary: A (Google) maps library for Android. Adding a lot of useful features.

13.25 Gradle
Who: Lukas Jarosh – And labs ?
What: Gradle
Web:
Summary: Gradle, a less verbose Maven alternative.

14.30 OpenCV
Who: Eric – Sony
What: OpenCV library
Web: www.opencv.org
Summary: Open source Computer Vision library, containing loads of modules and image (related) algorithms.

Hardware accelerated Android emulator

A little gotcha when you “install” the “Intel Hardware Accelerated Execution Manager” using the SDK manager, it isn’t actually installed and/or enabled. You need to do a little bit more:

  1. Install Extras/Intel Hardware Accelerated Execution Manager using the “Android SDK Manager”
  2. Make sure “Intel x86 Atom System Image” in “Android 4.0.3 (API15)” is installed through the “Android SDK Manager” as well.
  3. Really install hardware acceleration by running [Android SDK folder]\extras\intel\Hardware_Accelerated_Execution_Manager\IntelHaxm.exe
  4. Update virtual device to use hardware acceleration in “AVD Manager”:
    – Set “CPU/ABI:” to “Intel Atom (x86)”
    – Under “Hardware”, add a new property “GPU Emulation” and set the value to “yes” (default is “no”).
  5. All done! Your hardware accelerated emulator is ready to launch

Note: Might not work with some libraries using JNI when they are built for ARM only.

IE9 and hidden Flash movies

Internet Explorer 9 (and Chrome sometimes as well) tries to be a little too smart and do too many things for you. The best example is removing the Flash movie from the DOM when you set its style to:

display: none !important;.

This small gotcha led to some headaches about why JS wasn’t able to call methods (via the ExternalInterface) on my Flash movie. As it turned out this way due to IE9 just completely removing the Flash movie from the DOM.

Using Android hardware devices on Ubuntu

I’ve been working on some Android applications lately and switched to Ubuntu for this. It took a while to figure out how to set up USB debugging on Unbuntu, but the steps below worked nicely for me.

  1. sudo vi /etc/udev/rules.d/51-android.rules
  2. For each vendor add: SUBSYSTEM==”usb”, ATTR{idVendor}==”0bb4″, MODE=”0666″, GROUP=”plugdev”
  3. chmod a+rx /etc/udev/rules.d/51-android.rules
  4. sudo restart udev
  5. adb devices (your phone should be listed there)

(Tested on Ubuntu 11)

Flash Player Debugger on Ubuntu

After having spent a good part of an hour on trying to install the Flash Player Debugger for FireFox on Ubuntu 11 64-bit, I found the following steps worked:

  1. sudo apt-get install nspluginwrapper
  2. copy libflashplayer.so (from debugger download) to /usr/lib/flashplugin-installer/
  3. sudo nspluginwrapper -i /usr/lib/flashplugin-installer/libflashplayer.so
  4. restart FireFox

Thanks to: AskUbuntu.com.

Don’t forget to set up mm.cfg.

When all is done, run:

tail -f ~/.macromedia/Flash_Player/Logs/flashlog.txt

Ant-Contrib for loop error

When trying to use Ant-Contrib for loops today, I ran into the error below:

BUILD FAILED
C:\Projects\…\ant\build.xml:200: Problem: failed to create task or type for
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.

To fix the error I had to update the Ant-Contrib taskdef resource path from using “antcontrib.properties” to use “antlib.xml” in my Ant build file.

  1. // Remove this line
  2. <taskdef resource="net/sf/antcontrib/antcontrib.properties>
  3. // And replace with this one
  4. <taskdef resource="net/sf/antcontrib/antlib.xml">

According to the Ant-Contrib manual (found in [Ant-Contrib install dir]/docs/manual/index.html) you need to use the “antcontrib.properties” file when you want Ant-Contrib to run with Ant Version 1.5. They even place a warning saying:

Keep in mind that some tasks will not be available to you , such as the <for> task

The confusing part is that on the project page they tell you to use the “antcontrib.properties” file.

Recording the microphone

Recording the microphone using AS3 is quite easy. Actually, storing the data or compressing it and sending it to a server is where it gets complicated. Normally, a Google search helps a lot when trying to find good information, but on this particular subject there seems to be a lot of misinformation. There are also a lot of libraries and / or frameworks available, but so far they didn’t really do what I wanted to do or did it in a far too complicated way. I’ve provided a list of audio libraries I tried out at the bottom.

Clearing things up

When you record data from the microphone using SampleDataEvents, the actual data is (part of a) 32-bit floating point (Big Endian) 44.1 kHz mono PCM audio stream (assuming that you left the rate of the Microphone at its default of 44). To store the microphone input, all you need to do is append this data to a buffer.

To play back the microphone input you can use the Sound class. The Sound class can only deal with a 32-bit floating point 44.1 kHz stereo PCM audio stream as input. Lucky for us, we’re almost there, we just need to convert mono into stereo. As you can see in the example below, creating (fake) stereo out of a mono signal is a matter of writing each sample twice.

The documentation for the Sound class shows an example of how to merge several Sounds into one using the extract method. We can apply the same technique to play back our ByteArray using the Sound class:

  1. // The buffer where we stored the microphone input.
  2. var playbackBuffer:ByteArray;
  3. // The number of channels the buffer contains,
  4. // 1 means mono, 2 means stereo.
  5. var channels:int = 1;
  6. var outputSound:Sound = new Sound();
  7.  
  8. outputSound.addEventListener(SampleDataEvent.SAMPLE_DATA,
  9. outputSampleDataHandler);
  10. outputChannel = outputSound.play();
  11.  
  12. private function outputSampleDataHandler(event:SampleDataEvent):void {
  13.     for (var i:int = 0; i < 8192 &&
  14.         playbackBuffer.bytesAvailable > 2; i++) {
  15.  
  16.         var sample:Number = playbackBuffer.readFloat();
  17.         event.data.writeFloat(sample);
  18.  
  19.         // Fake stereo as dual mono when the
  20.         // original data is only 1 channel.
  21.         if(channels > 1) {
  22.             event.data.writeFloat(sample);
  23.         }
  24.     }
  25. }

The above seems simple enough, but when you want to save the data to a file, things get complicated. First you need to choose a file format in which to store the output. Secondly, if you want to reduce the amount of data to be saved, you need to choose a codec to compress the audio stream. When I was experimenting with MP3 encoding of my recorded data, I found out that the codec required the stream input to be a 16-bit signed integer with a sampling rate of 44.1 kHz. When you get into this territory, it helps to read up a bit about the techniques behind digital audio. I’ll try to summarize some of the most useful things I learned.

Pulse-code modulation (PCM)

Pulse-code modulation is a way of representing analog audio signal on a digital system by sampling the signal at a fixed interval. See 1) in the image I created to explain some PCM examples.

By keeping the same playback frequency, but adding more samples (using some form of interpolation), you slow down playback / lower the pitch (blue curve). The opposite is also true, remove samples and playback will speed up / the pitch is higher (red curve). See 2) in the PCM examples image.

If you multiply or divide the each sample by a fixed value, you increase or decrease the signal strength (green curve). See 3) in the PCM examples image. Keep in mind that multiplying or dividing could result in clipping or complete cancellation of the signal if you overflow or underflow the bit depth precision.

Sample rate conversion

The sample rate defines how many samples are taken of the analogue sound per second and is expressed in Hertz, for example, CDs have a sample rate of 44.1 kHz. The higher the sample rate, the better the quality. Other typical sample rates are 8, 11.025, 22.05 and 48 kHz.

There are two types of sample rate conversion, there is upsampling and there is downsampling.

It is usually easier (whether you are upsampling or downsampling) to first upsample (using linear interpolation) to the least common multiple (LCM) and then downsample to the required sample rate.

Generally speaking when you downsample an audio signal you can get away with duplicating a sample when upsampling to the LCM, most of the data will be dropped anyway as you downsample to the required sample rate.

Since sample rate conversion is quite CPU intensive, there are some shortcuts you can take to convert to a certain sample rate from another. Say you want to convert 44.1 kHz into 8 kHz, it seems a bit redundant to first upsample to 3528000 Hz (which is the LCM), and then downsample to 8 kHz. What you could do instead, is alternate between using every 5th and 6th sample (since 44.1 / 8 is roughly 5.5).

Bit depth conversion

The bit depth determines granularity of a single sample, the higher the bit depth, the more accurate the sound can be represented. CDs have a bit depth of 16-bit, other typical bit depths are 8, 24 and 32.

Usually 8-bit audio streams are using unsigned integers, 16-bit ones are using signed integers and 32-bit streams use signed floating point. Knowing this it is quite straightforward to convert from one bit depth to the other, it’s a matter of multiplication.

Note: You may need to do some additional checks to make sure you aren’t overflowing the available bits when doing the conversion.

When you understand the theory I just talked about, it becomes a lot easier to write the tools you need to convert audio from one bit rate to the other as well as changing between sample rates. It also gave me some ideas about some filters to implement, like a normalization filter. To help you get started I’ve included some tips and references below.

Tips

  • The Microphone.rate property accepts values of 44, 22, 11 and 8. These values actually represent 44100, 22050, 11025 and 8000 Hz.
  • The WaveEncoder class of the MicRecorder library comes in quite handy when you want to save your recorded audio. Keep in mind that the encode method expects the passed in data to be 32-bit and will convert it to 16-bit on the fly. This tripped me up a couple of times as I passed in a 16-bit audio stream and was surprised to find out that the saved WAV file just produced a lot of white noise. On my copy of this class, I added an additional check to the create method, to make sure that the 16-bit space wasn’t being overflown when converting and multiplying by a _volume (multiplier) value.
  • When you want to output your recorded audio, make sure to keep the Endianness of your ByteArrays to Little Endian. I wondered countless times why playback of my ByteArray resulted in just noise, only to find out that I had forgotten about the Endianness of it.
  • Forget about the loadCompressedDataFromByteArray and loadPCMFromByteArray methods in the Sound class for Flash Player 11. They just don’t work, you’ll get a sound playing, but the last set of bytes seem to loop forever when the audio stream should be finished.
  • If you want to see how the sound you produced actually looks like, you may want to download sofware like Audacity. This tool can give you a visual representation of the wave form as well as a lot of information about the file that you opened. When you open a raw audio stream, you can also flick the settings around to figure out what sampling rate and bit depth the stream is using.

Further reading

AS3 audio libraries

Alchemy on Windows7

Installing Adobe Alchemy on Windows7 wasn’t as straightforward as the Adobe Labs site made me believe.

The following error would keep on showing when I tried to run the example:

$ gcc stringecho.c -O3 -Wall -swc -o stringecho.swc
llvm-gcc.exe: error while loading shared libraries: ? …

I finally got it to work by using the steps below:

  1. Install the Alchemy Repack, from www.covergraph.com in a temporary directory (I just want to copy some of the files).
  2. Download and install Alchemy from the Adobe website, as per their instructions.
  3. Copy the “achacks”, “avm2-libc”, “bin” and “flashlibs” folders from your “Alchemy Repack” installation folder.
  4. Uninstall / Delete Alchemy Repack
  5. Good to go! 🙂
  6. (Optional:) Set the “CYGWIN=nodosfilewarning” environment variable option to avoid Cygwin warnings about MS-Dos style paths. (Unfortunately, this doesn’t work for me, even though “echo ${CYGWIN}” prints “nodosfilewarning”.)

Note: If you already have Cygwin installed, you can install additional packages by running setup.exe again.

Sound from ByteArray

While writing a quick test application to record microphone input and playing that same recording, I found out that playing back a ByteArray directly using the Sound class wasn’t possible. Luckily a solution is never far away when doing a Google search and it turns out that FlexibleFactory has a good solution: the MP3FileReferenceLoader lib. With a bit of tweaking you can pass in a ByteArray directly and don’t need to rely on a FileReference.

Good news though! As per Flash Player 11, the following 2 methods have been added to the (native) Sound class that can be used to achieve the same behaviour:

  • Sound.loadCompressedDataFromByteArray(bytes:ByteArray, bytesLength:uint)
  • Sound.loadPCMFromByteArray(bytes:ByteArray, samples:uint, format:String = “float”, stereo:Boolean = true, sampleRate:Number = 44100.0)