The most important aspect of OpenSL support for libpd is that the audio thread is not attached to the Java virtual machine. This has two consequences that affect the design of the Java bindings. First, thread synchronization can no longer be done in Java. That’s easy to fix; just get rid of locks on the Java side and use pthread mutexes in the JNI layer instead. Second, the audio processing methods of libpd can no longer invoke message callbacks in Java when Pd sends messages to libpd’s receiver objects. Instead, it now writes a binary representation of Pd messages to a lock-free ring buffer, and the Java API has a new method,
pollMessageQueue, that reads messages from the ring buffer and invokes the corresponding callbacks in Java.
From the point of view of Android developers, this change makes no difference because the new version of the audio components of Pd for Android will automatically poll the message queue every 20ms as long as the audio is playing; all messages will be delivered almost instantaneously, and existing projects will work unchanged. In particular, my book remains up to date, except for one minor subsection that provides some background on Pd for Android. Most importantly, all sample code in the book is still current.
The new message queuing mechanism is factored in such a way that it’s easy reuse. There’s a new pair of source files, z_queued.[hc], that installs the queuing mechanism and provides a new set of message hooks:
EXTERN t_libpd_printhook libpd_queued_printhook;
EXTERN t_libpd_banghook libpd_queued_banghook;
EXTERN t_libpd_floathook libpd_queued_floathook;
EXTERN t_libpd_symbolhook libpd_queued_symbolhook;
EXTERN t_libpd_listhook libpd_queued_listhook;
EXTERN t_libpd_messagehook libpd_queued_messagehook;
EXTERN t_libpd_noteonhook libpd_queued_noteonhook;
EXTERN t_libpd_controlchangehook libpd_queued_controlchangehook;
EXTERN t_libpd_programchangehook libpd_queued_programchangehook;
EXTERN t_libpd_pitchbendhook libpd_queued_pitchbendhook;
EXTERN t_libpd_aftertouchhook libpd_queued_aftertouchhook;
EXTERN t_libpd_polyaftertouchhook libpd_queued_polyaftertouchhook;
EXTERN t_libpd_midibytehook libpd_queued_midibytehook;
If you use libpd in C or C++ and would like to add the new queuing mechanism, the transition is straightforward: Use
libpd_queued_init instead of
libpd_init, and assign your message callbacks to the queued hooks instead of the original hooks. Call
libpd_queue_receive in order to poll the queue and invoke callbacks, and call
libpd_queued_release when you’re done with libpd. That’s all.