Saturday, 24 December 2011

I got hold of a Kindle Fire via a re-seller on eBay UK, so we could make sure that Mixtikl worked fine on there.

This being Android, Mixtikl worked first time! I installed Mixtikl using "adb install", having first configured adb to recognise the Kindle Fire.

I changed just a couple of things to make it "Kindle Fire friendly". Those being:
- I had to increase the audio latency a bit to prevent audio break-up; that took just a few minutes...
- I had to account for Kindle Fire's taking-up the bottom 20 pixels to display the soft menu bar, which was also very easy...

I must say that Mixtikl works *really* well on the Kindle Fire. The Mixtikl icon doesn't display at the moment; but I have read that is because the icon is downloaded only when you purchase the app from the Amazon Kindle App Store.

I should say that I'm really very impressed with the Kindle Fire! It is a really nice size, fabulous for reading books (thanks to the touch screen, which isn't on the older Kindle of course). It seems very fast, with a lovely clear display and it is very responsive. Will I like it more than my iPad 1? Well, I prefer the size of the Kindle Fire, and like the stereo speakers; and I like that it was so easy to get our app running on it. :) The iPad has the advantage of having lots of good quality games for it... but it is *very* much more expensive ... if the Kindle Fire had more storage space, it'd make quite a nice MP3 player.

It's a pain that the Amazon App store is US-only at the moment, but I'm sure they'll roll that out worldwide soon enough. I think they're going to sell huge numbers of Kindle Fires!

I also want to mention that so far, the Amazon developer support team have been *incredibly* responsive to the questions I've had; I'm genuinely impressed!

Monday, 19 December 2011

I thought I'd share how I ended-up porting Mixtikl to Android, as this has been a long road!

When I first started looking at porting Mixtikl to Android, there were a couple of blocking issues;
- no support for C++ template library (though eventually STLPort arrived!)
- the original Mixtikl made heavy use of Modal code for dialog handling
Both of those two items made a port with Android a non-starter.

However, when Airplay (now renamed to Marmalade) added Android support, we were able to attempt a port of Mixtikl; as Airplay contained both C++ template library support, and supported modal code.
Ultimately however, the audio had too many problems (very, very high latency, mono only etc.) and this made the Airplay-based port too low quality to allow us to release.

Time moves on however, and a while back, Google added full support for the C++ standard template library to the Android NDK. And, critically, they added support for both OpenSL (to Android 2.3), and 32-bit ARM code generation (via armeabi-v7a). Given those changes, we spend a month or so removing all the modal code from Mixtikl (not an easy undertaking: you have to bear in mind that Mixtikl is > 500K lines of C++ code!).

So, given those changes in both the Android NDK and Mixtikl's own internal architecture, we were able to start and complete a full native port of Mixtikl to Android.

The bulk of Mixtikl remains in C++; all the graphics are drawn via the same C++-based graphics engine we use on all platforms. The interaction with Java is just a thin JNI layer that looks after drawing primitives and some native dialog interfacing. The OpenSL support is just a thin adaptor layer between our audio engine and OpenSL.

Mixtikl performs brilliantly on Android in my opinion; though as noted elsewhere the Android OpenSL implementation is missing a big trick in regards latency management; and we have to configure Mixtikl to run with slightly higher latency that we would like in order to avoid any potential audio break-up.

I should note that debugging C++ code on Android remains a pain, you have to rely on trace statements, though it is at least possible now to use gdb and the bt command to trap crashes when they happen and see where the code died in the call stack. The good news is that Mixtikl is very solid as 99% of the code is cross-platform and very well tested, so I've hardly had to touch gdb!

Tuesday, 6 December 2011

I been approached a few times recently about how to write low-latency audio latency apps in Android, and I point such queries to OpenSL and say "look how much better it is that it used to be" (provided you use C++ of course)...

But the bottom line is that the Android audio APIs - and that includes OpenSL - still miss the basic trick, which is to be able to offer a programmatic contract that is as simple as this:

App : what sets of audio rates and formats do you support?
(API responds, maybe only 22Khz stereo, for sake of simplicity here)
App asks: how many audio blocks do I need to keep prepared and primed in the queue to guarantee no break-up, at this rate/format, with minimal latency?
(API responds, maybe 2 blocks of 512 sample frames each).
App prepares the first 2 blocks, submits, and gets "block delivery" callbacks; it runs a separate thread to keep internal queues topped-up ready to deliver to the callbacks.

With that sort of contract, every app can run at minimal latency dictated by the underlying audio device (through the driver layer), on any device. Without that sort of contract, every app developer is kept guessing, and has to assume a worst case that works on all devices available for testing. :)

I implemented this scheme nearly a decade ago in the intent Sound System (I had the luxury of designing and implementing a complete audio architecture for mobile devices from scratch!). It is a piece of cake to do, and IMO audio developers for Android are screaming for it. Intent was focused on ultra-low audio latency for games / multimedia and musical instruments...

I should note, Apple have also missed the same trick - they've been able to get away with it however, as the offer a fixed range of hardware....

Sunday, 4 December 2011

I've just been through a very interesting period of work, sorting-out a high-performance audio interface for the Android port of Mixtikl. I've learned quite a few things - here are the highlights.

Firstly, target Android 2.3 or later. This allows you to use OpenSL ES, which is the only realistic approach for low-latency audio on Android. The audio allows you to delivery audio with pretty low latency, and totally avoids any problems of garbage collection blocking you. This of course assumes that all your audio code is written in C++!

As you're using OpenSL ES, and assuming you have some very heavy audio DSP going-on (like in Mixtikl!), you'll need to use a separate Posix thread to keep your audio callbacks pumped-up. Basically, if your OpenSL ES audio block callbacks take much time at all, then your audio will break-up. So, use a worker thread to keep sufficient audio pre-processed and ready to be picked-up and delivered via your callbacks!

Finally, and believe me this is important (!): make sure you target armeabi-v7a, and that you use the right compiler flags to generate 32-bit ARM7 code. If you on the other hand use the default settings, you'll generate Thumb code for armeabi - and your code will run staggeringly slower (!!), and audio break-up is inevitable if you're doing anything serious. So: don't bother targeting armeabi devices... and Thumb code is a no-no.