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>
23889f9952d8aa438d5aef6fea9046eddb38ea11b0Steven Moreland#include <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
292279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedUtfChars.h>
30fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov
31df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentusing namespace android;
32df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
33df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define VISUALIZER_SUCCESS                      0
340ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define VISUALIZER_ERROR                       (-1)
350ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define VISUALIZER_ERROR_ALREADY_EXISTS        (-2)
360ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define VISUALIZER_ERROR_NO_INIT               (-3)
370ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define VISUALIZER_ERROR_BAD_VALUE             (-4)
380ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define VISUALIZER_ERROR_INVALID_OPERATION     (-5)
390ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define VISUALIZER_ERROR_NO_MEMORY             (-6)
400ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define VISUALIZER_ERROR_DEAD_OBJECT           (-7)
41df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
42df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define NATIVE_EVENT_PCM_CAPTURE                0
43df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent#define NATIVE_EVENT_FFT_CAPTURE                1
443540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman#define NATIVE_EVENT_SERVER_DIED                2
45df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
46df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentstatic const char* const kClassPathName = "android/media/audiofx/Visualizer";
48badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivistatic const char* const kClassPeakRmsPathName =
49badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        "android/media/audiofx/Visualizer$MeasurementPeakRms";
50df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
51df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstruct fields_t {
52df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // these fields provide access from C++ to the...
53df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jclass    clazzEffect;          // Visualizer class
54df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jmethodID midPostNativeEvent;   // event post callback method
55df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jfieldID  fidNativeVisualizer; // stores in Java the native Visualizer object
56df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jfieldID  fidJniData;           // stores in Java additional resources used by the native Visualizer
57badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    jfieldID  fidPeak; // to access Visualizer.MeasurementPeakRms.mPeak
58badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    jfieldID  fidRms;  // to access Visualizer.MeasurementPeakRms.mRms
59df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent};
60df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic fields_t fields;
61df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
62df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstruct visualizer_callback_cookie {
63df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jclass      visualizer_class;  // Visualizer class
64df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jobject     visualizer_ref;    // Visualizer object instance
65449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
66449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // Lazily allocated arrays used to hold callback data provided to java
67449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // applications.  These arrays are allocated during the first callback and
68449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // reallocated when the size of the callback data changes.  Allocating on
69449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // demand and saving the arrays means that applications cannot safely hold a
70449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // reference to the provided data (they need to make a copy if they want to
71449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // hold onto outside of the callback scope), but it avoids GC thrash caused
72449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // by constantly allocating and releasing arrays to hold callback data.
73449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    Mutex       callback_data_lock;
74449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    jbyteArray  waveform_data;
75449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    jbyteArray  fft_data;
76449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
77449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    visualizer_callback_cookie() {
78449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        waveform_data = NULL;
79449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        fft_data = NULL;
80449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
81449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
82449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    ~visualizer_callback_cookie() {
83449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        cleanupBuffers();
84449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
85449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
86449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    void cleanupBuffers() {
87449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        AutoMutex lock(&callback_data_lock);
88449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        if (waveform_data || fft_data) {
89449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            JNIEnv *env = AndroidRuntime::getJNIEnv();
90449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
91449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            if (waveform_data) {
92449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman                env->DeleteGlobalRef(waveform_data);
93449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman                waveform_data = NULL;
94449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            }
95449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
96449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            if (fft_data) {
97449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman                env->DeleteGlobalRef(fft_data);
98449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman                fft_data = NULL;
99449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            }
100449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        }
101449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
102df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent };
103df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
104df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
10576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentclass VisualizerJniStorage {
106df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public:
107df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        visualizer_callback_cookie mCallbackData;
108df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
10976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    VisualizerJniStorage() {
110df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
111df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
11276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    ~VisualizerJniStorage() {
113df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
114df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent};
115df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
116df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
117df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint translateError(int code) {
118df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    switch(code) {
119df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case NO_ERROR:
120df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_SUCCESS;
121df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case ALREADY_EXISTS:
122df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_ALREADY_EXISTS;
123df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case NO_INIT:
124df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
125df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case BAD_VALUE:
126df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_BAD_VALUE;
127df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case INVALID_OPERATION:
128df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_INVALID_OPERATION;
129df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case NO_MEMORY:
130df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_MEMORY;
131df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case DEAD_OBJECT:
132df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_DEAD_OBJECT;
133df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    default:
134df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR;
135df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
136df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
137df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
13876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic Mutex sLock;
139df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
140df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
141449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossmanstatic void ensureArraySize(JNIEnv *env, jbyteArray *array, uint32_t size) {
142449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    if (NULL != *array) {
143449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        uint32_t len = env->GetArrayLength(*array);
144449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        if (len == size)
145449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            return;
146449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
147449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        env->DeleteGlobalRef(*array);
148449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        *array = NULL;
149449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
150449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
151449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    jbyteArray localRef = env->NewByteArray(size);
152449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    if (NULL != localRef) {
153449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        // Promote to global ref.
154449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        *array = (jbyteArray)env->NewGlobalRef(localRef);
155449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
156449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        // Release our (now pointless) local ref.
157449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        env->DeleteLocalRef(localRef);
158449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
159449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman}
160449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
161df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void captureCallback(void* user,
162df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint32_t waveformSize,
163df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint8_t *waveform,
164df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint32_t fftSize,
165df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint8_t *fft,
166df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint32_t samplingrate) {
167df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
168df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    visualizer_callback_cookie *callbackInfo = (visualizer_callback_cookie *)user;
169df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
17067a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen
17167a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen    if (!user || !env) {
17267a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen        ALOGW("captureCallback error user %p, env %p", user, env);
17367a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen        return;
17467a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen    }
175df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
17671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("captureCallback: callbackInfo %p, visualizer_ref %p visualizer_class %p",
177df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            callbackInfo,
178df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            callbackInfo->visualizer_ref,
179df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            callbackInfo->visualizer_class);
180df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
18167a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen    AutoMutex lock(&callbackInfo->callback_data_lock);
182df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
183df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (waveformSize != 0 && waveform != NULL) {
184449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        jbyteArray jArray;
185449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
186449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        ensureArraySize(env, &callbackInfo->waveform_data, waveformSize);
187449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        jArray = callbackInfo->waveform_data;
188449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
189df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        if (jArray != NULL) {
190df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
191df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            memcpy(nArray, waveform, waveformSize);
192df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            env->ReleaseByteArrayElements(jArray, nArray, 0);
193df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            env->CallStaticVoidMethod(
194df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                callbackInfo->visualizer_class,
195df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                fields.midPostNativeEvent,
196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                callbackInfo->visualizer_ref,
197df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                NATIVE_EVENT_PCM_CAPTURE,
198df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                samplingrate,
199df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                0,
200df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                jArray);
201df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
202df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
203df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
204df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (fftSize != 0 && fft != NULL) {
205449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        jbyteArray jArray;
206449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
207449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        ensureArraySize(env, &callbackInfo->fft_data, fftSize);
208449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        jArray = callbackInfo->fft_data;
209449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
210df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        if (jArray != NULL) {
211df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
212df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            memcpy(nArray, fft, fftSize);
213df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            env->ReleaseByteArrayElements(jArray, nArray, 0);
214df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            env->CallStaticVoidMethod(
215df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                callbackInfo->visualizer_class,
216df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                fields.midPostNativeEvent,
217df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                callbackInfo->visualizer_ref,
218df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                NATIVE_EVENT_FFT_CAPTURE,
219df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                samplingrate,
220df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                0,
221df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                jArray);
222df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
223df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
224df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
225df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (env->ExceptionCheck()) {
226df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        env->ExceptionDescribe();
227df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        env->ExceptionClear();
228df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
229df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
230df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
23176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent// ----------------------------------------------------------------------------
23276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
23376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic sp<Visualizer> getVisualizer(JNIEnv* env, jobject thiz)
234df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
23576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    Mutex::Autolock l(sLock);
23676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    Visualizer* const v =
23776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent            (Visualizer*)env->GetLongField(thiz, fields.fidNativeVisualizer);
23876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    return sp<Visualizer>(v);
23976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent}
24076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
24176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic sp<Visualizer> setVisualizer(JNIEnv* env, jobject thiz,
24276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent                                    const sp<Visualizer>& v)
24376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent{
24476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    Mutex::Autolock l(sLock);
24576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> old =
24676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent            (Visualizer*)env->GetLongField(thiz, fields.fidNativeVisualizer);
24776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (v.get()) {
24876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        v->incStrong((void*)setVisualizer);
24976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    }
25076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (old != 0) {
25176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        old->decStrong((void*)setVisualizer);
252df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
25376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    env->SetLongField(thiz, fields.fidNativeVisualizer, (jlong)v.get());
25476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    return old;
255df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
256df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
257df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
258df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// This function gets some field IDs, which in turn causes class initialization.
259df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// It is called from a static block in Visualizer, which won't run until the
260df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// first time an instance of this class is used.
261df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void
262df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_init(JNIEnv *env)
263df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
264df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
26571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("android_media_visualizer_native_init");
266df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
267df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.clazzEffect = NULL;
268df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
269df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Get the Visualizer class
270df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jclass clazz = env->FindClass(kClassPathName);
271df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (clazz == NULL) {
2723762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find %s", kClassPathName);
273df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return;
274df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
275df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
276df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.clazzEffect = (jclass)env->NewGlobalRef(clazz);
277df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
278badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    // Get the Visualizer.MeasurementPeakRms class
279badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    clazz = env->FindClass(kClassPeakRmsPathName);
280badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (clazz == NULL) {
281badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        ALOGE("Can't find %s", kClassPeakRmsPathName);
282badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return;
283badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
284badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    jclass clazzMeasurementPeakRms = (jclass)env->NewGlobalRef(clazz);
285badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi
286df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Get the postEvent method
287df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.midPostNativeEvent = env->GetStaticMethodID(
288df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fields.clazzEffect,
289df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");
290df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (fields.midPostNativeEvent == NULL) {
2913762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find Visualizer.%s", "postEventFromNative");
292df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return;
293df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
294df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
295df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Get the variables fields
296df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //      nativeTrackInJavaObj
297df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.fidNativeVisualizer = env->GetFieldID(
298df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fields.clazzEffect,
299ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat            "mNativeVisualizer", "J");
300df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (fields.fidNativeVisualizer == NULL) {
3013762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find Visualizer.%s", "mNativeVisualizer");
302df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return;
303df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
304df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //      fidJniData;
305df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.fidJniData = env->GetFieldID(
306df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fields.clazzEffect,
307ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat            "mJniData", "J");
308df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (fields.fidJniData == NULL) {
3093762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find Visualizer.%s", "mJniData");
310df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return;
311df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
312badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    //      fidPeak
313badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    fields.fidPeak = env->GetFieldID(
314badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi            clazzMeasurementPeakRms,
315badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi            "mPeak", "I");
316badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (fields.fidPeak == NULL) {
317badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        ALOGE("Can't find Visualizer.MeasurementPeakRms.%s", "mPeak");
318badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return;
319badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
320badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    //      fidRms
321badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    fields.fidRms = env->GetFieldID(
322badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi            clazzMeasurementPeakRms,
323badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi            "mRms", "I");
324badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (fields.fidRms == NULL) {
325badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        ALOGE("Can't find Visualizer.MeasurementPeakRms.%s", "mPeak");
326badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return;
327badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
328df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
329badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    env->DeleteGlobalRef(clazzMeasurementPeakRms);
330df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
331df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
3323540a0197f56c4bcd7d7419f4502bfca34257de2John Grossmanstatic void android_media_visualizer_effect_callback(int32_t event,
3333540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                                                     void *user,
3343540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                                                     void *info) {
3353540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    if ((event == AudioEffect::EVENT_ERROR) &&
3363540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        (*((status_t*)info) == DEAD_OBJECT)) {
33776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        VisualizerJniStorage* lpJniStorage = (VisualizerJniStorage*)user;
3383540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        visualizer_callback_cookie* callbackInfo = &lpJniStorage->mCallbackData;
3393540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        JNIEnv *env = AndroidRuntime::getJNIEnv();
3403540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
3413540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        env->CallStaticVoidMethod(
3423540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            callbackInfo->visualizer_class,
3433540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            fields.midPostNativeEvent,
3443540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            callbackInfo->visualizer_ref,
3453540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            NATIVE_EVENT_SERVER_DIED,
3468bd6a203ca753e9181564221e4faf7703d520b78Haitao Feng            0, 0, NULL);
3473540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    }
3483540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman}
349df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
350df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
351df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
352fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov        jint sessionId, jintArray jId, jstring opPackageName)
353df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
35471f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("android_media_visualizer_native_setup");
35576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    VisualizerJniStorage* lpJniStorage = NULL;
356df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    int lStatus = VISUALIZER_ERROR_NO_MEMORY;
35776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer;
358df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jint* nId = NULL;
359df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
360fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    ScopedUtfChars opPackageNameStr(env, opPackageName);
361fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov
36276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    setVisualizer(env, thiz, 0);
36376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
36476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    lpJniStorage = new VisualizerJniStorage();
365df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpJniStorage == NULL) {
3663762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: Error creating JNI Storage");
367df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto setup_failure;
368df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
369df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
370df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    lpJniStorage->mCallbackData.visualizer_class = (jclass)env->NewGlobalRef(fields.clazzEffect);
371df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // we use a weak reference so the Visualizer object can be garbage collected.
372df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    lpJniStorage->mCallbackData.visualizer_ref = env->NewGlobalRef(weak_this);
373df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
37471f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("setup: lpJniStorage: %p visualizer_ref %p visualizer_class %p, &mCallbackData %p",
375df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            lpJniStorage,
376df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            lpJniStorage->mCallbackData.visualizer_ref,
377df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            lpJniStorage->mCallbackData.visualizer_class,
378df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            &lpJniStorage->mCallbackData);
379df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
3802fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    if (jId == NULL) {
3813762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: NULL java array for id pointer");
382df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        lStatus = VISUALIZER_ERROR_BAD_VALUE;
383df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto setup_failure;
384df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
385df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
386df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // create the native Visualizer object
387fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    lpVisualizer = new Visualizer(String16(opPackageNameStr.c_str()),
388fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov                                  0,
3893540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                                  android_media_visualizer_effect_callback,
3903540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                                  lpJniStorage,
39133b840444f5a481dd31e129079d3c0cf3acdf80eGlenn Kasten                                  (audio_session_t) sessionId);
39276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
3933762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error creating Visualizer");
394df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto setup_failure;
395df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
396df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
397df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    lStatus = translateError(lpVisualizer->initCheck());
398df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lStatus != VISUALIZER_SUCCESS && lStatus != VISUALIZER_ERROR_ALREADY_EXISTS) {
3993762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Visualizer initCheck failed %d", lStatus);
400df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto setup_failure;
401df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
402df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
4032fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
4042fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    if (nId == NULL) {
4053762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: Error retrieving id pointer");
4062fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent        lStatus = VISUALIZER_ERROR_BAD_VALUE;
4072fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent        goto setup_failure;
4082fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    }
409df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    nId[0] = lpVisualizer->id();
410df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->ReleasePrimitiveArrayCritical(jId, nId, 0);
411df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    nId = NULL;
412df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
41376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    setVisualizer(env, thiz, lpVisualizer);
414df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
415ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    env->SetLongField(thiz, fields.fidJniData, (jlong)lpJniStorage);
416df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
417df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return VISUALIZER_SUCCESS;
418df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
419df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // failures:
420df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentsetup_failure:
421df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
422df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (nId != NULL) {
423df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        env->ReleasePrimitiveArrayCritical(jId, nId, 0);
424df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
425df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
426df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpJniStorage) {
42776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_class);
42876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_ref);
429df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        delete lpJniStorage;
430df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
431ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    env->SetLongField(thiz, fields.fidJniData, 0);
432df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
433ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint) lStatus;
434df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
435df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
436df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
43776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic void android_media_visualizer_native_release(JNIEnv *env,  jobject thiz) {
4388dc9afa9666507930f30ec0d11e2dba7db2ae142rago    { //limit scope so that lpVisualizer is deleted before JNI storage data.
4397b9f5be9149dc84cd16842757ee6fe04f3092dc1ganxiaolin        sp<Visualizer> lpVisualizer = setVisualizer(env, thiz, 0);
4407b9f5be9149dc84cd16842757ee6fe04f3092dc1ganxiaolin        if (lpVisualizer == 0) {
4417b9f5be9149dc84cd16842757ee6fe04f3092dc1ganxiaolin            return;
4427b9f5be9149dc84cd16842757ee6fe04f3092dc1ganxiaolin        }
443df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
444df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // delete the JNI data
44576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    VisualizerJniStorage* lpJniStorage =
44676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        (VisualizerJniStorage *)env->GetLongField(thiz, fields.fidJniData);
44776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
44876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    // reset the native resources in the Java object so any attempt to access
44976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    // them after a call to release fails.
45076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    env->SetLongField(thiz, fields.fidJniData, 0);
45176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
452df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpJniStorage) {
453ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        ALOGV("deleting pJniStorage: %p\n", lpJniStorage);
454077999844f306d31d3ea9593b7e7b2f06e7f7483Eric Laurent        env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_class);
455077999844f306d31d3ea9593b7e7b2f06e7f7483Eric Laurent        env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_ref);
456df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        delete lpJniStorage;
457df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
458df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
459df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
46076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic void android_media_visualizer_native_finalize(JNIEnv *env,  jobject thiz) {
46176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    ALOGV("android_media_visualizer_native_finalize jobject: %p\n", thiz);
46276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    android_media_visualizer_native_release(env, thiz);
463df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
464df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
46576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent// ----------------------------------------------------------------------------
466df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
467df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
468df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
46976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
47076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
471df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
472df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
473df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
474449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    jint retVal = translateError(lpVisualizer->setEnabled(enabled));
475449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
476449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    if (!enabled) {
47776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        VisualizerJniStorage* lpJniStorage = (VisualizerJniStorage *)env->GetLongField(
478449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            thiz, fields.fidJniData);
479449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
480449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        if (NULL != lpJniStorage)
481449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            lpJniStorage->mCallbackData.cleanupBuffers();
482449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
483449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
484449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    return retVal;
485df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
486df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
487df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jboolean
488df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getEnabled(JNIEnv *env, jobject thiz)
489df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
49076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
49176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
492ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_FALSE;
493df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
494df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
495ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    if (lpVisualizer->getEnabled()) {
496ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_TRUE;
497ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    } else {
498ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_FALSE;
499ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    }
500df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
501df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
502df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jintArray
5035a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject /* thiz */)
504df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
505df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jintArray jRange = env->NewIntArray(2);
506df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jint *nRange = env->GetIntArrayElements(jRange, NULL);
507df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    nRange[0] = Visualizer::getMinCaptureSize();
508df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    nRange[1] = Visualizer::getMaxCaptureSize();
50971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("getCaptureSizeRange() min %d max %d", nRange[0], nRange[1]);
510df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->ReleaseIntArrayElements(jRange, nRange, 0);
511df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return jRange;
512df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
513df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
514df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
5155a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_visualizer_native_getMaxCaptureRate(JNIEnv* /* env */, jobject /* thiz */)
516df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
517ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint) Visualizer::getMaxCaptureRate();
518df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
519df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
520df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
521df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setCaptureSize(JNIEnv *env, jobject thiz, jint size)
522df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
52376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
52476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
525df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
526df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
527df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
528df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return translateError(lpVisualizer->setCaptureSize(size));
529df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
530df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
531df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
532df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getCaptureSize(JNIEnv *env, jobject thiz)
533df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
53476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
53576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
536df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return -1;
537df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
538ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint) lpVisualizer->getCaptureSize();
539df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
540df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
541df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
542e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Triviandroid_media_visualizer_native_setScalingMode(JNIEnv *env, jobject thiz, jint mode)
543e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi{
54476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
54576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
546e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi        return VISUALIZER_ERROR_NO_INIT;
547e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    }
548e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
549e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    return translateError(lpVisualizer->setScalingMode(mode));
550e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi}
551e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
552e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivistatic jint
553e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Triviandroid_media_visualizer_native_getScalingMode(JNIEnv *env, jobject thiz)
554e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi{
55576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
55676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
557e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi        return -1;
558e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    }
559ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint)lpVisualizer->getScalingMode();
560e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi}
561e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
562e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivistatic jint
563badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Triviandroid_media_visualizer_native_setMeasurementMode(JNIEnv *env, jobject thiz, jint mode)
564badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi{
56576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
56676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
567badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return VISUALIZER_ERROR_NO_INIT;
568badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
569badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    return translateError(lpVisualizer->setMeasurementMode(mode));
570badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi}
571badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi
572badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivistatic jint
573badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Triviandroid_media_visualizer_native_getMeasurementMode(JNIEnv *env, jobject thiz)
574badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi{
57576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
57676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
577badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return MEASUREMENT_MODE_NONE;
578badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
579badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    return lpVisualizer->getMeasurementMode();
580badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi}
581badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi
582badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivistatic jint
583df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getSamplingRate(JNIEnv *env, jobject thiz)
584df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
58576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
58676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
587df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return -1;
588df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
589ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint) lpVisualizer->getSamplingRate();
590df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
591df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
592df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
593df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getWaveForm(JNIEnv *env, jobject thiz, jbyteArray jWaveform)
594df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
59576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
59676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
597df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
598df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
599df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
600df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jbyte* nWaveform = (jbyte *) env->GetPrimitiveArrayCritical(jWaveform, NULL);
601df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (nWaveform == NULL) {
602df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_MEMORY;
603df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
604df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jint status = translateError(lpVisualizer->getWaveForm((uint8_t *)nWaveform));
605df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
606df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->ReleasePrimitiveArrayCritical(jWaveform, nWaveform, 0);
607df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return status;
608df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
609df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
610df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
611df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getFft(JNIEnv *env, jobject thiz, jbyteArray jFft)
612df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
61376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
61476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
615df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
616df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
617df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
618df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jbyte* nFft = (jbyte *) env->GetPrimitiveArrayCritical(jFft, NULL);
619df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (nFft == NULL) {
620df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_MEMORY;
621df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
622df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jint status = translateError(lpVisualizer->getFft((uint8_t *)nFft));
623df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
624df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->ReleasePrimitiveArrayCritical(jFft, nFft, 0);
625df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
626df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return status;
627df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
628df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
629df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
630badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Triviandroid_media_visualizer_native_getPeakRms(JNIEnv *env, jobject thiz, jobject jPeakRmsObj)
631badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi{
63276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
63376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
634badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return VISUALIZER_ERROR_NO_INIT;
635badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
636badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    int32_t measurements[2];
637badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    jint status = translateError(
638badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi                lpVisualizer->getIntMeasurements(MEASUREMENT_MODE_PEAK_RMS,
639badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi                        2, measurements));
640badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (status == VISUALIZER_SUCCESS) {
641badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        // measurement worked, write the values to the java object
642badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        env->SetIntField(jPeakRmsObj, fields.fidPeak, measurements[MEASUREMENT_IDX_PEAK]);
643badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        env->SetIntField(jPeakRmsObj, fields.fidRms, measurements[MEASUREMENT_IDX_RMS]);
644badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
645badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    return status;
646badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi}
647badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi
648badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivistatic jint
649df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_setPeriodicCapture(JNIEnv *env, jobject thiz, jint rate, jboolean jWaveform, jboolean jFft)
650df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
65176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<Visualizer> lpVisualizer = getVisualizer(env, thiz);
65276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpVisualizer == 0) {
653df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
654df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
65576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    VisualizerJniStorage* lpJniStorage = (VisualizerJniStorage *)env->GetLongField(thiz,
656df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fields.fidJniData);
657df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpJniStorage == NULL) {
658df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
659df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
660df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
66171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("setPeriodicCapture: rate %d, jWaveform %d jFft %d",
662df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            rate,
663df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            jWaveform,
664df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            jFft);
665df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
666df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    uint32_t flags = Visualizer::CAPTURE_CALL_JAVA;
667df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (jWaveform) flags |= Visualizer::CAPTURE_WAVEFORM;
668df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (jFft) flags |= Visualizer::CAPTURE_FFT;
669df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer::capture_cbk_t cbk = captureCallback;
670df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (!jWaveform && !jFft) cbk = NULL;
671df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
672df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return translateError(lpVisualizer->setCaptureCallBack(cbk,
673df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                                &lpJniStorage->mCallbackData,
674df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                                flags,
675df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                                rate));
676df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
677df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
678df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
679df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
680df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// Dalvik VM type signatures
68176f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = {
682df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_init",            "()V",     (void *)android_media_visualizer_native_init},
683fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    {"native_setup",           "(Ljava/lang/Object;I[ILjava/lang/String;)I",
684df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                          (void *)android_media_visualizer_native_setup},
685df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_finalize",          "()V",   (void *)android_media_visualizer_native_finalize},
686df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_release",           "()V",   (void *)android_media_visualizer_native_release},
687df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_setEnabled",        "(Z)I",  (void *)android_media_visualizer_native_setEnabled},
688df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getEnabled",        "()Z",   (void *)android_media_visualizer_native_getEnabled},
689df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"getCaptureSizeRange",      "()[I",  (void *)android_media_visualizer_native_getCaptureSizeRange},
690df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"getMaxCaptureRate",        "()I",   (void *)android_media_visualizer_native_getMaxCaptureRate},
691df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_setCaptureSize",    "(I)I",  (void *)android_media_visualizer_native_setCaptureSize},
692df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getCaptureSize",    "()I",   (void *)android_media_visualizer_native_getCaptureSize},
693e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    {"native_setScalingMode",    "(I)I",  (void *)android_media_visualizer_native_setScalingMode},
694e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    {"native_getScalingMode",    "()I",   (void *)android_media_visualizer_native_getScalingMode},
695badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    {"native_setMeasurementMode","(I)I",  (void *)android_media_visualizer_native_setMeasurementMode},
696badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    {"native_getMeasurementMode","()I",   (void *)android_media_visualizer_native_getMeasurementMode},
697df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getSamplingRate",   "()I",   (void *)android_media_visualizer_native_getSamplingRate},
698df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getWaveForm",       "([B)I", (void *)android_media_visualizer_native_getWaveForm},
699df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getFft",            "([B)I", (void *)android_media_visualizer_native_getFft},
700badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    {"native_getPeakRms",      "(Landroid/media/audiofx/Visualizer$MeasurementPeakRms;)I",
701badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi                                          (void *)android_media_visualizer_native_getPeakRms},
702df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_setPeriodicCapture","(IZZ)I",(void *)android_media_setPeriodicCapture},
703df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent};
704df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
705df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
706df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
707df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentint register_android_media_visualizer(JNIEnv *env)
708df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
709df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
710df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
711df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
712