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";
46badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivistatic const char* const kClassPeakRmsPathName =
47badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        "android/media/audiofx/Visualizer$MeasurementPeakRms";
48df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
49df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstruct fields_t {
50df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // these fields provide access from C++ to the...
51df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jclass    clazzEffect;          // Visualizer class
52df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jmethodID midPostNativeEvent;   // event post callback method
53df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jfieldID  fidNativeVisualizer; // stores in Java the native Visualizer object
54df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jfieldID  fidJniData;           // stores in Java additional resources used by the native Visualizer
55badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    jfieldID  fidPeak; // to access Visualizer.MeasurementPeakRms.mPeak
56badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    jfieldID  fidRms;  // to access Visualizer.MeasurementPeakRms.mRms
57df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent};
58df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic fields_t fields;
59df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
60df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstruct visualizer_callback_cookie {
61df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jclass      visualizer_class;  // Visualizer class
62df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jobject     visualizer_ref;    // Visualizer object instance
63449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
64449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // Lazily allocated arrays used to hold callback data provided to java
65449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // applications.  These arrays are allocated during the first callback and
66449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // reallocated when the size of the callback data changes.  Allocating on
67449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // demand and saving the arrays means that applications cannot safely hold a
68449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // reference to the provided data (they need to make a copy if they want to
69449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // hold onto outside of the callback scope), but it avoids GC thrash caused
70449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    // by constantly allocating and releasing arrays to hold callback data.
71449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    Mutex       callback_data_lock;
72449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    jbyteArray  waveform_data;
73449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    jbyteArray  fft_data;
74449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
75449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    visualizer_callback_cookie() {
76449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        waveform_data = NULL;
77449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        fft_data = NULL;
78449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
79449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
80449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    ~visualizer_callback_cookie() {
81449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        cleanupBuffers();
82449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
83449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
84449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    void cleanupBuffers() {
85449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        AutoMutex lock(&callback_data_lock);
86449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        if (waveform_data || fft_data) {
87449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            JNIEnv *env = AndroidRuntime::getJNIEnv();
88449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
89449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            if (waveform_data) {
90449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman                env->DeleteGlobalRef(waveform_data);
91449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman                waveform_data = NULL;
92449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            }
93449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
94449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            if (fft_data) {
95449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman                env->DeleteGlobalRef(fft_data);
96449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman                fft_data = NULL;
97449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            }
98449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        }
99449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
100df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent };
101df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
102df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
103df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentclass visualizerJniStorage {
104df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public:
105df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        visualizer_callback_cookie mCallbackData;
106df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
107df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    visualizerJniStorage() {
108df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
109df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
110df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    ~visualizerJniStorage() {
111df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
112df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent};
113df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
114df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
115df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint translateError(int code) {
116df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    switch(code) {
117df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case NO_ERROR:
118df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_SUCCESS;
119df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case ALREADY_EXISTS:
120df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_ALREADY_EXISTS;
121df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case NO_INIT:
122df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
123df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case BAD_VALUE:
124df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_BAD_VALUE;
125df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case INVALID_OPERATION:
126df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_INVALID_OPERATION;
127df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case NO_MEMORY:
128df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_MEMORY;
129df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    case DEAD_OBJECT:
130df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_DEAD_OBJECT;
131df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    default:
132df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR;
133df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
134df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
135df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
136df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
137df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
138449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossmanstatic void ensureArraySize(JNIEnv *env, jbyteArray *array, uint32_t size) {
139449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    if (NULL != *array) {
140449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        uint32_t len = env->GetArrayLength(*array);
141449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        if (len == size)
142449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            return;
143449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
144449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        env->DeleteGlobalRef(*array);
145449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        *array = NULL;
146449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
147449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
148449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    jbyteArray localRef = env->NewByteArray(size);
149449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    if (NULL != localRef) {
150449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        // Promote to global ref.
151449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        *array = (jbyteArray)env->NewGlobalRef(localRef);
152449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
153449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        // Release our (now pointless) local ref.
154449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        env->DeleteLocalRef(localRef);
155449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
156449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman}
157449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
158df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void captureCallback(void* user,
159df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint32_t waveformSize,
160df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint8_t *waveform,
161df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint32_t fftSize,
162df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint8_t *fft,
163df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        uint32_t samplingrate) {
164df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
165df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    int arg1 = 0;
166df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    int arg2 = 0;
167df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    size_t size;
168df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
169df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    visualizer_callback_cookie *callbackInfo = (visualizer_callback_cookie *)user;
170df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
17167a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen
17267a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen    if (!user || !env) {
17367a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen        ALOGW("captureCallback error user %p, env %p", user, env);
17467a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen        return;
17567a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen    }
176df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
17771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("captureCallback: callbackInfo %p, visualizer_ref %p visualizer_class %p",
178df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            callbackInfo,
179df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            callbackInfo->visualizer_ref,
180df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            callbackInfo->visualizer_class);
181df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
18267a12184776605b6e6ddc01ca91b533a2e37a40bMike J. Chen    AutoMutex lock(&callbackInfo->callback_data_lock);
183df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
184df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (waveformSize != 0 && waveform != NULL) {
185449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        jbyteArray jArray;
186449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
187449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        ensureArraySize(env, &callbackInfo->waveform_data, waveformSize);
188449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        jArray = callbackInfo->waveform_data;
189449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
190df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        if (jArray != NULL) {
191df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
192df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            memcpy(nArray, waveform, waveformSize);
193df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            env->ReleaseByteArrayElements(jArray, nArray, 0);
194df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            env->CallStaticVoidMethod(
195df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                callbackInfo->visualizer_class,
196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                fields.midPostNativeEvent,
197df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                callbackInfo->visualizer_ref,
198df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                NATIVE_EVENT_PCM_CAPTURE,
199df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                samplingrate,
200df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                0,
201df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                jArray);
202df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
203df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
204df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
205df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (fftSize != 0 && fft != NULL) {
206449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        jbyteArray jArray;
207449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
208449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        ensureArraySize(env, &callbackInfo->fft_data, fftSize);
209449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        jArray = callbackInfo->fft_data;
210449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
211df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        if (jArray != NULL) {
212df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
213df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            memcpy(nArray, fft, fftSize);
214df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            env->ReleaseByteArrayElements(jArray, nArray, 0);
215df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            env->CallStaticVoidMethod(
216df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                callbackInfo->visualizer_class,
217df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                fields.midPostNativeEvent,
218df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                callbackInfo->visualizer_ref,
219df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                NATIVE_EVENT_FFT_CAPTURE,
220df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                samplingrate,
221df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                0,
222df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                jArray);
223df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
224df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
225df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
226df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (env->ExceptionCheck()) {
227df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        env->ExceptionDescribe();
228df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        env->ExceptionClear();
229df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
230df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
231df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
232df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic Visualizer *getVisualizer(JNIEnv* env, jobject thiz)
233df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
234df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer *v = (Visualizer *)env->GetIntField(
235df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        thiz, fields.fidNativeVisualizer);
236df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (v == NULL) {
237df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        jniThrowException(env, "java/lang/IllegalStateException",
238df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            "Unable to retrieve Visualizer pointer");
239df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
240df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return v;
241df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
242df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
243df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
244df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// This function gets some field IDs, which in turn causes class initialization.
245df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// It is called from a static block in Visualizer, which won't run until the
246df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// first time an instance of this class is used.
247df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void
248df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_init(JNIEnv *env)
249df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
250df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
25171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("android_media_visualizer_native_init");
252df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
253df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.clazzEffect = NULL;
254df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
255df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Get the Visualizer class
256df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jclass clazz = env->FindClass(kClassPathName);
257df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (clazz == NULL) {
2583762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find %s", kClassPathName);
259df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return;
260df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
261df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
262df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.clazzEffect = (jclass)env->NewGlobalRef(clazz);
263df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
264badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    // Get the Visualizer.MeasurementPeakRms class
265badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    clazz = env->FindClass(kClassPeakRmsPathName);
266badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (clazz == NULL) {
267badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        ALOGE("Can't find %s", kClassPeakRmsPathName);
268badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return;
269badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
270badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    jclass clazzMeasurementPeakRms = (jclass)env->NewGlobalRef(clazz);
271badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi
272df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Get the postEvent method
273df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.midPostNativeEvent = env->GetStaticMethodID(
274df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fields.clazzEffect,
275df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");
276df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (fields.midPostNativeEvent == NULL) {
2773762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find Visualizer.%s", "postEventFromNative");
278df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return;
279df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
280df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
281df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Get the variables fields
282df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //      nativeTrackInJavaObj
283df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.fidNativeVisualizer = env->GetFieldID(
284df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fields.clazzEffect,
285df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            "mNativeVisualizer", "I");
286df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (fields.fidNativeVisualizer == NULL) {
2873762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find Visualizer.%s", "mNativeVisualizer");
288df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return;
289df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
290df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //      fidJniData;
291df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    fields.fidJniData = env->GetFieldID(
292df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fields.clazzEffect,
293df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            "mJniData", "I");
294df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (fields.fidJniData == NULL) {
2953762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find Visualizer.%s", "mJniData");
296df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return;
297df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
298badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    //      fidPeak
299badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    fields.fidPeak = env->GetFieldID(
300badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi            clazzMeasurementPeakRms,
301badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi            "mPeak", "I");
302badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (fields.fidPeak == NULL) {
303badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        ALOGE("Can't find Visualizer.MeasurementPeakRms.%s", "mPeak");
304badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return;
305badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
306badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    //      fidRms
307badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    fields.fidRms = env->GetFieldID(
308badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi            clazzMeasurementPeakRms,
309badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi            "mRms", "I");
310badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (fields.fidRms == NULL) {
311badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        ALOGE("Can't find Visualizer.MeasurementPeakRms.%s", "mPeak");
312badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return;
313badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
314df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
315badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    env->DeleteGlobalRef(clazzMeasurementPeakRms);
316df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
317df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
3183540a0197f56c4bcd7d7419f4502bfca34257de2John Grossmanstatic void android_media_visualizer_effect_callback(int32_t event,
3193540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                                                     void *user,
3203540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                                                     void *info) {
3213540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    if ((event == AudioEffect::EVENT_ERROR) &&
3223540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        (*((status_t*)info) == DEAD_OBJECT)) {
3233540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        visualizerJniStorage* lpJniStorage = (visualizerJniStorage*)user;
3243540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        visualizer_callback_cookie* callbackInfo = &lpJniStorage->mCallbackData;
3253540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        JNIEnv *env = AndroidRuntime::getJNIEnv();
3263540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
3273540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        env->CallStaticVoidMethod(
3283540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            callbackInfo->visualizer_class,
3293540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            fields.midPostNativeEvent,
3303540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            callbackInfo->visualizer_ref,
3313540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            NATIVE_EVENT_SERVER_DIED,
3323540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            0, 0, 0);
3333540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    }
3343540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman}
335df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
336df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
337df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
338df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        jint sessionId, jintArray jId)
339df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
34071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("android_media_visualizer_native_setup");
341df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    visualizerJniStorage* lpJniStorage = NULL;
342df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    int lStatus = VISUALIZER_ERROR_NO_MEMORY;
343df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = NULL;
344df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jint* nId = NULL;
345df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
346df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    lpJniStorage = new visualizerJniStorage();
347df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpJniStorage == NULL) {
3483762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: Error creating JNI Storage");
349df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto setup_failure;
350df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
351df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
352df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    lpJniStorage->mCallbackData.visualizer_class = (jclass)env->NewGlobalRef(fields.clazzEffect);
353df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // we use a weak reference so the Visualizer object can be garbage collected.
354df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    lpJniStorage->mCallbackData.visualizer_ref = env->NewGlobalRef(weak_this);
355df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
35671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("setup: lpJniStorage: %p visualizer_ref %p visualizer_class %p, &mCallbackData %p",
357df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            lpJniStorage,
358df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            lpJniStorage->mCallbackData.visualizer_ref,
359df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            lpJniStorage->mCallbackData.visualizer_class,
360df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            &lpJniStorage->mCallbackData);
361df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
3622fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    if (jId == NULL) {
3633762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: NULL java array for id pointer");
364df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        lStatus = VISUALIZER_ERROR_BAD_VALUE;
365df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto setup_failure;
366df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
367df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
368df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // create the native Visualizer object
369df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    lpVisualizer = new Visualizer(0,
3703540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                                  android_media_visualizer_effect_callback,
3713540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                                  lpJniStorage,
372df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                  sessionId);
373df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
3743762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error creating Visualizer");
375df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto setup_failure;
376df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
377df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
378df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    lStatus = translateError(lpVisualizer->initCheck());
379df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lStatus != VISUALIZER_SUCCESS && lStatus != VISUALIZER_ERROR_ALREADY_EXISTS) {
3803762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Visualizer initCheck failed %d", lStatus);
381df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto setup_failure;
382df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
383df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
3842fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
3852fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    if (nId == NULL) {
3863762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: Error retrieving id pointer");
3872fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent        lStatus = VISUALIZER_ERROR_BAD_VALUE;
3882fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent        goto setup_failure;
3892fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    }
390df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    nId[0] = lpVisualizer->id();
391df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->ReleasePrimitiveArrayCritical(jId, nId, 0);
392df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    nId = NULL;
393df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
394df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->SetIntField(thiz, fields.fidNativeVisualizer, (int)lpVisualizer);
395df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
396df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->SetIntField(thiz, fields.fidJniData, (int)lpJniStorage);
397df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
398df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return VISUALIZER_SUCCESS;
399df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
400df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // failures:
401df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentsetup_failure:
402df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
403df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (nId != NULL) {
404df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        env->ReleasePrimitiveArrayCritical(jId, nId, 0);
405df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
406df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
407df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer) {
408df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        delete lpVisualizer;
409df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
410df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->SetIntField(thiz, fields.fidNativeVisualizer, 0);
411df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
412df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpJniStorage) {
413df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        delete lpJniStorage;
414df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
415df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->SetIntField(thiz, fields.fidJniData, 0);
416df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
417df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return lStatus;
418df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
419df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
420df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
421df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void android_media_visualizer_native_finalize(JNIEnv *env,  jobject thiz) {
42271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("android_media_visualizer_native_finalize jobject: %x\n", (int)thiz);
423df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
424df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // delete the Visualizer object
425df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = (Visualizer *)env->GetIntField(
426df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        thiz, fields.fidNativeVisualizer);
427df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer) {
42871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("deleting Visualizer: %x\n", (int)lpVisualizer);
429df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        delete lpVisualizer;
430df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
431df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
432df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // delete the JNI data
433df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField(
434df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        thiz, fields.fidJniData);
435df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpJniStorage) {
43671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("deleting pJniStorage: %x\n", (int)lpJniStorage);
437df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        delete lpJniStorage;
438df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
439df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
440df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
441df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
442df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic void android_media_visualizer_native_release(JNIEnv *env,  jobject thiz) {
443df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
444df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // do everything a call to finalize would
445df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    android_media_visualizer_native_finalize(env, thiz);
446df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // + reset the native resources in the Java object so any attempt to access
447df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // them after a call to release fails.
448df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->SetIntField(thiz, fields.fidNativeVisualizer, 0);
449df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->SetIntField(thiz, fields.fidJniData, 0);
450df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
451df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
452df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
453df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
454df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
455df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = getVisualizer(env, thiz);
456df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
457df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
458df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
459df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
460449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    jint retVal = translateError(lpVisualizer->setEnabled(enabled));
461449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
462449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    if (!enabled) {
463449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField(
464449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            thiz, fields.fidJniData);
465449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
466449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman        if (NULL != lpJniStorage)
467449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman            lpJniStorage->mCallbackData.cleanupBuffers();
468449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    }
469449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman
470449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman    return retVal;
471df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
472df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
473df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jboolean
474df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getEnabled(JNIEnv *env, jobject thiz)
475df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
476df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = getVisualizer(env, thiz);
477df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
478df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return false;
479df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
480df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
481df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return (jboolean)lpVisualizer->getEnabled();
482df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
483df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
484df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jintArray
485df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject thiz)
486df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
487df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jintArray jRange = env->NewIntArray(2);
488df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jint *nRange = env->GetIntArrayElements(jRange, NULL);
489df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    nRange[0] = Visualizer::getMinCaptureSize();
490df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    nRange[1] = Visualizer::getMaxCaptureSize();
49171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("getCaptureSizeRange() min %d max %d", nRange[0], nRange[1]);
492df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->ReleaseIntArrayElements(jRange, nRange, 0);
493df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return jRange;
494df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
495df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
496df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
497df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getMaxCaptureRate(JNIEnv *env, jobject thiz)
498df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
499df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return Visualizer::getMaxCaptureRate();
500df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
501df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
502df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
503df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_setCaptureSize(JNIEnv *env, jobject thiz, jint size)
504df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
505df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = getVisualizer(env, thiz);
506df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
507df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
508df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
509df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
510df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return translateError(lpVisualizer->setCaptureSize(size));
511df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
512df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
513df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
514df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getCaptureSize(JNIEnv *env, jobject thiz)
515df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
516df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = getVisualizer(env, thiz);
517df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
518df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return -1;
519df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
520df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return lpVisualizer->getCaptureSize();
521df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
522df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
523df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
524e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Triviandroid_media_visualizer_native_setScalingMode(JNIEnv *env, jobject thiz, jint mode)
525e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi{
526e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    Visualizer* lpVisualizer = getVisualizer(env, thiz);
527e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    if (lpVisualizer == NULL) {
528e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi        return VISUALIZER_ERROR_NO_INIT;
529e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    }
530e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
531e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    return translateError(lpVisualizer->setScalingMode(mode));
532e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi}
533e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
534e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivistatic jint
535e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Triviandroid_media_visualizer_native_getScalingMode(JNIEnv *env, jobject thiz)
536e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi{
537e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    Visualizer* lpVisualizer = getVisualizer(env, thiz);
538e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    if (lpVisualizer == NULL) {
539e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi        return -1;
540e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    }
541e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    return lpVisualizer->getScalingMode();
542e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi}
543e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
544e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivistatic jint
545badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Triviandroid_media_visualizer_native_setMeasurementMode(JNIEnv *env, jobject thiz, jint mode)
546badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi{
547badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    Visualizer* lpVisualizer = getVisualizer(env, thiz);
548badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (lpVisualizer == NULL) {
549badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return VISUALIZER_ERROR_NO_INIT;
550badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
551badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    return translateError(lpVisualizer->setMeasurementMode(mode));
552badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi}
553badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi
554badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivistatic jint
555badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Triviandroid_media_visualizer_native_getMeasurementMode(JNIEnv *env, jobject thiz)
556badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi{
557badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    Visualizer* lpVisualizer = getVisualizer(env, thiz);
558badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (lpVisualizer == NULL) {
559badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return MEASUREMENT_MODE_NONE;
560badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
561badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    return lpVisualizer->getMeasurementMode();
562badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi}
563badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi
564badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivistatic jint
565df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getSamplingRate(JNIEnv *env, jobject thiz)
566df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
567df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = getVisualizer(env, thiz);
568df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
569df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return -1;
570df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
571df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return lpVisualizer->getSamplingRate();
572df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
573df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
574df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
575df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getWaveForm(JNIEnv *env, jobject thiz, jbyteArray jWaveform)
576df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
577df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = getVisualizer(env, thiz);
578df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
579df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
580df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
581df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
582df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jbyte* nWaveform = (jbyte *) env->GetPrimitiveArrayCritical(jWaveform, NULL);
583df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (nWaveform == NULL) {
584df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_MEMORY;
585df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
586df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jint status = translateError(lpVisualizer->getWaveForm((uint8_t *)nWaveform));
587df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
588df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->ReleasePrimitiveArrayCritical(jWaveform, nWaveform, 0);
589df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return status;
590df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
591df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
592df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
593df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_visualizer_native_getFft(JNIEnv *env, jobject thiz, jbyteArray jFft)
594df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
595df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = getVisualizer(env, thiz);
596df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
597df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
598df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
599df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
600df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jbyte* nFft = (jbyte *) env->GetPrimitiveArrayCritical(jFft, NULL);
601df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (nFft == NULL) {
602df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_MEMORY;
603df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
604df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    jint status = translateError(lpVisualizer->getFft((uint8_t *)nFft));
605df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
606df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    env->ReleasePrimitiveArrayCritical(jFft, nFft, 0);
607df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
608df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return status;
609df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
610df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
611df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic jint
612badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Triviandroid_media_visualizer_native_getPeakRms(JNIEnv *env, jobject thiz, jobject jPeakRmsObj)
613badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi{
614badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    Visualizer* lpVisualizer = getVisualizer(env, thiz);
615badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (lpVisualizer == NULL) {
616badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        return VISUALIZER_ERROR_NO_INIT;
617badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
618badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    int32_t measurements[2];
619badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    jint status = translateError(
620badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi                lpVisualizer->getIntMeasurements(MEASUREMENT_MODE_PEAK_RMS,
621badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi                        2, measurements));
622badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    if (status == VISUALIZER_SUCCESS) {
623badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        // measurement worked, write the values to the java object
624badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        env->SetIntField(jPeakRmsObj, fields.fidPeak, measurements[MEASUREMENT_IDX_PEAK]);
625badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi        env->SetIntField(jPeakRmsObj, fields.fidRms, measurements[MEASUREMENT_IDX_RMS]);
626badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    }
627badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    return status;
628badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi}
629badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi
630badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivistatic jint
631df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_setPeriodicCapture(JNIEnv *env, jobject thiz, jint rate, jboolean jWaveform, jboolean jFft)
632df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
633df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer* lpVisualizer = getVisualizer(env, thiz);
634df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpVisualizer == NULL) {
635df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
636df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
637df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField(thiz,
638df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fields.fidJniData);
639df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (lpJniStorage == NULL) {
640df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return VISUALIZER_ERROR_NO_INIT;
641df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
642df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
64371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("setPeriodicCapture: rate %d, jWaveform %d jFft %d",
644df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            rate,
645df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            jWaveform,
646df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            jFft);
647df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
648df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    uint32_t flags = Visualizer::CAPTURE_CALL_JAVA;
649df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (jWaveform) flags |= Visualizer::CAPTURE_WAVEFORM;
650df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (jFft) flags |= Visualizer::CAPTURE_FFT;
651df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    Visualizer::capture_cbk_t cbk = captureCallback;
652df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (!jWaveform && !jFft) cbk = NULL;
653df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
654df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return translateError(lpVisualizer->setCaptureCallBack(cbk,
655df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                                &lpJniStorage->mCallbackData,
656df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                                flags,
657df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                                rate));
658df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
659df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
660df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
661df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
662df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// Dalvik VM type signatures
663df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentstatic JNINativeMethod gMethods[] = {
664df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_init",            "()V",     (void *)android_media_visualizer_native_init},
665df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_setup",           "(Ljava/lang/Object;I[I)I",
666df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                          (void *)android_media_visualizer_native_setup},
667df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_finalize",          "()V",   (void *)android_media_visualizer_native_finalize},
668df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_release",           "()V",   (void *)android_media_visualizer_native_release},
669df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_setEnabled",        "(Z)I",  (void *)android_media_visualizer_native_setEnabled},
670df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getEnabled",        "()Z",   (void *)android_media_visualizer_native_getEnabled},
671df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"getCaptureSizeRange",      "()[I",  (void *)android_media_visualizer_native_getCaptureSizeRange},
672df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"getMaxCaptureRate",        "()I",   (void *)android_media_visualizer_native_getMaxCaptureRate},
673df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_setCaptureSize",    "(I)I",  (void *)android_media_visualizer_native_setCaptureSize},
674df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getCaptureSize",    "()I",   (void *)android_media_visualizer_native_getCaptureSize},
675e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    {"native_setScalingMode",    "(I)I",  (void *)android_media_visualizer_native_setScalingMode},
676e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    {"native_getScalingMode",    "()I",   (void *)android_media_visualizer_native_getScalingMode},
677badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    {"native_setMeasurementMode","(I)I",  (void *)android_media_visualizer_native_setMeasurementMode},
678badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    {"native_getMeasurementMode","()I",   (void *)android_media_visualizer_native_getMeasurementMode},
679df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getSamplingRate",   "()I",   (void *)android_media_visualizer_native_getSamplingRate},
680df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getWaveForm",       "([B)I", (void *)android_media_visualizer_native_getWaveForm},
681df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getFft",            "([B)I", (void *)android_media_visualizer_native_getFft},
682badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi    {"native_getPeakRms",      "(Landroid/media/audiofx/Visualizer$MeasurementPeakRms;)I",
683badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi                                          (void *)android_media_visualizer_native_getPeakRms},
684df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_setPeriodicCapture","(IZZ)I",(void *)android_media_setPeriodicCapture},
685df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent};
686df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
687df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent// ----------------------------------------------------------------------------
688df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
689df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentint register_android_media_visualizer(JNIEnv *env)
690df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent{
691df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
692df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
693df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
694