android_media_AudioTrack.cpp revision 973b8851eecbdcbab4992be01aaab568fd371a0a
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "AudioTrack-JNI" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "android_media_AudioTrack.h" 21071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 22c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <JNIHelp.h> 237ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi#include <JniConstants.h> 24ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h" 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 267ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi#include "ScopedBytes.h" 277ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi 28c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <utils/Log.h> 29c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <media/AudioSystem.h> 30c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <media/AudioTrack.h> 3137967d46f40c8c52c88ff8c011972a1489d465ecGlenn Kasten#include <audio_utils/primitives.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 330795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/MemoryHeapBase.h> 340795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/MemoryBase.h> 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36fe834d30f4f3f51b754d55fecb36f11279733948Glenn Kasten#include "android_media_AudioFormat.h" 37bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent#include "android_media_AudioErrors.h" 382d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia#include "android_media_PlaybackParams.h" 394bcdba848449b33d7022de527c526943aff1f5fdEric Laurent#include "android_media_DeviceCallback.h" 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char* const kClassPathName = "android/media/AudioTrack"; 47a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivistatic const char* const kAudioAttributesClassPathName = "android/media/AudioAttributes"; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivistruct audio_track_fields_t { 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these fields provide access from C++ to the... 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jmethodID postNativeEventInJava; //... event post callback method 5283b368505052f59616d29558e65e2250d01fd848Eric Laurent jfieldID nativeTrackInJavaObj; // stores in Java the native AudioTrack object 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID jniData; // stores in Java additional resources used by the native AudioTrack 54a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi jfieldID fieldStreamType; // ... mStreamType field in the AudioTrack Java object 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 56a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivistruct audio_attributes_fields_t { 57701d6ff12f36bf5e9de0dafdaced06744fd411ebJean-Michel Trivi jfieldID fieldUsage; // AudioAttributes.mUsage 58701d6ff12f36bf5e9de0dafdaced06744fd411ebJean-Michel Trivi jfieldID fieldContentType; // AudioAttributes.mContentType 59701d6ff12f36bf5e9de0dafdaced06744fd411ebJean-Michel Trivi jfieldID fieldFlags; // AudioAttributes.mFlags 60701d6ff12f36bf5e9de0dafdaced06744fd411ebJean-Michel Trivi jfieldID fieldFormattedTags;// AudioAttributes.mFormattedTags 61a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi}; 62a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivistatic audio_track_fields_t javaAudioTrackFields; 63a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivistatic audio_attributes_fields_t javaAudioAttrFields; 642d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic PlaybackParams::fields_t gPlaybackParamsFields; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct audiotrack_callback_cookie { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass audioTrack_class; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject audioTrack_ref; 69532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent bool busy; 70532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent Condition cond; 71532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent}; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 733d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten// keep these values in sync with AudioTrack.java 743d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten#define MODE_STATIC 0 753d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten#define MODE_STREAM 1 763d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass AudioTrackJniStorage { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public: 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<MemoryHeapBase> mMemHeap; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<MemoryBase> mMemBase; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audiotrack_callback_cookie mCallbackData; 834bcdba848449b33d7022de527c526943aff1f5fdEric Laurent sp<JNIDeviceCallback> mDeviceCallback; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AudioTrackJniStorage() { 868a1496855cb81a6f2e9e8d51dd6b6ed595047a2aJean-Michel Trivi mCallbackData.audioTrack_class = 0; 878a1496855cb81a6f2e9e8d51dd6b6ed595047a2aJean-Michel Trivi mCallbackData.audioTrack_ref = 0; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~AudioTrackJniStorage() { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMemBase.clear(); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMemHeap.clear(); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool allocSharedMem(int sizeInBytes) { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMemHeap = new MemoryHeapBase(sizeInBytes, 0, "AudioTrack Heap Base"); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMemHeap->getHeapID() < 0) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMemBase = new MemoryBase(mMemHeap, 0, sizeInBytes); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 105532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurentstatic Mutex sLock; 106532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurentstatic SortedVector <audiotrack_callback_cookie *> sAudioTrackCallBackCookies; 107532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEFAULT_OUTPUT_SAMPLE_RATE 44100 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM -16 112fb2ab9efc3805c81521afb9ff91a58ff5097a36eGlenn Kasten#define AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK -17 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT -18 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define AUDIOTRACK_ERROR_SETUP_INVALIDSTREAMTYPE -19 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED -20 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 118e46a86fcb6a0849fc05c4cade6cb94aad0325295Glenn Kastenstatic void audioCallback(int event, void* user, void *info) { 119532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent 120532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent audiotrack_callback_cookie *callbackInfo = (audiotrack_callback_cookie *)user; 121532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent { 122532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent Mutex::Autolock l(sLock); 123532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (sAudioTrackCallBackCookies.indexOf(callbackInfo) < 0) { 124532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return; 125532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent } 126532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent callbackInfo->busy = true; 127532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent } 128532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent 1295b1576ccbd9ab43d5e3238589cf5b43a4834447dGlenn Kasten switch (event) { 1305b1576ccbd9ab43d5e3238589cf5b43a4834447dGlenn Kasten case AudioTrack::EVENT_MARKER: { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv *env = AndroidRuntime::getJNIEnv(); 132a667ff30e4fb6f741c2a930e7c31ef7e962d3b40Glenn Kasten if (user != NULL && env != NULL) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallStaticVoidMethod( 13418db49a46259020387c40fff36d92edc1087a366Glenn Kasten callbackInfo->audioTrack_class, 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaAudioTrackFields.postNativeEventInJava, 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callbackInfo->audioTrack_ref, event, 0,0, NULL); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionCheck()) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ExceptionDescribe(); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ExceptionClear(); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1425b1576ccbd9ab43d5e3238589cf5b43a4834447dGlenn Kasten } break; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1445b1576ccbd9ab43d5e3238589cf5b43a4834447dGlenn Kasten case AudioTrack::EVENT_NEW_POS: { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv *env = AndroidRuntime::getJNIEnv(); 146a667ff30e4fb6f741c2a930e7c31ef7e962d3b40Glenn Kasten if (user != NULL && env != NULL) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallStaticVoidMethod( 14818db49a46259020387c40fff36d92edc1087a366Glenn Kasten callbackInfo->audioTrack_class, 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaAudioTrackFields.postNativeEventInJava, 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callbackInfo->audioTrack_ref, event, 0,0, NULL); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionCheck()) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ExceptionDescribe(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ExceptionClear(); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1565b1576ccbd9ab43d5e3238589cf5b43a4834447dGlenn Kasten } break; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1585b1576ccbd9ab43d5e3238589cf5b43a4834447dGlenn Kasten 159532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent { 160532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent Mutex::Autolock l(sLock); 161532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent callbackInfo->busy = false; 162532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent callbackInfo->cond.broadcast(); 163532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 168532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurentstatic sp<AudioTrack> getAudioTrack(JNIEnv* env, jobject thiz) 169532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent{ 170532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent Mutex::Autolock l(sLock); 171532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent AudioTrack* const at = 172075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat (AudioTrack*)env->GetLongField(thiz, javaAudioTrackFields.nativeTrackInJavaObj); 173532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return sp<AudioTrack>(at); 174532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent} 175532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent 176532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurentstatic sp<AudioTrack> setAudioTrack(JNIEnv* env, jobject thiz, const sp<AudioTrack>& at) 177532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent{ 178532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent Mutex::Autolock l(sLock); 179532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> old = 180075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat (AudioTrack*)env->GetLongField(thiz, javaAudioTrackFields.nativeTrackInJavaObj); 181532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (at.get()) { 182b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian at->incStrong((void*)setAudioTrack); 183532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent } 184532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (old != 0) { 185b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian old->decStrong((void*)setAudioTrack); 186532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent } 187075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, (jlong)at.get()); 188532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return old; 189532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent} 190071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 191071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia// ---------------------------------------------------------------------------- 192071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiasp<AudioTrack> android_media_AudioTrack_getAudioTrack(JNIEnv* env, jobject audioTrackObj) { 193071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return getAudioTrack(env, audioTrackObj); 194071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 195071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 19630d794360f35592554403922bcc07835fea4737bAndy Hung// This function converts Java channel masks to a native channel mask. 19730d794360f35592554403922bcc07835fea4737bAndy Hung// validity should be checked with audio_is_output_channel(). 19830d794360f35592554403922bcc07835fea4737bAndy Hungstatic inline audio_channel_mask_t nativeChannelMaskFromJavaChannelMasks( 19930d794360f35592554403922bcc07835fea4737bAndy Hung jint channelPositionMask, jint channelIndexMask) 20030d794360f35592554403922bcc07835fea4737bAndy Hung{ 20130d794360f35592554403922bcc07835fea4737bAndy Hung if (channelIndexMask != 0) { // channel index mask takes priority 20230d794360f35592554403922bcc07835fea4737bAndy Hung // To convert to a native channel mask, the Java channel index mask 20330d794360f35592554403922bcc07835fea4737bAndy Hung // requires adding the index representation. 20430d794360f35592554403922bcc07835fea4737bAndy Hung return audio_channel_mask_from_representation_and_bits( 20530d794360f35592554403922bcc07835fea4737bAndy Hung AUDIO_CHANNEL_REPRESENTATION_INDEX, 20630d794360f35592554403922bcc07835fea4737bAndy Hung channelIndexMask); 20730d794360f35592554403922bcc07835fea4737bAndy Hung } 20830d794360f35592554403922bcc07835fea4737bAndy Hung // To convert to a native channel mask, the Java channel position mask 20930d794360f35592554403922bcc07835fea4737bAndy Hung // requires a shift by 2 to skip the two deprecated channel 21030d794360f35592554403922bcc07835fea4737bAndy Hung // configurations "default" and "mono". 21130d794360f35592554403922bcc07835fea4737bAndy Hung return (audio_channel_mask_t)(channelPositionMask >> 2); 21230d794360f35592554403922bcc07835fea4737bAndy Hung} 21330d794360f35592554403922bcc07835fea4737bAndy Hung 214532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent// ---------------------------------------------------------------------------- 215075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint 216eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Triviandroid_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this, 217a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi jobject jaa, 21830d794360f35592554403922bcc07835fea4737bAndy Hung jint sampleRateInHertz, jint channelPositionMask, jint channelIndexMask, 219a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession) { 220a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 22130d794360f35592554403922bcc07835fea4737bAndy Hung ALOGV("sampleRate=%d, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d", 22230d794360f35592554403922bcc07835fea4737bAndy Hung sampleRateInHertz, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 224a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi if (jaa == 0) { 225a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi ALOGE("Error creating AudioTrack: invalid audio attributes"); 226a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi return (jint) AUDIO_JAVA_ERROR; 227a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi } 228a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 229a9470c19a9dfe362a201c569f14b669b7aa69ee4Andy Hung // Invalid channel representations are caught by !audio_is_output_channel() below. 23030d794360f35592554403922bcc07835fea4737bAndy Hung audio_channel_mask_t nativeChannelMask = nativeChannelMaskFromJavaChannelMasks( 23130d794360f35592554403922bcc07835fea4737bAndy Hung channelPositionMask, channelIndexMask); 232d9ae1c573e37e245c7f4f0480a8fa925e57bd49dJean-Michel Trivi if (!audio_is_output_channel(nativeChannelMask)) { 23330d794360f35592554403922bcc07835fea4737bAndy Hung ALOGE("Error creating AudioTrack: invalid native channel mask %#x.", nativeChannelMask); 234075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 236d9ae1c573e37e245c7f4f0480a8fa925e57bd49dJean-Michel Trivi 237dbf55665c5c4802cbfc56463198805be48ec75afEric Laurent uint32_t channelCount = audio_channel_count_from_out_mask(nativeChannelMask); 23818db49a46259020387c40fff36d92edc1087a366Glenn Kasten 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check the format. 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This function was called from Java, so we compare the format against the Java constants 241fe834d30f4f3f51b754d55fecb36f11279733948Glenn Kasten audio_format_t format = audioFormatToNative(audioFormat); 242fe834d30f4f3f51b754d55fecb36f11279733948Glenn Kasten if (format == AUDIO_FORMAT_INVALID) { 2438f81d0832bd2eea2e479f38160961fbcf35bd591Glenn Kasten ALOGE("Error creating AudioTrack: unsupported audio format %d.", audioFormat); 244075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the frame count 248ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent size_t frameCount; 249ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent if (audio_is_linear_pcm(format)) { 250ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent const size_t bytesPerSample = audio_bytes_per_sample(format); 251ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent frameCount = buffSizeInBytes / (channelCount * bytesPerSample); 252ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent } else { 253ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent frameCount = buffSizeInBytes; 254ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent } 25518db49a46259020387c40fff36d92edc1087a366Glenn Kasten 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz = env->GetObjectClass(thiz); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (clazz == NULL) { 2583762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Can't find %s when setting up callback.", kClassPathName); 259075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2612fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent 2622fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent if (jSession == NULL) { 2633762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Error creating AudioTrack: invalid session ID pointer"); 264bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint) AUDIO_JAVA_ERROR; 265619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent } 266619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent 2672fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); 2682fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent if (nSession == NULL) { 2693762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Error creating AudioTrack: Error retrieving session id pointer"); 270bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint) AUDIO_JAVA_ERROR; 2712fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent } 2722fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent int sessionId = nSession[0]; 2732fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); 2742fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent nSession = NULL; 2752fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create the native AudioTrack object 277532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = new AudioTrack(); 27818db49a46259020387c40fff36d92edc1087a366Glenn Kasten 279a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi audio_attributes_t *paa = NULL; 280a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi // read the AudioAttributes values 281a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi paa = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t)); 282701d6ff12f36bf5e9de0dafdaced06744fd411ebJean-Michel Trivi const jstring jtags = 283701d6ff12f36bf5e9de0dafdaced06744fd411ebJean-Michel Trivi (jstring) env->GetObjectField(jaa, javaAudioAttrFields.fieldFormattedTags); 284a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi const char* tags = env->GetStringUTFChars(jtags, NULL); 285a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi // copying array size -1, char array for tags was calloc'd, no need to NULL-terminate it 286a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi strncpy(paa->tags, tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1); 287a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi env->ReleaseStringUTFChars(jtags, tags); 288a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi paa->usage = (audio_usage_t) env->GetIntField(jaa, javaAudioAttrFields.fieldUsage); 289a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi paa->content_type = 290a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi (audio_content_type_t) env->GetIntField(jaa, javaAudioAttrFields.fieldContentType); 291a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi paa->flags = env->GetIntField(jaa, javaAudioAttrFields.fieldFlags); 292a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 293a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi ALOGV("AudioTrack_setup for usage=%d content=%d flags=0x%#x tags=%s", 294a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi paa->usage, paa->content_type, paa->flags, paa->tags); 295a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 296532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent // initialize the callback information: 297532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent // this data will be passed with every AudioTrack callback 298532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent AudioTrackJniStorage* lpJniStorage = new AudioTrackJniStorage(); 299532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent lpJniStorage->mCallbackData.audioTrack_class = (jclass)env->NewGlobalRef(clazz); 300532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent // we use a weak reference so the AudioTrack object can be garbage collected. 301532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent lpJniStorage->mCallbackData.audioTrack_ref = env->NewGlobalRef(weak_this); 302532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent lpJniStorage->mCallbackData.busy = false; 303532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // initialize the native AudioTrack object 3052defed988f74c98d5af8d02551ebf7262490cc5bJean-Michel Trivi status_t status = NO_ERROR; 3063d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten switch (memoryMode) { 3073d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten case MODE_STREAM: 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309c5d142428ad68dd8aa4ffb80719667b13ad5049fGlenn Kasten status = lpTrack->set( 310c8d6b6fc7dd05c10ca301e654f063cc89781c9beJean-Michel Trivi AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument) 311a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi sampleRateInHertz, 312a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi format,// word length, PCM 313a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi nativeChannelMask, 314a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi frameCount, 315a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi AUDIO_OUTPUT_FLAG_NONE, 316a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user) 317a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack 318a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 0,// shared mem 319a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi true,// thread can call Java 320a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi sessionId,// audio session ID 321c8d6b6fc7dd05c10ca301e654f063cc89781c9beJean-Michel Trivi AudioTrack::TRANSFER_SYNC, 322a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi NULL, // default offloadInfo 323a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi -1, -1, // default uid, pid values 324a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi paa); 3253d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten break; 32618db49a46259020387c40fff36d92edc1087a366Glenn Kasten 3273d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten case MODE_STATIC: 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // AudioTrack is using shared memory 32918db49a46259020387c40fff36d92edc1087a366Glenn Kasten 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!lpJniStorage->allocSharedMem(buffSizeInBytes)) { 3313762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Error creating AudioTrack in static mode: error creating mem heap base"); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto native_init_failure; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33418db49a46259020387c40fff36d92edc1087a366Glenn Kasten 335c5d142428ad68dd8aa4ffb80719667b13ad5049fGlenn Kasten status = lpTrack->set( 336c8d6b6fc7dd05c10ca301e654f063cc89781c9beJean-Michel Trivi AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument) 337a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi sampleRateInHertz, 338a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi format,// word length, PCM 339a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi nativeChannelMask, 340a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi frameCount, 341a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi AUDIO_OUTPUT_FLAG_NONE, 342a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)); 343a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack 344a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi lpJniStorage->mMemBase,// shared mem 345a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi true,// thread can call Java 346a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi sessionId,// audio session ID 347c8d6b6fc7dd05c10ca301e654f063cc89781c9beJean-Michel Trivi AudioTrack::TRANSFER_SHARED, 348a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi NULL, // default offloadInfo 349a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi -1, -1, // default uid, pid values 350a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi paa); 3513d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten break; 3523d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten 3533d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten default: 3543d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten ALOGE("Unknown mode %d", memoryMode); 3553d301cb2b1d9e61c3af8a8b0b9db370d3d7abf77Glenn Kasten goto native_init_failure; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 358c5d142428ad68dd8aa4ffb80719667b13ad5049fGlenn Kasten if (status != NO_ERROR) { 359c5d142428ad68dd8aa4ffb80719667b13ad5049fGlenn Kasten ALOGE("Error %d initializing AudioTrack", status); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto native_init_failure; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3632fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); 3642fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent if (nSession == NULL) { 3653762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Error creating AudioTrack: Error retrieving session id pointer"); 3662fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent goto native_init_failure; 3672fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent } 368619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent // read the audio session ID back from AudioTrack in case we create a new session 369619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent nSession[0] = lpTrack->getSessionId(); 370619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); 371619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent nSession = NULL; 372619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent 373532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent { // scope for the lock 374532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent Mutex::Autolock l(sLock); 375532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sAudioTrackCallBackCookies.add(&lpJniStorage->mCallbackData); 376532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent } 37718db49a46259020387c40fff36d92edc1087a366Glenn Kasten // save our newly created C++ AudioTrack in the "nativeTrackInJavaObj" field 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of the Java object (in mNativeTrackInJavaObj) 379532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent setAudioTrack(env, thiz, lpTrack); 38018db49a46259020387c40fff36d92edc1087a366Glenn Kasten 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // save the JNI resources so we can free them later 382075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat //ALOGV("storing lpJniStorage: %x\n", (long)lpJniStorage); 383075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, javaAudioTrackFields.jniData, (jlong)lpJniStorage); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 385a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi // since we had audio attributes, the stream type was derived from them during the 386a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi // creation of the native AudioTrack: push the same value to the Java object 387a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi env->SetIntField(thiz, javaAudioTrackFields.fieldStreamType, (jint) lpTrack->streamType()); 388a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi // audio attributes were copied in AudioTrack creation 389a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi free(paa); 390a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi paa = NULL; 391a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 392a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 393bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint) AUDIO_JAVA_SUCCESS; 39418db49a46259020387c40fff36d92edc1087a366Glenn Kasten 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // failures: 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnative_init_failure: 397a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi if (paa != NULL) { 398a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi free(paa); 399a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi } 400619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent if (nSession != NULL) { 401619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); 402619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent } 4038a1496855cb81a6f2e9e8d51dd6b6ed595047a2aJean-Michel Trivi env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_class); 4048a1496855cb81a6f2e9e8d51dd6b6ed595047a2aJean-Michel Trivi env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_ref); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete lpJniStorage; 406075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, javaAudioTrackFields.jniData, 0); 40718db49a46259020387c40fff36d92edc1087a366Glenn Kasten 408075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid_media_AudioTrack_start(JNIEnv *env, jobject thiz) 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 416532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 417532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for start()"); 4207070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent return; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42221dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lpTrack->start(); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid_media_AudioTrack_stop(JNIEnv *env, jobject thiz) 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 431532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 432532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for stop()"); 4357070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent return; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lpTrack->stop(); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid_media_AudioTrack_pause(JNIEnv *env, jobject thiz) 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 446532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 447532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for pause()"); 4507070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent return; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lpTrack->pause(); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid_media_AudioTrack_flush(JNIEnv *env, jobject thiz) 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 461532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 462532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for flush()"); 4657070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent return; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lpTrack->flush(); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid_media_AudioTrack_set_volume(JNIEnv *env, jobject thiz, jfloat leftVol, jfloat rightVol ) 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 475532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 476532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for setVolume()"); 4797070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent return; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lpTrack->setVolume(leftVol, rightVol); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 48618db49a46259020387c40fff36d92edc1087a366Glenn Kasten 487532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent#define CALLBACK_COND_WAIT_TIMEOUT_MS 1000 488eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Trivistatic void android_media_AudioTrack_release(JNIEnv *env, jobject thiz) { 489532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = setAudioTrack(env, thiz, 0); 490532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 491532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 493532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent //ALOGV("deleting lpTrack: %x\n", (int)lpTrack); 494532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent lpTrack->stop(); 49518db49a46259020387c40fff36d92edc1087a366Glenn Kasten 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // delete the JNI data 497075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField( 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thiz, javaAudioTrackFields.jniData); 499532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent // reset the native resources in the Java object so any attempt to access 500532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent // them after a call to release fails. 501075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, javaAudioTrackFields.jniData, 0); 502532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pJniStorage) { 504532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent Mutex::Autolock l(sLock); 505532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent audiotrack_callback_cookie *lpCookie = &pJniStorage->mCallbackData; 50671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block //ALOGV("deleting pJniStorage: %x\n", (int)pJniStorage); 507532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent while (lpCookie->busy) { 508532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpCookie->cond.waitRelative(sLock, 509532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent milliseconds(CALLBACK_COND_WAIT_TIMEOUT_MS)) != 510532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent NO_ERROR) { 511532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent break; 512532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent } 513532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent } 514532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sAudioTrackCallBackCookies.remove(lpCookie); 515532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent // delete global refs created in native_setup 516532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent env->DeleteGlobalRef(lpCookie->audioTrack_class); 517532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent env->DeleteGlobalRef(lpCookie->audioTrack_ref); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete pJniStorage; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52218db49a46259020387c40fff36d92edc1087a366Glenn Kasten 523532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent// ---------------------------------------------------------------------------- 524eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Trivistatic void android_media_AudioTrack_finalize(JNIEnv *env, jobject thiz) { 525eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Trivi //ALOGV("android_media_AudioTrack_finalize jobject: %x\n", (int)thiz); 526eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Trivi android_media_AudioTrack_release(env, thiz); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5294aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung// overloaded JNI array helper functions (same as in android_media_AudioRecord) 5304aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungstatic inline 5314aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungjbyte *envGetArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy) { 5324aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return env->GetByteArrayElements(array, isCopy); 5334aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung} 5344aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung 5354aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungstatic inline 5364aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungvoid envReleaseArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems, jint mode) { 5374aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung env->ReleaseByteArrayElements(array, elems, mode); 5384aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung} 5394aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung 5404aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungstatic inline 5414aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungjshort *envGetArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy) { 5424aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return env->GetShortArrayElements(array, isCopy); 5434aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung} 5444aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung 5454aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungstatic inline 5464aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungvoid envReleaseArrayElements(JNIEnv *env, jshortArray array, jshort *elems, jint mode) { 5474aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung env->ReleaseShortArrayElements(array, elems, mode); 5484aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung} 5494aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung 5504aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungstatic inline 5514aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungjfloat *envGetArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy) { 5524aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return env->GetFloatArrayElements(array, isCopy); 5534aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung} 5544aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung 5554aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungstatic inline 5564aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungvoid envReleaseArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems, jint mode) { 5574aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung env->ReleaseFloatArrayElements(array, elems, mode); 5584aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung} 5594aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 5614aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungtemplate <typename T> 5624aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungstatic jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, const T *data, 5634aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung jint offsetInSamples, jint sizeInSamples, bool blocking) { 56421dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi // give the data to the native AudioTrack object (the data starts at the offset) 56521dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi ssize_t written = 0; 56621dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi // regular write() or copy the data to the AudioTrack's shared memory? 5674aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung size_t sizeInBytes = sizeInSamples * sizeof(T); 568532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (track->sharedBuffer() == 0) { 5694aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung written = track->write(data + offsetInSamples, sizeInBytes, blocking); 5709b53db378aa76c3c24bd423113a46e696fa9af22Glenn Kasten // for compatibility with earlier behavior of write(), return 0 in this case 5719b53db378aa76c3c24bd423113a46e696fa9af22Glenn Kasten if (written == (ssize_t) WOULD_BLOCK) { 5729b53db378aa76c3c24bd423113a46e696fa9af22Glenn Kasten written = 0; 5739b53db378aa76c3c24bd423113a46e696fa9af22Glenn Kasten } 57421dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi } else { 5752c0e17c029eccc06deb883d8d564a7e19d98f65eAndy Hung // writing to shared memory, check for capacity 5762c0e17c029eccc06deb883d8d564a7e19d98f65eAndy Hung if ((size_t)sizeInBytes > track->sharedBuffer()->size()) { 5772c0e17c029eccc06deb883d8d564a7e19d98f65eAndy Hung sizeInBytes = track->sharedBuffer()->size(); 57821dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi } 5794aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung memcpy(track->sharedBuffer()->pointer(), data + offsetInSamples, sizeInBytes); 5802c0e17c029eccc06deb883d8d564a7e19d98f65eAndy Hung written = sizeInBytes; 58121dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi } 5824aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung if (written > 0) { 5834aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return written / sizeof(T); 5844aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung } 5854aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung // for compatibility, error codes pass through unchanged 58621dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi return written; 58721dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi} 58821dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi 58921dc037e7e7c51e33b5808320f47339ee3a2b103Jean-Michel Trivi// ---------------------------------------------------------------------------- 5904aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungtemplate <typename T> 5914aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hungstatic jint android_media_AudioTrack_writeArray(JNIEnv *env, jobject thiz, 5924aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung T javaAudioData, 5934aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung jint offsetInSamples, jint sizeInSamples, 5944aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung jint javaAudioFormat, 5954aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung jboolean isWriteBlocking) { 5964aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung //ALOGV("android_media_AudioTrack_writeArray(offset=%d, sizeInSamples=%d) called", 5974aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung // offsetInSamples, sizeInSamples); 598532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lpTrack == NULL) { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for write()"); 6024aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return (jint)AUDIO_JAVA_INVALID_OPERATION; 6034aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung } 6044aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung 6054aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung if (javaAudioData == NULL) { 6064aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung ALOGE("NULL java array of audio data to play"); 6074aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return (jint)AUDIO_JAVA_BAD_VALUE; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 610421ddc014b31478ba0ef115e098d8780a35af331Eric Laurent // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such 611421ddc014b31478ba0ef115e098d8780a35af331Eric Laurent // a way that it becomes much more efficient. When doing so, we will have to prevent the 612421ddc014b31478ba0ef115e098d8780a35af331Eric Laurent // AudioSystem callback to be called while in critical section (in case of media server 613421ddc014b31478ba0ef115e098d8780a35af331Eric Laurent // process crash for instance) 6144aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung 6154aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung // get the pointer for the audio data from the java array 6164aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung auto cAudioData = envGetArrayElements(env, javaAudioData, NULL); 6174aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung if (cAudioData == NULL) { 6184aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung ALOGE("Error retrieving source of audio data to play"); 6194aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return (jint)AUDIO_JAVA_BAD_VALUE; // out of memory or no data to load 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6224aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung jint samplesWritten = writeToTrack(lpTrack, javaAudioFormat, cAudioData, 6234aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung offsetInSamples, sizeInSamples, isWriteBlocking == JNI_TRUE /* blocking */); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6254aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung envReleaseArrayElements(env, javaAudioData, cAudioData, 0); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6274aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung //ALOGV("write wrote %d (tried %d) samples in the native AudioTrack with offset %d", 6284aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung // (int)samplesWritten, (int)(sizeInSamples), (int)offsetInSamples); 6294aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return samplesWritten; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 6337ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivistatic jint android_media_AudioTrack_write_native_bytes(JNIEnv *env, jobject thiz, 6345d21f679c58dbb13c8c931ffec6e06b6b8cd454fJean-Michel Trivi jbyteArray javaBytes, jint byteOffset, jint sizeInBytes, 6357ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi jint javaAudioFormat, jboolean isWriteBlocking) { 6367ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi //ALOGV("android_media_AudioTrack_write_native_bytes(offset=%d, sizeInBytes=%d) called", 6377ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi // offsetInBytes, sizeInBytes); 6387ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 6397ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi if (lpTrack == NULL) { 6407ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi jniThrowException(env, "java/lang/IllegalStateException", 6417ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi "Unable to retrieve AudioTrack pointer for write()"); 6424aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung return (jint)AUDIO_JAVA_INVALID_OPERATION; 6437ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi } 6447ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi 6457ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi ScopedBytesRO bytes(env, javaBytes); 6467ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi if (bytes.get() == NULL) { 6477ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi ALOGE("Error retrieving source of audio data to play, can't play"); 648bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_BAD_VALUE; 6497ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi } 6507ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi 6515d21f679c58dbb13c8c931ffec6e06b6b8cd454fJean-Michel Trivi jint written = writeToTrack(lpTrack, javaAudioFormat, bytes.get(), byteOffset, 6527ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi sizeInBytes, isWriteBlocking == JNI_TRUE /* blocking */); 6537ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi 6547ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi return written; 6557ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi} 6567ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi 6577ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi// ---------------------------------------------------------------------------- 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_get_native_frame_count(JNIEnv *env, jobject thiz) { 659532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 660532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for frameCount()"); 663bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 665532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent 666532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return lpTrack->frameCount(); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 67188e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurentstatic jint android_media_AudioTrack_set_playback_rate(JNIEnv *env, jobject thiz, 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint sampleRateInHz) { 673532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 674532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for setSampleRate()"); 677bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 679bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return nativeToJavaStatus(lpTrack->setSampleRate(sampleRateInHz)); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_get_playback_rate(JNIEnv *env, jobject thiz) { 685532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 686532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for getSampleRate()"); 689bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 691532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return (jint) lpTrack->getSampleRate(); 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 6962d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic void android_media_AudioTrack_set_playback_params(JNIEnv *env, jobject thiz, 6972d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia jobject params) { 698263b4c97823295c41900210515d0c769a236190cAndy Hung sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 699263b4c97823295c41900210515d0c769a236190cAndy Hung if (lpTrack == NULL) { 700263b4c97823295c41900210515d0c769a236190cAndy Hung jniThrowException(env, "java/lang/IllegalStateException", 701263b4c97823295c41900210515d0c769a236190cAndy Hung "AudioTrack not initialized"); 702263b4c97823295c41900210515d0c769a236190cAndy Hung return; 703263b4c97823295c41900210515d0c769a236190cAndy Hung } 704263b4c97823295c41900210515d0c769a236190cAndy Hung 705973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung PlaybackParams pbp; 706973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung pbp.fillFromJobject(env, gPlaybackParamsFields, params); 707fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung 7082d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia ALOGV("setPlaybackParams: %d:%f %d:%f %d:%u %d:%u", 709973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung pbp.speedSet, pbp.audioRate.mSpeed, 710973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung pbp.pitchSet, pbp.audioRate.mPitch, 711973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung pbp.audioFallbackModeSet, pbp.audioRate.mFallbackMode, 712973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung pbp.audioStretchModeSet, pbp.audioRate.mStretchMode); 713973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung 714973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung // to simulate partially set params, we do a read-modify-write. 715973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung // TODO: pass in the valid set mask into AudioTrack. 716973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung AudioPlaybackRate rate = lpTrack->getPlaybackRate(); 717973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung bool updatedRate = false; 718973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung if (pbp.speedSet) { 719973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung rate.mSpeed = pbp.audioRate.mSpeed; 720973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung updatedRate = true; 721973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung } 722973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung if (pbp.pitchSet) { 723973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung rate.mPitch = pbp.audioRate.mPitch; 724973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung updatedRate = true; 725973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung } 726973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung if (pbp.audioFallbackModeSet) { 727973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung rate.mFallbackMode = pbp.audioRate.mFallbackMode; 728973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung updatedRate = true; 729973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung } 730973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung if (pbp.audioStretchModeSet) { 731973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung rate.mStretchMode = pbp.audioRate.mStretchMode; 732973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung updatedRate = true; 733973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung } 734973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung if (updatedRate) { 735973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung if (lpTrack->setPlaybackRate(rate) != OK) { 736973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung jniThrowException(env, "java/lang/IllegalArgumentException", 737973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung "arguments out of range"); 738973b8851eecbdcbab4992be01aaab568fd371a0aAndy Hung } 739263b4c97823295c41900210515d0c769a236190cAndy Hung } 740263b4c97823295c41900210515d0c769a236190cAndy Hung} 741263b4c97823295c41900210515d0c769a236190cAndy Hung 742263b4c97823295c41900210515d0c769a236190cAndy Hung 743263b4c97823295c41900210515d0c769a236190cAndy Hung// ---------------------------------------------------------------------------- 7442d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic jobject android_media_AudioTrack_get_playback_params(JNIEnv *env, jobject thiz, 7452d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia jobject params) { 746263b4c97823295c41900210515d0c769a236190cAndy Hung sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 747263b4c97823295c41900210515d0c769a236190cAndy Hung if (lpTrack == NULL) { 748263b4c97823295c41900210515d0c769a236190cAndy Hung jniThrowException(env, "java/lang/IllegalStateException", 749263b4c97823295c41900210515d0c769a236190cAndy Hung "AudioTrack not initialized"); 750fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung return NULL; 751263b4c97823295c41900210515d0c769a236190cAndy Hung } 752263b4c97823295c41900210515d0c769a236190cAndy Hung 7532d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia PlaybackParams pbs; 754fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung pbs.audioRate = lpTrack->getPlaybackRate(); 755fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung pbs.speedSet = true; 756fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung pbs.pitchSet = true; 757fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung pbs.audioFallbackModeSet = true; 758fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung pbs.audioStretchModeSet = true; 7592d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia return pbs.asJobject(env, gPlaybackParamsFields); 760263b4c97823295c41900210515d0c769a236190cAndy Hung} 761263b4c97823295c41900210515d0c769a236190cAndy Hung 762263b4c97823295c41900210515d0c769a236190cAndy Hung 763263b4c97823295c41900210515d0c769a236190cAndy Hung// ---------------------------------------------------------------------------- 76418db49a46259020387c40fff36d92edc1087a366Glenn Kastenstatic jint android_media_AudioTrack_set_marker_pos(JNIEnv *env, jobject thiz, 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint markerPos) { 766532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 767532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for setMarkerPosition()"); 770bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 772bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return nativeToJavaStatus( lpTrack->setMarkerPosition(markerPos) ); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_get_marker_pos(JNIEnv *env, jobject thiz) { 778532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t markerPos = 0; 78018db49a46259020387c40fff36d92edc1087a366Glenn Kasten 781532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for getMarkerPosition()"); 784bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 786532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent lpTrack->getMarkerPosition(&markerPos); 787532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return (jint)markerPos; 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_set_pos_update_period(JNIEnv *env, jobject thiz, 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint period) { 794532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 795532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for setPositionUpdatePeriod()"); 798bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 79918db49a46259020387c40fff36d92edc1087a366Glenn Kasten } 800bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return nativeToJavaStatus( lpTrack->setPositionUpdatePeriod(period) ); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_get_pos_update_period(JNIEnv *env, jobject thiz) { 806532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t period = 0; 80818db49a46259020387c40fff36d92edc1087a366Glenn Kasten 809532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for getPositionUpdatePeriod()"); 812bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 814532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent lpTrack->getPositionUpdatePeriod(&period); 815532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return (jint)period; 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 82018db49a46259020387c40fff36d92edc1087a366Glenn Kastenstatic jint android_media_AudioTrack_set_position(JNIEnv *env, jobject thiz, 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint position) { 822532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 823532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for setPosition()"); 826bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 828bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return nativeToJavaStatus( lpTrack->setPosition(position) ); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_get_position(JNIEnv *env, jobject thiz) { 834532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t position = 0; 83618db49a46259020387c40fff36d92edc1087a366Glenn Kasten 837532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for getPosition()"); 840bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 842532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent lpTrack->getPosition(&position); 843532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent return (jint)position; 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 84861dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodmanstatic jint android_media_AudioTrack_get_latency(JNIEnv *env, jobject thiz) { 84961dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 85061dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman 85161dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman if (lpTrack == NULL) { 85261dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman jniThrowException(env, "java/lang/IllegalStateException", 85361dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman "Unable to retrieve AudioTrack pointer for latency()"); 854bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 85561dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman } 85661dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman return (jint)lpTrack->latency(); 85761dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman} 85861dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman 85961dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman 86061dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman// ---------------------------------------------------------------------------- 861948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kastenstatic jint android_media_AudioTrack_get_timestamp(JNIEnv *env, jobject thiz, jlongArray jTimestamp) { 862948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 863948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten 864948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten if (lpTrack == NULL) { 865948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten ALOGE("Unable to retrieve AudioTrack pointer for getTimestamp()"); 866bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 867948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten } 868948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten AudioTimestamp timestamp; 869948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten status_t status = lpTrack->getTimestamp(timestamp); 870948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten if (status == OK) { 871948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten jlong* nTimestamp = (jlong *) env->GetPrimitiveArrayCritical(jTimestamp, NULL); 872948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten if (nTimestamp == NULL) { 873948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten ALOGE("Unable to get array for getTimestamp()"); 874bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 875948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten } 876948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten nTimestamp[0] = (jlong) timestamp.mPosition; 877948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten nTimestamp[1] = (jlong) ((timestamp.mTime.tv_sec * 1000000000LL) + timestamp.mTime.tv_nsec); 878948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten env->ReleasePrimitiveArrayCritical(jTimestamp, nTimestamp, 0); 879948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten } 880bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint) nativeToJavaStatus(status); 881948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten} 882948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten 883948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten 884948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten// ---------------------------------------------------------------------------- 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_set_loop(JNIEnv *env, jobject thiz, 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint loopStart, jint loopEnd, jint loopCount) { 887532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 888532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for setLoop()"); 891bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 893bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return nativeToJavaStatus( lpTrack->setLoop(loopStart, loopEnd, loopCount) ); 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_reload(JNIEnv *env, jobject thiz) { 899532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 900532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to retrieve AudioTrack pointer for reload()"); 903bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 905bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return nativeToJavaStatus( lpTrack->reload() ); 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_get_output_sample_rate(JNIEnv *env, jobject thiz, 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint javaStreamType) { 91285fbc871ded0f71f9638f85e7d2f03a35bf39ddaGlenn Kasten uint32_t afSamplingRate; 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // convert the stream type from Java to native value 914eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Trivi // FIXME: code duplication with android_media_AudioTrack_setup() 91524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin audio_stream_type_t nativeStreamType; 91629a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten switch (javaStreamType) { 91729a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten case AUDIO_STREAM_VOICE_CALL: 91829a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten case AUDIO_STREAM_SYSTEM: 91929a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten case AUDIO_STREAM_RING: 92029a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten case AUDIO_STREAM_MUSIC: 92129a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten case AUDIO_STREAM_ALARM: 92229a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten case AUDIO_STREAM_NOTIFICATION: 92329a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten case AUDIO_STREAM_BLUETOOTH_SCO: 92429a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten case AUDIO_STREAM_DTMF: 92529a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten nativeStreamType = (audio_stream_type_t) javaStreamType; 92629a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten break; 92729a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten default: 92824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin nativeStreamType = AUDIO_STREAM_DEFAULT; 92929a0909c5f777230b9f34ef0703fed3cd4633833Glenn Kasten break; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9328f81d0832bd2eea2e479f38160961fbcf35bd591Glenn Kasten status_t status = AudioSystem::getOutputSamplingRate(&afSamplingRate, nativeStreamType); 9338f81d0832bd2eea2e479f38160961fbcf35bd591Glenn Kasten if (status != NO_ERROR) { 9348f81d0832bd2eea2e479f38160961fbcf35bd591Glenn Kasten ALOGE("Error %d in AudioSystem::getOutputSamplingRate() for stream type %d " 9358f81d0832bd2eea2e479f38160961fbcf35bd591Glenn Kasten "in AudioTrack JNI", status, nativeStreamType); 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return DEFAULT_OUTPUT_SAMPLE_RATE; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afSamplingRate; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// returns the minimum required size for the successful creation of a streaming AudioTrack 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// returns -1 if there was an error querying the hardware. 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thiz, 9475b8fd44365f03601aaba41879ac18e70ce814a0fGlenn Kasten jint sampleRateInHertz, jint channelCount, jint audioFormat) { 948c3308074cd6f06bbb35c1999b5260f938742a9e7Chia-chi Yeh 949659a9712f2072f0bb3fa39de23f252f2f97440b4Glenn Kasten size_t frameCount; 950659a9712f2072f0bb3fa39de23f252f2f97440b4Glenn Kasten const status_t status = AudioTrack::getMinFrameCount(&frameCount, AUDIO_STREAM_DEFAULT, 951659a9712f2072f0bb3fa39de23f252f2f97440b4Glenn Kasten sampleRateInHertz); 952659a9712f2072f0bb3fa39de23f252f2f97440b4Glenn Kasten if (status != NO_ERROR) { 953659a9712f2072f0bb3fa39de23f252f2f97440b4Glenn Kasten ALOGE("AudioTrack::getMinFrameCount() for sample rate %d failed with status %d", 954659a9712f2072f0bb3fa39de23f252f2f97440b4Glenn Kasten sampleRateInHertz, status); 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 957fe834d30f4f3f51b754d55fecb36f11279733948Glenn Kasten const audio_format_t format = audioFormatToNative(audioFormat); 958ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent if (audio_is_linear_pcm(format)) { 959ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent const size_t bytesPerSample = audio_bytes_per_sample(format); 960ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent return frameCount * channelCount * bytesPerSample; 961ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent } else { 962ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent return frameCount; 963ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent } 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9667070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent// ---------------------------------------------------------------------------- 9673009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kastenstatic jint 9687070b36549d511d6627538c73dfbab23fbae5b43Eric Laurentandroid_media_AudioTrack_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level ) 9697070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent{ 970532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 9717070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent if (lpTrack == NULL ) { 9727070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent jniThrowException(env, "java/lang/IllegalStateException", 9737070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent "Unable to retrieve AudioTrack pointer for setAuxEffectSendLevel()"); 9743009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kasten return -1; 9757070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent } 9767070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent 9773009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kasten status_t status = lpTrack->setAuxEffectSendLevel(level); 9783009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kasten if (status != NO_ERROR) { 9793009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kasten ALOGE("AudioTrack::setAuxEffectSendLevel() for level %g failed with status %d", 9803009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kasten level, status); 9813009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kasten } 9823009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kasten return (jint) status; 9837070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent} 9847070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent 9857070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent// ---------------------------------------------------------------------------- 9867070b36549d511d6627538c73dfbab23fbae5b43Eric Laurentstatic jint android_media_AudioTrack_attachAuxEffect(JNIEnv *env, jobject thiz, 9877070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent jint effectId) { 988532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 989532bc1cb7da9fdbf34893fa48b2ae11f54cf6a8eEric Laurent if (lpTrack == NULL) { 9907070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent jniThrowException(env, "java/lang/IllegalStateException", 9917070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent "Unable to retrieve AudioTrack pointer for attachAuxEffect()"); 992bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return (jint)AUDIO_JAVA_ERROR; 9937070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent } 994bc11a696f6856624de532a6830d5db9dbbe2384cEric Laurent return nativeToJavaStatus( lpTrack->attachAuxEffect(effectId) ); 9957070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent} 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99788e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLeanstatic jboolean android_media_AudioTrack_setOutputDevice( 99888e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLean JNIEnv *env, jobject thiz, jint device_id) { 99988e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLean 100088e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLean sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 100188e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLean return lpTrack->setOutputDevice(device_id) == NO_ERROR; 100288e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLean} 100388e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLean 10044bcdba848449b33d7022de527c526943aff1f5fdEric Laurentstatic jint android_media_AudioTrack_getRoutedDeviceId( 10054bcdba848449b33d7022de527c526943aff1f5fdEric Laurent JNIEnv *env, jobject thiz) { 10064bcdba848449b33d7022de527c526943aff1f5fdEric Laurent 10074bcdba848449b33d7022de527c526943aff1f5fdEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 10084bcdba848449b33d7022de527c526943aff1f5fdEric Laurent if (lpTrack == NULL) { 10094bcdba848449b33d7022de527c526943aff1f5fdEric Laurent return 0; 10104bcdba848449b33d7022de527c526943aff1f5fdEric Laurent } 10114bcdba848449b33d7022de527c526943aff1f5fdEric Laurent return (jint)lpTrack->getRoutedDeviceId(); 10124bcdba848449b33d7022de527c526943aff1f5fdEric Laurent} 10134bcdba848449b33d7022de527c526943aff1f5fdEric Laurent 10144bcdba848449b33d7022de527c526943aff1f5fdEric Laurentstatic void android_media_AudioTrack_enableDeviceCallback( 10154bcdba848449b33d7022de527c526943aff1f5fdEric Laurent JNIEnv *env, jobject thiz) { 10164bcdba848449b33d7022de527c526943aff1f5fdEric Laurent 10174bcdba848449b33d7022de527c526943aff1f5fdEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 10184bcdba848449b33d7022de527c526943aff1f5fdEric Laurent if (lpTrack == NULL) { 10194bcdba848449b33d7022de527c526943aff1f5fdEric Laurent return; 10204bcdba848449b33d7022de527c526943aff1f5fdEric Laurent } 10214bcdba848449b33d7022de527c526943aff1f5fdEric Laurent AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField( 10224bcdba848449b33d7022de527c526943aff1f5fdEric Laurent thiz, javaAudioTrackFields.jniData); 10234bcdba848449b33d7022de527c526943aff1f5fdEric Laurent if (pJniStorage == NULL || pJniStorage->mDeviceCallback != 0) { 10244bcdba848449b33d7022de527c526943aff1f5fdEric Laurent return; 10254bcdba848449b33d7022de527c526943aff1f5fdEric Laurent } 10264bcdba848449b33d7022de527c526943aff1f5fdEric Laurent pJniStorage->mDeviceCallback = 10274bcdba848449b33d7022de527c526943aff1f5fdEric Laurent new JNIDeviceCallback(env, thiz, pJniStorage->mCallbackData.audioTrack_ref, 10284bcdba848449b33d7022de527c526943aff1f5fdEric Laurent javaAudioTrackFields.postNativeEventInJava); 10294bcdba848449b33d7022de527c526943aff1f5fdEric Laurent lpTrack->addAudioDeviceCallback(pJniStorage->mDeviceCallback); 10304bcdba848449b33d7022de527c526943aff1f5fdEric Laurent} 10314bcdba848449b33d7022de527c526943aff1f5fdEric Laurent 10324bcdba848449b33d7022de527c526943aff1f5fdEric Laurentstatic void android_media_AudioTrack_disableDeviceCallback( 10334bcdba848449b33d7022de527c526943aff1f5fdEric Laurent JNIEnv *env, jobject thiz) { 10344bcdba848449b33d7022de527c526943aff1f5fdEric Laurent 10354bcdba848449b33d7022de527c526943aff1f5fdEric Laurent sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); 10364bcdba848449b33d7022de527c526943aff1f5fdEric Laurent if (lpTrack == NULL) { 10374bcdba848449b33d7022de527c526943aff1f5fdEric Laurent return; 10384bcdba848449b33d7022de527c526943aff1f5fdEric Laurent } 10394bcdba848449b33d7022de527c526943aff1f5fdEric Laurent AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField( 10404bcdba848449b33d7022de527c526943aff1f5fdEric Laurent thiz, javaAudioTrackFields.jniData); 10414bcdba848449b33d7022de527c526943aff1f5fdEric Laurent if (pJniStorage == NULL || pJniStorage->mDeviceCallback == 0) { 10424bcdba848449b33d7022de527c526943aff1f5fdEric Laurent return; 10434bcdba848449b33d7022de527c526943aff1f5fdEric Laurent } 10444bcdba848449b33d7022de527c526943aff1f5fdEric Laurent lpTrack->removeAudioDeviceCallback(pJniStorage->mDeviceCallback); 10454bcdba848449b33d7022de527c526943aff1f5fdEric Laurent pJniStorage->mDeviceCallback.clear(); 10464bcdba848449b33d7022de527c526943aff1f5fdEric Laurent} 10474bcdba848449b33d7022de527c526943aff1f5fdEric Laurent 10484bcdba848449b33d7022de527c526943aff1f5fdEric Laurent 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // name, signature, funcPtr 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_start", "()V", (void *)android_media_AudioTrack_start}, 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_stop", "()V", (void *)android_media_AudioTrack_stop}, 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_pause", "()V", (void *)android_media_AudioTrack_pause}, 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_flush", "()V", (void *)android_media_AudioTrack_flush}, 105730d794360f35592554403922bcc07835fea4737bAndy Hung {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;IIIIII[I)I", 1058eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Trivi (void *)android_media_AudioTrack_setup}, 1059eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Trivi {"native_finalize", "()V", (void *)android_media_AudioTrack_finalize}, 1060eac8438a7dbe42e81f5273e0847a3f5e4247aa5bJean-Michel Trivi {"native_release", "()V", (void *)android_media_AudioTrack_release}, 10614aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung {"native_write_byte", "([BIIIZ)I",(void *)android_media_AudioTrack_writeArray<jbyteArray>}, 10627ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi {"native_write_native_bytes", 10635d21f679c58dbb13c8c931ffec6e06b6b8cd454fJean-Michel Trivi "(Ljava/lang/Object;IIIZ)I", 10647ca0452fa62b9c15bd45b0fd52aef97442555a6eJean-Michel Trivi (void *)android_media_AudioTrack_write_native_bytes}, 10654aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung {"native_write_short", "([SIIIZ)I",(void *)android_media_AudioTrack_writeArray<jshortArray>}, 10664aacc903e3f0216a1aec00d57d34f902025d5bd0Andy Hung {"native_write_float", "([FIIIZ)I",(void *)android_media_AudioTrack_writeArray<jfloatArray>}, 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_setVolume", "(FF)V", (void *)android_media_AudioTrack_set_volume}, 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_get_native_frame_count", 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "()I", (void *)android_media_AudioTrack_get_native_frame_count}, 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_set_playback_rate", 107188e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurent "(I)I", (void *)android_media_AudioTrack_set_playback_rate}, 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_get_playback_rate", 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "()I", (void *)android_media_AudioTrack_get_playback_rate}, 10742d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia {"native_set_playback_params", 10752d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia "(Landroid/media/PlaybackParams;)V", 10762d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia (void *)android_media_AudioTrack_set_playback_params}, 10772d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia {"native_get_playback_params", 10782d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia "()Landroid/media/PlaybackParams;", 10792d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia (void *)android_media_AudioTrack_get_playback_params}, 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_set_marker_pos","(I)I", (void *)android_media_AudioTrack_set_marker_pos}, 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_get_marker_pos","()I", (void *)android_media_AudioTrack_get_marker_pos}, 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_set_pos_update_period", 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(I)I", (void *)android_media_AudioTrack_set_pos_update_period}, 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_get_pos_update_period", 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "()I", (void *)android_media_AudioTrack_get_pos_update_period}, 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_set_position", "(I)I", (void *)android_media_AudioTrack_set_position}, 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_get_position", "()I", (void *)android_media_AudioTrack_get_position}, 108861dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman {"native_get_latency", "()I", (void *)android_media_AudioTrack_get_latency}, 1089948c2e6ff46d65942277f2e0e9ce0c038972b9d8Glenn Kasten {"native_get_timestamp", "([J)I", (void *)android_media_AudioTrack_get_timestamp}, 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_set_loop", "(III)I", (void *)android_media_AudioTrack_set_loop}, 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_reload_static", "()I", (void *)android_media_AudioTrack_reload}, 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_get_output_sample_rate", 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(I)I", (void *)android_media_AudioTrack_get_output_sample_rate}, 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_get_min_buff_size", 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(III)I", (void *)android_media_AudioTrack_get_min_buff_size}, 10967070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent {"native_setAuxEffectSendLevel", 10973009f0b911e39d3b26c69bd7667d6444eacb9d11Glenn Kasten "(F)I", (void *)android_media_AudioTrack_setAuxEffectSendLevel}, 10987070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent {"native_attachAuxEffect", 10997070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent "(I)I", (void *)android_media_AudioTrack_attachAuxEffect}, 110088e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLean {"native_setOutputDevice", "(I)Z", 110188e1d86a879d8802e775dd0566ffb64425e8e3c8Paul McLean (void *)android_media_AudioTrack_setOutputDevice}, 11024bcdba848449b33d7022de527c526943aff1f5fdEric Laurent {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioTrack_getRoutedDeviceId}, 11034bcdba848449b33d7022de527c526943aff1f5fdEric Laurent {"native_enableDeviceCallback", "()V", (void *)android_media_AudioTrack_enableDeviceCallback}, 11044bcdba848449b33d7022de527c526943aff1f5fdEric Laurent {"native_disableDeviceCallback", "()V", (void *)android_media_AudioTrack_disableDeviceCallback}, 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// field names found in android/media/AudioTrack.java 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define JAVA_POSTEVENT_CALLBACK_NAME "postEventFromNative" 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME "mNativeTrackInJavaObj" 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define JAVA_JNIDATA_FIELD_NAME "mJniData" 1112a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi#define JAVA_STREAMTYPE_FIELD_NAME "mStreamType" 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// preconditions: 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// theClass is valid 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool android_media_getIntConstantFromClass(JNIEnv* pEnv, jclass theClass, const char* className, 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* constName, int* constVal) { 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID javaConst = NULL; 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaConst = pEnv->GetStaticFieldID(theClass, constName, "I"); 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (javaConst != NULL) { 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *constVal = pEnv->GetStaticIntField(theClass, javaConst); 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11253762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Can't find %s.%s", className, constName); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_media_AudioTrack(JNIEnv *env) 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaAudioTrackFields.nativeTrackInJavaObj = NULL; 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaAudioTrackFields.postNativeEventInJava = NULL; 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the AudioTrack class 1138ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass audioTrackClass = FindClassOrDie(env, kClassPathName); 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the postEvent method 1141ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe javaAudioTrackFields.postNativeEventInJava = GetStaticMethodIDOrDie(env, 1142ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe audioTrackClass, JAVA_POSTEVENT_CALLBACK_NAME, 1143ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "(Ljava/lang/Object;IIILjava/lang/Object;)V"); 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the variables fields 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // nativeTrackInJavaObj 1147ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe javaAudioTrackFields.nativeTrackInJavaObj = GetFieldIDOrDie(env, 1148ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe audioTrackClass, JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME, "J"); 1149a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi // jniData 1150ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe javaAudioTrackFields.jniData = GetFieldIDOrDie(env, 1151ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe audioTrackClass, JAVA_JNIDATA_FIELD_NAME, "J"); 1152a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi // fieldStreamType 1153ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe javaAudioTrackFields.fieldStreamType = GetFieldIDOrDie(env, 1154ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe audioTrackClass, JAVA_STREAMTYPE_FIELD_NAME, "I"); 1155a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi 1156fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung env->DeleteLocalRef(audioTrackClass); 1157fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung 1158a1d80e3b1d210c60c6881a55ed39a4077ff66080Jean-Michel Trivi // Get the AudioAttributes class and fields 1159ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass audioAttrClass = FindClassOrDie(env, kAudioAttributesClassPathName); 1160ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe javaAudioAttrFields.fieldUsage = GetFieldIDOrDie(env, audioAttrClass, "mUsage", "I"); 1161ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe javaAudioAttrFields.fieldContentType = GetFieldIDOrDie(env, 1162ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe audioAttrClass, "mContentType", "I"); 1163ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe javaAudioAttrFields.fieldFlags = GetFieldIDOrDie(env, audioAttrClass, "mFlags", "I"); 1164ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe javaAudioAttrFields.fieldFormattedTags = GetFieldIDOrDie(env, 1165ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe audioAttrClass, "mFormattedTags", "Ljava/lang/String;"); 1166ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 1167fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung env->DeleteLocalRef(audioAttrClass); 1168fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung 11692d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia // initialize PlaybackParams field info 11702d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia gPlaybackParamsFields.init(env); 1171fe48e0dfb9862356cd4af645fb010236fc273a4aAndy Hung 1172ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 1177