android_media_Visualizer.cpp revision 3540a0197f56c4bcd7d7419f4502bfca34257de2
1df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent/* 2df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Copyright (C) 2010 The Android Open Source Project 3df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * 4df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 5df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * you may not use this file except in compliance with the License. 6df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * You may obtain a copy of the License at 7df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * 8df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 9df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * 10df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Unless required by applicable law or agreed to in writing, software 11df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 12df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * See the License for the specific language governing permissions and 14df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * limitations under the License. 15df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 16df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 17df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#include <stdio.h> 18df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 19df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent//#define LOG_NDEBUG 0 20df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define LOG_TAG "visualizers-JNI" 21df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 22df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#include <utils/Log.h> 23df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#include <nativehelper/jni.h> 24df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#include <nativehelper/JNIHelp.h> 25df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#include <android_runtime/AndroidRuntime.h> 26449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman#include <utils/threads.h> 27df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#include "media/Visualizer.h" 28df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 29df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentusing namespace android; 30df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 31df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_SUCCESS 0 32df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_ERROR -1 33df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_ERROR_ALREADY_EXISTS -2 34df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_ERROR_NO_INIT -3 35df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_ERROR_BAD_VALUE -4 36df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_ERROR_INVALID_OPERATION -5 37df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_ERROR_NO_MEMORY -6 38df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_ERROR_DEAD_OBJECT -7 39df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 40df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define NATIVE_EVENT_PCM_CAPTURE 0 41df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define NATIVE_EVENT_FFT_CAPTURE 1 423540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman#define NATIVE_EVENT_SERVER_DIED 2 43df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 44df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ---------------------------------------------------------------------------- 451a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentstatic const char* const kClassPathName = "android/media/audiofx/Visualizer"; 46df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 47df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstruct fields_t { 48df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // these fields provide access from C++ to the... 49df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jclass clazzEffect; // Visualizer class 50df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jmethodID midPostNativeEvent; // event post callback method 51df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jfieldID fidNativeVisualizer; // stores in Java the native Visualizer object 52df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jfieldID fidJniData; // stores in Java additional resources used by the native Visualizer 53df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}; 54df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic fields_t fields; 55df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 56df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstruct visualizer_callback_cookie { 57df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jclass visualizer_class; // Visualizer class 58df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jobject visualizer_ref; // Visualizer object instance 59449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 60449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // Lazily allocated arrays used to hold callback data provided to java 61449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // applications. These arrays are allocated during the first callback and 62449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // reallocated when the size of the callback data changes. Allocating on 63449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // demand and saving the arrays means that applications cannot safely hold a 64449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // reference to the provided data (they need to make a copy if they want to 65449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // hold onto outside of the callback scope), but it avoids GC thrash caused 66449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // by constantly allocating and releasing arrays to hold callback data. 67449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman Mutex callback_data_lock; 68449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman jbyteArray waveform_data; 69449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman jbyteArray fft_data; 70449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 71449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman visualizer_callback_cookie() { 72449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman waveform_data = NULL; 73449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman fft_data = NULL; 74449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 75449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 76449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman ~visualizer_callback_cookie() { 77449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman cleanupBuffers(); 78449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 79449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 80449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman void cleanupBuffers() { 81449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman AutoMutex lock(&callback_data_lock); 82449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman if (waveform_data || fft_data) { 83449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman JNIEnv *env = AndroidRuntime::getJNIEnv(); 84449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 85449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman if (waveform_data) { 86449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman env->DeleteGlobalRef(waveform_data); 87449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman waveform_data = NULL; 88449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 89449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 90449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman if (fft_data) { 91449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman env->DeleteGlobalRef(fft_data); 92449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman fft_data = NULL; 93449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 94449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 95449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 96df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent }; 97df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 98df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ---------------------------------------------------------------------------- 99df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentclass visualizerJniStorage { 100df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public: 101df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent visualizer_callback_cookie mCallbackData; 102df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 103df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent visualizerJniStorage() { 104df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 105df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 106df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent ~visualizerJniStorage() { 107df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 108df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}; 109df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 110df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 111df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint translateError(int code) { 112df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent switch(code) { 113df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case NO_ERROR: 114df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_SUCCESS; 115df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case ALREADY_EXISTS: 116df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_ALREADY_EXISTS; 117df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case NO_INIT: 118df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_INIT; 119df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case BAD_VALUE: 120df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_BAD_VALUE; 121df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case INVALID_OPERATION: 122df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_INVALID_OPERATION; 123df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case NO_MEMORY: 124df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_MEMORY; 125df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case DEAD_OBJECT: 126df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_DEAD_OBJECT; 127df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent default: 128df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR; 129df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 130df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 131df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 132df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 133df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ---------------------------------------------------------------------------- 134449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossmanstatic void ensureArraySize(JNIEnv *env, jbyteArray *array, uint32_t size) { 135449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman if (NULL != *array) { 136449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman uint32_t len = env->GetArrayLength(*array); 137449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman if (len == size) 138449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman return; 139449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 140449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman env->DeleteGlobalRef(*array); 141449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman *array = NULL; 142449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 143449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 144449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman jbyteArray localRef = env->NewByteArray(size); 145449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman if (NULL != localRef) { 146449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // Promote to global ref. 147449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman *array = (jbyteArray)env->NewGlobalRef(localRef); 148449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 149449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman // Release our (now pointless) local ref. 150449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman env->DeleteLocalRef(localRef); 151449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 152449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman} 153449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 154df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void captureCallback(void* user, 155df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent uint32_t waveformSize, 156df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent uint8_t *waveform, 157df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent uint32_t fftSize, 158df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent uint8_t *fft, 159df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent uint32_t samplingrate) { 160df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 161df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int arg1 = 0; 162df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int arg2 = 0; 163df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent size_t size; 164df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 165df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent visualizer_callback_cookie *callbackInfo = (visualizer_callback_cookie *)user; 166df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent JNIEnv *env = AndroidRuntime::getJNIEnv(); 167449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman AutoMutex lock(&callbackInfo->callback_data_lock); 168df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 16971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("captureCallback: callbackInfo %p, visualizer_ref %p visualizer_class %p", 170df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent callbackInfo, 171df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent callbackInfo->visualizer_ref, 172df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent callbackInfo->visualizer_class); 173df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 174df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (!user || !env) { 1758564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("captureCallback error user %p, env %p", user, env); 176df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return; 177df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 178df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 179df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (waveformSize != 0 && waveform != NULL) { 180449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman jbyteArray jArray; 181449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 182449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman ensureArraySize(env, &callbackInfo->waveform_data, waveformSize); 183449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman jArray = callbackInfo->waveform_data; 184449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 185df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (jArray != NULL) { 186df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jbyte *nArray = env->GetByteArrayElements(jArray, NULL); 187df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent memcpy(nArray, waveform, waveformSize); 188df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ReleaseByteArrayElements(jArray, nArray, 0); 189df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->CallStaticVoidMethod( 190df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent callbackInfo->visualizer_class, 191df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.midPostNativeEvent, 192df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent callbackInfo->visualizer_ref, 193df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent NATIVE_EVENT_PCM_CAPTURE, 194df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent samplingrate, 195df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 0, 196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jArray); 197df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 198df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 199df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 200df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (fftSize != 0 && fft != NULL) { 201449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman jbyteArray jArray; 202449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 203449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman ensureArraySize(env, &callbackInfo->fft_data, fftSize); 204449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman jArray = callbackInfo->fft_data; 205449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 206df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (jArray != NULL) { 207df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jbyte *nArray = env->GetByteArrayElements(jArray, NULL); 208df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent memcpy(nArray, fft, fftSize); 209df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ReleaseByteArrayElements(jArray, nArray, 0); 210df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->CallStaticVoidMethod( 211df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent callbackInfo->visualizer_class, 212df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.midPostNativeEvent, 213df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent callbackInfo->visualizer_ref, 214df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent NATIVE_EVENT_FFT_CAPTURE, 215df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent samplingrate, 216df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 0, 217df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jArray); 218df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 219df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 220df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 221df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (env->ExceptionCheck()) { 222df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ExceptionDescribe(); 223df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ExceptionClear(); 224df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 225df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 226df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 227df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic Visualizer *getVisualizer(JNIEnv* env, jobject thiz) 228df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 229df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer *v = (Visualizer *)env->GetIntField( 230df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent thiz, fields.fidNativeVisualizer); 231df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (v == NULL) { 232df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jniThrowException(env, "java/lang/IllegalStateException", 233df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent "Unable to retrieve Visualizer pointer"); 234df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 235df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return v; 236df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 237df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 238df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ---------------------------------------------------------------------------- 239df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// This function gets some field IDs, which in turn causes class initialization. 240df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// It is called from a static block in Visualizer, which won't run until the 241df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// first time an instance of this class is used. 242df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void 243df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_init(JNIEnv *env) 244df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 245df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 24671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("android_media_visualizer_native_init"); 247df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 248df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.clazzEffect = NULL; 249df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 250df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Get the Visualizer class 251df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jclass clazz = env->FindClass(kClassPathName); 252df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (clazz == NULL) { 2533762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Can't find %s", kClassPathName); 254df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return; 255df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 256df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 257df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.clazzEffect = (jclass)env->NewGlobalRef(clazz); 258df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 259df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Get the postEvent method 260df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.midPostNativeEvent = env->GetStaticMethodID( 261df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.clazzEffect, 262df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V"); 263df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (fields.midPostNativeEvent == NULL) { 2643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Can't find Visualizer.%s", "postEventFromNative"); 265df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return; 266df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 267df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 268df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Get the variables fields 269df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // nativeTrackInJavaObj 270df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.fidNativeVisualizer = env->GetFieldID( 271df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.clazzEffect, 272df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent "mNativeVisualizer", "I"); 273df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (fields.fidNativeVisualizer == NULL) { 2743762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Can't find Visualizer.%s", "mNativeVisualizer"); 275df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return; 276df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 277df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // fidJniData; 278df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.fidJniData = env->GetFieldID( 279df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.clazzEffect, 280df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent "mJniData", "I"); 281df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (fields.fidJniData == NULL) { 2823762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Can't find Visualizer.%s", "mJniData"); 283df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return; 284df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 285df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 286df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 287df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 2883540a0197f56c4bcd7d7419f4502bfca34257de2John Grossmanstatic void android_media_visualizer_effect_callback(int32_t event, 2893540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman void *user, 2903540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman void *info) { 2913540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman if ((event == AudioEffect::EVENT_ERROR) && 2923540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman (*((status_t*)info) == DEAD_OBJECT)) { 2933540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman visualizerJniStorage* lpJniStorage = (visualizerJniStorage*)user; 2943540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman visualizer_callback_cookie* callbackInfo = &lpJniStorage->mCallbackData; 2953540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman JNIEnv *env = AndroidRuntime::getJNIEnv(); 2963540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 2973540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman env->CallStaticVoidMethod( 2983540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman callbackInfo->visualizer_class, 2993540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman fields.midPostNativeEvent, 3003540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman callbackInfo->visualizer_ref, 3013540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman NATIVE_EVENT_SERVER_DIED, 3023540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 0, 0, 0); 3033540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 3043540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman} 305df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 306df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 307df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, 308df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jint sessionId, jintArray jId) 309df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 31071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("android_media_visualizer_native_setup"); 311df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent visualizerJniStorage* lpJniStorage = NULL; 312df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int lStatus = VISUALIZER_ERROR_NO_MEMORY; 313df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = NULL; 314df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jint* nId = NULL; 315df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 316df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lpJniStorage = new visualizerJniStorage(); 317df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpJniStorage == NULL) { 3183762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("setup: Error creating JNI Storage"); 319df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent goto setup_failure; 320df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 321df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 322df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lpJniStorage->mCallbackData.visualizer_class = (jclass)env->NewGlobalRef(fields.clazzEffect); 323df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // we use a weak reference so the Visualizer object can be garbage collected. 324df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lpJniStorage->mCallbackData.visualizer_ref = env->NewGlobalRef(weak_this); 325df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 32671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("setup: lpJniStorage: %p visualizer_ref %p visualizer_class %p, &mCallbackData %p", 327df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lpJniStorage, 328df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lpJniStorage->mCallbackData.visualizer_ref, 329df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lpJniStorage->mCallbackData.visualizer_class, 330df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent &lpJniStorage->mCallbackData); 331df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 3322fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent if (jId == NULL) { 3333762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("setup: NULL java array for id pointer"); 334df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lStatus = VISUALIZER_ERROR_BAD_VALUE; 335df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent goto setup_failure; 336df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 337df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 338df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // create the native Visualizer object 339df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lpVisualizer = new Visualizer(0, 3403540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman android_media_visualizer_effect_callback, 3413540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman lpJniStorage, 342df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent sessionId); 343df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 3443762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Error creating Visualizer"); 345df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent goto setup_failure; 346df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 347df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 348df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent lStatus = translateError(lpVisualizer->initCheck()); 349df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lStatus != VISUALIZER_SUCCESS && lStatus != VISUALIZER_ERROR_ALREADY_EXISTS) { 3503762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Visualizer initCheck failed %d", lStatus); 351df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent goto setup_failure; 352df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 353df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 3542fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL); 3552fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent if (nId == NULL) { 3563762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("setup: Error retrieving id pointer"); 3572fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent lStatus = VISUALIZER_ERROR_BAD_VALUE; 3582fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent goto setup_failure; 3592fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent } 360df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent nId[0] = lpVisualizer->id(); 361df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ReleasePrimitiveArrayCritical(jId, nId, 0); 362df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent nId = NULL; 363df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 364df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->SetIntField(thiz, fields.fidNativeVisualizer, (int)lpVisualizer); 365df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 366df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->SetIntField(thiz, fields.fidJniData, (int)lpJniStorage); 367df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 368df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_SUCCESS; 369df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 370df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // failures: 371df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentsetup_failure: 372df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 373df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (nId != NULL) { 374df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ReleasePrimitiveArrayCritical(jId, nId, 0); 375df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 376df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 377df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer) { 378df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent delete lpVisualizer; 379df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 380df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->SetIntField(thiz, fields.fidNativeVisualizer, 0); 381df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 382df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpJniStorage) { 383df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent delete lpJniStorage; 384df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 385df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->SetIntField(thiz, fields.fidJniData, 0); 386df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 387df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return lStatus; 388df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 389df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 390df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ---------------------------------------------------------------------------- 391df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void android_media_visualizer_native_finalize(JNIEnv *env, jobject thiz) { 39271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("android_media_visualizer_native_finalize jobject: %x\n", (int)thiz); 393df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 394df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // delete the Visualizer object 395df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = (Visualizer *)env->GetIntField( 396df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent thiz, fields.fidNativeVisualizer); 397df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer) { 39871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("deleting Visualizer: %x\n", (int)lpVisualizer); 399df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent delete lpVisualizer; 400df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 401df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 402df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // delete the JNI data 403df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField( 404df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent thiz, fields.fidJniData); 405df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpJniStorage) { 40671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("deleting pJniStorage: %x\n", (int)lpJniStorage); 407df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent delete lpJniStorage; 408df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 409df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 410df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 411df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ---------------------------------------------------------------------------- 412df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void android_media_visualizer_native_release(JNIEnv *env, jobject thiz) { 413df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 414df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // do everything a call to finalize would 415df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent android_media_visualizer_native_finalize(env, thiz); 416df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // + reset the native resources in the Java object so any attempt to access 417df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // them after a call to release fails. 418df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->SetIntField(thiz, fields.fidNativeVisualizer, 0); 419df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->SetIntField(thiz, fields.fidJniData, 0); 420df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 421df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 422df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 423df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setEnabled(JNIEnv *env, jobject thiz, jboolean enabled) 424df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 425df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = getVisualizer(env, thiz); 426df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 427df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_INIT; 428df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 429df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 430449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman jint retVal = translateError(lpVisualizer->setEnabled(enabled)); 431449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 432449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman if (!enabled) { 433449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField( 434449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman thiz, fields.fidJniData); 435449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 436449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman if (NULL != lpJniStorage) 437449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman lpJniStorage->mCallbackData.cleanupBuffers(); 438449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman } 439449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman 440449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman return retVal; 441df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 442df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 443df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jboolean 444df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getEnabled(JNIEnv *env, jobject thiz) 445df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 446df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = getVisualizer(env, thiz); 447df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 448df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return false; 449df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 450df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 451df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return (jboolean)lpVisualizer->getEnabled(); 452df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 453df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 454df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jintArray 455df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject thiz) 456df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 457df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jintArray jRange = env->NewIntArray(2); 458df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jint *nRange = env->GetIntArrayElements(jRange, NULL); 459df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent nRange[0] = Visualizer::getMinCaptureSize(); 460df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent nRange[1] = Visualizer::getMaxCaptureSize(); 46171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("getCaptureSizeRange() min %d max %d", nRange[0], nRange[1]); 462df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ReleaseIntArrayElements(jRange, nRange, 0); 463df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return jRange; 464df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 465df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 466df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 467df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getMaxCaptureRate(JNIEnv *env, jobject thiz) 468df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 469df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return Visualizer::getMaxCaptureRate(); 470df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 471df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 472df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 473df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setCaptureSize(JNIEnv *env, jobject thiz, jint size) 474df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 475df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = getVisualizer(env, thiz); 476df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 477df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_INIT; 478df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 479df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 480df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return translateError(lpVisualizer->setCaptureSize(size)); 481df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 482df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 483df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 484df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getCaptureSize(JNIEnv *env, jobject thiz) 485df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 486df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = getVisualizer(env, thiz); 487df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 488df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return -1; 489df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 490df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return lpVisualizer->getCaptureSize(); 491df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 492df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 493df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 494df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getSamplingRate(JNIEnv *env, jobject thiz) 495df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 496df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = getVisualizer(env, thiz); 497df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 498df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return -1; 499df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 500df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return lpVisualizer->getSamplingRate(); 501df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 502df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 503df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 504df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getWaveForm(JNIEnv *env, jobject thiz, jbyteArray jWaveform) 505df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 506df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = getVisualizer(env, thiz); 507df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 508df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_INIT; 509df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 510df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 511df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jbyte* nWaveform = (jbyte *) env->GetPrimitiveArrayCritical(jWaveform, NULL); 512df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (nWaveform == NULL) { 513df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_MEMORY; 514df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 515df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jint status = translateError(lpVisualizer->getWaveForm((uint8_t *)nWaveform)); 516df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 517df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ReleasePrimitiveArrayCritical(jWaveform, nWaveform, 0); 518df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return status; 519df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 520df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 521df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 522df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getFft(JNIEnv *env, jobject thiz, jbyteArray jFft) 523df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 524df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = getVisualizer(env, thiz); 525df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 526df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_INIT; 527df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 528df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 529df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jbyte* nFft = (jbyte *) env->GetPrimitiveArrayCritical(jFft, NULL); 530df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (nFft == NULL) { 531df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_MEMORY; 532df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 533df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jint status = translateError(lpVisualizer->getFft((uint8_t *)nFft)); 534df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 535df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent env->ReleasePrimitiveArrayCritical(jFft, nFft, 0); 536df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 537df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return status; 538df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 539df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 540df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint 541df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_setPeriodicCapture(JNIEnv *env, jobject thiz, jint rate, jboolean jWaveform, jboolean jFft) 542df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 543df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer* lpVisualizer = getVisualizer(env, thiz); 544df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpVisualizer == NULL) { 545df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_INIT; 546df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 547df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField(thiz, 548df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fields.fidJniData); 549df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (lpJniStorage == NULL) { 550df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return VISUALIZER_ERROR_NO_INIT; 551df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 552df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 55371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("setPeriodicCapture: rate %d, jWaveform %d jFft %d", 554df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent rate, 555df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jWaveform, 556df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent jFft); 557df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 558df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent uint32_t flags = Visualizer::CAPTURE_CALL_JAVA; 559df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (jWaveform) flags |= Visualizer::CAPTURE_WAVEFORM; 560df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (jFft) flags |= Visualizer::CAPTURE_FFT; 561df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer::capture_cbk_t cbk = captureCallback; 562df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (!jWaveform && !jFft) cbk = NULL; 563df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 564df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return translateError(lpVisualizer->setCaptureCallBack(cbk, 565df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent &lpJniStorage->mCallbackData, 566df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent flags, 567df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent rate)); 568df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 569df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 570df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ---------------------------------------------------------------------------- 571df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 572df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// Dalvik VM type signatures 573df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic JNINativeMethod gMethods[] = { 574df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_init", "()V", (void *)android_media_visualizer_native_init}, 575df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_setup", "(Ljava/lang/Object;I[I)I", 576df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent (void *)android_media_visualizer_native_setup}, 577df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_finalize", "()V", (void *)android_media_visualizer_native_finalize}, 578df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_release", "()V", (void *)android_media_visualizer_native_release}, 579df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_setEnabled", "(Z)I", (void *)android_media_visualizer_native_setEnabled}, 580df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_getEnabled", "()Z", (void *)android_media_visualizer_native_getEnabled}, 581df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"getCaptureSizeRange", "()[I", (void *)android_media_visualizer_native_getCaptureSizeRange}, 582df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"getMaxCaptureRate", "()I", (void *)android_media_visualizer_native_getMaxCaptureRate}, 583df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_setCaptureSize", "(I)I", (void *)android_media_visualizer_native_setCaptureSize}, 584df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_getCaptureSize", "()I", (void *)android_media_visualizer_native_getCaptureSize}, 585df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_getSamplingRate", "()I", (void *)android_media_visualizer_native_getSamplingRate}, 586df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_getWaveForm", "([B)I", (void *)android_media_visualizer_native_getWaveForm}, 587df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_getFft", "([B)I", (void *)android_media_visualizer_native_getFft}, 588df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent {"native_setPeriodicCapture","(IZZ)I",(void *)android_media_setPeriodicCapture}, 589df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}; 590df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 591df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ---------------------------------------------------------------------------- 592df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 593df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentint register_android_media_visualizer(JNIEnv *env) 594df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{ 595df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 596df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 597df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 598