comparison src/SDL_android.cpp @ 4996:8d7315668e35

Fixed audio buffer lifecycle and implemented audio shutdown
author Sam Lantinga <slouken@libsdl.org>
date Thu, 13 Jan 2011 12:32:55 -0800
parents 9f9bea41e88f
children a21501393bef
comparison
equal deleted inserted replaced
4995:9f9bea41e88f 4996:8d7315668e35
53 static jmethodID midCreateGLContext; 53 static jmethodID midCreateGLContext;
54 static jmethodID midFlipBuffers; 54 static jmethodID midFlipBuffers;
55 static jmethodID midAudioInit; 55 static jmethodID midAudioInit;
56 static jmethodID midAudioWriteShortBuffer; 56 static jmethodID midAudioWriteShortBuffer;
57 static jmethodID midAudioWriteByteBuffer; 57 static jmethodID midAudioWriteByteBuffer;
58 static jmethodID midAudioQuit;
58 59
59 // Accelerometer data storage 60 // Accelerometer data storage
60 float fLastAccelerometer[3]; 61 float fLastAccelerometer[3];
61 62
62 63
81 82
82 jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity"); 83 jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity");
83 mActivityInstance = cls; 84 mActivityInstance = cls;
84 midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V"); 85 midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V");
85 midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V"); 86 midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V");
86 midAudioInit = mEnv->GetStaticMethodID(cls, "audioInit", "(IZZI)Ljava/lang/Object;"); 87 midAudioInit = mEnv->GetStaticMethodID(cls, "audioInit", "(IZZI)Ljava/lang/Object;");
87 midAudioWriteShortBuffer = mEnv->GetStaticMethodID(cls, "audioWriteShortBuffer", "([S)V"); 88 midAudioWriteShortBuffer = mEnv->GetStaticMethodID(cls, "audioWriteShortBuffer", "([S)V");
88 midAudioWriteByteBuffer = mEnv->GetStaticMethodID(cls, "audioWriteByteBuffer", "([B)V"); 89 midAudioWriteByteBuffer = mEnv->GetStaticMethodID(cls, "audioWriteByteBuffer", "([B)V");
90 midAudioQuit = mEnv->GetStaticMethodID(cls, "audioQuit", "()V");
89 91
90 if(!midCreateGLContext || !midFlipBuffers || !midAudioInit || 92 if(!midCreateGLContext || !midFlipBuffers || !midAudioInit ||
91 !midAudioWriteShortBuffer || !midAudioWriteByteBuffer) { 93 !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit) {
92 __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly"); 94 __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
93 } 95 }
94 } 96 }
95 97
96 // Resize 98 // Resize
97 extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize( 99 extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize(
148 } 150 }
149 151
150 extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread( 152 extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread(
151 JNIEnv* env) 153 JNIEnv* env)
152 { 154 {
153 mVM->AttachCurrentThread(&mAudioEnv, NULL); 155 mVM->AttachCurrentThread(&mAudioEnv, NULL);
154 Android_RunAudioThread(); 156 Android_RunAudioThread();
155 } 157 }
156 158
157 159
158 /******************************************************************************* 160 /*******************************************************************************
159 Functions called by SDL into Java 161 Functions called by SDL into Java
169 } 171 }
170 172
171 // 173 //
172 // Audio support 174 // Audio support
173 // 175 //
174 static jint audioBufferFrames = 0; 176 static jboolean audioBuffer16Bit = JNI_FALSE;
175 static bool audioBuffer16Bit = false; 177 static jboolean audioBufferStereo = JNI_FALSE;
176 static bool audioBufferStereo = false; 178 static jobject audioBuffer = NULL;
177 179 static void* audioBufferPinned = NULL;
178 static jobject audioBuffer;
179 static void * audioPinnedBuffer;
180 180
181 extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames) 181 extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
182 { 182 {
183 __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device"); 183 int audioBufferFrames;
184 audioBuffer16Bit = is16Bit; 184
185 audioBufferStereo = channelCount > 1; 185 __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
186 186 audioBuffer16Bit = is16Bit;
187 audioBuffer = mEnv->CallStaticObjectMethod(mActivityInstance, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames); 187 audioBufferStereo = channelCount > 1;
188 audioBuffer = mEnv->NewGlobalRef(audioBuffer); 188
189 189 audioBuffer = mEnv->CallStaticObjectMethod(mActivityInstance, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
190 if (audioBuffer == NULL) { 190
191 __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!"); 191 if (audioBuffer == NULL) {
192 return 0; 192 __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
193 } 193 return 0;
194 194 }
195 if (audioBufferStereo) { 195 audioBuffer = mEnv->NewGlobalRef(audioBuffer);
196 audioBufferFrames = mEnv->GetArrayLength((jshortArray)audioBuffer) / 2; 196
197 } else { 197 jboolean isCopy = JNI_FALSE;
198 audioBufferFrames = mEnv->GetArrayLength((jbyteArray)audioBuffer); 198 if (audioBuffer16Bit) {
199 } 199 audioBufferPinned = mEnv->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
200 200 audioBufferFrames = mEnv->GetArrayLength((jshortArray)audioBuffer);
201 return audioBufferFrames; 201 } else {
202 } 202 audioBufferPinned = mEnv->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy);
203 203 audioBufferFrames = mEnv->GetArrayLength((jbyteArray)audioBuffer);
204 extern "C" void * Android_JNI_PinAudioBuffer() 204 }
205 { 205 if (audioBufferStereo) {
206 jboolean isCopy = JNI_FALSE; 206 audioBufferFrames /= 2;
207 207 }
208 if (audioPinnedBuffer != NULL) { 208
209 return audioPinnedBuffer; 209 return audioBufferFrames;
210 } 210 }
211 211
212 if (audioBuffer16Bit) { 212 extern "C" void * Android_JNI_GetAudioBuffer()
213 audioPinnedBuffer = mAudioEnv->GetShortArrayElements((jshortArray)audioBuffer, &isCopy); 213 {
214 } else { 214 //jboolean isCopy = JNI_FALSE;
215 audioPinnedBuffer = mAudioEnv->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy); 215 //audioBufferPinned = mAudioEnv->GetPrimitiveArrayCritical((jarray)audioBuffer, &isCopy);
216 } 216 return audioBufferPinned;
217 217 }
218 return audioPinnedBuffer; 218
219 } 219 extern "C" void Android_JNI_WriteAudioBuffer()
220 220 {
221 extern "C" void Android_JNI_WriteAudioBufferAndUnpin() 221 //mAudioEnv->ReleasePrimitiveArrayCritical((jarray)audioBuffer, audioBufferPinned, 0);
222 { 222 if (audioBuffer16Bit) {
223 if (audioPinnedBuffer == NULL) { 223 mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
224 return; 224 mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
225 } 225 } else {
226 226 mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
227 if (audioBuffer16Bit) { 227 mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
228 mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioPinnedBuffer, JNI_COMMIT); 228 }
229 mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteShortBuffer, (jshortArray)audioBuffer); 229
230 } else { 230 /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
231 mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioPinnedBuffer, JNI_COMMIT);
232 mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
233 }
234
235 audioPinnedBuffer = NULL;
236 } 231 }
237 232
238 extern "C" void Android_JNI_CloseAudioDevice() 233 extern "C" void Android_JNI_CloseAudioDevice()
239 { 234 {
240 if (audioBuffer) { 235 mEnv->CallStaticVoidMethod(mActivityInstance, midAudioQuit);
241 mEnv->DeleteGlobalRef(audioBuffer); 236
242 audioBuffer = NULL; 237 mEnv->DeleteGlobalRef(audioBuffer);
243 } 238 audioBuffer = NULL;
244
245 // TODO: Implement
246 } 239 }
247 240
248 /* vi: set ts=4 sw=4 expandtab: */ 241 /* vi: set ts=4 sw=4 expandtab: */