Mercurial > sdl-ios-xcode
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: */ |