Pure Data, Android audio, and random stuff

Noisepages: Websites for smart artists.

With all the prerequisites for OpenSL support in place, the last step was to make the new functionality accessible in a way that’s transparent to existing Android projects. After giving the matter much thought, I settled on the following solution: Extend the existing Java API with native methods for controlling OpenSL; provide two different native binaries, one implementing the new methods for Android 2.3 or later, and one leaving them as no-ops for Android 2.2 or earlier.

The new methods are quite simple. First, there is a method that indicates whether the new methods provide meaningful functionality: boolean implementsAudio() If this method returns false, Pd for Android falls back on the old Java components for audio. Second, there is a pair of methods for creating and destroying the audio components: int openAudio(int inputChannels, int outputChannels, int sampleRate) and void closeAudio(). The openAudio method was actually there before, but the original version only set the audio parameters of Pd; the new version creates the corresponding OpenSL objects as well. Third, there are the usual transport methods: int startAudio(), int pauseAudio(), and boolean isRunning().

None of these new methods will actually concern developers who build apps on top of Pd for Android; just like the audio processing methods that existed before, they will only be called by the PdAudio class that hides all technicalities of the audio setup. PdAudio now supports both the old and the new audio components, but its public API remains unchanged. It also automatically polls the message queue, so that the new take on receiving messages from Pd will also be transparent to developers.

Coda

When I started contemplating OpenSL support for libpd, I didn’t even see how this could possibly work without without breaking existing projects. With the joy of hindsight, however, all the changes seem perfectly straightforward, maybe even obvious. This gives me a good feeling, about the new additions as well as the original design.

The one (very minor) drawback is that this change requires a slight change to the way non-Android applications use the Java bindings because developers will have to remember to poll the message queue if they want to receive messages from Pd, but I believe that the improved performance of the audio processing methods will more than make up for this inconvenience.

Moreover, although it wasn’t the goal, it turns out that this revision opens up a number of exciting new possibilities for non-Android uses of the Java components. To wit, there’s no reason why this technique, swapping out audio binaries underneath the same Java API, should be limited to Android. There’s no reason why we can’t have binaries that implement audio with JACK or PulseAudio for Linux, CoreAudio for Macs, or ASIO for Windows. Alternatively, one might just implement it once, using PortAudio, and compile it for all major platforms. (I already have a PortAudio prototype that seems to work nicely.) The Processing branch might also benefit from this.

2

2 Responses

  1. [...] libpd and OpenSL ES, Part IV: Extending the API [...]

  2. [...] I wrote up my reasoning behind the OpenSL support of libpd in June, I thought I was done, but then, due to the number of devices and Android versions out [...]

Leave a Reply