I have been working on a little application which requires mixing of a number of audio tracks. It should be multi-screen and run on PC’s as well as Android devices.
Ideally I would like it to be able to mix at least some 12 tracks, but making that happen on Android is proving to be very difficult. There are a few ways to do the calculations, and the benefits of different techniques varies depending on the machine running the code.
In a previous post I showed some code for a audio mixer made with Pixel Bender.
It works great on my PC, drastically reducing the CPU load compared to simply using ByteArray.readFloat and ByteArray.writeFloat.
Unfortunately it does not provide the same performance gains when I run the application on Android, either in the Flash Player or as an AIR app. In fact it does slightly worse that simply mixing in AS. I’m not sure why that is, but I guess it has something to do with threading.
So I have been thinking of possible solutions to squeeze out a few more tracks on Android. My first idea was that since there is no need for stereo audio, there could be some way to do the mixing in mono. But since Sound.extract will only produce a stereo output and one needs to write to SampleDataEvent.data in stereo it does not seem possible to reduce CPU strain much that way. When mixing in pure AS it removes the need for multiplying every second sample with the volume value, but that is pretty much it. You still need to increment the pointer when reading the audio data on every second sample, which seems to be about as taxing as reading an extra float that one does not use. And of course one needs to write twice to the SampleDataEvent.data. So any gains is very marginal. If Sound.extract had a flag to extract audio as mono it might have been possible to make a noticeable increase in track count by mixing in mono.
Also, Pixel Bender does not support single channel inputs and outputs, so I could not figure out a way to make a shader for mono mixing that reduces CPU load.
Another option I considered was using fast memory solutions such as Azoth or Apparat. It turns out to be a no-go since it requires the ByteArray to be little endian, and SampleDataEvent.data is big endian. Having to flip the bits for each sample would surely turn out to negate any benefits of the faster memory access.
Also Vector is faster than ByteArray, and I have seen claims that on Android it’s even faster than Alchemy memory. But since Sound.extract returns a ByteArray there is nothing to be gained by using a Vector for straight mixing since the samples are only accessed once.
So no matter what I try I seem to be hitting a dead end. The best track count I get on Android is still using basic mixing in AS, and on the PC Pixel Bender performs a lot better. So currently I have decided to keep two different engines in the application and switch between them depending on the device used.
Of course, if anyone can think of a solution I have not explored or are aware of any errors in my conclusions, your input would be greatly appreciated.
Related posts:
hi,
i’m currently facing the same probs
generating/mixing sounds with sampledata in air for android
apparently the readfloat/writefloat takes alot of cpu on a mobile device
did u have any luck optimizing the code?
thx
thomas
I haven’t figured out any more approaches to try, but in the last test I did I did get better performance using my PixelBender audio mixer than straight mixing in AS. Not sure if that has to do with software updates on my Galaxy S or not, and the difference is still somewhat marginal. And I’m afraid I can’t think of any optimizations that can be done to the code used in the approaches I have tried.
So for now I have accepted the low track count that can be achieved. I just hope Adobe eventually can find a way to improve performance of ByteArray access on Air and Flash Player on Android.
Hi,
please check this code: http://wonderfl.net/c/gyTW
Try to record more than 2-3 seconds and then listen saved mix. Mixed sound is distorted after couple of seconds of recording
Wav encoder is working ok…
How to fix this?
Thanks in advance!