blob: f015afbaf20948876569e54be384241c544299a9 [file] [log] [blame]
Eric Laurentdf9b81c2010-07-02 08:12:41 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18
19//#define LOG_NDEBUG 0
20#define LOG_TAG "visualizers-JNI"
21
22#include <utils/Log.h>
23#include <nativehelper/jni.h>
24#include <nativehelper/JNIHelp.h>
25#include <android_runtime/AndroidRuntime.h>
John Grossman449725f2012-01-10 12:17:03 -080026#include <utils/threads.h>
Eric Laurentdf9b81c2010-07-02 08:12:41 -070027#include "media/Visualizer.h"
28
29using namespace android;
30
31#define VISUALIZER_SUCCESS 0
32#define VISUALIZER_ERROR -1
33#define VISUALIZER_ERROR_ALREADY_EXISTS -2
34#define VISUALIZER_ERROR_NO_INIT -3
35#define VISUALIZER_ERROR_BAD_VALUE -4
36#define VISUALIZER_ERROR_INVALID_OPERATION -5
37#define VISUALIZER_ERROR_NO_MEMORY -6
38#define VISUALIZER_ERROR_DEAD_OBJECT -7
39
40#define NATIVE_EVENT_PCM_CAPTURE 0
41#define NATIVE_EVENT_FFT_CAPTURE 1
John Grossman3540a012012-01-11 12:23:42 -080042#define NATIVE_EVENT_SERVER_DIED 2
Eric Laurentdf9b81c2010-07-02 08:12:41 -070043
44// ----------------------------------------------------------------------------
Eric Laurent1a5149e2010-09-21 18:18:20 -070045static const char* const kClassPathName = "android/media/audiofx/Visualizer";
Eric Laurentdf9b81c2010-07-02 08:12:41 -070046
47struct fields_t {
48 // these fields provide access from C++ to the...
49 jclass clazzEffect; // Visualizer class
50 jmethodID midPostNativeEvent; // event post callback method
51 jfieldID fidNativeVisualizer; // stores in Java the native Visualizer object
52 jfieldID fidJniData; // stores in Java additional resources used by the native Visualizer
53};
54static fields_t fields;
55
56struct visualizer_callback_cookie {
57 jclass visualizer_class; // Visualizer class
58 jobject visualizer_ref; // Visualizer object instance
John Grossman449725f2012-01-10 12:17:03 -080059
60 // Lazily allocated arrays used to hold callback data provided to java
61 // applications. These arrays are allocated during the first callback and
62 // reallocated when the size of the callback data changes. Allocating on
63 // demand and saving the arrays means that applications cannot safely hold a
64 // reference to the provided data (they need to make a copy if they want to
65 // hold onto outside of the callback scope), but it avoids GC thrash caused
66 // by constantly allocating and releasing arrays to hold callback data.
67 Mutex callback_data_lock;
68 jbyteArray waveform_data;
69 jbyteArray fft_data;
70
71 visualizer_callback_cookie() {
72 waveform_data = NULL;
73 fft_data = NULL;
74 }
75
76 ~visualizer_callback_cookie() {
77 cleanupBuffers();
78 }
79
80 void cleanupBuffers() {
81 AutoMutex lock(&callback_data_lock);
82 if (waveform_data || fft_data) {
83 JNIEnv *env = AndroidRuntime::getJNIEnv();
84
85 if (waveform_data) {
86 env->DeleteGlobalRef(waveform_data);
87 waveform_data = NULL;
88 }
89
90 if (fft_data) {
91 env->DeleteGlobalRef(fft_data);
92 fft_data = NULL;
93 }
94 }
95 }
Eric Laurentdf9b81c2010-07-02 08:12:41 -070096 };
97
98// ----------------------------------------------------------------------------
99class visualizerJniStorage {
100 public:
101 visualizer_callback_cookie mCallbackData;
102
103 visualizerJniStorage() {
104 }
105
106 ~visualizerJniStorage() {
107 }
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700108};
109
110
111static jint translateError(int code) {
112 switch(code) {
113 case NO_ERROR:
114 return VISUALIZER_SUCCESS;
115 case ALREADY_EXISTS:
116 return VISUALIZER_ERROR_ALREADY_EXISTS;
117 case NO_INIT:
118 return VISUALIZER_ERROR_NO_INIT;
119 case BAD_VALUE:
120 return VISUALIZER_ERROR_BAD_VALUE;
121 case INVALID_OPERATION:
122 return VISUALIZER_ERROR_INVALID_OPERATION;
123 case NO_MEMORY:
124 return VISUALIZER_ERROR_NO_MEMORY;
125 case DEAD_OBJECT:
126 return VISUALIZER_ERROR_DEAD_OBJECT;
127 default:
128 return VISUALIZER_ERROR;
129 }
130}
131
132
133// ----------------------------------------------------------------------------
John Grossman449725f2012-01-10 12:17:03 -0800134static void ensureArraySize(JNIEnv *env, jbyteArray *array, uint32_t size) {
135 if (NULL != *array) {
136 uint32_t len = env->GetArrayLength(*array);
137 if (len == size)
138 return;
139
140 env->DeleteGlobalRef(*array);
141 *array = NULL;
142 }
143
144 jbyteArray localRef = env->NewByteArray(size);
145 if (NULL != localRef) {
146 // Promote to global ref.
147 *array = (jbyteArray)env->NewGlobalRef(localRef);
148
149 // Release our (now pointless) local ref.
150 env->DeleteLocalRef(localRef);
151 }
152}
153
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700154static void captureCallback(void* user,
155 uint32_t waveformSize,
156 uint8_t *waveform,
157 uint32_t fftSize,
158 uint8_t *fft,
159 uint32_t samplingrate) {
160
161 int arg1 = 0;
162 int arg2 = 0;
163 size_t size;
164
165 visualizer_callback_cookie *callbackInfo = (visualizer_callback_cookie *)user;
166 JNIEnv *env = AndroidRuntime::getJNIEnv();
John Grossman449725f2012-01-10 12:17:03 -0800167 AutoMutex lock(&callbackInfo->callback_data_lock);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700168
Steve Block71f2cf12011-10-20 11:56:00 +0100169 ALOGV("captureCallback: callbackInfo %p, visualizer_ref %p visualizer_class %p",
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700170 callbackInfo,
171 callbackInfo->visualizer_ref,
172 callbackInfo->visualizer_class);
173
174 if (!user || !env) {
Steve Block8564c8d2012-01-05 23:22:43 +0000175 ALOGW("captureCallback error user %p, env %p", user, env);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700176 return;
177 }
178
179 if (waveformSize != 0 && waveform != NULL) {
John Grossman449725f2012-01-10 12:17:03 -0800180 jbyteArray jArray;
181
182 ensureArraySize(env, &callbackInfo->waveform_data, waveformSize);
183 jArray = callbackInfo->waveform_data;
184
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700185 if (jArray != NULL) {
186 jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
187 memcpy(nArray, waveform, waveformSize);
188 env->ReleaseByteArrayElements(jArray, nArray, 0);
189 env->CallStaticVoidMethod(
190 callbackInfo->visualizer_class,
191 fields.midPostNativeEvent,
192 callbackInfo->visualizer_ref,
193 NATIVE_EVENT_PCM_CAPTURE,
194 samplingrate,
195 0,
196 jArray);
197 }
198 }
199
200 if (fftSize != 0 && fft != NULL) {
John Grossman449725f2012-01-10 12:17:03 -0800201 jbyteArray jArray;
202
203 ensureArraySize(env, &callbackInfo->fft_data, fftSize);
204 jArray = callbackInfo->fft_data;
205
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700206 if (jArray != NULL) {
207 jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
208 memcpy(nArray, fft, fftSize);
209 env->ReleaseByteArrayElements(jArray, nArray, 0);
210 env->CallStaticVoidMethod(
211 callbackInfo->visualizer_class,
212 fields.midPostNativeEvent,
213 callbackInfo->visualizer_ref,
214 NATIVE_EVENT_FFT_CAPTURE,
215 samplingrate,
216 0,
217 jArray);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700218 }
219 }
220
221 if (env->ExceptionCheck()) {
222 env->ExceptionDescribe();
223 env->ExceptionClear();
224 }
225}
226
227static Visualizer *getVisualizer(JNIEnv* env, jobject thiz)
228{
229 Visualizer *v = (Visualizer *)env->GetIntField(
230 thiz, fields.fidNativeVisualizer);
231 if (v == NULL) {
232 jniThrowException(env, "java/lang/IllegalStateException",
233 "Unable to retrieve Visualizer pointer");
234 }
235 return v;
236}
237
238// ----------------------------------------------------------------------------
239// This function gets some field IDs, which in turn causes class initialization.
240// It is called from a static block in Visualizer, which won't run until the
241// first time an instance of this class is used.
242static void
243android_media_visualizer_native_init(JNIEnv *env)
244{
245
Steve Block71f2cf12011-10-20 11:56:00 +0100246 ALOGV("android_media_visualizer_native_init");
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700247
248 fields.clazzEffect = NULL;
249
250 // Get the Visualizer class
251 jclass clazz = env->FindClass(kClassPathName);
252 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000253 ALOGE("Can't find %s", kClassPathName);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700254 return;
255 }
256
257 fields.clazzEffect = (jclass)env->NewGlobalRef(clazz);
258
259 // Get the postEvent method
260 fields.midPostNativeEvent = env->GetStaticMethodID(
261 fields.clazzEffect,
262 "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");
263 if (fields.midPostNativeEvent == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000264 ALOGE("Can't find Visualizer.%s", "postEventFromNative");
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700265 return;
266 }
267
268 // Get the variables fields
269 // nativeTrackInJavaObj
270 fields.fidNativeVisualizer = env->GetFieldID(
271 fields.clazzEffect,
272 "mNativeVisualizer", "I");
273 if (fields.fidNativeVisualizer == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000274 ALOGE("Can't find Visualizer.%s", "mNativeVisualizer");
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700275 return;
276 }
277 // fidJniData;
278 fields.fidJniData = env->GetFieldID(
279 fields.clazzEffect,
280 "mJniData", "I");
281 if (fields.fidJniData == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000282 ALOGE("Can't find Visualizer.%s", "mJniData");
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700283 return;
284 }
285
286}
287
John Grossman3540a012012-01-11 12:23:42 -0800288static void android_media_visualizer_effect_callback(int32_t event,
289 void *user,
290 void *info) {
291 if ((event == AudioEffect::EVENT_ERROR) &&
292 (*((status_t*)info) == DEAD_OBJECT)) {
293 visualizerJniStorage* lpJniStorage = (visualizerJniStorage*)user;
294 visualizer_callback_cookie* callbackInfo = &lpJniStorage->mCallbackData;
295 JNIEnv *env = AndroidRuntime::getJNIEnv();
296
297 env->CallStaticVoidMethod(
298 callbackInfo->visualizer_class,
299 fields.midPostNativeEvent,
300 callbackInfo->visualizer_ref,
301 NATIVE_EVENT_SERVER_DIED,
302 0, 0, 0);
303 }
304}
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700305
306static jint
307android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
308 jint sessionId, jintArray jId)
309{
Steve Block71f2cf12011-10-20 11:56:00 +0100310 ALOGV("android_media_visualizer_native_setup");
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700311 visualizerJniStorage* lpJniStorage = NULL;
312 int lStatus = VISUALIZER_ERROR_NO_MEMORY;
313 Visualizer* lpVisualizer = NULL;
314 jint* nId = NULL;
315
316 lpJniStorage = new visualizerJniStorage();
317 if (lpJniStorage == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000318 ALOGE("setup: Error creating JNI Storage");
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700319 goto setup_failure;
320 }
321
322 lpJniStorage->mCallbackData.visualizer_class = (jclass)env->NewGlobalRef(fields.clazzEffect);
323 // we use a weak reference so the Visualizer object can be garbage collected.
324 lpJniStorage->mCallbackData.visualizer_ref = env->NewGlobalRef(weak_this);
325
Steve Block71f2cf12011-10-20 11:56:00 +0100326 ALOGV("setup: lpJniStorage: %p visualizer_ref %p visualizer_class %p, &mCallbackData %p",
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700327 lpJniStorage,
328 lpJniStorage->mCallbackData.visualizer_ref,
329 lpJniStorage->mCallbackData.visualizer_class,
330 &lpJniStorage->mCallbackData);
331
Eric Laurent2fb43ef2010-09-24 12:03:36 -0700332 if (jId == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000333 ALOGE("setup: NULL java array for id pointer");
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700334 lStatus = VISUALIZER_ERROR_BAD_VALUE;
335 goto setup_failure;
336 }
337
338 // create the native Visualizer object
339 lpVisualizer = new Visualizer(0,
John Grossman3540a012012-01-11 12:23:42 -0800340 android_media_visualizer_effect_callback,
341 lpJniStorage,
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700342 sessionId);
343 if (lpVisualizer == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000344 ALOGE("Error creating Visualizer");
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700345 goto setup_failure;
346 }
347
348 lStatus = translateError(lpVisualizer->initCheck());
349 if (lStatus != VISUALIZER_SUCCESS && lStatus != VISUALIZER_ERROR_ALREADY_EXISTS) {
Steve Block3762c312012-01-06 19:20:56 +0000350 ALOGE("Visualizer initCheck failed %d", lStatus);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700351 goto setup_failure;
352 }
353
Eric Laurent2fb43ef2010-09-24 12:03:36 -0700354 nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
355 if (nId == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000356 ALOGE("setup: Error retrieving id pointer");
Eric Laurent2fb43ef2010-09-24 12:03:36 -0700357 lStatus = VISUALIZER_ERROR_BAD_VALUE;
358 goto setup_failure;
359 }
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700360 nId[0] = lpVisualizer->id();
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700361 env->ReleasePrimitiveArrayCritical(jId, nId, 0);
362 nId = NULL;
363
364 env->SetIntField(thiz, fields.fidNativeVisualizer, (int)lpVisualizer);
365
366 env->SetIntField(thiz, fields.fidJniData, (int)lpJniStorage);
367
368 return VISUALIZER_SUCCESS;
369
370 // failures:
371setup_failure:
372
373 if (nId != NULL) {
374 env->ReleasePrimitiveArrayCritical(jId, nId, 0);
375 }
376
377 if (lpVisualizer) {
378 delete lpVisualizer;
379 }
380 env->SetIntField(thiz, fields.fidNativeVisualizer, 0);
381
382 if (lpJniStorage) {
383 delete lpJniStorage;
384 }
385 env->SetIntField(thiz, fields.fidJniData, 0);
386
387 return lStatus;
388}
389
390// ----------------------------------------------------------------------------
391static void android_media_visualizer_native_finalize(JNIEnv *env, jobject thiz) {
Steve Block71f2cf12011-10-20 11:56:00 +0100392 ALOGV("android_media_visualizer_native_finalize jobject: %x\n", (int)thiz);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700393
394 // delete the Visualizer object
395 Visualizer* lpVisualizer = (Visualizer *)env->GetIntField(
396 thiz, fields.fidNativeVisualizer);
397 if (lpVisualizer) {
Steve Block71f2cf12011-10-20 11:56:00 +0100398 ALOGV("deleting Visualizer: %x\n", (int)lpVisualizer);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700399 delete lpVisualizer;
400 }
401
402 // delete the JNI data
403 visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField(
404 thiz, fields.fidJniData);
405 if (lpJniStorage) {
Steve Block71f2cf12011-10-20 11:56:00 +0100406 ALOGV("deleting pJniStorage: %x\n", (int)lpJniStorage);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700407 delete lpJniStorage;
408 }
409}
410
411// ----------------------------------------------------------------------------
412static void android_media_visualizer_native_release(JNIEnv *env, jobject thiz) {
413
414 // do everything a call to finalize would
415 android_media_visualizer_native_finalize(env, thiz);
416 // + reset the native resources in the Java object so any attempt to access
417 // them after a call to release fails.
418 env->SetIntField(thiz, fields.fidNativeVisualizer, 0);
419 env->SetIntField(thiz, fields.fidJniData, 0);
420}
421
422static jint
423android_media_visualizer_native_setEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
424{
425 Visualizer* lpVisualizer = getVisualizer(env, thiz);
426 if (lpVisualizer == NULL) {
427 return VISUALIZER_ERROR_NO_INIT;
428 }
429
John Grossman449725f2012-01-10 12:17:03 -0800430 jint retVal = translateError(lpVisualizer->setEnabled(enabled));
431
432 if (!enabled) {
433 visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField(
434 thiz, fields.fidJniData);
435
436 if (NULL != lpJniStorage)
437 lpJniStorage->mCallbackData.cleanupBuffers();
438 }
439
440 return retVal;
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700441}
442
443static jboolean
444android_media_visualizer_native_getEnabled(JNIEnv *env, jobject thiz)
445{
446 Visualizer* lpVisualizer = getVisualizer(env, thiz);
447 if (lpVisualizer == NULL) {
448 return false;
449 }
450
451 return (jboolean)lpVisualizer->getEnabled();
452}
453
454static jintArray
455android_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject thiz)
456{
457 jintArray jRange = env->NewIntArray(2);
458 jint *nRange = env->GetIntArrayElements(jRange, NULL);
459 nRange[0] = Visualizer::getMinCaptureSize();
460 nRange[1] = Visualizer::getMaxCaptureSize();
Steve Block71f2cf12011-10-20 11:56:00 +0100461 ALOGV("getCaptureSizeRange() min %d max %d", nRange[0], nRange[1]);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700462 env->ReleaseIntArrayElements(jRange, nRange, 0);
463 return jRange;
464}
465
466static jint
467android_media_visualizer_native_getMaxCaptureRate(JNIEnv *env, jobject thiz)
468{
469 return Visualizer::getMaxCaptureRate();
470}
471
472static jint
473android_media_visualizer_native_setCaptureSize(JNIEnv *env, jobject thiz, jint size)
474{
475 Visualizer* lpVisualizer = getVisualizer(env, thiz);
476 if (lpVisualizer == NULL) {
477 return VISUALIZER_ERROR_NO_INIT;
478 }
479
480 return translateError(lpVisualizer->setCaptureSize(size));
481}
482
483static jint
484android_media_visualizer_native_getCaptureSize(JNIEnv *env, jobject thiz)
485{
486 Visualizer* lpVisualizer = getVisualizer(env, thiz);
487 if (lpVisualizer == NULL) {
488 return -1;
489 }
490 return lpVisualizer->getCaptureSize();
491}
492
493static jint
494android_media_visualizer_native_getSamplingRate(JNIEnv *env, jobject thiz)
495{
496 Visualizer* lpVisualizer = getVisualizer(env, thiz);
497 if (lpVisualizer == NULL) {
498 return -1;
499 }
500 return lpVisualizer->getSamplingRate();
501}
502
503static jint
504android_media_visualizer_native_getWaveForm(JNIEnv *env, jobject thiz, jbyteArray jWaveform)
505{
506 Visualizer* lpVisualizer = getVisualizer(env, thiz);
507 if (lpVisualizer == NULL) {
508 return VISUALIZER_ERROR_NO_INIT;
509 }
510
511 jbyte* nWaveform = (jbyte *) env->GetPrimitiveArrayCritical(jWaveform, NULL);
512 if (nWaveform == NULL) {
513 return VISUALIZER_ERROR_NO_MEMORY;
514 }
515 jint status = translateError(lpVisualizer->getWaveForm((uint8_t *)nWaveform));
516
517 env->ReleasePrimitiveArrayCritical(jWaveform, nWaveform, 0);
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700518 return status;
519}
520
521static jint
522android_media_visualizer_native_getFft(JNIEnv *env, jobject thiz, jbyteArray jFft)
523{
524 Visualizer* lpVisualizer = getVisualizer(env, thiz);
525 if (lpVisualizer == NULL) {
526 return VISUALIZER_ERROR_NO_INIT;
527 }
528
529 jbyte* nFft = (jbyte *) env->GetPrimitiveArrayCritical(jFft, NULL);
530 if (nFft == NULL) {
531 return VISUALIZER_ERROR_NO_MEMORY;
532 }
533 jint status = translateError(lpVisualizer->getFft((uint8_t *)nFft));
534
535 env->ReleasePrimitiveArrayCritical(jFft, nFft, 0);
536
537 return status;
538}
539
540static jint
541android_media_setPeriodicCapture(JNIEnv *env, jobject thiz, jint rate, jboolean jWaveform, jboolean jFft)
542{
543 Visualizer* lpVisualizer = getVisualizer(env, thiz);
544 if (lpVisualizer == NULL) {
545 return VISUALIZER_ERROR_NO_INIT;
546 }
547 visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField(thiz,
548 fields.fidJniData);
549 if (lpJniStorage == NULL) {
550 return VISUALIZER_ERROR_NO_INIT;
551 }
552
Steve Block71f2cf12011-10-20 11:56:00 +0100553 ALOGV("setPeriodicCapture: rate %d, jWaveform %d jFft %d",
Eric Laurentdf9b81c2010-07-02 08:12:41 -0700554 rate,
555 jWaveform,
556 jFft);
557
558 uint32_t flags = Visualizer::CAPTURE_CALL_JAVA;
559 if (jWaveform) flags |= Visualizer::CAPTURE_WAVEFORM;
560 if (jFft) flags |= Visualizer::CAPTURE_FFT;
561 Visualizer::capture_cbk_t cbk = captureCallback;
562 if (!jWaveform && !jFft) cbk = NULL;
563
564 return translateError(lpVisualizer->setCaptureCallBack(cbk,
565 &lpJniStorage->mCallbackData,
566 flags,
567 rate));
568}
569
570// ----------------------------------------------------------------------------
571
572// Dalvik VM type signatures
573static JNINativeMethod gMethods[] = {
574 {"native_init", "()V", (void *)android_media_visualizer_native_init},
575 {"native_setup", "(Ljava/lang/Object;I[I)I",
576 (void *)android_media_visualizer_native_setup},
577 {"native_finalize", "()V", (void *)android_media_visualizer_native_finalize},
578 {"native_release", "()V", (void *)android_media_visualizer_native_release},
579 {"native_setEnabled", "(Z)I", (void *)android_media_visualizer_native_setEnabled},
580 {"native_getEnabled", "()Z", (void *)android_media_visualizer_native_getEnabled},
581 {"getCaptureSizeRange", "()[I", (void *)android_media_visualizer_native_getCaptureSizeRange},
582 {"getMaxCaptureRate", "()I", (void *)android_media_visualizer_native_getMaxCaptureRate},
583 {"native_setCaptureSize", "(I)I", (void *)android_media_visualizer_native_setCaptureSize},
584 {"native_getCaptureSize", "()I", (void *)android_media_visualizer_native_getCaptureSize},
585 {"native_getSamplingRate", "()I", (void *)android_media_visualizer_native_getSamplingRate},
586 {"native_getWaveForm", "([B)I", (void *)android_media_visualizer_native_getWaveForm},
587 {"native_getFft", "([B)I", (void *)android_media_visualizer_native_getFft},
588 {"native_setPeriodicCapture","(IZZ)I",(void *)android_media_setPeriodicCapture},
589};
590
591// ----------------------------------------------------------------------------
592
593int register_android_media_visualizer(JNIEnv *env)
594{
595 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
596}
597