summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/Android.mk1241
-rw-r--r--android/AndroidShm.cpp251
-rw-r--r--android/AndroidShm.h51
-rw-r--r--android/AndroidShmServer/main_androidshmservice.cpp19
-rw-r--r--android/AndroidShmServer/readme.txt23
-rw-r--r--android/AndroidShmServer/test/shmservicedump.cpp177
-rw-r--r--android/AndroidShmServer/test/shmservicetest.cpp189
-rw-r--r--android/BnAndroidShm.cpp83
-rw-r--r--android/BnAndroidShm.h16
-rw-r--r--android/BpAndroidShm.cpp111
-rw-r--r--android/BpAndroidShm.h25
-rw-r--r--android/CleanSpec.mk66
-rw-r--r--android/IAndroidShm.cpp6
-rw-r--r--android/IAndroidShm.h41
-rw-r--r--android/JackAndroidSemaphore.cpp262
-rw-r--r--android/JackAndroidSemaphore.h76
-rw-r--r--android/JackAndroidThread.cpp374
-rw-r--r--android/JackAndroidThread.h97
-rw-r--r--android/JackAtomic_os.h42
-rw-r--r--android/JackCompilerDeps_os.h48
-rw-r--r--android/JackControlAPIAndroid.cpp89
-rw-r--r--android/JackControlAPIAndroid.h44
-rw-r--r--android/JackError.cpp153
-rw-r--r--android/JackGoldfishDriver.cpp212
-rw-r--r--android/JackGoldfishDriver.h70
-rw-r--r--android/JackOpenSLESDriver.cpp236
-rw-r--r--android/JackOpenSLESDriver.h70
-rw-r--r--android/JackPlatformPlug_os.h91
-rw-r--r--android/JackShmMem_os.h40
-rw-r--r--android/JackSystemDeps_os.h32
-rw-r--r--android/NOTICE869
-rw-r--r--android/Shm.cpp886
-rw-r--r--android/Shm.h144
-rw-r--r--android/config.h25
-rw-r--r--android/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/bits/ctype_base.h14
-rw-r--r--android/opensl_io.c539
-rw-r--r--android/opensl_io.h121
-rw-r--r--common/JackConstants.h2
-rw-r--r--common/Jackdmp.cpp34
-rw-r--r--common/jack/types.h4
-rw-r--r--common/shm.h22
-rw-r--r--example-clients/alsa_in.c9
-rw-r--r--example-clients/alsa_out.c9
-rw-r--r--example-clients/midi_latency_test.c2
-rw-r--r--example-clients/transport.c20
-rw-r--r--linux/alsa/JackAlsaDriver.cpp14
-rw-r--r--linux/alsa/alsa_driver.c24
-rw-r--r--linux/alsa/alsa_rawmidi.c26
-rw-r--r--linux/alsa/alsa_seqmidi.c5
-rw-r--r--linux/alsa/hammerfall.c2
50 files changed, 6989 insertions, 17 deletions
diff --git a/android/Android.mk b/android/Android.mk
new file mode 100644
index 00000000..464ca244
--- /dev/null
+++ b/android/Android.mk
@@ -0,0 +1,1241 @@
+#
+# jack-1.9.9.5
+#
+
+LOCAL_PATH := $(call my-dir)
+JACK_ROOT := $(call my-dir)/..
+SUPPORT_ALSA_IN_JACK := true
+ALSA_INCLUDES := vendor/samsung/common/external/alsa-lib/include
+JACK_STL_LDFLAGS := -Lprebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI) -lgnustl_static
+JACK_STL_INCLUDES := $(JACK_ROOT)/android/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI)/include \
+ prebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI)/include \
+ prebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/include
+
+##########################################################
+# common
+##########################################################
+
+common_cflags := -O0 -g -Wall -fexceptions -fvisibility=hidden -DHAVE_CONFIG_H
+common_cflags += -Wno-unused -Wno-sign-compare -Wno-deprecated-declarations -Wno-cpp
+common_cppflags := -frtti -Wno-sign-promo -fcheck-new
+common_shm_cflags := -O0 -g -Wall -fexceptions -DHAVE_CONFIG_H -Wno-unused
+common_c_includes := \
+ $(JACK_ROOT) \
+ $(JACK_ROOT)/common \
+ $(JACK_ROOT)/common/jack \
+ $(JACK_ROOT)/android \
+ $(JACK_ROOT)/linux \
+ $(JACK_ROOT)/linux/alsa \
+ $(JACK_ROOT)/posix \
+ $(JACK_STL_INCLUDES)
+
+# copy common source file
+common_libsource_server_dir = .server
+common_libsource_client_dir = .client
+
+$(shell rm -rf $(LOCAL_PATH)/$(common_libsource_server_dir))
+$(shell rm -rf $(LOCAL_PATH)/$(common_libsource_client_dir))
+$(shell mkdir $(LOCAL_PATH)/$(common_libsource_server_dir))
+$(shell mkdir $(LOCAL_PATH)/$(common_libsource_client_dir))
+
+$(shell cp -rf $(LOCAL_PATH)/../common/JackActivationCount.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackActivationCount.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackAPI.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackAPI.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackClient.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackClient.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackConnectionManager.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackConnectionManager.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/ringbuffer.c $(LOCAL_PATH)/$(common_libsource_server_dir)/ringbuffer.c)
+$(shell cp -rf $(LOCAL_PATH)/JackError.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackError.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackException.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackException.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackFrameTimer.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackFrameTimer.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackGraphManager.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackGraphManager.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackPort.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackPort.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackPortType.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackPortType.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackAudioPort.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackAudioPort.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackMidiPort.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackMidiPort.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackMidiAPI.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackMidiAPI.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackEngineControl.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackEngineControl.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackShmMem.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackShmMem.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackGenericClientChannel.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackGenericClientChannel.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackGlobals.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackGlobals.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackDebugClient.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackDebugClient.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackTransportEngine.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackTransportEngine.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/timestamps.c $(LOCAL_PATH)/$(common_libsource_server_dir)/timestamps.c)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackTools.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackTools.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackMessageBuffer.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackMessageBuffer.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackEngineProfiling.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackEngineProfiling.cpp)
+$(shell cp -rf $(LOCAL_PATH)/JackAndroidThread.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackAndroidThread.cpp)
+$(shell cp -rf $(LOCAL_PATH)/JackAndroidSemaphore.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackAndroidSemaphore.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../posix/JackPosixProcessSync.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackPosixProcessSync.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../posix/JackPosixMutex.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackPosixMutex.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../posix/JackSocket.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackSocket.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../linux/JackLinuxTime.c $(LOCAL_PATH)/$(common_libsource_server_dir)/JackLinuxTime.c)
+
+$(shell cp -rf $(LOCAL_PATH)/../common/JackActivationCount.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackActivationCount.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackAPI.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackAPI.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackClient.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackClient.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackConnectionManager.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackConnectionManager.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/ringbuffer.c $(LOCAL_PATH)/$(common_libsource_client_dir)/ringbuffer.c)
+$(shell cp -rf $(LOCAL_PATH)/JackError.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackError.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackException.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackException.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackFrameTimer.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackFrameTimer.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackGraphManager.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackGraphManager.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackPort.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackPort.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackPortType.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackPortType.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackAudioPort.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackAudioPort.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackMidiPort.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackMidiPort.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackMidiAPI.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackMidiAPI.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackEngineControl.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackEngineControl.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackShmMem.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackShmMem.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackGenericClientChannel.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackGenericClientChannel.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackGlobals.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackGlobals.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackDebugClient.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackDebugClient.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackTransportEngine.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackTransportEngine.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/timestamps.c $(LOCAL_PATH)/$(common_libsource_client_dir)/timestamps.c)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackTools.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackTools.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackMessageBuffer.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackMessageBuffer.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../common/JackEngineProfiling.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackEngineProfiling.cpp)
+$(shell cp -rf $(LOCAL_PATH)/JackAndroidThread.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackAndroidThread.cpp)
+$(shell cp -rf $(LOCAL_PATH)/JackAndroidSemaphore.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackAndroidSemaphore.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../posix/JackPosixProcessSync.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackPosixProcessSync.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../posix/JackPosixMutex.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackPosixMutex.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../posix/JackSocket.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackSocket.cpp)
+$(shell cp -rf $(LOCAL_PATH)/../linux/JackLinuxTime.c $(LOCAL_PATH)/$(common_libsource_client_dir)/JackLinuxTime.c)
+
+common_libsource_server := \
+ $(common_libsource_server_dir)/JackActivationCount.cpp \
+ $(common_libsource_server_dir)/JackAPI.cpp \
+ $(common_libsource_server_dir)/JackClient.cpp \
+ $(common_libsource_server_dir)/JackConnectionManager.cpp \
+ $(common_libsource_server_dir)/ringbuffer.c \
+ $(common_libsource_server_dir)/JackError.cpp \
+ $(common_libsource_server_dir)/JackException.cpp \
+ $(common_libsource_server_dir)/JackFrameTimer.cpp \
+ $(common_libsource_server_dir)/JackGraphManager.cpp \
+ $(common_libsource_server_dir)/JackPort.cpp \
+ $(common_libsource_server_dir)/JackPortType.cpp \
+ $(common_libsource_server_dir)/JackAudioPort.cpp \
+ $(common_libsource_server_dir)/JackMidiPort.cpp \
+ $(common_libsource_server_dir)/JackMidiAPI.cpp \
+ $(common_libsource_server_dir)/JackEngineControl.cpp \
+ $(common_libsource_server_dir)/JackShmMem.cpp \
+ $(common_libsource_server_dir)/JackGenericClientChannel.cpp \
+ $(common_libsource_server_dir)/JackGlobals.cpp \
+ $(common_libsource_server_dir)/JackDebugClient.cpp \
+ $(common_libsource_server_dir)/JackTransportEngine.cpp \
+ $(common_libsource_server_dir)/timestamps.c \
+ $(common_libsource_server_dir)/JackTools.cpp \
+ $(common_libsource_server_dir)/JackMessageBuffer.cpp \
+ $(common_libsource_server_dir)/JackEngineProfiling.cpp \
+ $(common_libsource_server_dir)/JackAndroidThread.cpp \
+ $(common_libsource_server_dir)/JackAndroidSemaphore.cpp \
+ $(common_libsource_server_dir)/JackPosixProcessSync.cpp \
+ $(common_libsource_server_dir)/JackPosixMutex.cpp \
+ $(common_libsource_server_dir)/JackSocket.cpp \
+ $(common_libsource_server_dir)/JackLinuxTime.c
+
+common_libsource_client := \
+ $(common_libsource_client_dir)/JackActivationCount.cpp \
+ $(common_libsource_client_dir)/JackAPI.cpp \
+ $(common_libsource_client_dir)/JackClient.cpp \
+ $(common_libsource_client_dir)/JackConnectionManager.cpp \
+ $(common_libsource_client_dir)/ringbuffer.c \
+ $(common_libsource_client_dir)/JackError.cpp \
+ $(common_libsource_client_dir)/JackException.cpp \
+ $(common_libsource_client_dir)/JackFrameTimer.cpp \
+ $(common_libsource_client_dir)/JackGraphManager.cpp \
+ $(common_libsource_client_dir)/JackPort.cpp \
+ $(common_libsource_client_dir)/JackPortType.cpp \
+ $(common_libsource_client_dir)/JackAudioPort.cpp \
+ $(common_libsource_client_dir)/JackMidiPort.cpp \
+ $(common_libsource_client_dir)/JackMidiAPI.cpp \
+ $(common_libsource_client_dir)/JackEngineControl.cpp \
+ $(common_libsource_client_dir)/JackShmMem.cpp \
+ $(common_libsource_client_dir)/JackGenericClientChannel.cpp \
+ $(common_libsource_client_dir)/JackGlobals.cpp \
+ $(common_libsource_client_dir)/JackDebugClient.cpp \
+ $(common_libsource_client_dir)/JackTransportEngine.cpp \
+ $(common_libsource_client_dir)/timestamps.c \
+ $(common_libsource_client_dir)/JackTools.cpp \
+ $(common_libsource_client_dir)/JackMessageBuffer.cpp \
+ $(common_libsource_client_dir)/JackEngineProfiling.cpp \
+ $(common_libsource_client_dir)/JackAndroidThread.cpp \
+ $(common_libsource_client_dir)/JackAndroidSemaphore.cpp \
+ $(common_libsource_client_dir)/JackPosixProcessSync.cpp \
+ $(common_libsource_client_dir)/JackPosixMutex.cpp \
+ $(common_libsource_client_dir)/JackSocket.cpp \
+ $(common_libsource_client_dir)/JackLinuxTime.c
+
+server_libsource := \
+ ../common/JackAudioDriver.cpp \
+ ../common/JackTimedDriver.cpp \
+ ../common/JackMidiDriver.cpp \
+ ../common/JackDriver.cpp \
+ ../common/JackEngine.cpp \
+ ../common/JackExternalClient.cpp \
+ ../common/JackFreewheelDriver.cpp \
+ ../common/JackInternalClient.cpp \
+ ../common/JackServer.cpp \
+ ../common/JackThreadedDriver.cpp \
+ ../common/JackRestartThreadedDriver.cpp \
+ ../common/JackWaitThreadedDriver.cpp \
+ ../common/JackServerAPI.cpp \
+ ../common/JackDriverLoader.cpp \
+ ../common/JackServerGlobals.cpp \
+ ../common/JackControlAPI.cpp \
+ JackControlAPIAndroid.cpp \
+ ../common/JackNetTool.cpp \
+ ../common/JackNetInterface.cpp \
+ ../common/JackArgParser.cpp \
+ ../common/JackRequestDecoder.cpp \
+ ../common/JackMidiAsyncQueue.cpp \
+ ../common/JackMidiAsyncWaitQueue.cpp \
+ ../common/JackMidiBufferReadQueue.cpp \
+ ../common/JackMidiBufferWriteQueue.cpp \
+ ../common/JackMidiRawInputWriteQueue.cpp \
+ ../common/JackMidiRawOutputWriteQueue.cpp \
+ ../common/JackMidiReadQueue.cpp \
+ ../common/JackMidiReceiveQueue.cpp \
+ ../common/JackMidiSendQueue.cpp \
+ ../common/JackMidiUtil.cpp \
+ ../common/JackMidiWriteQueue.cpp \
+ ../posix/JackSocketServerChannel.cpp \
+ ../posix/JackSocketNotifyChannel.cpp \
+ ../posix/JackSocketServerNotifyChannel.cpp \
+ ../posix/JackNetUnixSocket.cpp
+
+net_libsource := \
+ ../common/JackNetAPI.cpp \
+ ../common/JackNetInterface.cpp \
+ ../common/JackNetTool.cpp \
+ ../common/JackException.cpp \
+ ../common/JackAudioAdapterInterface.cpp \
+ ../common/JackLibSampleRateResampler.cpp \
+ ../common/JackResampler.cpp \
+ ../common/JackGlobals.cpp \
+ ../posix/JackPosixMutex.cpp \
+ ../common/ringbuffer.c \
+ ../posix/JackNetUnixSocket.cpp \
+ ../posix/JackPosixThread.cpp \
+ ../linux/JackLinuxTime.c
+
+client_libsource := \
+ ../common/JackLibClient.cpp \
+ ../common/JackLibAPI.cpp \
+ ../posix/JackSocketClientChannel.cpp \
+ ../posix/JackPosixServerLaunch.cpp
+
+netadapter_libsource := \
+ ../common/JackResampler.cpp \
+ ../common/JackLibSampleRateResampler.cpp \
+ ../common/JackAudioAdapter.cpp \
+ ../common/JackAudioAdapterInterface.cpp \
+ ../common/JackNetAdapter.cpp
+
+audioadapter_libsource := \
+ ../common/JackResampler.cpp \
+ ../common/JackLibSampleRateResampler.cpp \
+ ../common/JackAudioAdapter.cpp \
+ ../common/JackAudioAdapterInterface.cpp \
+ ../common/JackAudioAdapterFactory.cpp \
+ ../linux/alsa/JackAlsaAdapter.cpp
+
+# ========================================================
+# libjackserver.so
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(common_libsource_server) $(server_libsource)
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libjackshm
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := libjackserver
+
+include $(BUILD_SHARED_LIBRARY)
+
+## ========================================================
+## libjacknet.so
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := $(net_libsource)
+#LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+#LOCAL_CPPFLAGS := $(common_cppflags)
+#LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+#LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include
+#LOCAL_SHARED_LIBRARIES := libc libdl libcutils libsamplerate
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := libjacknet
+#
+#include $(BUILD_SHARED_LIBRARY)
+
+# ========================================================
+# libjack.so
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(common_libsource_client) $(client_libsource)
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libjackshm
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := libjack
+
+include $(BUILD_SHARED_LIBRARY)
+
+# ========================================================
+# netmanager.so
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../common/JackNetManager.cpp
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := netmanager
+
+include $(BUILD_SHARED_LIBRARY)
+
+# ========================================================
+# profiler.so
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../common/JackProfiler.cpp
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := profiler
+
+include $(BUILD_SHARED_LIBRARY)
+
+## ========================================================
+## netadapter.so
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := $(netadapter_libsource)
+#LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+#LOCAL_CPPFLAGS := $(common_cppflags)
+#LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+#LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include
+#LOCAL_SHARED_LIBRARIES := libc libdl libcutils libsamplerate libjackserver
+#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := netadapter
+#
+#include $(BUILD_SHARED_LIBRARY)
+
+## ========================================================
+## audioadapter.so
+## ========================================================
+#ifeq ($(SUPPORT_ALSA_IN_JACK),true)
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := $(audioadapter_libsource)
+#LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE -D_POSIX_SOURCE
+#LOCAL_CPPFLAGS := $(common_cppflags)
+#LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+#LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include $(ALSA_INCLUDES)
+#LOCAL_SHARED_LIBRARIES := libc libdl libcutils libasound libsamplerate libjackserver
+#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := audioadapter
+#
+#include $(BUILD_SHARED_LIBRARY)
+##endif
+
+##########################################################
+# linux
+##########################################################
+
+# ========================================================
+# jackd
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../common/Jackdmp.cpp
+# ../dbus/reserve.c
+# ../dbus/audio_reserve.c
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS) -ldl -Wl,--no-fatal-warnings
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libutils libjackserver
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jackd
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# driver - dummy
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../common/JackDummyDriver.cpp
+#'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_dummy
+
+include $(BUILD_SHARED_LIBRARY)
+
+# ========================================================
+# driver - alsa
+# ========================================================
+ifeq ($(SUPPORT_ALSA_IN_JACK),true)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../linux/alsa/JackAlsaDriver.cpp \
+ ../linux/alsa/alsa_rawmidi.c \
+ ../linux/alsa/alsa_seqmidi.c \
+ ../linux/alsa/alsa_midi_jackmp.cpp \
+ ../common/memops.c \
+ ../linux/alsa/generic_hw.c \
+ ../linux/alsa/hdsp.c \
+ ../linux/alsa/alsa_driver.c \
+ ../linux/alsa/hammerfall.c \
+ ../linux/alsa/ice1712.c
+#'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE -D_POSIX_SOURCE -D_XOPEN_SOURCE=600
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes) $(ALSA_INCLUDES)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver libasound
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_alsa
+
+include $(BUILD_SHARED_LIBRARY)
+endif
+
+## ========================================================
+## driver - alsarawmidi
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := \
+# ../linux/alsarawmidi/JackALSARawMidiDriver.cpp \
+# ../linux/alsarawmidi/JackALSARawMidiInputPort.cpp \
+# ../linux/alsarawmidi/JackALSARawMidiOutputPort.cpp \
+# ../linux/alsarawmidi/JackALSARawMidiPort.cpp \
+# ../linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp \
+# ../linux/alsarawmidi/JackALSARawMidiSendQueue.cpp \
+# ../linux/alsarawmidi/JackALSARawMidiUtil.cpp
+##'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD
+#LOCAL_CFLAGS := $(common_cflags) -D_POSIX_SOURCE -D__ALSA_RAWMIDI_H
+#LOCAL_CPPFLAGS := $(common_cppflags)
+#LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+#LOCAL_C_INCLUDES := $(common_c_includes) $(ALSA_INCLUDES)
+#LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver libasound
+#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := jack_alsarawmidi
+#
+#include $(BUILD_SHARED_LIBRARY)
+
+## LIBFREEBOB required
+## ========================================================
+## driver - freebob
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := ../linux/freebob/JackFreebobDriver.cpp
+##'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD
+#LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+#LOCAL_CPPFLAGS := $(common_cppflags)
+#LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+#LOCAL_C_INCLUDES := $(common_c_includes)
+#LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver
+#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := jack_freebob
+#
+#include $(BUILD_SHARED_LIBRARY)
+
+## LIBFFADO required
+## ========================================================
+## driver - firewire
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := \
+# ../linux/firewire/JackFFADODriver.cpp \
+# ../linux/firewire/JackFFADOMidiInputPort.cpp \
+# ../linux/firewire/JackFFADOMidiOutputPort.cpp \
+# ../linux/firewire/JackFFADOMidiReceiveQueue.cpp \
+# ../linux/firewire/JackFFADOMidiSendQueue.cpp
+##'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD
+#LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+#LOCAL_CPPFLAGS := $(common_cppflags)
+#LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+#LOCAL_C_INCLUDES := $(common_c_includes)
+#LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver
+#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := jack_firewire
+#
+#include $(BUILD_SHARED_LIBRARY)
+
+# ========================================================
+# driver - net
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../common/JackNetDriver.cpp
+#'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_net
+
+include $(BUILD_SHARED_LIBRARY)
+
+# ========================================================
+# driver - loopback
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../common/JackLoopbackDriver.cpp
+#'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_loopback
+
+include $(BUILD_SHARED_LIBRARY)
+
+##HAVE_SAMPLERATE, HAVE_CELT required
+## ========================================================
+## driver - netone
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := \
+# ../common/JackNetOneDriver.cpp \
+# ../common/netjack.c \
+# ../common/netjack_packet.c
+##'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD
+#LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+#LOCAL_CPPFLAGS := $(common_cppflags)
+#LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+#LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include
+#LOCAL_SHARED_LIBRARIES := libc libdl libcutils libsamplerate libjackserver
+#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := jack_netone
+#
+#include $(BUILD_SHARED_LIBRARY)
+
+##########################################################
+# android
+##########################################################
+
+# ========================================================
+# libjackshm.so
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := BnAndroidShm.cpp BpAndroidShm.cpp IAndroidShm.cpp AndroidShm.cpp Shm.cpp
+LOCAL_CFLAGS := $(common_shm_cflags) -DSERVER_SIDE
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libbinder
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := libjackshm
+
+include $(BUILD_SHARED_LIBRARY)
+
+# ========================================================
+# jack_goldfish.so - Goldfish driver for emulator
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := JackGoldfishDriver.cpp
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_goldfish
+
+include $(BUILD_SHARED_LIBRARY)
+
+# ========================================================
+# jack_opensles.so - OpenSL ES driver
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := JackOpenSLESDriver.cpp opensl_io.c
+LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes) frameworks/wilhelm/include
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver libOpenSLES
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_opensles
+
+include $(BUILD_SHARED_LIBRARY)
+
+##########################################################
+# android/AndroidShmServer
+##########################################################
+
+# ========================================================
+# androidshmservice
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ./AndroidShmServer/main_androidshmservice.cpp
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_CPPFLAGS := $(common_cppflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libcutils libutils libbinder libjackshm
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE:= androidshmservice
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# shmservicetest
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ./AndroidShmServer/test/shmservicetest.cpp
+LOCAL_SHARED_LIBRARIES := libcutils libutils libjackshm libbinder
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := shmservicetest
+LOCAL_CFLAGS += -DLOG_TAG=\"ShmServiceTest\"
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# shmservicedump
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ./AndroidShmServer/test/shmservicedump.cpp
+LOCAL_SHARED_LIBRARIES := libcutils libutils libjackshm libbinder
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := shmservicedump
+LOCAL_CFLAGS += $(common_cflags) -DLOG_TAG=\"ShmServiceDump\"
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+
+include $(BUILD_EXECUTABLE)
+
+##########################################################
+# example-clients
+##########################################################
+
+# ========================================================
+# jack_freewheel
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/freewheel.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_freewheel
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_connect
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/connect.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_connect
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_disconnect
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/connect.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_disconnect
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_lsp
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/lsp.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_lsp
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_metro
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/metro.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_metro
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_midiseq
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/midiseq.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_midiseq
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_midisine
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/midisine.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_midisine
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_showtime
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/showtime.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_showtime
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_simple_client
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/simple_client.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_simple_client
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_zombie
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/zombie.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_zombie
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_load
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/ipload.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_load
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_unload
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/ipunload.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_unload
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_alias
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/alias.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_alias
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_bufsize
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/bufsize.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_bufsize
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_wait
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/wait.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_wait
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_samplerate
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/samplerate.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_samplerate
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_evmon
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/evmon.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_evmon
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_monitor_client
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/monitor_client.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_monitor_client
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_thru
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/thru_client.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_thru
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_cpu_load
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/cpu_load.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_cpu_load
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_simple_session_client
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/simple_session_client.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_simple_session_client
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_session_notify
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/session_notify.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_session_notify
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_server_control
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/server_control.cpp
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjackserver
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_server_control
+
+include $(BUILD_EXECUTABLE)
+
+## ========================================================
+## jack_net_slave
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := ../example-clients/netslave.c
+#LOCAL_CFLAGS := $(common_cflags)
+#LOCAL_C_INCLUDES := $(common_c_includes)
+#LOCAL_SHARED_LIBRARIES := libjacknet
+#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := jack_net_slave
+#
+#include $(BUILD_EXECUTABLE)
+
+## ========================================================
+## jack_net_master
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := ../example-clients/netmaster.c
+#LOCAL_CFLAGS := $(common_cflags)
+#LOCAL_C_INCLUDES := $(common_c_includes)
+#LOCAL_SHARED_LIBRARIES := libjacknet
+#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := jack_net_master
+#
+#include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_latent_client
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/latent_client.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_latent_client
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_midi_dump
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/midi_dump.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_midi_dump
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_midi_latency_test
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/midi_latency_test.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_midi_latency_test
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_transport
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/transport.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_transport
+
+include $(BUILD_EXECUTABLE)
+
+## ========================================================
+## jack_rec
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := ../example-clients/capture_client.c
+#LOCAL_CFLAGS := $(common_cflags)
+#LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsndfile/src
+#LOCAL_SHARED_LIBRARIES := libjack libsndfile
+#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := jack_rec
+#
+#include $(BUILD_EXECUTABLE)
+
+## ========================================================
+## jack_netsource
+## ========================================================
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := ../example-clients/netsource.c ../common/netjack_packet.c
+#LOCAL_CFLAGS := $(common_cflags) -DNO_JACK_ERROR
+#LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include
+#LOCAL_SHARED_LIBRARIES := libsamplerate libjack
+#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := jack_netsource
+#
+#include $(BUILD_EXECUTABLE)
+
+## ========================================================
+## alsa_in
+## ========================================================
+#ifeq ($(SUPPORT_ALSA_IN_JACK),true)
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := ../example-clients/alsa_in.c ../common/memops.c
+#LOCAL_CFLAGS := $(common_cflags) -DNO_JACK_ERROR -D_POSIX_SOURCE -D_XOPEN_SOURCE=600
+#LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include $(ALSA_INCLUDES)
+#LOCAL_SHARED_LIBRARIES := libasound libsamplerate libjack
+#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := alsa_in
+#
+#include $(BUILD_EXECUTABLE)
+#endif
+
+## ========================================================
+## alsa_out
+## ========================================================
+#ifeq ($(SUPPORT_ALSA_IN_JACK),true)
+#include $(CLEAR_VARS)
+#
+#LOCAL_SRC_FILES := ../example-clients/alsa_out.c ../common/memops.c
+#LOCAL_CFLAGS := $(common_cflags) -DNO_JACK_ERROR -D_POSIX_SOURCE -D_XOPEN_SOURCE=600
+#LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include $(ALSA_INCLUDES)
+#LOCAL_SHARED_LIBRARIES := libasound libsamplerate libjack
+#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+#LOCAL_MODULE_TAGS := eng optional
+#LOCAL_MODULE := alsa_out
+#
+#include $(BUILD_EXECUTABLE)
+#endif
+
+# ========================================================
+# inprocess
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../example-clients/inprocess.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjackserver
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := example_lib
+
+include $(BUILD_SHARED_LIBRARY)
+
+##########################################################
+# tests
+##########################################################
+
+# ========================================================
+# jack_test
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../tests/test.cpp
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack libjackshm
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_test
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_cpu
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../tests/cpu.c
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack libjackshm
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_cpu
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_iodelay
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../tests/iodelay.cpp
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_CFLAGS += -Wno-narrowing
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack libjackshm
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_iodelay
+
+include $(BUILD_EXECUTABLE)
+
+# ========================================================
+# jack_multiple_metro
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../tests/external_metro.cpp
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS)
+LOCAL_C_INCLUDES := $(common_c_includes)
+LOCAL_SHARED_LIBRARIES := libjack libjackshm
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_MODULE := jack_multiple_metro
+
+include $(BUILD_EXECUTABLE)
diff --git a/android/AndroidShm.cpp b/android/AndroidShm.cpp
new file mode 100644
index 00000000..ff9847c3
--- /dev/null
+++ b/android/AndroidShm.cpp
@@ -0,0 +1,251 @@
+#define LOG_TAG "JAMSHMSERVICE"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <binder/MemoryHeapBase.h>
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <utils/Log.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include "BnAndroidShm.h"
+#include "AndroidShm.h"
+
+
+#include "JackConstants.h"
+
+
+#include <fcntl.h>
+#include <signal.h>
+#include <limits.h>
+#include <errno.h>
+#include <dirent.h>
+#include <sys/mman.h>
+#include <linux/ashmem.h>
+#include <cutils/ashmem.h>
+
+#include "JackError.h"
+
+#include <semaphore.h>
+
+
+#define MEMORY_SIZE 10*1024
+
+#define SEMAPHORE_NULL_CHAR '\0'
+
+// remove ALOGI log
+#undef ALOGI
+#define ALOGI
+
+namespace android {
+
+
+ int AndroidShm::instantiate() {
+ defaultServiceManager()->addService(String16("com.samsung.android.jam.IAndroidShm"), new AndroidShm); // SINGLETON WITH SAME NAME
+ return 0;
+ }
+
+ int AndroidShm::sendCommand(const char* command) {
+ ALOGI("I(pid:%d) send command is %s\n", getpid(), command);
+ if(strcmp(command, "semaphore") == 0) {
+ // print debug message about semaphore simulation
+ for(int i = MAX_SEMAPHORE_MEMORY_COUNT -1 ; i >= 0; i--) {
+ printf("index[%3d] = ptr[%p] name[%s]\n", i, (mSemaphore[i] != NULL)?mSemaphore[i]->getBase():0, mSemaphoreName[i]);
+ ALOGI("index[%3d] = ptr[%p] name[%s]\n", i, (mSemaphore[i] != NULL)?mSemaphore[i]->getBase():0, mSemaphoreName[i]);
+ }
+ }
+ return NO_ERROR;
+ }
+
+ int AndroidShm::testGetBufferByNewProcess() {
+ ALOGI("testGetBufferByNewProcess...");
+ int status;
+ int childPid = fork();
+
+ if(childPid > 0) {
+ ALOGI("I(pid%d) made a child process(pid:%d)", getpid(), childPid);
+ ALOGI("I(pid%d) wait until child(%d) was finish", getpid(), childPid);
+ wait(&status);
+ // wait ÇÏÁö ¾ÊÀ¸¸é child process°¡ ³²¾Æ ÀÖÀ½.
+ ALOGI("child(%d) was finished. ", childPid);
+ } else if(childPid == 0) {
+ ALOGI("im a new child process(pid:%d) ", getpid());
+ if(-1 == execlp("/system/bin/getbufferclient","getbufferclient",NULL)) {
+ ALOGE("failed to execute getbufferclient");
+ }
+ exit(0);
+ } else {
+ ALOGI("failed creating child process");
+ }
+ return 0;
+ }
+
+ int AndroidShm::testGetBuffer() {
+ ALOGI("I(pid:%d) trying to test get buffer...", getpid());
+ sp<IServiceManager> sm = defaultServiceManager();
+ ALOGI("get default ServiceManager is done");
+ sp<IBinder> b;
+ //String16* serviceName = new String16("com.samsung.android.jam.IAndroidShm");
+ do {
+ //ALOGI("here");
+ b = sm->getService(String16("com.samsung.android.jam.IAndroidShm"));
+ //ALOGI("getservice is done");
+
+ if(b != 0)
+ break;
+ //ALOGI("AndroidShm is not working, waiting...");
+ usleep(500000);
+
+ } while(true);
+
+ sp<IAndroidShm> service = interface_cast<IAndroidShm>(b);
+
+ //shared buffer.
+ sp<IMemoryHeap> receiverMemBase = service->getBuffer(0);
+
+ unsigned int *base = (unsigned int *) receiverMemBase->getBase();
+ int ret = 0;
+ if(base != (unsigned int *) -1) {
+ ALOGD("AndroidShm::testGetBuffer base=%p Data=0x%x\n",base, *base);
+ *base = (*base)+1;
+ ret = (unsigned int)(*base);
+ ALOGI("AndroidShm::testGetBuffer base=%p Data=0x%x CHANGED\n",base, *base);
+ receiverMemBase = 0;
+ } else {
+ ALOGE("Error shared memory not available\n");
+ }
+ return 0;
+ }
+
+ sp<IMemoryHeap> AndroidShm::getBuffer(int index) {
+ ALOGI("I(pid:%d) getBuffer index:%d", getpid(), index);
+ if(index < 0 || index >= MAX_SHARED_MEMORY_COUNT) {
+ ALOGE("error : out of index [%d]", index);
+ return NULL;
+ }
+ return mMemHeap[index];
+ }
+
+ int AndroidShm::MemAlloc(unsigned int size) {
+ ALOGI("try to allocate memory size[%d]", size);
+ for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) {
+ if(mMemHeap[i] == NULL) {
+ mMemHeap[i] = new MemoryHeapBase(size);
+ if(mMemHeap[i] == NULL){
+ ALOGI("fail to alloc, try one more...");
+ continue; // try one more.
+ }
+ return i;
+ }
+ }
+ ALOGE("fail to MemAlloc");
+ return -1; // fail to alloc
+ }
+
+ AndroidShm::AndroidShm() {
+ ALOGI("AndroidShm is created");
+ for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) {
+ mMemHeap[i] = NULL;
+ }
+ mRegistryIndex = 10000;
+ //mMemHeap = new MemoryHeapBase(MEMORY_SIZE);
+ //unsigned int *base = (unsigned int*) mMemHeap->getBase();
+ //*base = 0xdeadcafe;//
+
+ for(int j = 0; j < MAX_SEMAPHORE_MEMORY_COUNT; j++) {
+ mSemaphore[j] = NULL;
+ memset(mSemaphoreName[j], SEMAPHORE_NULL_CHAR, MAX_SEMAPHORE_NAME_LENGTH);
+ }
+ }
+
+ AndroidShm::~AndroidShm() {
+ ALOGI("AndroidShm is destroyed");
+ for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) {
+ (mMemHeap[i]).clear();
+ }
+ for(int j = 0; j < MAX_SEMAPHORE_MEMORY_COUNT; j++) {
+ (mSemaphore[j]).clear();
+ }
+ }
+
+ //status_t AndroidShm::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+ // return BnAndroidShm::onTransact(code, data, reply, flags);
+ //}
+
+ int AndroidShm::allocShm(const int size) { // if negative return value is error
+ ALOGI("try to alloc shared memory size[%d]", size);
+ return MemAlloc(size);
+ }
+
+ int AndroidShm::removeShm(const unsigned int index) { // shared memory Á¦°Å
+ ALOGI("try to remove shared memory index[%d]", index);
+ if(index >= MAX_SHARED_MEMORY_COUNT) {
+ ALOGE("remove shared memory: out of index");
+ return -1;
+ }
+ (mMemHeap[index]).clear();
+ return 1;
+ }
+
+ int AndroidShm::isAllocated(const unsigned int index) { // allocated ¿©ºÎ È®ÀÎ
+ ALOGI("try to check the memory allocation index[%d]", index);
+ if(index >= MAX_SHARED_MEMORY_COUNT) {
+ ALOGE("shared memory: out of index");
+ return 0;
+ }
+ if(mMemHeap[index] == NULL)
+ return 0;
+ else
+ return 1;
+ }
+
+ int AndroidShm::setRegistryIndex(const unsigned int index) {
+ ALOGI("set registry index %d", index);
+ mRegistryIndex = index;
+ return 1;
+ }
+
+ int AndroidShm::getRegistryIndex() {
+ return mRegistryIndex;
+ }
+
+ sp<IMemoryHeap> AndroidShm::InitSemaphore(const char* name) {
+ ALOGI("init semaphore [%s]", name);
+ for(int i = 0; i < MAX_SEMAPHORE_MEMORY_COUNT; i++) {
+ if(mSemaphoreName[i][0] == SEMAPHORE_NULL_CHAR) {
+ mSemaphore[i] = new MemoryHeapBase(sizeof(sem_t));
+ if(mSemaphore[i] == NULL){
+ ALOGI("fail to alloc, try one more...");
+ continue;
+ }
+ if(sem_init((sem_t*)(mSemaphore[i]->getBase()), 1, 0) == 0) {
+ strncpy(mSemaphoreName[i], name, MAX_SEMAPHORE_NAME_LENGTH - 1);
+ mSemaphoreName[i][MAX_SEMAPHORE_NAME_LENGTH - 1] = '\0';
+ ALOGI("sem_init success");
+ return mSemaphore[i];
+ } else {
+ (mSemaphore[i]).clear();
+ ALOGE("sem_init failed null returned");
+ return NULL;
+ }
+ } else {
+ // find already exist name
+ if(strcmp(mSemaphoreName[i], name) == 0) { // found
+ ALOGI("found - return alread allocated semaphore");
+ return mSemaphore[i];
+ }
+ }
+ }
+ ALOGE("sem_init failed null returned 2");
+ return NULL;
+ }
+
+};
+
diff --git a/android/AndroidShm.h b/android/AndroidShm.h
new file mode 100644
index 00000000..b868827a
--- /dev/null
+++ b/android/AndroidShm.h
@@ -0,0 +1,51 @@
+#ifndef ANDROIDSHM
+#define ANDROIDSHM
+
+#include <binder/Parcel.h>
+#include "BnAndroidShm.h"
+#include <utils/Log.h>
+#include <binder/MemoryHeapBase.h>
+#include "shm.h"
+#include "android/Shm.h" //android extension of shm.h
+
+namespace android {
+
+ class AndroidShm : public BnAndroidShm
+ {
+#define MAX_SHARED_MEMORY_COUNT 257
+ private:
+ int MemAlloc(unsigned int size);
+
+ public:
+ virtual ~AndroidShm();
+ static int instantiate();
+ virtual int sendCommand(const char* command);
+ virtual int allocShm(const int size); // if negative return value is error
+ virtual int removeShm(const unsigned int index); // shared memory Á¦°Å
+ virtual int isAllocated(const unsigned int index); // allocated ¿©ºÎ È®ÀÎ
+ virtual int setRegistryIndex(const unsigned int index);
+ virtual int getRegistryIndex();
+ virtual sp<IMemoryHeap> InitSemaphore(const char* name);
+ virtual sp<IMemoryHeap> getBuffer(int index);
+ //virtual status_t onTransact(
+ // uint32_t code,
+ // const Parcel& data,
+ // Parcel* reply,
+ // uint32_t flags);
+ private:
+ int testGetBuffer();
+ int testGetBufferByNewProcess();
+ AndroidShm();
+
+ sp<MemoryHeapBase> mMemHeap[MAX_SHARED_MEMORY_COUNT];
+ unsigned int mRegistryIndex;
+
+ // for named semaphore simulation
+ #define MAX_SEMAPHORE_MEMORY_COUNT 300
+ #define MAX_SEMAPHORE_NAME_LENGTH 300
+ sp<MemoryHeapBase> mSemaphore[MAX_SEMAPHORE_MEMORY_COUNT];
+ char mSemaphoreName[MAX_SEMAPHORE_MEMORY_COUNT][MAX_SEMAPHORE_NAME_LENGTH];
+ };
+};
+
+#endif
diff --git a/android/AndroidShmServer/main_androidshmservice.cpp b/android/AndroidShmServer/main_androidshmservice.cpp
new file mode 100644
index 00000000..1c6dde8f
--- /dev/null
+++ b/android/AndroidShmServer/main_androidshmservice.cpp
@@ -0,0 +1,19 @@
+#define LOG_TAG "main_androidshmservice"
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+#include "../../common/shm.h"
+#include "../Shm.h" //android extension of shm.h
+
+using namespace android;
+
+int main(int argc, char *argv[]) {
+ jack_instantiate();
+ ProcessState::self()->startThreadPool();
+ ALOGI("AndroidShmService is starting now");
+ IPCThreadState::self()->joinThreadPool();
+ return 0;
+}
diff --git a/android/AndroidShmServer/readme.txt b/android/AndroidShmServer/readme.txt
new file mode 100644
index 00000000..9b475beb
--- /dev/null
+++ b/android/AndroidShmServer/readme.txt
@@ -0,0 +1,23 @@
+IAndroidShmÀÇ ±â´ÉÀ» Å×½ºÆ® Çϱâ À§ÇÑ ¿ëµµ·Î »ç¿ëµÇ´Â ÇÁ·Î±×·¥ÀÔ´Ï´Ù.
+
+AndroidShmÀº service manager¿¡ shared memory¸¦ ÇÒ´çÇØÁÖ´Â ¼­ºñ½ºÀÔ´Ï´Ù.
+
+service name: com.sec.apa.IAndroidShm
+
+½ÇÇà ÆÄÀÏ:
+/system/bin/androidshmservice
+
+-------------------------------------------
+./test
+
+AndroidShmService¸¦ Å×½ºÆ®ÇÏ´Â ÇÁ·Î±×·¥
+
+/system/bin/shmservicetest
+
+AndroidShmService¿¡¼­ Á¦°øÇÏ´Â ±â´ÉÀ» UnitTestÇÕ´Ï´Ù.
+
+µ¿ÀÛ È®ÀÎ ¹æ¹ý:
+adb logcat À¸·Î ·Î±×·Î ¼º°ø/½ÇÆÐ È®ÀÎÇÔ.
+
+ÀüÁ¦ Á¶°Ç:
+/system/bin/androidshmservice¸¦ ½ÇÇàÁßÀÎ »óÅÂÀ̾î¾ß ÇÕ´Ï´Ù. \ No newline at end of file
diff --git a/android/AndroidShmServer/test/shmservicedump.cpp b/android/AndroidShmServer/test/shmservicedump.cpp
new file mode 100644
index 00000000..d7413f74
--- /dev/null
+++ b/android/AndroidShmServer/test/shmservicedump.cpp
@@ -0,0 +1,177 @@
+#include "../../IAndroidShm.h"
+#include <binder/MemoryHeapBase.h>
+#include <binder/IServiceManager.h>
+#include "../../../common/shm.h"
+
+namespace android {
+
+static sp<IMemoryHeap> receiverMemBase;
+#define MAX_SHARED_MEMORY_COUNT 257
+
+sp<IAndroidShm> getAndroidShmService() {
+ sp<IAndroidShm> shm = 0;
+
+ /* Get the buffer service */
+ if (shm == NULL) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder;
+ binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm"));
+ if (binder != 0) {
+ shm = IAndroidShm::asInterface(binder);
+ //shm = interface_cast<IAndroidShm>(binder);
+ }
+ }
+ return shm;
+}
+
+unsigned int * getBufferMemPointer(int index)
+{
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if (shm == NULL) {
+ printf("The EneaBufferServer is not published\n");
+ return (unsigned int *)-1; /* return an errorcode... */
+ } else {
+ receiverMemBase = shm->getBuffer(index);
+ if(receiverMemBase != NULL)
+ return (unsigned int *) receiverMemBase->getBase();
+ else
+ return (unsigned int*)-1;
+ }
+}
+
+}
+
+using namespace android;
+
+void showStatus() {
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if(shm == NULL) {
+ printf("shm service is not available\n");
+ return;
+ }
+
+ printf("<<<<<<<<<<< dump memory allocation status >>>>>>>>>>\n");
+ for(int i = 256; i >= 0; i--) {
+ if(shm->isAllocated(i) == 1) {
+ printf("Mem[%3d] == 0x%x\n", i, (unsigned int)getBufferMemPointer(i));
+ } else {
+ printf("Mem[%3d] == NULL\n", i);
+ }
+ }
+}
+
+void showRegistryIndex() {
+ sp<IAndroidShm> shm = getAndroidShmService();
+
+ if(shm == NULL) {
+ printf("shm service is not available\n");
+ return;
+ }
+
+ printf("<<<<<<<<<<< show registry index >>>>>>>>>>\n");
+
+ printf("index [%3d]\n",shm->getRegistryIndex());
+}
+
+void showHeader() {
+ sp<IAndroidShm> shm = getAndroidShmService();
+
+ if(shm == NULL) {
+ printf("shm service is not available\n");
+ return;
+ }
+
+ if(shm->getRegistryIndex() > 256) {
+ printf("don't have a registry header\n");
+ return;
+ }
+
+ unsigned int* buffer = getBufferMemPointer(shm->getRegistryIndex());
+ if(buffer) {
+ jack_shm_header_t * header = (jack_shm_header_t*)buffer;
+ printf("<<<<<<<<<< register header value >>>>>>>>>>\n");
+ printf("memory address 0x%x 0x%x\n", (unsigned int)(header), (unsigned int)buffer);
+ printf("magic = %d\n", header->magic);
+ printf("protocol = %d\n", header->protocol);
+ printf("type = %d\n", header->type);
+ printf("size = %d\n", header->size);
+ printf("hdr_len = %d\n", header->hdr_len);
+ printf("entry_len = %d\n", header->entry_len);
+ for(int j = 0; j < MAX_SERVERS; j++) {
+ //char name[256];
+ //memset(name, '\0', 256);
+ //strncpy(name, header->server[j].name, 10);
+ printf("server[%d] pid = %d, name = %s\n", j, header->server[j].pid, header->server[j].name);
+ }
+ }
+}
+
+void showBody() {
+ sp<IAndroidShm> shm = getAndroidShmService();
+
+ if(shm == NULL) {
+ printf("shm service is not available\n");
+ return;
+ }
+
+ if(shm->getRegistryIndex() > 256) {
+ printf("don't have a registry body\n");
+ return;
+ }
+ unsigned int* buffer = getBufferMemPointer(shm->getRegistryIndex());
+ if(buffer) {
+ jack_shm_header_t * header = (jack_shm_header_t*)buffer;
+ printf("<<<<<<<<<< registry body value >>>>>>>>>>\n");
+ jack_shm_registry_t * registry = (jack_shm_registry_t *) (header + 1);
+ for(int k = 255; k >= 0; k--) {
+ printf("registry[%3d] index[%3d],allocator[%3d],size[%6d],id[%10s],fd[%3d]\n", k,
+ registry[k].index, registry[k].allocator, registry[k].size,
+ registry[k].id,
+ registry[k].fd);
+ }
+ }
+}
+
+void showSemaphore() {
+ sp<IAndroidShm> shm = getAndroidShmService();
+
+ if(shm == NULL) {
+ printf("shm service is not available\n");
+ return;
+ }
+
+ shm->sendCommand("semaphore");
+ printf("log will be shown in the logcat log\n");
+}
+
+int main(int argc, char** argv) {
+ // base could be on same address as Servers base but this
+ // is purely by luck do NEVER rely on this. Linux memory
+ // management may put it wherever it likes.
+
+ if(argc < 2) {
+ printf("usage\n shmservicedump [status|header|body|index|semaphore]\n");
+ printf(" status: show the shared memory allocation status\n");
+ printf(" header: show the registry header infomations if the registry exist\n");
+ printf(" body: show the registry body infomations if the registry exist\n");
+ printf(" index: show the index of array that is allocated registry shared memory\n");
+ printf(" semaphore: show the memory array about semaphore simulation\n");
+ return 0;
+ }
+
+ if(strcmp(argv[1], "semaphore") == 0) {
+ showSemaphore();
+ } else if(strcmp(argv[1], "index") == 0) {
+ showRegistryIndex();
+ } else if(strcmp(argv[1], "status") == 0) {
+ showStatus();
+ } else if(strcmp(argv[1], "header") == 0) {
+ showHeader();
+ } else if(strcmp(argv[1], "body") == 0) {
+ showBody();
+ } else {
+ printf("%s is invalid parameter\n", argv[1]);
+ }
+
+ return 0;
+}
diff --git a/android/AndroidShmServer/test/shmservicetest.cpp b/android/AndroidShmServer/test/shmservicetest.cpp
new file mode 100644
index 00000000..d91670cc
--- /dev/null
+++ b/android/AndroidShmServer/test/shmservicetest.cpp
@@ -0,0 +1,189 @@
+#include "../../IAndroidShm.h"
+#include <binder/MemoryHeapBase.h>
+#include <binder/IServiceManager.h>
+
+namespace android {
+
+static sp<IMemoryHeap> receiverMemBase;
+#define MAX_SHARED_MEMORY_COUNT 257
+
+sp<IAndroidShm> getAndroidShmService() {
+ sp<IAndroidShm> shm = 0;
+
+ /* Get the buffer service */
+ if (shm == NULL) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder;
+ binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm"));
+ if (binder != 0) {
+ shm = IAndroidShm::asInterface(binder);
+ //shm = interface_cast<IAndroidShm>(binder);
+ }
+ }
+ return shm;
+}
+
+unsigned int * getBufferMemPointer(int index) {
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if (shm == NULL) {
+ ALOGE("The EneaBufferServer is not published");
+ return (unsigned int *)-1; /* return an errorcode... */
+ } else {
+ receiverMemBase = shm->getBuffer(index);
+ if(receiverMemBase != NULL)
+ return (unsigned int *) receiverMemBase->getBase();
+ else
+ return (unsigned int*)-1;
+ }
+}
+
+}
+
+using namespace android;
+
+void setup_test() {
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if(shm == NULL) return;
+ for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) {
+ shm->removeShm(i);
+ }
+}
+
+void teardown_test() {
+}
+
+void increase_value_once() {
+ ALOGD("*****test: increase_value_once*****\n");
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if(shm == NULL) return;
+
+ int slot = shm->allocShm(10000);
+ unsigned int *base = getBufferMemPointer(slot);
+ if(base != (unsigned int *)-1) {
+ ALOGD("ShmServiceTest base=%p Data=0x%x\n",base, *base);
+ *base = (*base)+1;
+ ALOGD("ShmServiceTest base=%p Data=0x%x CHANGED\n",base, *base);
+ //receiverMemBase = 0;
+ } else {
+ ALOGE("Error shared memory not available\n");
+ }
+}
+
+void increase_value_10times() {
+ ALOGD("*****test: increase_value_10times*****\n");
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if(shm == NULL) return;
+
+ int slot = shm->allocShm(10000);
+
+ for(int i = 0; i < 10; i++) {
+ unsigned int *base = getBufferMemPointer(slot);
+ if(base != (unsigned int *)-1) {
+ ALOGD("ShmServiceTest base=%p Data=0x%x\n",base, *base);
+ *base = (*base)+1;
+ ALOGD("ShmServiceTest base=%p Data=0x%x CHANGED\n",base, *base);
+ //receiverMemBase = 0;
+ } else {
+ ALOGE("Error shared memory not available\n");
+ }
+ }
+}
+
+void check_allocated() {
+ ALOGD("*****test: check_allocated*****\n");
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if(shm == NULL) return;
+
+ int slot = shm->allocShm(10000);
+ int i = 0;
+ for(; i < MAX_SHARED_MEMORY_COUNT; i++) {
+ if(slot == i) {
+ if(shm->isAllocated(i) == 1) {
+ //ALOGD("pass\n");
+ } else {
+ ALOGD("failed\n");
+ }
+ } else {
+ if(shm->isAllocated(i) == 0) {
+ //ALOGD("pass\n");
+ } else {
+ ALOGD("failed\n");
+ }
+ }
+ }
+
+ if(i == MAX_SHARED_MEMORY_COUNT) {
+ ALOGD("pass\n");
+ }
+}
+
+void test_set_get_registry_index() {
+ ALOGD("*****test: test_set_get_registry_index*****\n");
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if(shm == NULL) return;
+
+ int registry = 1;
+ shm->setRegistryIndex(registry);
+ if(registry == shm->getRegistryIndex()) {
+ ALOGD("pass\n");
+ } else {
+ ALOGD("fail\n");
+ }
+
+ registry = 0;
+ shm->setRegistryIndex(registry);
+ if(registry == shm->getRegistryIndex()) {
+ ALOGD("pass\n");
+ } else {
+ ALOGD("fail\n");
+ }
+}
+
+void test_memset() {
+ ALOGD("*****test: test_memset*****\n");
+ sp<IAndroidShm> shm = getAndroidShmService();
+ if(shm == NULL) return;
+
+ int slot = shm->allocShm(10000);
+
+ unsigned int * pnt = getBufferMemPointer(slot);
+
+ memset (pnt, 0, 10000);
+
+ ALOGD("result : 0 0 0 0\n");
+ ALOGD("memory dump : %d %d %d %d\n", pnt[0], pnt[1], pnt[2], pnt[3]);
+
+ memset (pnt, 0xffffffff, 10000);
+
+ ALOGD("result : -1 -1 -1 -1\n");
+ ALOGD("memory dump : %d %d %d %d", pnt[0], pnt[1], pnt[2], pnt[3]);
+}
+
+int main(int argc, char** argv) {
+ // base could be on same address as Servers base but this
+ // is purely by luck do NEVER rely on this. Linux memory
+ // management may put it wherever it likes.
+
+ setup_test();
+ increase_value_once();
+ teardown_test();
+
+ setup_test();
+ increase_value_10times();
+ teardown_test();
+
+ setup_test();
+ check_allocated();
+ teardown_test();
+
+ setup_test();
+ test_set_get_registry_index();
+ teardown_test();
+
+ setup_test();
+ test_memset();
+ teardown_test();
+
+ return 0;
+}
+
diff --git a/android/BnAndroidShm.cpp b/android/BnAndroidShm.cpp
new file mode 100644
index 00000000..6ea0afcc
--- /dev/null
+++ b/android/BnAndroidShm.cpp
@@ -0,0 +1,83 @@
+#include "BnAndroidShm.h"
+#include <binder/Parcel.h>
+
+namespace android {
+ status_t BnAndroidShm::onTransact( uint32_t code,
+ const Parcel &data,
+ Parcel *reply,
+ uint32_t flags)
+ {
+ switch(code) {
+ case HW_SENDCOMMAND:{
+ CHECK_INTERFACE(IAndroidShm, data, reply);
+ const char *str;
+ str = data.readCString();
+ reply->writeInt32(sendCommand(str));
+ return NO_ERROR;
+ }break;
+
+ case HW_GETBUFFER:{
+ CHECK_INTERFACE(IAndroidShm, data, reply);
+ int32_t index;
+ data.readInt32(&index);
+ sp<IMemoryHeap> Data = getBuffer(index);
+ if(Data != NULL){
+ reply->writeStrongBinder(Data->asBinder());
+ }
+ return NO_ERROR;
+ }break;
+
+ case HW_ALLOC_SHM:{
+ CHECK_INTERFACE(IAndroidShm, data, reply);
+ int32_t size;
+ data.readInt32(&size);
+ reply->writeInt32(allocShm(size));
+ return NO_ERROR;
+ }break;
+
+ case HW_REMOVE_SHM:{
+ CHECK_INTERFACE(IAndroidShm, data, reply);
+ int32_t index;
+ data.readInt32(&index);
+ reply->writeInt32(removeShm(index));
+ return NO_ERROR;
+ }break;
+
+ case HW_IS_ALLOCATED:{
+ CHECK_INTERFACE(IAndroidShm, data, reply);
+ int32_t index;
+ data.readInt32(&index);
+ reply->writeInt32(isAllocated(index));
+ return NO_ERROR;
+ }break;
+
+ case HW_SET_REGISTRY_INDEX:{
+ CHECK_INTERFACE(IAndroidShm, data, reply);
+ int32_t index;
+ data.readInt32(&index);
+ reply->writeInt32(setRegistryIndex(index));
+ return NO_ERROR;
+ }break;
+
+ case HW_GET_REGISTRY_INDEX:{
+ CHECK_INTERFACE(IAndroidShm, data, reply);
+ reply->writeInt32(getRegistryIndex());
+ return NO_ERROR;
+ }break;
+
+ case HW_INIT_SEMAPHORE:{
+ CHECK_INTERFACE(IAndroidShm, data, reply);
+ const char *name;
+ name = data.readCString();
+ sp<IMemoryHeap> Data = InitSemaphore(name);
+ if(Data != NULL){
+ reply->writeStrongBinder(Data->asBinder());
+ }
+ return NO_ERROR;
+ }break;
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+ }
+};
diff --git a/android/BnAndroidShm.h b/android/BnAndroidShm.h
new file mode 100644
index 00000000..9b3a46af
--- /dev/null
+++ b/android/BnAndroidShm.h
@@ -0,0 +1,16 @@
+#ifndef BNANDROIDSHM
+#define BNANDROIDSHM
+
+#include <binder/Parcel.h>
+#include "IAndroidShm.h"
+
+namespace android {
+ class BnAndroidShm : public BnInterface<IAndroidShm> {
+ public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+ };
+};
+#endif
diff --git a/android/BpAndroidShm.cpp b/android/BpAndroidShm.cpp
new file mode 100644
index 00000000..49dc8c47
--- /dev/null
+++ b/android/BpAndroidShm.cpp
@@ -0,0 +1,111 @@
+#include <binder/Parcel.h>
+#include <utils/Log.h>
+#include "BpAndroidShm.h"
+
+namespace android{
+
+ int BpAndroidShm::sendCommand(const char*command) {
+ Parcel data, reply;
+ data.writeInterfaceToken(
+ IAndroidShm::getInterfaceDescriptor());
+ data.writeCString(command);
+ status_t status = remote()->transact(HW_SENDCOMMAND, data, &reply);
+ if(status != NO_ERROR) {
+ ALOGE("print sendCommand error: %s", strerror(-status));
+ } else {
+ status= reply.readInt32();
+ }
+ return status;
+ }
+
+ sp<IMemoryHeap> BpAndroidShm::getBuffer(int index) {
+ Parcel data, reply;
+ sp<IMemoryHeap> memHeap = NULL;
+ data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor());
+ data.writeInt32(index);
+ remote()->transact(HW_GETBUFFER, data, &reply);
+ memHeap = interface_cast<IMemoryHeap> (reply.readStrongBinder());
+ return memHeap;
+ }
+
+ BpAndroidShm::BpAndroidShm( const sp<IBinder>& impl)
+ : BpInterface<IAndroidShm>(impl)
+ {}
+
+ BpAndroidShm::~BpAndroidShm()
+ {}
+
+ int BpAndroidShm::allocShm(const int size) { // if negative return value is error
+ Parcel data, reply;
+ data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor());
+ data.writeInt32(size);
+ status_t status = remote()->transact(HW_ALLOC_SHM, data, &reply);
+ if(status != NO_ERROR) {
+ ALOGE("print allocShm error: %s", strerror(-status));
+ } else {
+ status= reply.readInt32();
+ }
+ return status;
+ }
+
+ int BpAndroidShm::removeShm(const unsigned int index) { // shared memory Á¦°Å
+ Parcel data, reply;
+ data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor());
+ data.writeInt32(index);
+ status_t status = remote()->transact(HW_REMOVE_SHM, data, &reply);
+ if(status != NO_ERROR) {
+ ALOGE("print removeShm error: %s", strerror(-status));
+ } else {
+ status= reply.readInt32();
+ }
+ return status;
+ }
+
+ int BpAndroidShm::isAllocated(const unsigned int index) { // allocated ¿©ºÎ È®ÀÎ
+ Parcel data, reply;
+ data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor());
+ data.writeInt32(index);
+ status_t status = remote()->transact(HW_IS_ALLOCATED, data, &reply);
+ if(status != NO_ERROR) {
+ ALOGE("print isAllocated error: %s", strerror(-status));
+ } else {
+ status= reply.readInt32();
+ }
+ return status;
+ }
+
+ int BpAndroidShm::setRegistryIndex(const unsigned int index) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor());
+ data.writeInt32(index);
+ status_t status = remote()->transact(HW_SET_REGISTRY_INDEX, data, &reply);
+ if(status != NO_ERROR) {
+ ALOGE("print setRegistryIndex error: %s", strerror(-status));
+ } else {
+ status= reply.readInt32();
+ }
+ return status;
+ }
+
+ int BpAndroidShm::getRegistryIndex() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor());
+ status_t status = remote()->transact(HW_GET_REGISTRY_INDEX, data, &reply);
+ if(status != NO_ERROR) {
+ ALOGE("print getRegistryIndex error: %s", strerror(-status));
+ } else {
+ status= reply.readInt32();
+ }
+ return status;
+ }
+
+ sp<IMemoryHeap> BpAndroidShm::InitSemaphore(const char* name) {
+ Parcel data, reply;
+ sp<IMemoryHeap> memHeap = NULL;
+ data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor());
+ data.writeCString(name);
+ status_t status = remote()->transact(HW_INIT_SEMAPHORE, data, &reply);
+ memHeap = interface_cast<IMemoryHeap> (reply.readStrongBinder());
+ return memHeap;
+ }
+};
diff --git a/android/BpAndroidShm.h b/android/BpAndroidShm.h
new file mode 100644
index 00000000..e079cc49
--- /dev/null
+++ b/android/BpAndroidShm.h
@@ -0,0 +1,25 @@
+#ifndef BPANDROIDSHM
+#define BPANDROIDSHM
+
+#include <binder/Parcel.h>
+#include "IAndroidShm.h"
+#include <binder/IMemory.h>
+
+namespace android {
+ class BpAndroidShm: public BpInterface<IAndroidShm> {
+ public:
+ BpAndroidShm( const sp<IBinder> & impl);
+ virtual ~BpAndroidShm();
+ virtual sp<IMemoryHeap> getBuffer(int index);
+ virtual int sendCommand(const char *command);
+ virtual int allocShm(const int size); // if negative return value is error
+ virtual int removeShm(const unsigned int index); // shared memory Á¦°Å
+ virtual int isAllocated(const unsigned int index); // allocated ¿©ºÎ È®ÀÎ
+ virtual int setRegistryIndex(const unsigned int index);
+ virtual int getRegistryIndex();
+
+ virtual sp<IMemoryHeap> InitSemaphore(const char* name);
+ };
+};
+
+#endif
diff --git a/android/CleanSpec.mk b/android/CleanSpec.mk
new file mode 100644
index 00000000..cdcf505e
--- /dev/null
+++ b/android/CleanSpec.mk
@@ -0,0 +1,66 @@
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/common)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/alsa_in_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/alsa_out_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/androidshmservice_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/shmservicetest_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/shmservicedump_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_samplerate_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_freewheel_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_connect_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_disconnect_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_latent_client_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_midiseq_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_zombie_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_lsp_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_load_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jackd_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_monitor_client_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_looper_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_client_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_cpu_load_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_iodelay_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_midisine_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_cpu_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_keyboard_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_unload_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_wait_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_alias_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_metro_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_bufsize_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_thru_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_session_notify_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_midi_latency_test_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_rec_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_netsource_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_net_master_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_net_slave_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_showtime_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_server_control_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_evmon_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_test_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_transport_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_session_client_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_effect_intermediates)
+$(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_multiple_metro_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_midi_dump_intermediates)
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/common)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/posix)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjack_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjacknet_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjackserver_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjackshm_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_alsa_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_dummy_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_net_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_loopback_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_netone_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/audioadapter_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/example_lib_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/netadapter_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/netmanager_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/profiler_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_goldfish_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_opensles_intermediates)
+
diff --git a/android/IAndroidShm.cpp b/android/IAndroidShm.cpp
new file mode 100644
index 00000000..95f5924b
--- /dev/null
+++ b/android/IAndroidShm.cpp
@@ -0,0 +1,6 @@
+#include "IAndroidShm.h"
+#include "BpAndroidShm.h"
+
+namespace android{
+ IMPLEMENT_META_INTERFACE(AndroidShm, "com.samsung.android.jam.IAndroidShm");
+};
diff --git a/android/IAndroidShm.h b/android/IAndroidShm.h
new file mode 100644
index 00000000..a890162c
--- /dev/null
+++ b/android/IAndroidShm.h
@@ -0,0 +1,41 @@
+#ifndef IANDROIDSHM
+#define IANDROIDSHM
+
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+
+ namespace android {
+
+ enum {
+ HW_GETBUFFER = IBinder::FIRST_CALL_TRANSACTION,
+ HW_MULTIPLY,
+ HW_STARTSERVER,
+ HW_MAKECLIENT,
+ HW_SENDCOMMAND,
+ HW_LOADSO,
+ HW_ALLOC_SHM,
+ HW_REMOVE_SHM,
+ HW_IS_ALLOCATED,
+ HW_SET_REGISTRY_INDEX,
+ HW_GET_REGISTRY_INDEX,
+ HW_INIT_SEMAPHORE
+ };
+
+ class IAndroidShm: public IInterface {
+ public:
+ DECLARE_META_INTERFACE(AndroidShm);
+
+ virtual sp<IMemoryHeap> getBuffer(int index) = 0;
+ virtual int sendCommand(const char *command) = 0;
+ virtual int allocShm(const int size) = 0; // if negative return value is error
+ virtual int removeShm(const unsigned int index) = 0; // shared memory Á¦°Å
+ virtual int isAllocated(const unsigned int index) = 0; // allocated ¿©ºÎ È®ÀÎ
+ virtual int setRegistryIndex(const unsigned int index) = 0;
+ virtual int getRegistryIndex() = 0;
+
+ // for named semaphore simulation
+ virtual sp<IMemoryHeap> InitSemaphore(const char* name) = 0;
+ };
+};
+
+#endif
diff --git a/android/JackAndroidSemaphore.cpp b/android/JackAndroidSemaphore.cpp
new file mode 100644
index 00000000..703e289c
--- /dev/null
+++ b/android/JackAndroidSemaphore.cpp
@@ -0,0 +1,262 @@
+/*
+Copyright (C) 2004-2008 Grame
+Copyright (C) 2013 Samsung Electronics
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "JackAndroidSemaphore.h"
+#include "JackTools.h"
+#include "JackConstants.h"
+#include "JackError.h"
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include "IAndroidShm.h"
+#include "shm.h"
+#include "android/Shm.h" //android extension of shm.h
+
+namespace Jack
+{
+
+pthread_mutex_t JackAndroidSemaphore::mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void JackAndroidSemaphore::BuildName(const char* client_name, const char* server_name, char* res, int size)
+{
+ char ext_client_name[SYNC_MAX_NAME_SIZE + 1];
+ JackTools::RewriteName(client_name, ext_client_name);
+ if (getenv("JACK_PROMISCUOUS_SERVER")) {
+ snprintf(res, size, "jack_sem.%s_%s", server_name, ext_client_name);
+ } else {
+ snprintf(res, size, "jack_sem.%d_%s_%s", JackTools::GetUID(), server_name, ext_client_name);
+ }
+}
+
+bool JackAndroidSemaphore::Signal()
+{
+ int res;
+
+ if (!fSemaphore) {
+ jack_error("JackAndroidSemaphore::Signal name = %s already deallocated!!", fName);
+ return false;
+ }
+
+ if (fFlush)
+ return true;
+
+ if ((res = sem_post(fSemaphore)) != 0) {
+ jack_error("JackAndroidSemaphore::Signal name = %s err = %s", fName, strerror(errno));
+ }
+ return (res == 0);
+}
+
+bool JackAndroidSemaphore::SignalAll()
+{
+ int res;
+
+ if (!fSemaphore) {
+ jack_error("JackAndroidSemaphore::SignalAll name = %s already deallocated!!", fName);
+ return false;
+ }
+
+ if (fFlush)
+ return true;
+
+ if ((res = sem_post(fSemaphore)) != 0) {
+ jack_error("JackAndroidSemaphore::SignalAll name = %s err = %s", fName, strerror(errno));
+ }
+ return (res == 0);
+}
+
+/*
+bool JackAndroidSemaphore::Wait()
+{
+ int res;
+
+ if (!fSemaphore) {
+ jack_error("JackAndroidSemaphore::Wait name = %s already deallocated!!", fName);
+ return false;
+ }
+
+ if ((res = sem_wait(fSemaphore)) != 0) {
+ jack_error("JackAndroidSemaphore::Wait name = %s err = %s", fName, strerror(errno));
+ }
+ return (res == 0);
+}
+*/
+
+bool JackAndroidSemaphore::Wait()
+{
+ int res;
+
+ while ((res = sem_wait(fSemaphore) < 0)) {
+ jack_error("JackAndroidSemaphore::Wait name = %s err = %s", fName, strerror(errno));
+ if (errno != EINTR) {
+ break;
+ }
+ }
+ return (res == 0);
+}
+
+bool JackAndroidSemaphore::TimedWait(long usec)
+{
+ int res;
+ struct timeval now;
+ timespec time;
+
+ if (!fSemaphore) {
+ jack_error("JackAndroidSemaphore::TimedWait name = %s already deallocated!!", fName);
+ return false;
+ }
+ gettimeofday(&now, 0);
+ time.tv_sec = now.tv_sec + usec / 1000000;
+ long tv_usec = (now.tv_usec + (usec % 1000000));
+ time.tv_sec += tv_usec / 1000000;
+ time.tv_nsec = (tv_usec % 1000000) * 1000;
+
+ while ((res = sem_timedwait(fSemaphore, &time)) < 0) {
+ jack_error("JackAndroidSemaphore::TimedWait err = %s", strerror(errno));
+ jack_log("JackAndroidSemaphore::TimedWait now : %ld %ld ", now.tv_sec, now.tv_usec);
+ jack_log("JackAndroidSemaphore::TimedWait next : %ld %ld ", time.tv_sec, time.tv_nsec/1000);
+ if (errno == ETIMEDOUT) {
+ timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec = time.tv_sec - ts.tv_sec;
+ ts.tv_nsec = time.tv_nsec - ts.tv_nsec;
+ if (ts.tv_nsec < 0) {
+ ts.tv_nsec += 1000000000;
+ ts.tv_sec -= 1;
+ }
+ if (ts.tv_sec < 0 || ts.tv_nsec < 0) {
+ jack_error("JackAndroidSemaphore::TimedWait time may changed or client killed already! wait again!");
+ gettimeofday(&now, 0);
+ time.tv_sec = now.tv_sec + usec / 1000000;
+ long tv_usec = (now.tv_usec + (usec % 1000000));
+ time.tv_sec += tv_usec / 1000000;
+ time.tv_nsec = (tv_usec % 1000000) * 1000;
+ if ((res = sem_timedwait(fSemaphore, &time)) < 0) {
+ jack_error("JackAndroidSemaphore::TimedWait err = %s", strerror(errno));
+ jack_log("JackAndroidSemaphore::TimedWait now : %ld %ld ", now.tv_sec, now.tv_usec);
+ jack_log("JackAndroidSemaphore::TimedWait next : %ld %ld ", time.tv_sec, time.tv_nsec/1000);
+ }
+ }
+ }
+ if (errno != EINTR) {
+ break;
+ }
+ }
+ return (res == 0);
+}
+
+// Server side : publish the semaphore in the global namespace
+bool JackAndroidSemaphore::Allocate(const char* name, const char* server_name, int value)
+{
+ pthread_mutex_lock (&mutex);
+ BuildName(name, server_name, fName, sizeof(fName));
+ jack_log("JackAndroidSemaphore::Allocate name = %s val = %ld", fName, value);
+
+ android::sp<android::IAndroidShm> service = android::Shm::getShmService();
+ if(service == NULL){
+ jack_error("shm service is null");
+ return false;
+ }
+ fSemaphoreMemory = service->InitSemaphore(fName);
+ if(fSemaphoreMemory != NULL){
+ fSemaphore = (sem_t*)(fSemaphoreMemory->getBase());
+ }
+
+ if(fSemaphore == NULL) {
+ jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
+ pthread_mutex_unlock (&mutex);
+ return false;
+ } else {
+ sem_init(fSemaphore, 1, 0);
+ jack_log("sem_init()");
+ pthread_mutex_unlock (&mutex);
+ return true;
+ }
+}
+
+// Client side : get the published semaphore from server
+bool JackAndroidSemaphore::ConnectInput(const char* name, const char* server_name)
+{
+ pthread_mutex_lock (&mutex);
+ BuildName(name, server_name, fName, sizeof(fName));
+ jack_log("JackAndroidSemaphore::Connect name = %s", fName);
+
+ // Temporary...
+ if (fSemaphore) {
+ jack_log("Already connected name = %s", name);
+ pthread_mutex_unlock (&mutex);
+ return true;
+ }
+
+ android::sp<android::IAndroidShm> service = android::Shm::getShmService();
+ if(service == NULL){
+ jack_error("shm service is null");
+ return false;
+ }
+
+ fSemaphoreMemory = service->InitSemaphore(fName);
+ if(fSemaphoreMemory != NULL){
+ fSemaphore = (sem_t*)(fSemaphoreMemory->getBase());
+ }
+
+ if(fSemaphore == NULL) {
+ jack_error("Connect: can't connect named semaphore name = %s err = %s", fName, strerror(errno));
+ pthread_mutex_unlock (&mutex);
+ return false;
+ } else {
+ int val = 0;
+ sem_getvalue(fSemaphore, &val);
+ jack_log("JackAndroidSemaphore::Connect sem_getvalue %ld", val);
+ pthread_mutex_unlock (&mutex);
+ return true;
+ }
+}
+
+bool JackAndroidSemaphore::Connect(const char* name, const char* server_name)
+{
+ return ConnectInput(name, server_name);
+}
+
+bool JackAndroidSemaphore::ConnectOutput(const char* name, const char* server_name)
+{
+ return ConnectInput(name, server_name);
+}
+
+bool JackAndroidSemaphore::Disconnect()
+{
+ if (fSemaphore) {
+ jack_log("JackAndroidSemaphore::Disconnect name = %s", fName);
+ fSemaphore = NULL;
+ }
+ return true;
+}
+
+// Server side : destroy the semaphore
+void JackAndroidSemaphore::Destroy()
+{
+ if (fSemaphore != NULL) {
+ jack_log("JackAndroidSemaphore::Disconnect name = %s", fName);
+ fSemaphore = NULL;
+ } else {
+ jack_error("JackAndroidSemaphore::Destroy semaphore == NULL");
+ }
+}
+
+} // end of namespace
+
diff --git a/android/JackAndroidSemaphore.h b/android/JackAndroidSemaphore.h
new file mode 100644
index 00000000..dd8afdb9
--- /dev/null
+++ b/android/JackAndroidSemaphore.h
@@ -0,0 +1,76 @@
+/*
+Copyright (C) 2004-2008 Grame
+Copyright (C) 2013 Samsung Electronics
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef __JackAndroidSemaphore__
+#define __JackAndroidSemaphore__
+
+#include "JackSynchro.h"
+#include "JackCompilerDeps.h"
+#include <semaphore.h>
+#include <time.h>
+#include <assert.h>
+
+#include <binder/IMemory.h>
+#include <binder/MemoryHeapBase.h>
+#include <utils/RefBase.h>
+
+namespace Jack
+{
+
+/*!
+\brief Inter process synchronization using POSIX semaphore.
+*/
+
+class SERVER_EXPORT JackAndroidSemaphore : public detail::JackSynchro
+{
+
+ private:
+
+ sem_t* fSemaphore;
+ android::sp<android::IMemoryHeap> fSemaphoreMemory;
+ static pthread_mutex_t mutex;
+
+ protected:
+
+ void BuildName(const char* name, const char* server_name, char* res, int size);
+
+ public:
+
+ JackAndroidSemaphore():JackSynchro(), fSemaphore(NULL)
+ {}
+
+ bool Signal();
+ bool SignalAll();
+ bool Wait();
+ bool TimedWait(long usec);
+
+ bool Allocate(const char* name, const char* server_name, int value);
+ bool Connect(const char* name, const char* server_name);
+ bool ConnectInput(const char* name, const char* server_name);
+ bool ConnectOutput(const char* name, const char* server_name);
+ bool Disconnect();
+ void Destroy();
+};
+
+} // end of namespace
+
+
+#endif
+
diff --git a/android/JackAndroidThread.cpp b/android/JackAndroidThread.cpp
new file mode 100644
index 00000000..6c9e135d
--- /dev/null
+++ b/android/JackAndroidThread.cpp
@@ -0,0 +1,374 @@
+/*
+Copyright (C) 2001 Paul Davis
+Copyright (C) 2004-2008 Grame
+Copyright (C) 2013 Samsung Electronics
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "JackAndroidThread.h"
+#include "JackError.h"
+#include "JackTime.h"
+#include "JackGlobals.h"
+#include <string.h> // for memset
+#include <unistd.h> // for _POSIX_PRIORITY_SCHEDULING check
+#include <signal.h>
+
+//#define JACK_SCHED_POLICY SCHED_RR
+#define JACK_SCHED_POLICY SCHED_FIFO
+
+namespace Jack
+{
+
+void JackAndroidThread::thread_exit_handler(int sig)
+{
+ printf("this signal is %d \n", sig);
+ pthread_exit(0);
+}
+
+void* JackAndroidThread::ThreadHandler(void* arg)
+{
+ JackAndroidThread* obj = (JackAndroidThread*)arg;
+ JackRunnableInterface* runnable = obj->fRunnable;
+ int err;
+
+ struct sigaction actions;
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_exit_handler;
+ sigaction(SIGUSR1,&actions,NULL);
+
+ // Signal creation thread when started with StartSync
+ jack_log("JackAndroidThread::ThreadHandler : start");
+ obj->fStatus = kIniting;
+
+ // Call Init method
+ if (!runnable->Init()) {
+ jack_error("Thread init fails: thread quits");
+ return 0;
+ }
+
+ obj->fStatus = kRunning;
+
+ // If Init succeed, start the thread loop
+ bool res = true;
+ while (obj->fStatus == kRunning && res) {
+ res = runnable->Execute();
+ }
+
+ jack_log("JackAndroidThread::ThreadHandler : exit");
+ pthread_exit(0);
+ return 0; // never reached
+}
+
+int JackAndroidThread::Start()
+{
+ fStatus = kStarting;
+
+ // Check if the thread was correctly started
+ if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) {
+ fStatus = kIdle;
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+int JackAndroidThread::StartSync()
+{
+ fStatus = kStarting;
+
+ if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) {
+ fStatus = kIdle;
+ return -1;
+ } else {
+ int count = 0;
+ while (fStatus == kStarting && ++count < 1000) {
+ JackSleep(1000);
+ }
+ return (count == 1000) ? -1 : 0;
+ }
+}
+
+int JackAndroidThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg)
+{
+ pthread_attr_t attributes;
+ struct sched_param rt_param;
+ pthread_attr_init(&attributes);
+ int res;
+
+ if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) {
+ jack_error("Cannot request joinable thread creation for thread res = %d", res);
+ return -1;
+ }
+
+ if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
+ jack_error("Cannot set scheduling scope for thread res = %d", res);
+ return -1;
+ }
+
+ if (realtime) {
+
+ jack_log("JackAndroidThread::StartImp : create RT thread");
+
+ if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) {
+ jack_error("Cannot set RR scheduling class for RT thread res = %d", res);
+ return -1;
+ }
+
+ memset(&rt_param, 0, sizeof(rt_param));
+ rt_param.sched_priority = priority;
+
+ if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
+ jack_error("Cannot set scheduling priority for RT thread res = %d", res);
+ return -1;
+ }
+
+ } else {
+ jack_log("JackAndroidThread::StartImp : create non RT thread");
+ }
+
+ if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) {
+ jack_error("Cannot set thread stack size res = %d", res);
+ return -1;
+ }
+
+ if ((res = JackGlobals::fJackThreadCreator(thread, &attributes, start_routine, arg))) {
+ jack_error("Cannot create thread res = %d", res);
+ return -1;
+ }
+
+ pthread_attr_destroy(&attributes);
+ return 0;
+}
+
+int JackAndroidThread::Kill()
+{
+ if (fThread != (jack_native_thread_t)NULL) { // If thread has been started
+ jack_log("JackAndroidThread::Kill");
+ void* status;
+
+ pthread_kill(fThread, SIGUSR1);
+ pthread_join(fThread, &status);
+ fStatus = kIdle;
+ fThread = (jack_native_thread_t)NULL;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+int JackAndroidThread::Stop()
+{
+ if (fThread != (jack_native_thread_t)NULL) { // If thread has been started
+ jack_log("JackAndroidThread::Stop");
+ void* status;
+ fStatus = kIdle; // Request for the thread to stop
+ pthread_join(fThread, &status);
+ fThread = (jack_native_thread_t)NULL;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+int JackAndroidThread::KillImp(jack_native_thread_t thread)
+{
+ if (thread != (jack_native_thread_t)NULL) { // If thread has been started
+ jack_log("JackAndroidThread::Kill");
+ void* status;
+ pthread_kill(thread, SIGUSR1);
+ pthread_join(thread, &status);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+int JackAndroidThread::StopImp(jack_native_thread_t thread)
+{
+ if (thread != (jack_native_thread_t)NULL) { // If thread has been started
+ jack_log("JackAndroidThread::Stop");
+ void* status;
+ pthread_join(thread, &status);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+int JackAndroidThread::AcquireRealTime()
+{
+ return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1;
+}
+
+int JackAndroidThread::AcquireSelfRealTime()
+{
+ return AcquireRealTimeImp(pthread_self(), fPriority);
+}
+
+int JackAndroidThread::AcquireRealTime(int priority)
+{
+ fPriority = priority;
+ return AcquireRealTime();
+}
+
+int JackAndroidThread::AcquireSelfRealTime(int priority)
+{
+ fPriority = priority;
+ return AcquireSelfRealTime();
+}
+int JackAndroidThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority)
+{
+ struct sched_param rtparam;
+ int res;
+ memset(&rtparam, 0, sizeof(rtparam));
+ rtparam.sched_priority = priority;
+
+ jack_log("JackAndroidThread::AcquireRealTimeImp priority = %d", priority);
+
+ if ((res = pthread_setschedparam(thread, JACK_SCHED_POLICY, &rtparam)) != 0) {
+ jack_error("Cannot use real-time scheduling (RR/%d)"
+ "(%d: %s)", rtparam.sched_priority, res,
+ strerror(res));
+ return -1;
+ }
+ return 0;
+}
+
+int JackAndroidThread::DropRealTime()
+{
+ return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1;
+}
+
+int JackAndroidThread::DropSelfRealTime()
+{
+ return DropRealTimeImp(pthread_self());
+}
+
+int JackAndroidThread::DropRealTimeImp(jack_native_thread_t thread)
+{
+ struct sched_param rtparam;
+ int res;
+ memset(&rtparam, 0, sizeof(rtparam));
+ rtparam.sched_priority = 0;
+
+ if ((res = pthread_setschedparam(thread, SCHED_OTHER, &rtparam)) != 0) {
+ jack_error("Cannot switch to normal scheduling priority(%s)", strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+jack_native_thread_t JackAndroidThread::GetThreadID()
+{
+ return fThread;
+}
+
+bool JackAndroidThread::IsThread()
+{
+ return pthread_self() == fThread;
+}
+
+void JackAndroidThread::Terminate()
+{
+ jack_log("JackAndroidThread::Terminate");
+ pthread_exit(0);
+}
+
+SERVER_EXPORT void ThreadExit()
+{
+ jack_log("ThreadExit");
+ pthread_exit(0);
+}
+
+} // end of namespace
+
+bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr)
+{
+#if defined(_POSIX_PRIORITY_SCHEDULING) && !defined(__APPLE__)
+ int min, max;
+
+ min = sched_get_priority_min(JACK_SCHED_POLICY);
+ if (min == -1)
+ {
+ jack_error("sched_get_priority_min() failed.");
+ return false;
+ }
+
+ max = sched_get_priority_max(JACK_SCHED_POLICY);
+ if (max == -1)
+ {
+ jack_error("sched_get_priority_max() failed.");
+ return false;
+ }
+
+ *min_ptr = min;
+ *max_ptr = max;
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool jack_tls_allocate_key(jack_tls_key *key_ptr)
+{
+ int ret;
+
+ ret = pthread_key_create(key_ptr, NULL);
+ if (ret != 0)
+ {
+ jack_error("pthread_key_create() failed with error %d", ret);
+ return false;
+ }
+
+ return true;
+}
+
+bool jack_tls_free_key(jack_tls_key key)
+{
+ int ret;
+
+ ret = pthread_key_delete(key);
+ if (ret != 0)
+ {
+ jack_error("pthread_key_delete() failed with error %d", ret);
+ return false;
+ }
+
+ return true;
+}
+
+bool jack_tls_set(jack_tls_key key, void *data_ptr)
+{
+ int ret;
+
+ ret = pthread_setspecific(key, (const void *)data_ptr);
+ if (ret != 0)
+ {
+ jack_error("pthread_setspecific() failed with error %d", ret);
+ return false;
+ }
+
+ return true;
+}
+
+void *jack_tls_get(jack_tls_key key)
+{
+ return pthread_getspecific(key);
+}
diff --git a/android/JackAndroidThread.h b/android/JackAndroidThread.h
new file mode 100644
index 00000000..d6ec66d8
--- /dev/null
+++ b/android/JackAndroidThread.h
@@ -0,0 +1,97 @@
+/*
+Copyright (C) 2001 Paul Davis
+Copyright (C) 2004-2008 Grame
+Copyright (C) 2013 Samsung Electronics
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef __JackAndroidThread__
+#define __JackAndroidThread__
+
+#include "JackThread.h"
+#include <pthread.h>
+
+namespace Jack
+{
+
+/* use 512KB stack per thread - the default is way too high to be feasible
+ * with mlockall() on many systems */
+#define THREAD_STACK 524288
+
+enum
+{
+ PTHREAD_CANCEL_DEFERRED,
+ PTHREAD_CANCEL_ASYNCHRONOUS
+};
+
+/*!
+\brief The POSIX thread base class.
+*/
+
+class SERVER_EXPORT JackAndroidThread : public detail::JackThreadInterface
+{
+
+ protected:
+
+ jack_native_thread_t fThread;
+ static void* ThreadHandler(void* arg);
+ static void thread_exit_handler(int sig);
+
+ public:
+
+ JackAndroidThread(JackRunnableInterface* runnable, bool real_time, int priority, int cancellation)
+ : JackThreadInterface(runnable, priority, real_time, cancellation), fThread((jack_native_thread_t)NULL)
+ {}
+ JackAndroidThread(JackRunnableInterface* runnable, int cancellation = PTHREAD_CANCEL_ASYNCHRONOUS)
+ : JackThreadInterface(runnable, 0, false, cancellation), fThread((jack_native_thread_t)NULL)
+ {}
+
+ int Start();
+ int StartSync();
+ int Kill();
+ int Stop();
+ void Terminate();
+
+ int AcquireRealTime(); // Used when called from another thread
+ int AcquireSelfRealTime(); // Used when called from thread itself
+
+ int AcquireRealTime(int priority); // Used when called from another thread
+ int AcquireSelfRealTime(int priority); // Used when called from thread itself
+
+ int DropRealTime(); // Used when called from another thread
+ int DropSelfRealTime(); // Used when called from thread itself
+
+ jack_native_thread_t GetThreadID();
+ bool IsThread();
+
+ static int AcquireRealTimeImp(jack_native_thread_t thread, int priority);
+ static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint)
+ {
+ return JackAndroidThread::AcquireRealTimeImp(thread, priority);
+ }
+ static int DropRealTimeImp(jack_native_thread_t thread);
+ static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg);
+ static int StopImp(jack_native_thread_t thread);
+ static int KillImp(jack_native_thread_t thread);
+};
+
+SERVER_EXPORT void ThreadExit();
+
+} // end of namespace
+
+
+#endif
diff --git a/android/JackAtomic_os.h b/android/JackAtomic_os.h
new file mode 100644
index 00000000..8b0ba2c6
--- /dev/null
+++ b/android/JackAtomic_os.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2004-2008 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __JackAtomic_android__
+#define __JackAtomic_android__
+
+#include "JackTypes.h"
+
+#include <sys/atomics.h>
+static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr)
+{
+#if 1
+ return !__atomic_cmpxchg(value, newvalue, (volatile int *)addr);
+#else
+ //slow compare_and_swap_32
+ if (*(UInt32*)addr == value) {
+ *(UInt32*)addr = newvalue;
+ return true;
+ }
+ return false;
+#endif
+}
+
+#endif
+
diff --git a/android/JackCompilerDeps_os.h b/android/JackCompilerDeps_os.h
new file mode 100644
index 00000000..8e6e5ff5
--- /dev/null
+++ b/android/JackCompilerDeps_os.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2004-2008 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __JackCompilerDeps_android__
+#define __JackCompilerDeps_android__
+
+#include "JackConstants.h"
+
+#if __GNUC__
+
+ #define MEM_ALIGN(x,y) x __attribute__((aligned(y)))
+ #define LIB_EXPORT __attribute__((visibility("default")))
+ #ifdef SERVER_SIDE
+ #if (__GNUC__< 4)
+ #define SERVER_EXPORT
+ #else
+ #define SERVER_EXPORT __attribute__((visibility("default")))
+ #endif
+ #else
+ #define SERVER_EXPORT __attribute__((visibility("hidden")))
+ #endif
+
+#else
+ #define MEM_ALIGN(x,y) x
+ #define LIB_EXPORT
+ #define SERVER_EXPORT
+
+ /* Add other things here for non-gcc platforms */
+#endif
+
+#endif /* __JackCompilerDeps_android__ */
diff --git a/android/JackControlAPIAndroid.cpp b/android/JackControlAPIAndroid.cpp
new file mode 100644
index 00000000..a915b4dd
--- /dev/null
+++ b/android/JackControlAPIAndroid.cpp
@@ -0,0 +1,89 @@
+// u/* -*- Mode: C++ ; c-basic-offset: 4 -*- */
+/*
+ JACK control API implementation
+
+ Copyright (C) 2008 Nedko Arnaudov
+ Copyright (C) 2008 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef WIN32
+#include <stdint.h>
+#include <dirent.h>
+#include <pthread.h>
+#endif
+
+#include "types.h"
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <assert.h>
+#include <signal.h>
+
+#include "JackControlAPIAndroid.h"
+#include "JackConstants.h"
+#include "JackServerGlobals.h"
+
+using namespace Jack;
+
+struct jackctl_sigmask
+{
+ sigset_t signals;
+};
+
+static jackctl_sigmask sigmask;
+
+SERVER_EXPORT int
+jackctl_wait_signals_and_return(jackctl_sigmask_t * sigmask)
+{
+ int sig;
+ bool waiting = true;
+
+ while (waiting) {
+ #if defined(sun) && !defined(__sun__) // SUN compiler only, to check
+ sigwait(&sigmask->signals);
+ #else
+ sigwait(&sigmask->signals, &sig);
+ #endif
+ fprintf(stderr, "Jack main caught signal %d\n", sig);
+
+ switch (sig) {
+ case SIGUSR1:
+ //jack_dump_configuration(engine, 1);
+ break;
+ case SIGUSR2:
+ // driver exit
+ waiting = false;
+ break;
+ case SIGTTOU:
+ break;
+ default:
+ waiting = false;
+ break;
+ }
+ }
+
+ if (sig != SIGSEGV) {
+ // unblock signals so we can see them during shutdown.
+ // this will help prod developers not to lose sight of
+ // bugs that cause segfaults etc. during shutdown.
+ sigprocmask(SIG_UNBLOCK, &sigmask->signals, 0);
+ }
+
+ return sig;
+}
+
diff --git a/android/JackControlAPIAndroid.h b/android/JackControlAPIAndroid.h
new file mode 100644
index 00000000..92694113
--- /dev/null
+++ b/android/JackControlAPIAndroid.h
@@ -0,0 +1,44 @@
+/*
+ JACK control API
+
+ Copyright (C) 2008 Nedko Arnaudov
+ Copyright (C) 2008 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __JackControlAPIAndroid__
+#define __JackControlAPIAndroid__
+
+#include "JackCompilerDeps.h"
+
+/** opaque type for sigmask object */
+typedef struct jackctl_sigmask jackctl_sigmask_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SERVER_EXPORT int
+jackctl_wait_signals_and_return(
+ jackctl_sigmask_t * signals);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
+
diff --git a/android/JackError.cpp b/android/JackError.cpp
new file mode 100644
index 00000000..af9b08b5
--- /dev/null
+++ b/android/JackError.cpp
@@ -0,0 +1,153 @@
+/*
+ Copyright (C) 2001 Paul Davis
+ Copyright (C) 2004-2008 Grame
+ Copyright (C) 2008 Nedko Arnaudov
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "JackError.h"
+#include "JackGlobals.h"
+#include "JackMessageBuffer.h"
+
+#define LOG_BUF_SIZE 1024
+#undef LOG_TAG
+#ifdef SERVER_SIDE
+#define LOG_TAG "JackAudioServer"
+#else
+#define LOG_TAG "JackAudioClient"
+#endif
+#include <utils/Log.h>
+
+using namespace Jack;
+
+static bool change_thread_log_function(jack_log_function_t log_function)
+{
+ return (jack_tls_get(JackGlobals::fKeyLogFunction) == NULL
+ && jack_tls_set(JackGlobals::fKeyLogFunction, (void*)log_function));
+}
+
+SERVER_EXPORT int set_threaded_log_function()
+{
+ return change_thread_log_function(JackMessageBufferAdd);
+}
+
+void jack_log_function(int level, const char *message)
+{
+ void (* log_callback)(const char *);
+
+ switch (level)
+ {
+ case LOG_LEVEL_INFO:
+ log_callback = jack_info_callback;
+ break;
+ case LOG_LEVEL_ERROR:
+ log_callback = jack_error_callback;
+ break;
+ default:
+ return;
+ }
+
+ log_callback(message);
+}
+
+static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap)
+{
+ char buffer[256];
+ size_t len;
+ jack_log_function_t log_function;
+
+ if (prefix != NULL) {
+ len = strlen(prefix);
+ assert(len < 256);
+ memcpy(buffer, prefix, len);
+ } else {
+ len = 0;
+ }
+
+ vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap);
+
+ log_function = (jack_log_function_t)jack_tls_get(JackGlobals::fKeyLogFunction);
+
+ /* if log function is not overriden for thread, use default one */
+ if (log_function == NULL)
+ {
+ log_function = jack_log_function;
+ //log_function(LOG_LEVEL_INFO, "------ Using default log function");
+ }
+ else
+ {
+ //log_function(LOG_LEVEL_INFO, "++++++ Using thread-specific log function");
+ }
+
+ log_function(level, buffer);
+}
+
+SERVER_EXPORT void jack_error(const char *fmt, ...)
+{
+ va_list ap;
+ char buf[LOG_BUF_SIZE];
+ va_start(ap, fmt);
+ vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
+ va_end(ap);
+ __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, buf);
+}
+
+SERVER_EXPORT void jack_info(const char *fmt, ...)
+{
+ va_list ap;
+ char buf[LOG_BUF_SIZE];
+ va_start(ap, fmt);
+ vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
+ va_end(ap);
+ __android_log_write(ANDROID_LOG_INFO, LOG_TAG, buf);
+}
+
+SERVER_EXPORT void jack_log(const char *fmt,...)
+{
+ va_list ap;
+ char buf[LOG_BUF_SIZE];
+ if (JackGlobals::fVerbose) {
+ va_start(ap, fmt);
+ vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
+ va_end(ap);
+ __android_log_write(ANDROID_LOG_VERBOSE, LOG_TAG, buf);
+ }
+}
+
+SERVER_EXPORT void default_jack_error_callback(const char *desc)
+{
+ fprintf(stderr, "%s\n", desc);
+ fflush(stderr);
+}
+
+SERVER_EXPORT void default_jack_info_callback(const char *desc)
+{
+ fprintf(stdout, "%s\n", desc);
+ fflush(stdout);
+}
+
+SERVER_EXPORT void silent_jack_error_callback(const char *desc)
+{}
+
+SERVER_EXPORT void silent_jack_info_callback(const char *desc)
+{}
+
+SERVER_EXPORT void (*jack_error_callback)(const char *desc) = &default_jack_error_callback;
+SERVER_EXPORT void (*jack_info_callback)(const char *desc) = &default_jack_info_callback;
diff --git a/android/JackGoldfishDriver.cpp b/android/JackGoldfishDriver.cpp
new file mode 100644
index 00000000..0765d8b3
--- /dev/null
+++ b/android/JackGoldfishDriver.cpp
@@ -0,0 +1,212 @@
+/*
+Copyright (C) 2001 Paul Davis
+Copyright (C) 2004-2008 Grame
+Copyright (C) 2013 Samsung Electronics
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "JackGoldfishDriver.h"
+#include "JackDriverLoader.h"
+#include "JackThreadedDriver.h"
+#include "JackEngineControl.h"
+#include "JackGraphManager.h"
+#include "JackCompilerDeps.h"
+#include <iostream>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+
+#define JACK_GOLDFISH_BUFFER_SIZE 4096
+
+namespace Jack
+{
+
+static char const * const kAudioDeviceName = "/dev/eac";
+
+int JackGoldfishDriver::Open(jack_nframes_t buffer_size,
+ jack_nframes_t samplerate,
+ bool capturing,
+ bool playing,
+ int inchannels,
+ int outchannels,
+ bool monitor,
+ const char* capture_driver_uid,
+ const char* playback_driver_uid,
+ jack_nframes_t capture_latency,
+ jack_nframes_t playback_latency) {
+ jack_log("JackGoldfishDriver::Open");
+
+ // Generic JackAudioDriver Open
+ if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor,
+ capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) {
+ return -1;
+ }
+
+ mFd = ::open(kAudioDeviceName, O_RDWR);
+ jack_log("JackGoldfishDriver::Open(mFd=%d)", mFd);
+
+ if (!mBuffer)
+ mBuffer = (short *) malloc(sizeof(short) * JACK_GOLDFISH_BUFFER_SIZE * 2);
+
+ //JackAudioDriver::SetBufferSize(buffer_size);
+ //JackAudioDriver::SetSampleRate(samplerate);
+
+ return 0;
+}
+
+int JackGoldfishDriver::Close() {
+ jack_log("JackGoldfishDriver::Close");
+
+ // Generic audio driver close
+ int res = JackAudioDriver::Close();
+
+ if (mFd >= 0) ::close(mFd);
+
+ if (mBuffer) {
+ free(mBuffer);
+ mBuffer = NULL;
+ }
+
+ return res;
+}
+
+int JackGoldfishDriver::Read() {
+ jack_log("JackGoldfishDriver::Read");
+ for (int i = 0; i < fCaptureChannels; i++) {
+ //silence
+ memset(GetInputBuffer(i), 0, sizeof(jack_default_audio_sample_t) * JACK_GOLDFISH_BUFFER_SIZE /* fEngineControl->fBufferSize */);
+ }
+ return 0;
+}
+
+int JackGoldfishDriver::Write() {
+ jack_log("JackGoldfishDriver::Write");
+ //write(mFd, GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize);
+
+ jack_default_audio_sample_t* outputBuffer_1 = GetOutputBuffer(0);
+ jack_default_audio_sample_t* outputBuffer_2 = GetOutputBuffer(1);
+
+ for(int i=0, j=0; i<JACK_GOLDFISH_BUFFER_SIZE /* fEngineControl->fBufferSize */; i++) {
+ //convert float to short
+ *(mBuffer + j) = (short) (*(outputBuffer_1 + i) * 32640); j++;
+ *(mBuffer + j) = (short) (*(outputBuffer_2 + i) * 32640); j++;
+ }
+ write(mFd, mBuffer, sizeof(short) * JACK_GOLDFISH_BUFFER_SIZE * 2);
+ return 0;
+}
+
+int JackGoldfishDriver::SetBufferSize(jack_nframes_t buffer_size) {
+ jack_log("JackGoldfishDriver::SetBufferSize");
+ JackAudioDriver::SetBufferSize(buffer_size);
+ return 0;
+}
+
+} // end of namespace
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor () {
+ jack_driver_desc_t * desc;
+ jack_driver_desc_filler_t filler;
+ jack_driver_param_value_t value;
+
+ desc = jack_driver_descriptor_construct("goldfish", JackDriverMaster, "Timer based backend", &filler);
+
+ value.ui = 2U;
+ jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamUInt, &value, NULL, "Number of capture ports", NULL);
+ jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamUInt, &value, NULL, "Number of playback ports", NULL);
+
+ value.ui = 44100U;
+ jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
+
+ value.i = 0;
+ jack_driver_descriptor_add_parameter(desc, &filler, "monitor", 'm', JackDriverParamBool, &value, NULL, "Provide monitor ports for the output", NULL);
+
+ value.ui = JACK_GOLDFISH_BUFFER_SIZE;
+ jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);
+
+ value.ui = 21333U;
+ jack_driver_descriptor_add_parameter(desc, &filler, "wait", 'w', JackDriverParamUInt, &value, NULL, "Number of usecs to wait between engine processes", NULL);
+
+ return desc;
+ }
+
+ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) {
+ jack_nframes_t sample_rate = 44100;
+ jack_nframes_t buffer_size = JACK_GOLDFISH_BUFFER_SIZE;
+ unsigned int capture_ports = 2;
+ unsigned int playback_ports = 2;
+ int wait_time = 0;
+ const JSList * node;
+ const jack_driver_param_t * param;
+ bool monitor = false;
+
+ for (node = params; node; node = jack_slist_next (node)) {
+ param = (const jack_driver_param_t *) node->data;
+
+ switch (param->character) {
+
+ case 'C':
+ capture_ports = param->value.ui;
+ break;
+
+ case 'P':
+ playback_ports = param->value.ui;
+ break;
+
+ case 'r':
+ sample_rate = param->value.ui;
+ break;
+
+ case 'p':
+ buffer_size = param->value.ui;
+ break;
+
+ case 'w':
+ wait_time = param->value.ui;
+ break;
+
+ case 'm':
+ monitor = param->value.i;
+ break;
+ }
+ }
+
+ if (wait_time > 0) {
+ buffer_size = lroundf((wait_time * sample_rate) / 1000000.0f);
+ if (buffer_size > BUFFER_SIZE_MAX) {
+ buffer_size = BUFFER_SIZE_MAX;
+ jack_error("Buffer size set to %d", BUFFER_SIZE_MAX);
+ }
+ }
+
+ Jack::JackDriverClientInterface* driver = new Jack::JackThreadedDriver(new Jack::JackGoldfishDriver("system", "goldfish_pcm", engine, table));
+ if (driver->Open(buffer_size, sample_rate, 1, 1, capture_ports, playback_ports, monitor, "goldfish", "goldfish", 0, 0) == 0) {
+ return driver;
+ } else {
+ delete driver;
+ return NULL;
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/android/JackGoldfishDriver.h b/android/JackGoldfishDriver.h
new file mode 100644
index 00000000..c30aec5c
--- /dev/null
+++ b/android/JackGoldfishDriver.h
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 2001 Paul Davis
+Copyright (C) 2004-2008 Grame
+Copyright (C) 2013 Samsung Electronics
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __JackGoldfishDriver__
+#define __JackGoldfishDriver__
+
+#include "JackAudioDriver.h"
+
+namespace Jack
+{
+
+/*!
+\brief The goldfish driver.
+*/
+
+class JackGoldfishDriver : public JackAudioDriver
+{
+
+ public:
+
+ JackGoldfishDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
+ : JackAudioDriver(name, alias, engine, table), mFd(-1), mBuffer(NULL)
+ {}
+ virtual ~JackGoldfishDriver()
+ {}
+
+ int Open(jack_nframes_t buffe_size,
+ jack_nframes_t samplerate,
+ bool capturing,
+ bool playing,
+ int chan_in,
+ int chan_out,
+ bool monitor,
+ const char* capture_driver_name,
+ const char* playback_driver_name,
+ jack_nframes_t capture_latency,
+ jack_nframes_t playback_latency);
+ int Close();
+ int Read();
+ int Write();
+ int SetBufferSize(jack_nframes_t buffer_size);
+
+private:
+
+ int mFd;
+ short *mBuffer;
+
+};
+
+} // end of namespace
+
+#endif
diff --git a/android/JackOpenSLESDriver.cpp b/android/JackOpenSLESDriver.cpp
new file mode 100644
index 00000000..61a07da1
--- /dev/null
+++ b/android/JackOpenSLESDriver.cpp
@@ -0,0 +1,236 @@
+/*
+Copyright (C) 2001 Paul Davis
+Copyright (C) 2004-2008 Grame
+Copyright (C) 2013 Samsung Electronics
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "JackOpenSLESDriver.h"
+#include "JackDriverLoader.h"
+#include "JackThreadedDriver.h"
+#include "JackEngineControl.h"
+#include "JackGraphManager.h"
+#include "JackCompilerDeps.h"
+#include <iostream>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+
+#include <android/log.h>
+#include "opensl_io.h"
+
+#define JACK_OPENSLES_DEFAULT_SAMPLERATE 48000
+#define JACK_OPENSLES_DEFAULT_BUFFER_SIZE 1024
+
+namespace Jack
+{
+
+static OPENSL_STREAM *pOpenSL_stream;
+
+int JackOpenSLESDriver::Open(jack_nframes_t buffer_size,
+ jack_nframes_t samplerate,
+ bool capturing,
+ bool playing,
+ int inchannels,
+ int outchannels,
+ bool monitor,
+ const char* capture_driver_uid,
+ const char* playback_driver_uid,
+ jack_nframes_t capture_latency,
+ jack_nframes_t playback_latency) {
+ jack_log("JackOpenSLESDriver::Open");
+
+ // Generic JackAudioDriver Open
+ if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor,
+ capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) {
+ return -1;
+ }
+ //JackAudioDriver::SetBufferSize(buffer_size);
+ //JackAudioDriver::SetSampleRate(samplerate);
+
+ if (capturing) {
+ inbuffer = (float *) malloc(sizeof(float) * buffer_size); //mono input
+ memset(inbuffer, 0, sizeof(float) * buffer_size);
+ }
+ if (playing) {
+ outbuffer = (float *) malloc(sizeof(float) * buffer_size * 2); //stereo output
+ memset(outbuffer, 0, sizeof(float) * buffer_size * 2);
+ }
+ pOpenSL_stream = android_OpenAudioDevice(samplerate, capturing ? 1 : 0, playing ? 2 : 0, buffer_size);
+ if (pOpenSL_stream == NULL) return -1;
+
+ return 0;
+}
+
+int JackOpenSLESDriver::Close() {
+ jack_log("JackOpenSLESDriver::Close");
+
+ // Generic audio driver close
+ int res = JackAudioDriver::Close();
+
+ android_CloseAudioDevice(pOpenSL_stream);
+
+ if (inbuffer) {
+ free(inbuffer);
+ inbuffer = NULL;
+ }
+ if (outbuffer) {
+ free(outbuffer);
+ outbuffer = NULL;
+ }
+ return res;
+}
+
+int JackOpenSLESDriver::Read() {
+ //jack_log("JackOpenSLESDriver::Read");
+ jack_default_audio_sample_t* inputBuffer_1 = GetInputBuffer(0);
+ jack_default_audio_sample_t* inputBuffer_2 = GetInputBuffer(1);
+
+ if (inbuffer) {
+ int samps = android_AudioIn(pOpenSL_stream,inbuffer,fEngineControl->fBufferSize);
+ //jack_log("JackOpenSLESDriver::Read(%d)", samps); //for debug
+ for (int i = 0; i < samps; i++) {
+ *(inputBuffer_1 + i) = *(inbuffer + i);
+ *(inputBuffer_2 + i) = *(inbuffer + i);
+ }
+ } else {
+ for (int i = 0; i < fCaptureChannels; i++) {
+ memset(GetInputBuffer(i), 0, sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); //silence
+ }
+ }
+
+ return 0;
+}
+
+int JackOpenSLESDriver::Write() {
+ //jack_log("JackOpenSLESDriver::Write");
+ jack_default_audio_sample_t* outputBuffer_1 = GetOutputBuffer(0);
+ jack_default_audio_sample_t* outputBuffer_2 = GetOutputBuffer(1);
+
+ if (outbuffer) {
+ android_AudioOut(pOpenSL_stream, outbuffer, fEngineControl->fBufferSize * 2); //stereo output
+ for (unsigned int i = 0, j = 0; i < fEngineControl->fBufferSize; i++) {
+ *(outbuffer + j) = *(outputBuffer_1 + i); j++;
+ *(outbuffer + j) = *(outputBuffer_2 + i); j++;
+ }
+ }
+
+ return 0;
+}
+
+int JackOpenSLESDriver::SetBufferSize(jack_nframes_t buffer_size) {
+ jack_log("JackOpenSLESDriver::SetBufferSize");
+ JackAudioDriver::SetBufferSize(buffer_size);
+ return 0;
+}
+
+} // end of namespace
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor () {
+ jack_driver_desc_t * desc;
+ jack_driver_desc_filler_t filler;
+ jack_driver_param_value_t value;
+
+ desc = jack_driver_descriptor_construct("opensles", JackDriverMaster, "Timer based backend", &filler);
+
+ value.ui = 2U;
+ jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamUInt, &value, NULL, "Number of capture ports", NULL);
+ jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamUInt, &value, NULL, "Number of playback ports", NULL);
+
+ value.ui = 48000U;
+ jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
+
+ value.i = 0;
+ jack_driver_descriptor_add_parameter(desc, &filler, "monitor", 'm', JackDriverParamBool, &value, NULL, "Provide monitor ports for the output", NULL);
+
+ value.ui = JACK_OPENSLES_DEFAULT_BUFFER_SIZE;
+ jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);
+
+ value.ui = 21333U;
+ jack_driver_descriptor_add_parameter(desc, &filler, "wait", 'w', JackDriverParamUInt, &value, NULL, "Number of usecs to wait between engine processes", NULL);
+
+ return desc;
+ }
+
+ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) {
+ jack_nframes_t sample_rate = JACK_OPENSLES_DEFAULT_SAMPLERATE;
+ jack_nframes_t buffer_size = JACK_OPENSLES_DEFAULT_BUFFER_SIZE;
+ unsigned int capture_ports = 2;
+ unsigned int playback_ports = 2;
+ int wait_time = 0;
+ const JSList * node;
+ const jack_driver_param_t * param;
+ bool monitor = false;
+
+ for (node = params; node; node = jack_slist_next (node)) {
+ param = (const jack_driver_param_t *) node->data;
+
+ switch (param->character) {
+
+ case 'C':
+ capture_ports = param->value.ui;
+ break;
+
+ case 'P':
+ playback_ports = param->value.ui;
+ break;
+
+ case 'r':
+ sample_rate = param->value.ui;
+ break;
+
+ case 'p':
+ buffer_size = param->value.ui;
+ break;
+
+ case 'w':
+ wait_time = param->value.ui;
+ break;
+
+ case 'm':
+ monitor = param->value.i;
+ break;
+ }
+ }
+
+ if (wait_time > 0) {
+ buffer_size = lroundf((wait_time * sample_rate) / 1000000.0f);
+ if (buffer_size > BUFFER_SIZE_MAX) {
+ buffer_size = BUFFER_SIZE_MAX;
+ jack_error("Buffer size set to %d", BUFFER_SIZE_MAX);
+ }
+ }
+
+ Jack::JackDriverClientInterface* driver = new Jack::JackThreadedDriver(new Jack::JackOpenSLESDriver("system", "opensles_pcm", engine, table));
+ if (driver->Open(buffer_size, sample_rate, capture_ports? 1 : 0, playback_ports? 1 : 0, capture_ports, playback_ports, monitor, "opensles", "opensles", 0, 0) == 0) {
+ return driver;
+ } else {
+ delete driver;
+ return NULL;
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/android/JackOpenSLESDriver.h b/android/JackOpenSLESDriver.h
new file mode 100644
index 00000000..04ddf6a1
--- /dev/null
+++ b/android/JackOpenSLESDriver.h
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 2001 Paul Davis
+Copyright (C) 2004-2008 Grame
+Copyright (C) 2013 Samsung Electronics
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __JackOpenSLESDriver__
+#define __JackOpenSLESDriver__
+
+#include "JackAudioDriver.h"
+
+namespace Jack
+{
+
+/*!
+\brief The OpenSLES driver.
+*/
+
+class JackOpenSLESDriver : public JackAudioDriver
+{
+
+ public:
+
+ JackOpenSLESDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
+ : JackAudioDriver(name, alias, engine, table), inbuffer(NULL), outbuffer(NULL)
+ {}
+ virtual ~JackOpenSLESDriver()
+ {}
+
+ int Open(jack_nframes_t buffe_size,
+ jack_nframes_t samplerate,
+ bool capturing,
+ bool playing,
+ int chan_in,
+ int chan_out,
+ bool monitor,
+ const char* capture_driver_name,
+ const char* playback_driver_name,
+ jack_nframes_t capture_latency,
+ jack_nframes_t playback_latency);
+ int Close();
+ int Read();
+ int Write();
+ int SetBufferSize(jack_nframes_t buffer_size);
+
+ private:
+
+ float *inbuffer;
+ float *outbuffer;
+
+};
+
+} // end of namespace
+
+#endif
diff --git a/android/JackPlatformPlug_os.h b/android/JackPlatformPlug_os.h
new file mode 100644
index 00000000..cc35d478
--- /dev/null
+++ b/android/JackPlatformPlug_os.h
@@ -0,0 +1,91 @@
+/*
+ Copyright (C) 2004-2008 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __JackPlatformPlug_android__
+#define __JackPlatformPlug_android__
+
+#define jack_server_dir "/data/misc/jack"
+#define jack_client_dir "/data/misc/jack"
+#define JACK_DEFAULT_DRIVER "alsa"
+
+namespace Jack
+{
+ struct JackRequest;
+ struct JackResult;
+
+ class JackPosixMutex;
+ class JackAndroidThread;
+ class JackFifo;
+ class JackSocketServerChannel;
+ class JackSocketClientChannel;
+ class JackSocketServerNotifyChannel;
+ class JackSocketNotifyChannel;
+ class JackClientSocket;
+ class JackNetUnixSocket;
+}
+
+/* __JackPlatformMutex__ */
+#include "JackPosixMutex.h"
+namespace Jack {typedef JackPosixMutex JackMutex; }
+
+/* __JackPlatformThread__ */
+#include "JackAndroidThread.h"
+namespace Jack { typedef JackAndroidThread JackThread; }
+
+/* __JackPlatformSynchro__ client activation */
+/*
+#include "JackFifo.h"
+namespace Jack { typedef JackFifo JackSynchro; }
+*/
+
+#include "JackAndroidSemaphore.h"
+namespace Jack { typedef JackAndroidSemaphore JackSynchro; }
+
+/* __JackPlatformChannelTransaction__ */
+/*
+#include "JackSocket.h"
+namespace Jack { typedef JackClientSocket JackChannelTransaction; }
+*/
+
+/* __JackPlatformProcessSync__ */
+#include "JackPosixProcessSync.h"
+namespace Jack { typedef JackPosixProcessSync JackProcessSync; }
+
+/* __JackPlatformServerChannel__ */
+#include "JackSocketServerChannel.h"
+namespace Jack { typedef JackSocketServerChannel JackServerChannel; }
+
+/* __JackPlatformClientChannel__ */
+#include "JackSocketClientChannel.h"
+namespace Jack { typedef JackSocketClientChannel JackClientChannel; }
+
+/* __JackPlatformServerNotifyChannel__ */
+#include "JackSocketServerNotifyChannel.h"
+namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; }
+
+/* __JackPlatformNotifyChannel__ */
+#include "JackSocketNotifyChannel.h"
+namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; }
+
+/* __JackPlatformNetSocket__ */
+#include "JackNetUnixSocket.h"
+namespace Jack { typedef JackNetUnixSocket JackNetSocket; }
+
+#endif
diff --git a/android/JackShmMem_os.h b/android/JackShmMem_os.h
new file mode 100644
index 00000000..3f9027a5
--- /dev/null
+++ b/android/JackShmMem_os.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2004-2008 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __JackShmMem__android__
+#define __JackShmMem__android__
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#define CHECK_MLOCK(ptr, size) (mlock((ptr), (size)) == 0)
+#define CHECK_MUNLOCK(ptr, size) (munlock((ptr), (size)) == 0)
+#define CHECK_MLOCKALL() (false)
+#define CHECK_MUNLOCKALL() (false)
+
+/* fix for crash jack server issue:
+ * case 1) jack_destroy_shm() in JackShmReadWritePtr1::Init() causes crash
+ * because server lost shared memory by destroying client side ahead.
+ */
+#ifndef SERVER_SIDE
+#define jack_destroy_shm(x) (0)
+#endif
+
+#endif /* __JackShmMem__android__ */
diff --git a/android/JackSystemDeps_os.h b/android/JackSystemDeps_os.h
new file mode 100644
index 00000000..48406f33
--- /dev/null
+++ b/android/JackSystemDeps_os.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2004-2008 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __JackSystemDeps_android__
+#define __JackSystemDeps_android__
+
+
+#include "../posix/JackSystemDeps_os.h"
+
+/**
+ * bionic c dependant functions
+ */
+#define pthread_setcanceltype(x,y) (0)
+
+#endif /* __JackSystemDeps_android__ */
diff --git a/android/NOTICE b/android/NOTICE
new file mode 100644
index 00000000..b56eebe8
--- /dev/null
+++ b/android/NOTICE
@@ -0,0 +1,869 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+-------------------------------------------------------------------------------
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+-------------------------------------------------------------------------------
+opensl_io.c:
+Android OpenSL input/output module (header)
+Copyright (c) 2012, Victor Lazzarini
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/android/Shm.cpp b/android/Shm.cpp
new file mode 100644
index 00000000..1149616f
--- /dev/null
+++ b/android/Shm.cpp
@@ -0,0 +1,886 @@
+/*
+ Copyright (C) 2001-2003 Paul Davis
+ Copyright (C) 2005-2012 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#define LOG_TAG "JAMSHMSERVICE"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <binder/MemoryHeapBase.h>
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <utils/Log.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include "BnAndroidShm.h"
+#include "AndroidShm.h"
+
+#include "JackConstants.h"
+
+#include <fcntl.h>
+#include <signal.h>
+#include <limits.h>
+#include <errno.h>
+#include <dirent.h>
+#include <sys/mman.h>
+#include <linux/ashmem.h>
+#include <cutils/ashmem.h>
+
+#include "JackError.h"
+
+// remove ALOGI log
+#define jack_d
+//#define jack_d ALOGI
+#define jack_error ALOGE
+#define MEMORY_SIZE 10*1024
+
+
+namespace android {
+
+ jack_shmtype_t Shm::jack_shmtype = shm_ANDROID;
+
+ /* The JACK SHM registry is a chunk of memory for keeping track of the
+ * shared memory used by each active JACK server. This allows the
+ * server to clean up shared memory when it exits. To avoid memory
+ * leakage due to kill -9, crashes or debugger-driven exits, this
+ * cleanup is also done when a new instance of that server starts.
+ */
+
+ /* per-process global data for the SHM interfaces */
+ jack_shm_id_t Shm::registry_id; /* SHM id for the registry */
+ jack_shm_fd_t Shm::registry_fd = JACK_SHM_REGISTRY_FD;
+
+ jack_shm_info_t Shm::registry_info = {
+ JACK_SHM_NULL_INDEX, 0, 0, { MAP_FAILED }
+ };
+
+ /* pointers to registry header and array */
+ jack_shm_header_t *Shm::jack_shm_header = NULL;
+ jack_shm_registry_t *Shm::jack_shm_registry = NULL;
+ char Shm::jack_shm_server_prefix[JACK_SERVER_NAME_SIZE] = "";
+
+ /* jack_shm_lock_registry() serializes updates to the shared memory
+ * segment JACK uses to keep track of the SHM segments allocated to
+ * all its processes, including multiple servers.
+ *
+ * This is not a high-contention lock, but it does need to work across
+ * multiple processes. High transaction rates and realtime safety are
+ * not required. Any solution needs to at least be portable to POSIX
+ * and POSIX-like systems.
+ *
+ * We must be particularly careful to ensure that the lock be released
+ * if the owning process terminates abnormally. Otherwise, a segfault
+ * or kill -9 at the wrong moment could prevent JACK from ever running
+ * again on that machine until after a reboot.
+ */
+
+ #define JACK_SEMAPHORE_KEY 0x282929
+ #define JACK_SHM_REGISTRY_KEY JACK_SEMAPHORE_KEY
+ #define JACK_REGISTRY_NAME "/jack-shm-registry"
+
+ int Shm::semid = -1;
+ pthread_mutex_t Shm::mutex = PTHREAD_MUTEX_INITIALIZER;
+
+ //sp<IAndroidShm> Shm::mShmService;
+ sp<IMemoryHeap> Shm::mShmMemBase[JACK_SHM_HEAP_ENOUGH_COUNT] = {0,};
+
+ Shm* Shm::ref = NULL;
+
+ Shm* Shm::Instantiate() {
+ if(Shm::ref == NULL) {
+ jack_d("shm::Instantiate is called");
+ Shm::ref = new Shm;
+ //AndroidShm::instantiate();
+ }
+ return ref;
+ }
+
+ Shm::Shm() { }
+
+ Shm::~Shm() { }
+
+ sp<IAndroidShm> Shm::getShmService(){
+ return interface_cast<IAndroidShm>(defaultServiceManager()->getService(String16("com.samsung.android.jam.IAndroidShm")));
+ }
+
+ //sp<IAndroidShm>& Shm::getShmService() {
+ // if (mShmService.get() == 0) {
+ // sp<IServiceManager> sm = defaultServiceManager();
+ // sp<IBinder> binder;
+ // do {
+ // binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm"));
+ // if (binder != 0)
+ // break;
+ // ALOGW("CameraService not published, waiting...");
+ // usleep(500000); // 0.5 s
+ // } while(true);
+ // mShmService = interface_cast<IAndroidShm>(binder);
+ // }
+ // ALOGE_IF(mShmService==0, "no CameraService!?");
+ // return mShmService;
+ //}
+
+ void Shm::shm_copy_from_registry (jack_shm_info_t* /*si*/, jack_shm_registry_index_t ) {
+ // not used
+ }
+ void Shm::shm_copy_to_registry (jack_shm_info_t* /*si*/, jack_shm_registry_index_t*) {
+ // not used
+ }
+
+ void Shm::jack_release_shm_entry (jack_shm_registry_index_t index) {
+ /* the registry must be locked */
+ jack_shm_registry[index].size = 0;
+ jack_shm_registry[index].allocator = 0;
+ memset (&jack_shm_registry[index].id, 0,
+ sizeof (jack_shm_registry[index].id));
+ jack_shm_registry[index].fd = 0;
+ }
+
+ int Shm::release_shm_info (jack_shm_registry_index_t index) {
+ /* must NOT have the registry locked */
+ if (jack_shm_registry[index].allocator == GetPID()) {
+ if (jack_shm_lock_registry () < 0) {
+ jack_error ("jack_shm_lock_registry fails...");
+ return -1;
+ }
+ jack_release_shm_entry (index);
+ jack_shm_unlock_registry ();
+ jack_d ("release_shm_info: success!");
+ }
+ else
+ jack_error ("release_shm_info: error!");
+
+ return 0;
+ }
+ char* Shm::shm_addr (unsigned int fd) {
+ if(fd >= JACK_SHM_HEAP_ENOUGH_COUNT) {
+ jack_error("ignore to get memory buffer : index[%d] is too big", fd);
+ return NULL;
+ }
+
+ sp<IAndroidShm> service = Shm::getShmService();
+ if(service == NULL){
+ jack_error("shm service is null");
+ return NULL;
+ }
+ mShmMemBase[fd] = service->getBuffer(fd);
+ if(mShmMemBase[fd] == NULL) {
+ jack_error("fail to get memory buffer");
+ return NULL;
+ }
+
+ return ((char *) mShmMemBase[fd]->getBase());
+ }
+
+ int Shm::shm_lock_registry (void) {
+ pthread_mutex_lock (&mutex);
+ return 0;
+ }
+
+ void Shm::shm_unlock_registry (void) {
+ pthread_mutex_unlock (&mutex);
+ }
+
+ void Shm::release_shm_entry (jack_shm_registry_index_t index) {
+ /* the registry must be locked */
+ jack_shm_registry[index].size = 0;
+ jack_shm_registry[index].allocator = 0;
+ memset (&jack_shm_registry[index].id, 0,
+ sizeof (jack_shm_registry[index].id));
+ }
+
+ void Shm::remove_shm (jack_shm_id_t *id) {
+ int shm_fd = -1;
+ jack_d("remove_id [%s]",(char*)id);
+ if(!strcmp((const char*)id, JACK_REGISTRY_NAME)) {
+ shm_fd = registry_fd;
+ } else {
+ for (int i = 0; i < MAX_SHM_ID; i++) {
+ if(!strcmp((const char*)id, jack_shm_registry[i].id)) {
+ shm_fd = jack_shm_registry[i].fd;
+ break;
+ }
+ }
+ }
+
+ if (shm_fd >= 0) {
+ sp<IAndroidShm> service = getShmService();
+ if(service != NULL) {
+ service->removeShm(shm_fd);
+ } else {
+ jack_error("shm service is null");
+ }
+ }
+ jack_d ("[APA] jack_remove_shm : ok ");
+ }
+
+ int Shm::access_registry (jack_shm_info_t * ri) {
+ jack_d("access_registry\n");
+ /* registry must be locked */
+ sp<IAndroidShm> service = getShmService();
+ if(service == NULL){
+ jack_error("shm service is null");
+ return EINVAL;
+ }
+ int shm_fd = service->getRegistryIndex();
+
+ strncpy (registry_id, JACK_REGISTRY_NAME, sizeof (registry_id) - 1);
+ registry_id[sizeof (registry_id) - 1] = '\0';
+
+ if(service->isAllocated(shm_fd) == FALSE) {
+ //jack_error ("Cannot mmap shm registry segment (%s)",
+ // strerror (errno));
+ jack_error ("Cannot mmap shm registry segment");
+ //close (shm_fd);
+ ri->ptr.attached_at = NULL;
+ registry_fd = JACK_SHM_REGISTRY_FD;
+ return EINVAL;
+ }
+
+ ri->fd = shm_fd;
+ registry_fd = shm_fd;
+ ri->ptr.attached_at = shm_addr(shm_fd);
+
+ if(ri->ptr.attached_at == NULL) {
+ ALOGE("attached pointer is null !");
+ jack_shm_header = NULL;
+ jack_shm_registry = NULL;
+ return 0;
+ }
+
+ /* set up global pointers */
+ ri->index = JACK_SHM_REGISTRY_INDEX;
+ jack_shm_header = (jack_shm_header_t*)(ri->ptr.attached_at);
+ jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1);
+
+ jack_d("jack_shm_header[%p],jack_shm_registry[%p]", jack_shm_header, jack_shm_registry);
+ //close (shm_fd); // steph
+ return 0;
+ }
+
+ int Shm::GetUID() {
+ return getuid();
+ }
+
+ int Shm::GetPID() {
+ return getpid();
+ }
+
+ int Shm::jack_shm_lock_registry (void) {
+ // TODO: replace semaphore to mutex
+ pthread_mutex_lock (&mutex);
+ return 0;
+ }
+
+ void Shm::jack_shm_unlock_registry (void) {
+ // TODO: replace semaphore to mutex
+ pthread_mutex_unlock (&mutex);
+ return;
+ }
+
+ void Shm::shm_init_registry () {
+ if(jack_shm_header == NULL)
+ return;
+
+ /* registry must be locked */
+
+ memset (jack_shm_header, 0, JACK_SHM_REGISTRY_SIZE);
+
+ jack_shm_header->magic = JACK_SHM_MAGIC;
+ //jack_shm_header->protocol = JACK_PROTOCOL_VERSION;
+ jack_shm_header->type = jack_shmtype;
+ jack_shm_header->size = JACK_SHM_REGISTRY_SIZE;
+ jack_shm_header->hdr_len = sizeof (jack_shm_header_t);
+ jack_shm_header->entry_len = sizeof (jack_shm_registry_t);
+
+ for (int i = 0; i < MAX_SHM_ID; ++i) {
+ jack_shm_registry[i].index = i;
+ }
+ }
+
+ void Shm::set_server_prefix (const char *server_name) {
+ snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix),
+ "jack-%d:%s:", GetUID(), server_name);
+ }
+
+ /* create a new SHM registry segment
+ *
+ * sets up global registry pointers, if successful
+ *
+ * returns: 0 if registry created successfully
+ * nonzero error code if unable to allocate a new registry
+ */
+ int Shm::create_registry (jack_shm_info_t * ri) {
+ jack_d("create_registry\n");
+ /* registry must be locked */
+ int shm_fd = 0;
+
+ strncpy (registry_id, JACK_REGISTRY_NAME, sizeof (registry_id) - 1);
+ registry_id[sizeof (registry_id) - 1] = '\0';
+
+ sp<IAndroidShm> service = getShmService();
+ if(service == NULL){
+ jack_error("shm service is null");
+ return EINVAL;
+ }
+
+ if((shm_fd = service->allocShm(JACK_SHM_REGISTRY_SIZE)) < 0) {
+ jack_error("Cannot create shm registry segment");
+ registry_fd = JACK_SHM_REGISTRY_FD;
+ return EINVAL;
+ }
+
+ service->setRegistryIndex(shm_fd);
+
+ /* set up global pointers */
+ ri->fd = shm_fd;
+ ri->index = JACK_SHM_REGISTRY_INDEX;
+ registry_fd = shm_fd;
+ ri->ptr.attached_at = shm_addr(shm_fd);
+ ri->size = JACK_SHM_REGISTRY_SIZE;
+
+ jack_shm_header = (jack_shm_header_t*)(ri->ptr.attached_at);
+ jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1);
+
+ jack_d("create_registry jack_shm_header[%p], jack_shm_registry[%p]", jack_shm_header, jack_shm_registry);
+
+ /* initialize registry contents */
+ shm_init_registry ();
+ //close (shm_fd); // steph
+
+ return 0;
+ }
+
+ int Shm::shm_validate_registry () {
+ /* registry must be locked */
+ if(jack_shm_header == NULL) {
+ return -1;
+ }
+
+ if ((jack_shm_header->magic == JACK_SHM_MAGIC)
+ //&& (jack_shm_header->protocol == JACK_PROTOCOL_VERSION)
+ && (jack_shm_header->type == jack_shmtype)
+ && (jack_shm_header->size == JACK_SHM_REGISTRY_SIZE)
+ && (jack_shm_header->hdr_len == sizeof (jack_shm_header_t))
+ && (jack_shm_header->entry_len == sizeof (jack_shm_registry_t))) {
+
+ return 0; /* registry OK */
+ }
+
+ return -1;
+ }
+
+ int Shm::server_initialize_shm (int new_registry) {
+ int rc;
+
+ jack_d("server_initialize_shm\n");
+
+ if (jack_shm_header)
+ return 0; /* already initialized */
+
+ if (shm_lock_registry () < 0) {
+ jack_error ("jack_shm_lock_registry fails...");
+ return -1;
+ }
+
+ rc = access_registry (&registry_info);
+
+ if (new_registry) {
+ remove_shm (&registry_id);
+ rc = ENOENT;
+ }
+
+ switch (rc) {
+ case ENOENT: /* registry does not exist */
+ rc = create_registry (&registry_info);
+ break;
+ case 0: /* existing registry */
+ if (shm_validate_registry () == 0)
+ break;
+ /* else it was invalid, so fall through */
+ case EINVAL: /* bad registry */
+ /* Apparently, this registry was created by an older
+ * JACK version. Delete it so we can try again. */
+ release_shm (&registry_info);
+ remove_shm (&registry_id);
+ if ((rc = create_registry (&registry_info)) != 0) {
+ //jack_error ("incompatible shm registry (%s)",
+ // strerror (errno));
+ jack_error ("incompatible shm registry");
+//#ifndef USE_POSIX_SHM
+// jack_error ("to delete, use `ipcrm -M 0x%0.8x'", JACK_SHM_REGISTRY_KEY);
+//#endif
+ }
+ break;
+ default: /* failure return code */
+ break;
+ }
+
+ shm_unlock_registry ();
+ return rc;
+ }
+
+ // here begin the API
+ int Shm::register_server (const char *server_name, int new_registry) {
+ int i, res = 0;
+
+ jack_d("register_server new_registry[%d]\n", new_registry);
+
+ set_server_prefix (server_name);
+
+ if (server_initialize_shm (new_registry))
+ return ENOMEM;
+
+ if (shm_lock_registry () < 0) {
+ jack_error ("jack_shm_lock_registry fails...");
+ return -1;
+ }
+
+ /* See if server_name already registered. Since server names
+ * are per-user, we register the unique server prefix string.
+ */
+ for (i = 0; i < MAX_SERVERS; i++) {
+
+ if (strncmp (jack_shm_header->server[i].name,
+ jack_shm_server_prefix,
+ JACK_SERVER_NAME_SIZE) != 0)
+ continue; /* no match */
+
+ if (jack_shm_header->server[i].pid == GetPID()) {
+ res = 0; /* it's me */
+ goto unlock;
+ }
+
+ /* see if server still exists */
+ if (kill (jack_shm_header->server[i].pid, 0) == 0) {
+ res = EEXIST; /* other server running */
+ goto unlock;
+ }
+
+ /* it's gone, reclaim this entry */
+ memset (&jack_shm_header->server[i], 0,
+ sizeof (jack_shm_server_t));
+ }
+
+ /* find a free entry */
+ for (i = 0; i < MAX_SERVERS; i++) {
+ if (jack_shm_header->server[i].pid == 0)
+ break;
+ }
+
+ if (i >= MAX_SERVERS) {
+ res = ENOSPC; /* out of space */
+ goto unlock;
+ }
+
+ /* claim it */
+ jack_shm_header->server[i].pid = GetPID();
+ strncpy (jack_shm_header->server[i].name,
+ jack_shm_server_prefix,
+ JACK_SERVER_NAME_SIZE - 1);
+ jack_shm_header->server[i].name[JACK_SERVER_NAME_SIZE - 1] = '\0';
+
+ unlock:
+ shm_unlock_registry ();
+ return res;
+ }
+
+ int Shm::unregister_server (const char * /* server_name */) {
+ int i;
+ if (shm_lock_registry () < 0) {
+ jack_error ("jack_shm_lock_registry fails...");
+ return -1;
+ }
+
+ for (i = 0; i < MAX_SERVERS; i++) {
+ if (jack_shm_header->server[i].pid == GetPID()) {
+ memset (&jack_shm_header->server[i], 0,
+ sizeof (jack_shm_server_t));
+ }
+ }
+
+ shm_unlock_registry ();
+ return 0;
+ }
+
+ int Shm::initialize_shm (const char *server_name) {
+ int rc;
+
+ if (jack_shm_header)
+ return 0; /* already initialized */
+
+ set_server_prefix (server_name);
+
+ if (shm_lock_registry () < 0) {
+ jack_error ("jack_shm_lock_registry fails...");
+ return -1;
+ }
+
+ if ((rc = access_registry (&registry_info)) == 0) {
+ if ((rc = shm_validate_registry ()) != 0) {
+ jack_error ("Incompatible shm registry, "
+ "are jackd and libjack in sync?");
+ }
+ }
+ shm_unlock_registry ();
+
+ return rc;
+ }
+
+ int Shm::initialize_shm_server (void) {
+ // not used
+ return 0;
+ }
+
+ int Shm::initialize_shm_client (void) {
+ // not used
+ return 0;
+ }
+
+ int Shm::cleanup_shm (void) {
+ int i;
+ int destroy;
+ jack_shm_info_t copy;
+
+ if (shm_lock_registry () < 0) {
+ jack_error ("jack_shm_lock_registry fails...");
+ return -1;
+ }
+
+ for (i = 0; i < MAX_SHM_ID; i++) {
+ jack_shm_registry_t* r;
+
+ r = &jack_shm_registry[i];
+ memcpy (&copy, r, sizeof (jack_shm_info_t));
+ destroy = FALSE;
+
+ /* ignore unused entries */
+ if (r->allocator == 0)
+ continue;
+
+ /* is this my shm segment? */
+ if (r->allocator == GetPID()) {
+
+ /* allocated by this process, so unattach
+ and destroy. */
+ release_shm (&copy);
+ destroy = TRUE;
+
+ } else {
+
+ /* see if allocator still exists */
+ if (kill (r->allocator, 0)) {
+ if (errno == ESRCH) {
+ /* allocator no longer exists,
+ * so destroy */
+ destroy = TRUE;
+ }
+ }
+ }
+
+ if (destroy) {
+
+ int index = copy.index;
+
+ if ((index >= 0) && (index < MAX_SHM_ID)) {
+ remove_shm (&jack_shm_registry[index].id);
+ release_shm_entry (index);
+ }
+ r->size = 0;
+ r->allocator = 0;
+ }
+ }
+
+ shm_unlock_registry ();
+ return TRUE;
+
+ }
+
+ jack_shm_registry_t * Shm::get_free_shm_info () {
+ /* registry must be locked */
+ jack_shm_registry_t* si = NULL;
+ int i;
+
+ for (i = 0; i < MAX_SHM_ID; ++i) {
+ if (jack_shm_registry[i].size == 0) {
+ break;
+ }
+ }
+
+ if (i < MAX_SHM_ID) {
+ si = &jack_shm_registry[i];
+ }
+
+ return si;
+ }
+
+ int Shm::shmalloc (const char * /*shm_name*/, jack_shmsize_t size, jack_shm_info_t* si) {
+ jack_shm_registry_t* registry;
+ int shm_fd;
+ int rc = -1;
+ char name[SHM_NAME_MAX+1];
+
+ if (shm_lock_registry () < 0) {
+ jack_error ("jack_shm_lock_registry fails...");
+ return -1;
+ }
+
+ sp<IAndroidShm> service = getShmService();
+ if(service == NULL){
+ rc = errno;
+ jack_error("shm service is null");
+ goto unlock;
+ }
+
+ if ((registry = get_free_shm_info ()) == NULL) {
+ jack_error ("shm registry full");
+ goto unlock;
+ }
+
+ snprintf (name, sizeof (name), "/jack-%d-%d", GetUID(), registry->index);
+ if (strlen (name) >= sizeof (registry->id)) {
+ jack_error ("shm segment name too long %s", name);
+ goto unlock;
+ }
+
+ if((shm_fd = service->allocShm(size)) < 0) {
+ rc = errno;
+ jack_error ("Cannot create shm segment %s", name);
+ goto unlock;
+ }
+
+ //close (shm_fd);
+ registry->size = size;
+ strncpy (registry->id, name, sizeof (registry->id) - 1);
+ registry->id[sizeof (registry->id) - 1] = '\0';
+ registry->allocator = GetPID();
+ registry->fd = shm_fd;
+ si->fd = shm_fd;
+ si->index = registry->index;
+ si->ptr.attached_at = MAP_FAILED; /* not attached */
+ rc = 0; /* success */
+
+ jack_d ("[APA] jack_shmalloc : ok ");
+
+unlock:
+ shm_unlock_registry ();
+ return rc;
+ }
+
+ void Shm::release_shm (jack_shm_info_t* /*si*/) {
+ // do nothing
+ }
+
+ void Shm::release_lib_shm (jack_shm_info_t* /*si*/) {
+ // do nothing
+ }
+
+ void Shm::destroy_shm (jack_shm_info_t* si) {
+ /* must NOT have the registry locked */
+ if (si->index == JACK_SHM_NULL_INDEX)
+ return; /* segment not allocated */
+
+ remove_shm (&jack_shm_registry[si->index].id);
+ release_shm_info (si->index);
+ }
+
+ int Shm::attach_shm (jack_shm_info_t* si) {
+ jack_shm_registry_t *registry = &jack_shm_registry[si->index];
+
+ if((si->ptr.attached_at = shm_addr(registry->fd)) == NULL) {
+ jack_error ("Cannot mmap shm segment %s", registry->id);
+ close (si->fd);
+ return -1;
+ }
+ return 0;
+ }
+
+ int Shm::attach_lib_shm (jack_shm_info_t* si) {
+ int res = attach_shm(si);
+ if (res == 0)
+ si->size = jack_shm_registry[si->index].size; // Keep size in si struct
+ return res;
+ }
+
+ int Shm::attach_shm_read (jack_shm_info_t* si) {
+ jack_shm_registry_t *registry = &jack_shm_registry[si->index];
+
+ if((si->ptr.attached_at = shm_addr(registry->fd)) == NULL) {
+ jack_error ("Cannot mmap shm segment %s", registry->id);
+ close (si->fd);
+ return -1;
+ }
+ return 0;
+ }
+
+ int Shm::attach_lib_shm_read (jack_shm_info_t* si) {
+ int res = attach_shm_read(si);
+ if (res == 0)
+ si->size = jack_shm_registry[si->index].size; // Keep size in si struct
+ return res;
+ }
+
+ int Shm::resize_shm (jack_shm_info_t* si, jack_shmsize_t size) {
+ jack_shm_id_t id;
+
+ /* The underlying type of `id' differs for SYSV and POSIX */
+ memcpy (&id, &jack_shm_registry[si->index].id, sizeof (id));
+
+ release_shm (si);
+ destroy_shm (si);
+
+ if (shmalloc ((char *) id, size, si)) {
+ return -1;
+ }
+ return attach_shm (si);
+ }
+
+ void Shm::jack_shm_copy_from_registry (jack_shm_info_t* si, jack_shm_registry_index_t t) {
+ Shm::Instantiate()->shm_copy_from_registry(si,t);
+ }
+ void Shm::jack_shm_copy_to_registry (jack_shm_info_t* si, jack_shm_registry_index_t* t) {
+ Shm::Instantiate()->shm_copy_to_registry(si,t);
+ }
+ int Shm::jack_release_shm_info (jack_shm_registry_index_t t) {
+ return Shm::Instantiate()->release_shm_info(t);
+ }
+ char* Shm::jack_shm_addr (jack_shm_info_t* si) {
+ if(si != NULL) {
+ return (char*)si->ptr.attached_at;
+ } else {
+ jack_error ("jack_shm_addr : jack_shm_info_t is NULL!");
+ return NULL;
+ }
+ }
+ int Shm::jack_register_server (const char *server_name, int new_registry) {
+ return Shm::Instantiate()->register_server(server_name, new_registry);
+ }
+ int Shm::jack_unregister_server (const char *server_name) {
+ return Shm::Instantiate()->unregister_server(server_name);
+ }
+ int Shm::jack_initialize_shm (const char *server_name) {
+ return Shm::Instantiate()->initialize_shm(server_name);
+ }
+ int Shm::jack_initialize_shm_server (void) {
+ return Shm::Instantiate()->initialize_shm_server();
+ }
+ int Shm::jack_initialize_shm_client () {
+ return Shm::Instantiate()->initialize_shm_client();
+ }
+ int Shm::jack_cleanup_shm (void) {
+ return Shm::Instantiate()->cleanup_shm();
+ }
+ int Shm::jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result) {
+ return Shm::Instantiate()->shmalloc(shm_name, size, result);
+ }
+ void Shm::jack_release_shm (jack_shm_info_t* si) {
+ Shm::Instantiate()->release_shm(si);
+ }
+ void Shm::jack_release_lib_shm (jack_shm_info_t* si) {
+ Shm::Instantiate()->release_lib_shm(si);
+ }
+ void Shm::jack_destroy_shm (jack_shm_info_t* si) {
+ Shm::Instantiate()->destroy_shm(si);
+ }
+ int Shm::jack_attach_shm (jack_shm_info_t* si) {
+ return Shm::Instantiate()->attach_shm(si);
+ }
+ int Shm::jack_attach_lib_shm (jack_shm_info_t* si) {
+ return Shm::Instantiate()->attach_lib_shm(si);
+ }
+ int Shm::jack_attach_shm_read (jack_shm_info_t* si) {
+ return Shm::Instantiate()->attach_shm_read(si);
+ }
+ int Shm::jack_attach_lib_shm_read (jack_shm_info_t* si) {
+ return Shm::Instantiate()->attach_lib_shm_read(si);
+ }
+ int Shm::jack_resize_shm (jack_shm_info_t* si, jack_shmsize_t size) {
+ return Shm::Instantiate()->resize_shm(si, size);
+ }
+};
+
+void jack_shm_copy_from_registry (jack_shm_info_t* si, jack_shm_registry_index_t t) {
+ android::Shm::jack_shm_copy_from_registry(si, t);
+}
+void jack_shm_copy_to_registry (jack_shm_info_t* si, jack_shm_registry_index_t* t) {
+ android::Shm::jack_shm_copy_to_registry(si, t);
+}
+int jack_release_shm_info (jack_shm_registry_index_t t) {
+ return android::Shm::jack_release_shm_info(t);
+}
+char* jack_shm_addr (jack_shm_info_t* si) {
+ return android::Shm::jack_shm_addr(si);
+}
+int jack_register_server (const char *server_name, int new_registry) {
+ return android::Shm::jack_register_server(server_name, new_registry);
+}
+int jack_unregister_server (const char *server_name) {
+ return android::Shm::jack_unregister_server(server_name);
+}
+int jack_initialize_shm (const char *server_name) {
+ return android::Shm::jack_initialize_shm(server_name);
+}
+int jack_initialize_shm_server (void) {
+ return android::Shm::jack_initialize_shm_server();
+}
+int jack_initialize_shm_client (void) {
+ return android::Shm::jack_initialize_shm_client();
+}
+int jack_cleanup_shm (void) {
+ return android::Shm::jack_cleanup_shm();
+}
+int jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result) {
+ return android::Shm::jack_shmalloc(shm_name, size, result);
+}
+void jack_release_shm (jack_shm_info_t* si) {
+ android::Shm::jack_release_shm(si);
+}
+void jack_release_lib_shm (jack_shm_info_t* si) {
+ android::Shm::jack_release_lib_shm(si);
+}
+void jack_destroy_shm (jack_shm_info_t* si) {
+ android::Shm::jack_destroy_shm(si);
+}
+int jack_attach_shm (jack_shm_info_t* si) {
+ return android::Shm::jack_attach_shm(si);
+}
+int jack_attach_lib_shm (jack_shm_info_t* si) {
+ return android::Shm::jack_attach_lib_shm(si);
+}
+int jack_attach_shm_read (jack_shm_info_t* si) {
+ return android::Shm::jack_attach_shm_read(si);
+}
+int jack_attach_lib_shm_read (jack_shm_info_t* si) {
+ return android::Shm::jack_attach_lib_shm_read(si);
+}
+int jack_resize_shm (jack_shm_info_t* si, jack_shmsize_t size) {
+ return android::Shm::jack_resize_shm(si, size);
+}
+void jack_instantiate() {
+ android::AndroidShm::instantiate();
+}
+
diff --git a/android/Shm.h b/android/Shm.h
new file mode 100644
index 00000000..cb75396e
--- /dev/null
+++ b/android/Shm.h
@@ -0,0 +1,144 @@
+/*
+ Copyright (C) 2001-2003 Paul Davis
+ Copyright (C) 2005-2012 Grame
+ Copyright (C) 2013 Samsung Electronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __jack_shm_android_h__
+#define __jack_shm_android_h__
+
+#include <limits.h>
+#include <sys/types.h>
+#include "types.h"
+#include "JackCompilerDeps.h"
+#include <binder/MemoryHeapBase.h>
+#include <utils/RefBase.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define JACK_SHM_REGISTRY_FD -1
+#define JACK_SHM_HEAP_ENOUGH_COUNT 300
+
+void jack_instantiate();
+
+#ifdef __cplusplus
+}
+#endif
+
+namespace android {
+
+ class IAndroidShm;
+
+ class Shm {
+ public:
+ static Shm* Instantiate();
+ virtual ~Shm();
+ private:
+ Shm();
+ Shm( const Shm&);
+ Shm& operator=(const Shm);
+
+ private:
+ void set_server_prefix (const char *server_name);
+ int server_initialize_shm (int new_registry);
+ int shm_lock_registry (void);
+ void shm_unlock_registry (void);
+ int access_registry (jack_shm_info_t *ri);
+ void remove_shm (jack_shm_id_t *id);
+ int create_registry (jack_shm_info_t *ri);
+ int shm_validate_registry ();
+ int GetUID();
+ int GetPID();
+ void shm_init_registry ();
+ void release_shm_entry (jack_shm_registry_index_t index);
+ jack_shm_registry_t * get_free_shm_info ();
+
+ public:
+ static void jack_shm_copy_from_registry (jack_shm_info_t*, jack_shm_registry_index_t);
+ static void jack_shm_copy_to_registry (jack_shm_info_t*, jack_shm_registry_index_t*);
+ static int jack_release_shm_info (jack_shm_registry_index_t);
+ static char* jack_shm_addr (jack_shm_info_t* si);
+ static int jack_register_server (const char *server_name, int new_registry);
+ static int jack_unregister_server (const char *server_name);
+ static int jack_initialize_shm (const char *server_name);
+ static int jack_initialize_shm_server (void);
+ static int jack_initialize_shm_client (void);
+ static int jack_cleanup_shm (void);
+ static int jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result);
+ static void jack_release_shm (jack_shm_info_t*);
+ static void jack_release_lib_shm (jack_shm_info_t*);
+ static void jack_destroy_shm (jack_shm_info_t*);
+ static int jack_attach_shm (jack_shm_info_t*);
+ static int jack_attach_lib_shm (jack_shm_info_t*);
+ static int jack_attach_shm_read (jack_shm_info_t*);
+ static int jack_attach_lib_shm_read (jack_shm_info_t*);
+ static int jack_resize_shm (jack_shm_info_t*, jack_shmsize_t size);
+
+ public:
+ void shm_copy_from_registry (jack_shm_info_t*, jack_shm_registry_index_t);
+ void shm_copy_to_registry (jack_shm_info_t*, jack_shm_registry_index_t*);
+ int release_shm_info (jack_shm_registry_index_t);
+ char* shm_addr (unsigned int fd);
+
+ // here begin the API
+ int register_server (const char *server_name, int new_registry);
+ int unregister_server (const char *server_name);
+
+ int initialize_shm (const char *server_name);
+ int initialize_shm_server (void);
+ int initialize_shm_client (void);
+ int cleanup_shm (void);
+
+ int shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result);
+ void release_shm (jack_shm_info_t*);
+ void release_lib_shm (jack_shm_info_t*);
+ void destroy_shm (jack_shm_info_t*);
+ int attach_shm (jack_shm_info_t*);
+ int attach_lib_shm (jack_shm_info_t*);
+ int attach_shm_read (jack_shm_info_t*);
+ int attach_lib_shm_read (jack_shm_info_t*);
+ int resize_shm (jack_shm_info_t*, jack_shmsize_t size);
+
+ private:
+ static jack_shmtype_t jack_shmtype;
+ static jack_shm_id_t registry_id;
+ static jack_shm_fd_t registry_fd;
+ static jack_shm_info_t registry_info;
+ static jack_shm_header_t *jack_shm_header;
+ static jack_shm_registry_t *jack_shm_registry;
+ static char jack_shm_server_prefix[JACK_SERVER_NAME_SIZE];
+ static int semid;
+ static pthread_mutex_t mutex;
+ static Shm* ref;
+
+ void jack_release_shm_entry (jack_shm_registry_index_t index);
+ int jack_shm_lock_registry (void);
+ void jack_shm_unlock_registry (void);
+
+ //static sp<IAndroidShm> mShmService;
+ static sp<IMemoryHeap> mShmMemBase[JACK_SHM_HEAP_ENOUGH_COUNT];
+
+ public:
+ static sp<IAndroidShm> getShmService();
+ };
+};
+
+#endif /* __jack_shm_android_h__ */
diff --git a/android/config.h b/android/config.h
new file mode 100644
index 00000000..35ff9878
--- /dev/null
+++ b/android/config.h
@@ -0,0 +1,25 @@
+/* Configuration header created by Waf - do not edit */
+#ifndef _CONFIG_H_WAF
+#define _CONFIG_H_WAF
+
+/* #define HAVE_SAMPLERATE 0 */
+/* #define HAVE_PPOLL 0 */
+/* #define HAVE_SNDFILE */
+/* #define HAVE_NCURSES 0 */
+/* #define HAVE_CELT 0 */
+/* #define HAVE_CELT_API_0_11 0 */
+/* #define HAVE_CELT_API_0_8 0 */
+/* #define HAVE_CELT_API_0_7 0 */
+/* #define HAVE_CELT_API_0_5 0 */
+/* #define HAVE_READLINE 0 */
+#define CLIENT_NUM 16
+#define PORT_NUM_FOR_CLIENT 16
+#define PORT_NUM 128
+#define PORT_NUM_MAX 256
+#define ADDON_DIR "/system/lib/jack"
+#define JACK_LOCATION "/system/bin"
+#define JACKMP 1
+/* #define USE_POSIX_SHM 0 */
+/* #define __CLIENTDEBUG__ 1 */
+
+#endif /* _CONFIG_H_WAF */
diff --git a/android/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/bits/ctype_base.h b/android/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/bits/ctype_base.h
new file mode 100644
index 00000000..c52689b4
--- /dev/null
+++ b/android/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/bits/ctype_base.h
@@ -0,0 +1,14 @@
+
+//fix build error in KitKat
+
+#define _U _CTYPE_U
+#define _L _CTYPE_L
+#define _N _CTYPE_N
+#define _S _CTYPE_S
+#define _P _CTYPE_P
+#define _C _CTYPE_C
+#define _X _CTYPE_X
+#define _B _CTYPE_B
+
+#include <../../../../../../../../../../../prebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/bits/ctype_base.h>
+
diff --git a/android/opensl_io.c b/android/opensl_io.c
new file mode 100644
index 00000000..38b6ec0c
--- /dev/null
+++ b/android/opensl_io.c
@@ -0,0 +1,539 @@
+/*
+opensl_io.c:
+Android OpenSL input/output module
+Copyright (c) 2012, Victor Lazzarini
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "opensl_io.h"
+//#define CONV16BIT 32768
+//#define CONVMYFLT (1./32768.)
+#define CONV16BIT 32640
+#define CONVMYFLT (1./32640.)
+
+static void* createThreadLock(void);
+static int waitThreadLock(void *lock);
+static void notifyThreadLock(void *lock);
+static void destroyThreadLock(void *lock);
+static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
+static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
+
+// creates the OpenSL ES audio engine
+static SLresult openSLCreateEngine(OPENSL_STREAM *p)
+{
+ SLresult result;
+ // create engine
+ result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
+ if(result != SL_RESULT_SUCCESS) goto engine_end;
+
+ // realize the engine
+ result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
+ if(result != SL_RESULT_SUCCESS) goto engine_end;
+
+ // get the engine interface, which is needed in order to create other objects
+ result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine));
+ if(result != SL_RESULT_SUCCESS) goto engine_end;
+
+ engine_end:
+ return result;
+}
+
+// opens the OpenSL ES device for output
+static SLresult openSLPlayOpen(OPENSL_STREAM *p)
+{
+ SLresult result;
+ SLuint32 sr = p->sr;
+ SLuint32 channels = p->outchannels;
+
+ if(channels){
+ // configure audio source
+ SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
+
+ switch(sr){
+
+ case 8000:
+ sr = SL_SAMPLINGRATE_8;
+ break;
+ case 11025:
+ sr = SL_SAMPLINGRATE_11_025;
+ break;
+ case 16000:
+ sr = SL_SAMPLINGRATE_16;
+ break;
+ case 22050:
+ sr = SL_SAMPLINGRATE_22_05;
+ break;
+ case 24000:
+ sr = SL_SAMPLINGRATE_24;
+ break;
+ case 32000:
+ sr = SL_SAMPLINGRATE_32;
+ break;
+ case 44100:
+ sr = SL_SAMPLINGRATE_44_1;
+ break;
+ case 48000:
+ sr = SL_SAMPLINGRATE_48;
+ break;
+ case 64000:
+ sr = SL_SAMPLINGRATE_64;
+ break;
+ case 88200:
+ sr = SL_SAMPLINGRATE_88_2;
+ break;
+ case 96000:
+ sr = SL_SAMPLINGRATE_96;
+ break;
+ case 192000:
+ sr = SL_SAMPLINGRATE_192;
+ break;
+ default:
+ return -1;
+ }
+
+ const SLInterfaceID ids[] = {SL_IID_VOLUME};
+ const SLboolean req[] = {SL_BOOLEAN_FALSE};
+ result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req);
+ if(result != SL_RESULT_SUCCESS) goto end_openaudio;
+
+ // realize the output mix
+ result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE);
+
+ int speakers;
+ if(channels > 1)
+ speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+ else speakers = SL_SPEAKER_FRONT_CENTER;
+ SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,channels, sr,
+ SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
+ speakers, SL_BYTEORDER_LITTLEENDIAN};
+
+ SLDataSource audioSrc = {&loc_bufq, &format_pcm};
+
+ // configure audio sink
+ SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject};
+ SLDataSink audioSnk = {&loc_outmix, NULL};
+
+ // create audio player
+ const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
+ const SLboolean req1[] = {SL_BOOLEAN_TRUE};
+ result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine, &(p->bqPlayerObject), &audioSrc, &audioSnk,
+ 1, ids1, req1);
+ if(result != SL_RESULT_SUCCESS) goto end_openaudio;
+
+ // realize the player
+ result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE);
+ if(result != SL_RESULT_SUCCESS) goto end_openaudio;
+
+ // get the play interface
+ result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay));
+ if(result != SL_RESULT_SUCCESS) goto end_openaudio;
+
+ // get the buffer queue interface
+ result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+ &(p->bqPlayerBufferQueue));
+ if(result != SL_RESULT_SUCCESS) goto end_openaudio;
+
+ // register callback on the buffer queue
+ result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p);
+ if(result != SL_RESULT_SUCCESS) goto end_openaudio;
+
+ // set the player's state to playing
+ result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING);
+
+ end_openaudio:
+ return result;
+ }
+ return SL_RESULT_SUCCESS;
+}
+
+// Open the OpenSL ES device for input
+static SLresult openSLRecOpen(OPENSL_STREAM *p){
+
+ SLresult result;
+ SLuint32 sr = p->sr;
+ SLuint32 channels = p->inchannels;
+
+ if(channels){
+
+ switch(sr){
+
+ case 8000:
+ sr = SL_SAMPLINGRATE_8;
+ break;
+ case 11025:
+ sr = SL_SAMPLINGRATE_11_025;
+ break;
+ case 16000:
+ sr = SL_SAMPLINGRATE_16;
+ break;
+ case 22050:
+ sr = SL_SAMPLINGRATE_22_05;
+ break;
+ case 24000:
+ sr = SL_SAMPLINGRATE_24;
+ break;
+ case 32000:
+ sr = SL_SAMPLINGRATE_32;
+ break;
+ case 44100:
+ sr = SL_SAMPLINGRATE_44_1;
+ break;
+ case 48000:
+ sr = SL_SAMPLINGRATE_48;
+ break;
+ case 64000:
+ sr = SL_SAMPLINGRATE_64;
+ break;
+ case 88200:
+ sr = SL_SAMPLINGRATE_88_2;
+ break;
+ case 96000:
+ sr = SL_SAMPLINGRATE_96;
+ break;
+ case 192000:
+ sr = SL_SAMPLINGRATE_192;
+ break;
+ default:
+ return -1;
+ }
+
+ // configure audio source
+ SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
+ SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
+ SLDataSource audioSrc = {&loc_dev, NULL};
+
+ // configure audio sink
+ int speakers;
+ if(channels > 1)
+ speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+ else speakers = SL_SPEAKER_FRONT_CENTER;
+ SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
+ SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channels, sr,
+ SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
+ speakers, SL_BYTEORDER_LITTLEENDIAN};
+ SLDataSink audioSnk = {&loc_bq, &format_pcm};
+
+ // create audio recorder
+ // (requires the RECORD_AUDIO permission)
+ const SLInterfaceID id[1] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
+ const SLboolean req[1] = {SL_BOOLEAN_TRUE};
+ result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine, &(p->recorderObject), &audioSrc,
+ &audioSnk, 1, id, req);
+ if (SL_RESULT_SUCCESS != result) goto end_recopen;
+
+ // realize the audio recorder
+ result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE);
+ if (SL_RESULT_SUCCESS != result) goto end_recopen;
+
+ // get the record interface
+ result = (*p->recorderObject)->GetInterface(p->recorderObject, SL_IID_RECORD, &(p->recorderRecord));
+ if (SL_RESULT_SUCCESS != result) goto end_recopen;
+
+ // get the buffer queue interface
+ result = (*p->recorderObject)->GetInterface(p->recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+ &(p->recorderBufferQueue));
+ if (SL_RESULT_SUCCESS != result) goto end_recopen;
+
+ // register callback on the buffer queue
+ result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue, bqRecorderCallback,
+ p);
+ if (SL_RESULT_SUCCESS != result) goto end_recopen;
+ result = (*p->recorderRecord)->SetRecordState(p->recorderRecord, SL_RECORDSTATE_RECORDING);
+
+ end_recopen:
+ return result;
+ }
+ else return SL_RESULT_SUCCESS;
+
+
+}
+
+// close the OpenSL IO and destroy the audio engine
+static void openSLDestroyEngine(OPENSL_STREAM *p){
+
+ // destroy buffer queue audio player object, and invalidate all associated interfaces
+ if (p->bqPlayerObject != NULL) {
+ (*p->bqPlayerObject)->Destroy(p->bqPlayerObject);
+ p->bqPlayerObject = NULL;
+ p->bqPlayerPlay = NULL;
+ p->bqPlayerBufferQueue = NULL;
+ p->bqPlayerEffectSend = NULL;
+ }
+
+ // destroy audio recorder object, and invalidate all associated interfaces
+ if (p->recorderObject != NULL) {
+ (*p->recorderObject)->Destroy(p->recorderObject);
+ p->recorderObject = NULL;
+ p->recorderRecord = NULL;
+ p->recorderBufferQueue = NULL;
+ }
+
+ // destroy output mix object, and invalidate all associated interfaces
+ if (p->outputMixObject != NULL) {
+ (*p->outputMixObject)->Destroy(p->outputMixObject);
+ p->outputMixObject = NULL;
+ }
+
+ // destroy engine object, and invalidate all associated interfaces
+ if (p->engineObject != NULL) {
+ (*p->engineObject)->Destroy(p->engineObject);
+ p->engineObject = NULL;
+ p->engineEngine = NULL;
+ }
+
+}
+
+
+// open the android audio device for input and/or output
+OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, int bufferframes){
+
+ OPENSL_STREAM *p;
+ p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM),1);
+
+ p->inchannels = inchannels;
+ p->outchannels = outchannels;
+ p->sr = sr;
+ p->inlock = createThreadLock();
+ p->outlock = createThreadLock();
+
+ if((p->outBufSamples = bufferframes*outchannels) != 0) {
+ if((p->outputBuffer[0] = (short *) calloc(p->outBufSamples, sizeof(short))) == NULL ||
+ (p->outputBuffer[1] = (short *) calloc(p->outBufSamples, sizeof(short))) == NULL) {
+ android_CloseAudioDevice(p);
+ return NULL;
+ }
+ }
+
+ if((p->inBufSamples = bufferframes*inchannels) != 0){
+ if((p->inputBuffer[0] = (short *) calloc(p->inBufSamples, sizeof(short))) == NULL ||
+ (p->inputBuffer[1] = (short *) calloc(p->inBufSamples, sizeof(short))) == NULL){
+ android_CloseAudioDevice(p);
+ return NULL;
+ }
+ }
+
+ p->currentInputIndex = 0;
+ p->currentOutputBuffer = 0;
+ p->currentInputIndex = p->inBufSamples;
+ p->currentInputBuffer = 0;
+
+ if(openSLCreateEngine(p) != SL_RESULT_SUCCESS) {
+ android_CloseAudioDevice(p);
+ return NULL;
+ }
+
+ if(openSLRecOpen(p) != SL_RESULT_SUCCESS) {
+ android_CloseAudioDevice(p);
+ return NULL;
+ }
+
+ if(openSLPlayOpen(p) != SL_RESULT_SUCCESS) {
+ android_CloseAudioDevice(p);
+ return NULL;
+ }
+
+ notifyThreadLock(p->outlock);
+ notifyThreadLock(p->inlock);
+
+ p->time = 0.;
+ return p;
+}
+
+// close the android audio device
+void android_CloseAudioDevice(OPENSL_STREAM *p){
+
+ if (p == NULL)
+ return;
+
+ openSLDestroyEngine(p);
+
+ if (p->inlock != NULL) {
+ notifyThreadLock(p->inlock);
+ destroyThreadLock(p->inlock);
+ p->inlock = NULL;
+ }
+
+ if (p->outlock != NULL) {
+ notifyThreadLock(p->outlock);
+ destroyThreadLock(p->outlock);
+ p->inlock = NULL;
+ }
+
+ if (p->outputBuffer[0] != NULL) {
+ free(p->outputBuffer[0]);
+ p->outputBuffer[0] = NULL;
+ }
+
+ if (p->outputBuffer[1] != NULL) {
+ free(p->outputBuffer[1]);
+ p->outputBuffer[1] = NULL;
+ }
+
+ if (p->inputBuffer[0] != NULL) {
+ free(p->inputBuffer[0]);
+ p->inputBuffer[0] = NULL;
+ }
+
+ if (p->inputBuffer[1] != NULL) {
+ free(p->inputBuffer[1]);
+ p->inputBuffer[1] = NULL;
+ }
+
+ free(p);
+}
+
+// returns timestamp of the processed stream
+double android_GetTimestamp(OPENSL_STREAM *p){
+ return p->time;
+}
+
+
+// this callback handler is called every time a buffer finishes recording
+void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
+{
+ OPENSL_STREAM *p = (OPENSL_STREAM *) context;
+ notifyThreadLock(p->inlock);
+}
+
+// gets a buffer of size samples from the device
+int android_AudioIn(OPENSL_STREAM *p,float *buffer,int size){
+ short *inBuffer;
+ int i, bufsamps, index;
+ if(p == NULL) return 0;
+ bufsamps = p->inBufSamples;
+ if(bufsamps == 0) return 0;
+ index = p->currentInputIndex;
+
+ inBuffer = p->inputBuffer[p->currentInputBuffer];
+ for(i=0; i < size; i++){
+ if (index >= bufsamps) {
+ waitThreadLock(p->inlock);
+ (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue,
+ inBuffer,bufsamps*sizeof(short));
+ p->currentInputBuffer = (p->currentInputBuffer ? 0 : 1);
+ index = 0;
+ inBuffer = p->inputBuffer[p->currentInputBuffer];
+ }
+ buffer[i] = (float) inBuffer[index++]*CONVMYFLT;
+ }
+ p->currentInputIndex = index;
+ if(p->outchannels == 0) p->time += (double) size/(p->sr*p->inchannels);
+ return i;
+}
+
+// this callback handler is called every time a buffer finishes playing
+void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
+{
+ OPENSL_STREAM *p = (OPENSL_STREAM *) context;
+ notifyThreadLock(p->outlock);
+}
+
+// puts a buffer of size samples to the device
+int android_AudioOut(OPENSL_STREAM *p, float *buffer,int size){
+
+ short *outBuffer;
+ int i, bufsamps, index;
+ if(p == NULL) return 0;
+ bufsamps = p->outBufSamples;
+ if(bufsamps == 0) return 0;
+ index = p->currentOutputIndex;
+ outBuffer = p->outputBuffer[p->currentOutputBuffer];
+
+ for(i=0; i < size; i++){
+ outBuffer[index++] = (short) (buffer[i]*CONV16BIT);
+ if (index >= p->outBufSamples) {
+ waitThreadLock(p->outlock);
+ (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue,
+ outBuffer,bufsamps*sizeof(short));
+ p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1);
+ index = 0;
+ outBuffer = p->outputBuffer[p->currentOutputBuffer];
+ }
+ }
+ p->currentOutputIndex = index;
+ p->time += (double) size/(p->sr*p->outchannels);
+ return i;
+}
+
+//----------------------------------------------------------------------
+// thread Locks
+// to ensure synchronisation between callbacks and processing code
+void* createThreadLock(void)
+{
+ threadLock *p;
+ p = (threadLock*) malloc(sizeof(threadLock));
+ if (p == NULL)
+ return NULL;
+ memset(p, 0, sizeof(threadLock));
+ if (pthread_mutex_init(&(p->m), (pthread_mutexattr_t*) NULL) != 0) {
+ free((void*) p);
+ return NULL;
+ }
+ if (pthread_cond_init(&(p->c), (pthread_condattr_t*) NULL) != 0) {
+ pthread_mutex_destroy(&(p->m));
+ free((void*) p);
+ return NULL;
+ }
+ p->s = (unsigned char) 1;
+
+ return p;
+}
+
+int waitThreadLock(void *lock)
+{
+ threadLock *p;
+ int retval = 0;
+ p = (threadLock*) lock;
+ pthread_mutex_lock(&(p->m));
+ while (!p->s) {
+ pthread_cond_wait(&(p->c), &(p->m));
+ }
+ p->s = (unsigned char) 0;
+ pthread_mutex_unlock(&(p->m));
+ return NULL;
+}
+
+void notifyThreadLock(void *lock)
+{
+ threadLock *p;
+ p = (threadLock*) lock;
+ pthread_mutex_lock(&(p->m));
+ p->s = (unsigned char) 1;
+ pthread_cond_signal(&(p->c));
+ pthread_mutex_unlock(&(p->m));
+ return;
+}
+
+void destroyThreadLock(void *lock)
+{
+ threadLock *p;
+ p = (threadLock*) lock;
+ if (p == NULL)
+ return;
+ notifyThreadLock(p);
+ pthread_cond_destroy(&(p->c));
+ pthread_mutex_destroy(&(p->m));
+ free(p);
+}
diff --git a/android/opensl_io.h b/android/opensl_io.h
new file mode 100644
index 00000000..501f0361
--- /dev/null
+++ b/android/opensl_io.h
@@ -0,0 +1,121 @@
+/*
+opensl_io.c:
+Android OpenSL input/output module header
+Copyright (c) 2012, Victor Lazzarini
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OPENSL_IO
+#define OPENSL_IO
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+typedef struct threadLock_{
+ pthread_mutex_t m;
+ pthread_cond_t c;
+ unsigned char s;
+} threadLock;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct opensl_stream {
+
+ // engine interfaces
+ SLObjectItf engineObject;
+ SLEngineItf engineEngine;
+
+ // output mix interfaces
+ SLObjectItf outputMixObject;
+
+ // buffer queue player interfaces
+ SLObjectItf bqPlayerObject;
+ SLPlayItf bqPlayerPlay;
+ SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
+ SLEffectSendItf bqPlayerEffectSend;
+
+ // recorder interfaces
+ SLObjectItf recorderObject;
+ SLRecordItf recorderRecord;
+ SLAndroidSimpleBufferQueueItf recorderBufferQueue;
+
+ // buffer indexes
+ int currentInputIndex;
+ int currentOutputIndex;
+
+ // current buffer half (0, 1)
+ int currentOutputBuffer;
+ int currentInputBuffer;
+
+ // buffers
+ short *outputBuffer[2];
+ short *inputBuffer[2];
+
+ // size of buffers
+ int outBufSamples;
+ int inBufSamples;
+
+ // locks
+ void* inlock;
+ void* outlock;
+
+ double time;
+ int inchannels;
+ int outchannels;
+ int sr;
+
+} OPENSL_STREAM;
+
+ /*
+ Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size
+ in frames. Returns a handle to the OpenSL stream
+ */
+ OPENSL_STREAM* android_OpenAudioDevice(int sr, int inchannels, int outchannels, int bufferframes);
+ /*
+ Close the audio device
+ */
+ void android_CloseAudioDevice(OPENSL_STREAM *p);
+ /*
+ Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read.
+ */
+ int android_AudioIn(OPENSL_STREAM *p, float *buffer,int size);
+ /*
+ Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written.
+ */
+ int android_AudioOut(OPENSL_STREAM *p, float *buffer,int size);
+ /*
+ Get the current IO block time in seconds
+ */
+ double android_GetTimestamp(OPENSL_STREAM *p);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // #ifndef OPENSL_IO
diff --git a/common/JackConstants.h b/common/JackConstants.h
index c7257d08..c5ae4af4 100644
--- a/common/JackConstants.h
+++ b/common/JackConstants.h
@@ -45,7 +45,9 @@
#define PORT_NUM 2048
#endif
+#ifndef PORT_NUM_MAX
#define PORT_NUM_MAX 4096 // The "max" value for ports used in connection manager, although port number in graph manager is dynamic
+#endif
#define DRIVER_PORT_NUM 256
diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp
index 5b16e0de..6d8db0d0 100644
--- a/common/Jackdmp.cpp
+++ b/common/Jackdmp.cpp
@@ -33,6 +33,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "control.h"
#include "JackConstants.h"
#include "JackPlatformPlug.h"
+#ifdef __ANDROID__
+#include "JackControlAPIAndroid.h"
+#endif
#if defined(JACK_DBUS) && defined(__linux__)
#include <dbus/dbus.h>
@@ -192,6 +195,25 @@ static void usage(FILE* file, jackctl_server_t *server)
}
}
+#ifdef __ANDROID__
+static void jackctl_server_switch_master_dummy(jackctl_server_t * server_ctl, char * master_driver_name)
+{
+ static bool is_dummy_driver = false;
+ if(!strcmp(master_driver_name, "dummy")) {
+ return;
+ }
+ jackctl_driver_t * driver_ctr;
+ if(is_dummy_driver) {
+ is_dummy_driver = false;
+ driver_ctr = jackctl_server_get_driver(server_ctl, master_driver_name);
+ } else {
+ is_dummy_driver = true;
+ driver_ctr = jackctl_server_get_driver(server_ctl, "dummy");
+ }
+ jackctl_server_switch_master(server_ctl, driver_ctr);
+}
+#endif
+
// Prototype to be found in libjackserver
extern "C" void silent_jack_error_callback(const char *desc);
@@ -556,7 +578,19 @@ int main(int argc, char** argv)
return_value = 0;
// Waits for signal
+#ifdef __ANDROID__
+ //reserve SIGUSR2 signal for switching master driver
+ while(1) {
+ int signal = jackctl_wait_signals_and_return(sigmask);
+ if (signal == SIGUSR2) {
+ jackctl_server_switch_master_dummy(server_ctl, master_driver_name);
+ } else {
+ break;
+ }
+ }
+#else
jackctl_wait_signals(sigmask);
+#endif
stop_server:
if (!jackctl_server_stop(server_ctl)) {
diff --git a/common/jack/types.h b/common/jack/types.h
index fa059159..c1625f5f 100644
--- a/common/jack/types.h
+++ b/common/jack/types.h
@@ -369,7 +369,7 @@ typedef int (*JackSampleRateCallback)(jack_nframes_t nframes, void *arg);
* @param register non-zero if the port is being registered,
* zero if the port is being unregistered
*/
-typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int register, void *arg);
+typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int /* register */, void *arg);
/**
* Prototype for the client supplied function that is called
@@ -380,7 +380,7 @@ typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int register,
* zero if the client is being unregistered
* @param arg pointer to a client supplied structure
*/
-typedef void (*JackClientRegistrationCallback)(const char* name, int register, void *arg);
+typedef void (*JackClientRegistrationCallback)(const char* name, int /* register */, void *arg);
/**
* Prototype for the client supplied function that is called
diff --git a/common/shm.h b/common/shm.h
index c539aa9f..ada2a9d0 100644
--- a/common/shm.h
+++ b/common/shm.h
@@ -79,6 +79,19 @@ extern "C"
typedef char shm_name_t[SHM_NAME_MAX];
typedef shm_name_t jack_shm_id_t;
+#elif __ANDROID__
+
+#ifndef NAME_MAX
+#define NAME_MAX 255
+#endif
+
+#ifndef SHM_NAME_MAX
+#define SHM_NAME_MAX NAME_MAX
+#endif
+ typedef char shm_name_t[SHM_NAME_MAX];
+ typedef shm_name_t jack_shm_id_t;
+ typedef int jack_shm_fd_t;
+
#else
/* System V SHM */
typedef int jack_shm_id_t;
@@ -88,7 +101,8 @@ extern "C"
typedef enum {
shm_POSIX = 1, /* POSIX shared memory */
shm_SYSV = 2, /* System V shared memory */
- shm_WIN32 = 3 /* Windows 32 shared memory */
+ shm_WIN32 = 3, /* Windows 32 shared memory */
+ shm_ANDROID = 4 /* Android shared memory */
} jack_shmtype_t;
typedef int16_t jack_shm_registry_index_t;
@@ -135,6 +149,9 @@ extern "C"
jack_shmsize_t size; /* for POSIX unattach */
jack_shm_id_t id; /* API specific, see above */
+#ifdef __ANDROID__
+ jack_shm_fd_t fd;
+#endif
}
jack_shm_registry_t;
@@ -153,6 +170,9 @@ extern "C"
struct _jack_shm_info {
jack_shm_registry_index_t index; /* offset into the registry */
uint32_t size;
+#ifdef __ANDROID__
+ jack_shm_fd_t fd;
+#endif
union {
void *attached_at; /* address where attached */
char ptr_size[8];
diff --git a/example-clients/alsa_in.c b/example-clients/alsa_in.c
index 9c31a05e..1a8c0332 100644
--- a/example-clients/alsa_in.c
+++ b/example-clients/alsa_in.c
@@ -99,6 +99,9 @@ alsa_format_t formats[] = {
{ SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" },
{ SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" },
{ SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" }
+#ifdef __ANDROID__
+ ,{ SND_PCM_FORMAT_S16_LE, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit little-endian" }
+#endif
};
#define NUMFORMATS (sizeof(formats)/sizeof(formats[0]))
int format=0;
@@ -127,6 +130,11 @@ static int xrun_recovery(snd_pcm_t *handle, int err) {
static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params )
{
+#ifdef __ANDROID__
+ format = 5;
+ snd_pcm_hw_params_set_format(handle, params, formats[format].format_id);
+ return 0;
+#else
int i;
int err;
@@ -140,6 +148,7 @@ static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params )
}
return err;
+#endif
}
static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) {
diff --git a/example-clients/alsa_out.c b/example-clients/alsa_out.c
index ac7a149c..d5fd2680 100644
--- a/example-clients/alsa_out.c
+++ b/example-clients/alsa_out.c
@@ -99,6 +99,9 @@ alsa_format_t formats[] = {
{ SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" },
{ SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" },
{ SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" }
+#ifdef __ANDROID__
+ ,{ SND_PCM_FORMAT_S16_LE, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit little-endian" }
+#endif
};
#define NUMFORMATS (sizeof(formats)/sizeof(formats[0]))
int format=0;
@@ -127,6 +130,11 @@ static int xrun_recovery(snd_pcm_t *handle, int err) {
static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params )
{
+#ifdef __ANDROID__
+ format = 5;
+ snd_pcm_hw_params_set_format(handle, params, formats[format].format_id);
+ return 0;
+#else
int i;
int err;
@@ -140,6 +148,7 @@ static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params )
}
return err;
+#endif
}
static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) {
diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c
index 39a36813..1a6988c0 100644
--- a/example-clients/midi_latency_test.c
+++ b/example-clients/midi_latency_test.c
@@ -635,7 +635,7 @@ main(int argc, char **argv)
timeout = 5;
for (;;) {
- char c = getopt_long(argc, argv, option_string, long_options,
+ signed char c = getopt_long(argc, argv, option_string, long_options,
&long_index);
switch (c) {
case 'h':
diff --git a/example-clients/transport.c b/example-clients/transport.c
index a2ff0eef..e5d22ec9 100644
--- a/example-clients/transport.c
+++ b/example-clients/transport.c
@@ -24,11 +24,16 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
+#endif
#include <jack/jack.h>
#include <jack/transport.h>
+#ifndef HAVE_READLINE
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
+#endif
char *package; /* program name */
int done = 0;
@@ -384,6 +389,7 @@ static char *command_generator (const char *text, int state)
static void command_loop()
{
+#ifdef HAVE_READLINE
char *line, *cmd;
char prompt[32];
@@ -394,10 +400,15 @@ static void command_loop()
/* Define a custom completion function. */
rl_completion_entry_function = command_generator;
+#else
+ char line[64] = {0,};
+ char *cmd = NULL;
+#endif
/* Read and execute commands until the user quits. */
while (!done) {
+#ifdef HAVE_READLINE
line = readline(prompt);
if (line == NULL) { /* EOF? */
@@ -405,6 +416,11 @@ static void command_loop()
done = 1;
break;
}
+#else
+ printf("%s> ", package);
+ fgets(line, sizeof(line), stdin);
+ line[strlen(line)-1] = '\0';
+#endif
/* Remove leading and trailing whitespace from the line. */
cmd = stripwhite(line);
@@ -412,11 +428,15 @@ static void command_loop()
/* If anything left, add to history and execute it. */
if (*cmd)
{
+#ifdef HAVE_READLINE
add_history(cmd);
+#endif
execute_command(cmd);
}
+#ifdef HAVE_READLINE
free(line); /* realine() called malloc() */
+#endif
}
}
diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp
index bfed2f11..7a3dfdcd 100644
--- a/linux/alsa/JackAlsaDriver.cpp
+++ b/linux/alsa/JackAlsaDriver.cpp
@@ -39,7 +39,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackPort.h"
#include "JackGraphManager.h"
#include "JackLockedEngine.h"
+#ifdef __ANDROID__
+#include "JackAndroidThread.h"
+#else
#include "JackPosixThread.h"
+#endif
#include "JackCompilerDeps.h"
#include "JackServerGlobals.h"
@@ -469,7 +473,11 @@ int JackAlsaDriver::is_realtime() const
int JackAlsaDriver::create_thread(pthread_t *thread, int priority, int realtime, void *(*start_routine)(void*), void *arg)
{
+#ifdef __ANDROID__
+ return JackAndroidThread::StartImp(thread, priority, realtime, start_routine, arg);
+#else
return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg);
+#endif
}
jack_port_id_t JackAlsaDriver::port_register(const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size)
@@ -739,7 +747,11 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor ()
desc = jack_driver_descriptor_construct("alsa", JackDriverMaster, "Linux ALSA API based audio backend", &filler);
strcpy(value.str, "hw:0");
- jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, enum_alsa_devices(), "ALSA device name", NULL);
+#ifdef __ANDROID__
+ jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "ALSA device name", NULL);
+#else
+ jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, enum_alsa_devices, "ALSA device name", NULL);
+#endif
strcpy(value.str, "none");
jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set device", NULL);
diff --git a/linux/alsa/alsa_driver.c b/linux/alsa/alsa_driver.c
index e14458b6..9d1068c9 100644
--- a/linux/alsa/alsa_driver.c
+++ b/linux/alsa/alsa_driver.c
@@ -368,7 +368,7 @@ alsa_driver_configure_stream (alsa_driver_t *driver, char *device_name,
snd_pcm_format_t format;
int swapped;
} formats[] = {
- {"32bit float little-endian", SND_PCM_FORMAT_FLOAT_LE},
+ {"32bit float little-endian", SND_PCM_FORMAT_FLOAT_LE, IS_LE},
{"32bit integer little-endian", SND_PCM_FORMAT_S32_LE, IS_LE},
{"32bit integer big-endian", SND_PCM_FORMAT_S32_BE, IS_BE},
{"24bit little-endian", SND_PCM_FORMAT_S24_3LE, IS_LE},
@@ -914,7 +914,7 @@ alsa_driver_get_channel_addresses (alsa_driver_t *driver,
snd_pcm_uframes_t *capture_offset,
snd_pcm_uframes_t *playback_offset)
{
- unsigned long err;
+ int err;
channel_t chn;
if (capture_avail) {
@@ -1320,7 +1320,11 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float
driver->poll_late++;
}
+#ifdef __ANDROID__
+ poll_result = poll (driver->pfd, nfds, -1); //fix for sleep issue
+#else
poll_result = poll (driver->pfd, nfds, driver->poll_timeout);
+#endif
if (poll_result < 0) {
if (errno == EINTR) {
@@ -2034,6 +2038,13 @@ alsa_driver_new (char *name, char *playback_alsa_device,
SND_PCM_NONBLOCK) < 0) {
switch (errno) {
case EBUSY:
+#ifdef __ANDROID__
+ jack_error ("\n\nATTENTION: The playback device \"%s\" is "
+ "already in use. Please stop the"
+ " application using it and "
+ "run JACK again",
+ playback_alsa_device);
+#else
current_apps = discover_alsa_using_apps ();
if (current_apps) {
jack_error ("\n\nATTENTION: The playback device \"%s\" is "
@@ -2051,6 +2062,7 @@ alsa_driver_new (char *name, char *playback_alsa_device,
"run JACK again",
playback_alsa_device);
}
+#endif
alsa_driver_delete (driver);
return NULL;
@@ -2078,6 +2090,13 @@ alsa_driver_new (char *name, char *playback_alsa_device,
SND_PCM_NONBLOCK) < 0) {
switch (errno) {
case EBUSY:
+#ifdef __ANDROID__
+ jack_error ("\n\nATTENTION: The capture (recording) device \"%s\" is "
+ "already in use. Please stop the"
+ " application using it and "
+ "run JACK again",
+ capture_alsa_device);
+#else
current_apps = discover_alsa_using_apps ();
if (current_apps) {
jack_error ("\n\nATTENTION: The capture device \"%s\" is "
@@ -2095,6 +2114,7 @@ alsa_driver_new (char *name, char *playback_alsa_device,
"run JACK again",
capture_alsa_device);
}
+#endif
alsa_driver_delete (driver);
return NULL;
break;
diff --git a/linux/alsa/alsa_rawmidi.c b/linux/alsa/alsa_rawmidi.c
index 521ad3d4..aa69e9dd 100644
--- a/linux/alsa/alsa_rawmidi.c
+++ b/linux/alsa/alsa_rawmidi.c
@@ -37,6 +37,8 @@
#include "midi_unpack.h"
#include "JackError.h"
+extern int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem);
+
enum {
NANOSLEEP_RESOLUTION = 7000
};
@@ -808,8 +810,9 @@ void jack_process(midi_stream_t *str, jack_nframes_t nframes)
str->jack.ports[w] = port;
++w;
}
- if (str->jack.nports != w)
+ if (str->jack.nports != w) {
debug_log("jack_%s: nports %d -> %d", str->name, str->jack.nports, w);
+ }
str->jack.nports = w;
jack_add_ports(str); // it makes no sense to add them earlier since they have no data yet
@@ -910,11 +913,13 @@ void *midi_thread(void *arg)
str->midi.ports[wp] = port;
++wp;
}
- if (str->midi.nports != wp)
+ if (str->midi.nports != wp) {
debug_log("midi_%s: nports %d -> %d", str->name, str->midi.nports, wp);
+ }
str->midi.nports = wp;
- if (npfds != w)
+ if (npfds != w) {
debug_log("midi_%s: npfds %d -> %d", str->name, npfds, w);
+ }
npfds = w;
/*
@@ -1054,8 +1059,9 @@ int do_midi_input(process_midi_t *proc)
jack_ringbuffer_get_write_vector(port->base.data_ring, vec);
if (jack_ringbuffer_write_space(port->base.event_ring) < sizeof(event_head_t) || vec[0].len < 1) {
port->overruns++;
- if (port->base.npfds)
+ if (port->base.npfds) {
debug_log("midi_in: internal overflow on %s", port->base.name);
+ }
// remove from poll to prevent busy-looping
port->base.npfds = 0;
return 1;
@@ -1106,8 +1112,9 @@ void do_jack_output(process_jack_t *proc)
output_port_t *port = (output_port_t*) proc->port;
int nevents = jack_midi_get_event_count(proc->buffer);
int i;
- if (nevents)
+ if (nevents) {
debug_log("jack_out: %d events in %s", nevents, port->base.name);
+ }
for (i=0; i<nevents; ++i) {
jack_midi_event_t event;
event_head_t hdr;
@@ -1146,12 +1153,14 @@ int do_midi_output(process_midi_t *proc)
port->next_event.time = 0;
port->next_event.size = 0;
break;
- } else
+ } else {
debug_log("midi_out: at %ld got %d bytes for %ld", (long)proc->cur_time, (int)port->next_event.size, (long)port->next_event.time);
+ }
}
- if (port->todo)
+ if (port->todo) {
debug_log("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time);
+ }
// calc next wakeup time
if (!port->todo && port->next_event.time && port->next_event.time < proc->next_time) {
@@ -1193,8 +1202,9 @@ int do_midi_output(process_midi_t *proc)
if (!port->todo) {
int i;
- if (worked)
+ if (worked) {
debug_log("midi_out: relaxing on %s", port->base.name);
+ }
for (i=0; i<port->base.npfds; ++i)
proc->wpfds[i].events &= ~POLLOUT;
} else {
diff --git a/linux/alsa/alsa_seqmidi.c b/linux/alsa/alsa_seqmidi.c
index 038bd8ea..f7583f39 100644
--- a/linux/alsa/alsa_seqmidi.c
+++ b/linux/alsa/alsa_seqmidi.c
@@ -438,8 +438,9 @@ void port_setdead(port_hash_t hash, snd_seq_addr_t addr)
port_t *port = port_get(hash, addr);
if (port)
port->is_dead = 1; // see jack_process
- else
+ else {
debug_log("port_setdead: not found (%d:%d)", addr.client, addr.port);
+ }
}
static
@@ -728,7 +729,7 @@ void do_jack_input(alsa_seqmidi_t *self, port_t *port, struct process_info *info
alsa_midi_event_t ev;
while (jack_ringbuffer_read(port->early_events, (char*)&ev, sizeof(ev))) {
jack_midi_data_t* buf;
- jack_nframes_t time = ev.time - info->period_start;
+ int64_t time = ev.time - info->period_start;
if (time < 0)
time = 0;
else if (time >= info->nframes)
diff --git a/linux/alsa/hammerfall.c b/linux/alsa/hammerfall.c
index c2e3efea..52354070 100644
--- a/linux/alsa/hammerfall.c
+++ b/linux/alsa/hammerfall.c
@@ -206,10 +206,12 @@ hammerfall_release (jack_hardware_t *hw)
return;
}
+#ifndef __ANDROID__
if (h->monitor_thread) {
pthread_cancel (h->monitor_thread);
pthread_join (h->monitor_thread, &status);
}
+#endif
free (h);
}