github.com/SahandAslani/gomobile@v0.0.0-20210909130135-2cb2d44c09b2/exp/audio/al/al_android.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package al 6 7 /* 8 #include <stdlib.h> 9 #include <string.h> 10 #include <dlfcn.h> 11 #include <jni.h> 12 #include <limits.h> 13 #include <AL/al.h> 14 #include <AL/alc.h> 15 16 void al_init(uintptr_t java_vm, uintptr_t jni_env, jobject context, void** handle) { 17 JavaVM* vm = (JavaVM*)java_vm; 18 JNIEnv* env = (JNIEnv*)jni_env; 19 20 jclass android_content_Context = (*env)->FindClass(env, "android/content/Context"); 21 jmethodID get_application_info = (*env)->GetMethodID(env, android_content_Context, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;"); 22 jclass android_content_pm_ApplicationInfo = (*env)->FindClass(env, "android/content/pm/ApplicationInfo"); 23 jfieldID native_library_dir = (*env)->GetFieldID(env, android_content_pm_ApplicationInfo, "nativeLibraryDir", "Ljava/lang/String;"); 24 jobject app_info = (*env)->CallObjectMethod(env, context, get_application_info); 25 jstring native_dir = (*env)->GetObjectField(env, app_info, native_library_dir); 26 const char *cnative_dir = (*env)->GetStringUTFChars(env, native_dir, 0); 27 28 char lib_path[PATH_MAX] = ""; 29 strlcat(lib_path, cnative_dir, sizeof(lib_path)); 30 strlcat(lib_path, "/libopenal.so", sizeof(lib_path)); 31 *handle = dlopen(lib_path, RTLD_LAZY); 32 (*env)->ReleaseStringUTFChars(env, native_dir, cnative_dir); 33 } 34 35 void call_alEnable(LPALENABLE fn, ALenum capability) { 36 fn(capability); 37 } 38 39 void call_alDisable(LPALDISABLE fn, ALenum capability) { 40 fn(capability); 41 } 42 43 ALboolean call_alIsEnabled(LPALISENABLED fn, ALenum capability) { 44 return fn(capability); 45 } 46 47 ALint call_alGetInteger(LPALGETINTEGER fn, ALenum p) { 48 return fn(p); 49 } 50 51 void call_alGetIntegerv(LPALGETINTEGERV fn, ALenum p, ALint* v) { 52 fn(p, v); 53 } 54 55 ALfloat call_alGetFloat(LPALGETFLOAT fn, ALenum p) { 56 return fn(p); 57 } 58 59 void call_alGetFloatv(LPALGETFLOATV fn, ALenum p, ALfloat* v) { 60 fn(p, v); 61 } 62 63 ALboolean call_alGetBoolean(LPALGETBOOLEAN fn, ALenum p) { 64 return fn(p); 65 } 66 67 void call_alGetBooleanv(LPALGETBOOLEANV fn, ALenum p, ALboolean* v) { 68 fn(p, v); 69 } 70 71 const char* call_alGetString(LPALGETSTRING fn, ALenum p) { 72 return fn(p); 73 } 74 75 void call_alDistanceModel(LPALDISTANCEMODEL fn, ALenum v) { 76 fn(v); 77 } 78 79 void call_alDopplerFactor(LPALDOPPLERFACTOR fn, ALfloat v) { 80 fn(v); 81 } 82 83 void call_alDopplerVelocity(LPALDOPPLERVELOCITY fn, ALfloat v) { 84 fn(v); 85 } 86 87 void call_alSpeedOfSound(LPALSPEEDOFSOUND fn, ALfloat v) { 88 fn(v); 89 } 90 91 ALint call_alGetError(LPALGETERROR fn) { 92 return fn(); 93 } 94 95 void call_alGenSources(LPALGENSOURCES fn, ALsizei n, ALuint* s) { 96 fn(n, s); 97 } 98 99 void call_alSourcePlayv(LPALSOURCEPLAYV fn, ALsizei n, const ALuint* s) { 100 fn(n, s); 101 } 102 103 void call_alSourcePausev(LPALSOURCEPAUSEV fn, ALsizei n, const ALuint* s) { 104 fn(n, s); 105 } 106 107 void call_alSourceStopv(LPALSOURCESTOPV fn, ALsizei n, const ALuint* s) { 108 fn(n, s); 109 } 110 111 void call_alSourceRewindv(LPALSOURCEREWINDV fn, ALsizei n, const ALuint* s) { 112 fn(n, s); 113 } 114 115 void call_alDeleteSources(LPALDELETESOURCES fn, ALsizei n, const ALuint* s) { 116 fn(n, s); 117 } 118 119 void call_alGetSourcei(LPALGETSOURCEI fn, ALuint s, ALenum k, ALint* v) { 120 fn(s, k, v); 121 } 122 123 void call_alGetSourcef(LPALGETSOURCEF fn, ALuint s, ALenum k, ALfloat* v) { 124 fn(s, k, v); 125 } 126 127 void call_alGetSourcefv(LPALGETSOURCEFV fn, ALuint s, ALenum k, ALfloat* v) { 128 fn(s, k, v); 129 } 130 131 void call_alSourcei(LPALSOURCEI fn, ALuint s, ALenum k, ALint v) { 132 fn(s, k, v); 133 } 134 135 void call_alSourcef(LPALSOURCEF fn, ALuint s, ALenum k, ALfloat v) { 136 fn(s, k, v); 137 } 138 139 void call_alSourcefv(LPALSOURCEFV fn, ALuint s, ALenum k, const ALfloat* v) { 140 fn(s, k, v); 141 } 142 143 void call_alSourceQueueBuffers(LPALSOURCEQUEUEBUFFERS fn, ALuint s, ALsizei n, const ALuint* b) { 144 fn(s, n, b); 145 } 146 147 void call_alSourceUnqueueBuffers(LPALSOURCEUNQUEUEBUFFERS fn, ALuint s, ALsizei n, ALuint* b) { 148 fn(s, n, b); 149 } 150 151 void call_alGetListenerf(LPALGETLISTENERF fn, ALenum k, ALfloat* v) { 152 fn(k, v); 153 } 154 155 void call_alGetListenerfv(LPALLISTENERFV fn, ALenum k, ALfloat* v) { 156 fn(k, v); 157 } 158 159 void call_alListenerf(LPALLISTENERF fn, ALenum k, ALfloat v) { 160 fn(k, v); 161 } 162 163 void call_alListenerfv(LPALLISTENERFV fn, ALenum k, const ALfloat* v) { 164 fn(k, v); 165 } 166 167 void call_alGenBuffers(LPALGENBUFFERS fn, ALsizei n, ALuint* v) { 168 fn(n, v); 169 } 170 171 void call_alDeleteBuffers(LPALDELETEBUFFERS fn, ALsizei n, ALuint* v) { 172 fn(n, v); 173 } 174 175 void call_alGetBufferi(LPALGETBUFFERI fn, ALuint b, ALenum k, ALint* v) { 176 fn(b, k, v); 177 } 178 179 void call_alBufferData(LPALBUFFERDATA fn, ALuint b, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq) { 180 fn(b, format, data, size, freq); 181 } 182 183 ALboolean call_alIsBuffer(LPALISBUFFER fn, ALuint b) { 184 return fn(b); 185 } 186 */ 187 import "C" 188 import ( 189 "errors" 190 "log" 191 "unsafe" 192 193 "github.com/SahandAslani/gomobile/internal/mobileinit" 194 ) 195 196 var ( 197 alHandle unsafe.Pointer 198 alEnableFunc C.LPALENABLE 199 alDisableFunc C.LPALDISABLE 200 alIsEnabledFunc C.LPALISENABLED 201 alGetIntegerFunc C.LPALGETINTEGER 202 alGetIntegervFunc C.LPALGETINTEGERV 203 alGetFloatFunc C.LPALGETFLOAT 204 alGetFloatvFunc C.LPALGETFLOATV 205 alGetBooleanFunc C.LPALGETBOOLEAN 206 alGetBooleanvFunc C.LPALGETBOOLEANV 207 alGetStringFunc C.LPALGETSTRING 208 alDistanceModelFunc C.LPALDISTANCEMODEL 209 alDopplerFactorFunc C.LPALDOPPLERFACTOR 210 alDopplerVelocityFunc C.LPALDOPPLERVELOCITY 211 alSpeedOfSoundFunc C.LPALSPEEDOFSOUND 212 alGetErrorFunc C.LPALGETERROR 213 alGenSourcesFunc C.LPALGENSOURCES 214 alSourcePlayvFunc C.LPALSOURCEPLAYV 215 alSourcePausevFunc C.LPALSOURCEPAUSEV 216 alSourceStopvFunc C.LPALSOURCESTOPV 217 alSourceRewindvFunc C.LPALSOURCEREWINDV 218 alDeleteSourcesFunc C.LPALDELETESOURCES 219 alGetSourceiFunc C.LPALGETSOURCEI 220 alGetSourcefFunc C.LPALGETSOURCEF 221 alGetSourcefvFunc C.LPALGETSOURCEFV 222 alSourceiFunc C.LPALSOURCEI 223 alSourcefFunc C.LPALSOURCEF 224 alSourcefvFunc C.LPALSOURCEFV 225 alSourceQueueBuffersFunc C.LPALSOURCEQUEUEBUFFERS 226 alSourceUnqueueBuffersFunc C.LPALSOURCEUNQUEUEBUFFERS 227 alGetListenerfFunc C.LPALGETLISTENERF 228 alGetListenerfvFunc C.LPALGETLISTENERFV 229 alListenerfFunc C.LPALLISTENERF 230 alListenerfvFunc C.LPALLISTENERFV 231 alGenBuffersFunc C.LPALGENBUFFERS 232 alDeleteBuffersFunc C.LPALDELETEBUFFERS 233 alGetBufferiFunc C.LPALGETBUFFERI 234 alBufferDataFunc C.LPALBUFFERDATA 235 alIsBufferFunc C.LPALISBUFFER 236 237 alcGetErrorFunc C.LPALCGETERROR 238 alcOpenDeviceFunc C.LPALCOPENDEVICE 239 alcCloseDeviceFunc C.LPALCCLOSEDEVICE 240 alcCreateContextFunc C.LPALCCREATECONTEXT 241 alcMakeContextCurrentFunc C.LPALCMAKECONTEXTCURRENT 242 alcDestroyContextFunc C.LPALCDESTROYCONTEXT 243 ) 244 245 func initAL() { 246 err := mobileinit.RunOnJVM(func(vm, env, ctx uintptr) error { 247 C.al_init(C.uintptr_t(vm), C.uintptr_t(env), C.jobject(ctx), &alHandle) 248 if alHandle == nil { 249 return errors.New("al: cannot load libopenal.so") 250 } 251 return nil 252 }) 253 if err != nil { 254 log.Fatalf("al: %v", err) 255 } 256 257 alEnableFunc = C.LPALENABLE(fn("alEnable")) 258 alDisableFunc = C.LPALDISABLE(fn("alDisable")) 259 alIsEnabledFunc = C.LPALISENABLED(fn("alIsEnabled")) 260 alGetIntegerFunc = C.LPALGETINTEGER(fn("alGetInteger")) 261 alGetIntegervFunc = C.LPALGETINTEGERV(fn("alGetIntegerv")) 262 alGetFloatFunc = C.LPALGETFLOAT(fn("alGetFloat")) 263 alGetFloatvFunc = C.LPALGETFLOATV(fn("alGetFloatv")) 264 alGetBooleanFunc = C.LPALGETBOOLEAN(fn("alGetBoolean")) 265 alGetBooleanvFunc = C.LPALGETBOOLEANV(fn("alGetBooleanv")) 266 alGetStringFunc = C.LPALGETSTRING(fn("alGetString")) 267 alDistanceModelFunc = C.LPALDISTANCEMODEL(fn("alDistanceModel")) 268 alDopplerFactorFunc = C.LPALDOPPLERFACTOR(fn("alDopplerFactor")) 269 alDopplerVelocityFunc = C.LPALDOPPLERVELOCITY(fn("alDopplerVelocity")) 270 alSpeedOfSoundFunc = C.LPALSPEEDOFSOUND(fn("alSpeedOfSound")) 271 alGetErrorFunc = C.LPALGETERROR(fn("alGetError")) 272 alGenSourcesFunc = C.LPALGENSOURCES(fn("alGenSources")) 273 alSourcePlayvFunc = C.LPALSOURCEPLAYV(fn("alSourcePlayv")) 274 alSourcePausevFunc = C.LPALSOURCEPAUSEV(fn("alSourcePausev")) 275 alSourceStopvFunc = C.LPALSOURCESTOPV(fn("alSourceStopv")) 276 alSourceRewindvFunc = C.LPALSOURCEREWINDV(fn("alSourceRewindv")) 277 alDeleteSourcesFunc = C.LPALDELETESOURCES(fn("alDeleteSources")) 278 alGetSourceiFunc = C.LPALGETSOURCEI(fn("alGetSourcei")) 279 alGetSourcefFunc = C.LPALGETSOURCEF(fn("alGetSourcef")) 280 alGetSourcefvFunc = C.LPALGETSOURCEFV(fn("alGetSourcefv")) 281 alSourceiFunc = C.LPALSOURCEI(fn("alSourcei")) 282 alSourcefFunc = C.LPALSOURCEF(fn("alSourcef")) 283 alSourcefvFunc = C.LPALSOURCEFV(fn("alSourcefv")) 284 alSourceQueueBuffersFunc = C.LPALSOURCEQUEUEBUFFERS(fn("alSourceQueueBuffers")) 285 alSourceUnqueueBuffersFunc = C.LPALSOURCEUNQUEUEBUFFERS(fn("alSourceUnqueueBuffers")) 286 alGetListenerfFunc = C.LPALGETLISTENERF(fn("alGetListenerf")) 287 alGetListenerfvFunc = C.LPALGETLISTENERFV(fn("alGetListenerfv")) 288 alListenerfFunc = C.LPALLISTENERF(fn("alListenerf")) 289 alListenerfvFunc = C.LPALLISTENERFV(fn("alListenerfv")) 290 alGenBuffersFunc = C.LPALGENBUFFERS(fn("alGenBuffers")) 291 alDeleteBuffersFunc = C.LPALDELETEBUFFERS(fn("alDeleteBuffers")) 292 alGetBufferiFunc = C.LPALGETBUFFERI(fn("alGetBufferi")) 293 alBufferDataFunc = C.LPALBUFFERDATA(fn("alBufferData")) 294 alIsBufferFunc = C.LPALISBUFFER(fn("alIsBuffer")) 295 296 alcGetErrorFunc = C.LPALCGETERROR(fn("alcGetError")) 297 alcOpenDeviceFunc = C.LPALCOPENDEVICE(fn("alcOpenDevice")) 298 alcCloseDeviceFunc = C.LPALCCLOSEDEVICE(fn("alcCloseDevice")) 299 alcCreateContextFunc = C.LPALCCREATECONTEXT(fn("alcCreateContext")) 300 alcMakeContextCurrentFunc = C.LPALCMAKECONTEXTCURRENT(fn("alcMakeContextCurrent")) 301 alcDestroyContextFunc = C.LPALCDESTROYCONTEXT(fn("alcDestroyContext")) 302 } 303 304 func fn(fname string) unsafe.Pointer { 305 name := C.CString(fname) 306 defer C.free(unsafe.Pointer(name)) 307 308 p := C.dlsym(alHandle, name) 309 if uintptr(p) == 0 { 310 log.Fatalf("al: couldn't dlsym %q", fname) 311 } 312 return p 313 } 314 315 func alEnable(capability int32) { 316 C.call_alEnable(alEnableFunc, C.ALenum(capability)) 317 } 318 319 func alDisable(capability int32) { 320 C.call_alDisable(alDisableFunc, C.ALenum(capability)) 321 } 322 323 func alIsEnabled(capability int32) bool { 324 return C.call_alIsEnabled(alIsEnabledFunc, C.ALenum(capability)) == C.AL_TRUE 325 } 326 327 func alGetInteger(k int) int32 { 328 return int32(C.call_alGetInteger(alGetIntegerFunc, C.ALenum(k))) 329 } 330 331 func alGetIntegerv(k int, v []int32) { 332 C.call_alGetIntegerv(alGetIntegervFunc, C.ALenum(k), (*C.ALint)(unsafe.Pointer(&v[0]))) 333 } 334 335 func alGetFloat(k int) float32 { 336 return float32(C.call_alGetFloat(alGetFloatFunc, C.ALenum(k))) 337 } 338 339 func alGetFloatv(k int, v []float32) { 340 C.call_alGetFloatv(alGetFloatvFunc, C.ALenum(k), (*C.ALfloat)(unsafe.Pointer(&v[0]))) 341 } 342 343 func alGetBoolean(k int) bool { 344 return C.call_alGetBoolean(alGetBooleanFunc, C.ALenum(k)) == C.AL_TRUE 345 } 346 347 func alGetBooleanv(k int, v []bool) { 348 val := make([]C.ALboolean, len(v)) 349 for i, bv := range v { 350 if bv { 351 val[i] = C.AL_TRUE 352 } else { 353 val[i] = C.AL_FALSE 354 } 355 } 356 C.call_alGetBooleanv(alGetBooleanvFunc, C.ALenum(k), &val[0]) 357 } 358 359 func alGetString(v int) string { 360 value := C.call_alGetString(alGetStringFunc, C.ALenum(v)) 361 return C.GoString(value) 362 } 363 364 func alDistanceModel(v int32) { 365 C.call_alDistanceModel(alDistanceModelFunc, C.ALenum(v)) 366 } 367 368 func alDopplerFactor(v float32) { 369 C.call_alDopplerFactor(alDopplerFactorFunc, C.ALfloat(v)) 370 } 371 372 func alDopplerVelocity(v float32) { 373 C.call_alDopplerVelocity(alDopplerVelocityFunc, C.ALfloat(v)) 374 } 375 376 func alSpeedOfSound(v float32) { 377 C.call_alSpeedOfSound(alSpeedOfSoundFunc, C.ALfloat(v)) 378 } 379 380 func alGetError() int32 { 381 return int32(C.call_alGetError(alGetErrorFunc)) 382 } 383 384 func alGenSources(n int) []Source { 385 s := make([]Source, n) 386 C.call_alGenSources(alGenSourcesFunc, C.ALsizei(n), (*C.ALuint)(unsafe.Pointer(&s[0]))) 387 return s 388 } 389 390 func alSourcePlayv(s []Source) { 391 C.call_alSourcePlayv(alSourcePlayvFunc, C.ALsizei(len(s)), (*C.ALuint)(unsafe.Pointer(&s[0]))) 392 } 393 394 func alSourcePausev(s []Source) { 395 C.call_alSourcePausev(alSourcePausevFunc, C.ALsizei(len(s)), (*C.ALuint)(unsafe.Pointer(&s[0]))) 396 } 397 398 func alSourceStopv(s []Source) { 399 C.call_alSourceStopv(alSourceStopvFunc, C.ALsizei(len(s)), (*C.ALuint)(unsafe.Pointer(&s[0]))) 400 } 401 402 func alSourceRewindv(s []Source) { 403 C.call_alSourceRewindv(alSourceRewindvFunc, C.ALsizei(len(s)), (*C.ALuint)(unsafe.Pointer(&s[0]))) 404 } 405 406 func alDeleteSources(s []Source) { 407 C.call_alDeleteSources(alDeleteSourcesFunc, C.ALsizei(len(s)), (*C.ALuint)(unsafe.Pointer(&s[0]))) 408 } 409 410 func alGetSourcei(s Source, k int) int32 { 411 var v C.ALint 412 C.call_alGetSourcei(alGetSourceiFunc, C.ALuint(s), C.ALenum(k), &v) 413 return int32(v) 414 } 415 416 func alGetSourcef(s Source, k int) float32 { 417 var v C.ALfloat 418 C.call_alGetSourcef(alGetSourcefFunc, C.ALuint(s), C.ALenum(k), &v) 419 return float32(v) 420 } 421 422 func alGetSourcefv(s Source, k int, v []float32) { 423 C.call_alGetSourcefv(alGetSourcefvFunc, C.ALuint(s), C.ALenum(k), (*C.ALfloat)(unsafe.Pointer(&v[0]))) 424 } 425 426 func alSourcei(s Source, k int, v int32) { 427 C.call_alSourcei(alSourcefFunc, C.ALuint(s), C.ALenum(k), C.ALint(v)) 428 } 429 430 func alSourcef(s Source, k int, v float32) { 431 C.call_alSourcef(alSourcefFunc, C.ALuint(s), C.ALenum(k), C.ALfloat(v)) 432 } 433 434 func alSourcefv(s Source, k int, v []float32) { 435 C.call_alSourcefv(alSourcefvFunc, C.ALuint(s), C.ALenum(k), (*C.ALfloat)(unsafe.Pointer(&v[0]))) 436 } 437 438 func alSourceQueueBuffers(s Source, b []Buffer) { 439 C.call_alSourceQueueBuffers(alSourceQueueBuffersFunc, C.ALuint(s), C.ALsizei(len(b)), (*C.ALuint)(unsafe.Pointer(&b[0]))) 440 } 441 442 func alSourceUnqueueBuffers(s Source, b []Buffer) { 443 C.call_alSourceUnqueueBuffers(alSourceUnqueueBuffersFunc, C.ALuint(s), C.ALsizei(len(b)), (*C.ALuint)(unsafe.Pointer(&b[0]))) 444 } 445 446 func alGetListenerf(k int) float32 { 447 var v C.ALfloat 448 C.call_alGetListenerf(alListenerfFunc, C.ALenum(k), &v) 449 return float32(v) 450 } 451 452 func alGetListenerfv(k int, v []float32) { 453 C.call_alGetListenerfv(alGetListenerfvFunc, C.ALenum(k), (*C.ALfloat)(unsafe.Pointer(&v[0]))) 454 } 455 456 func alListenerf(k int, v float32) { 457 C.call_alListenerf(alListenerfFunc, C.ALenum(k), C.ALfloat(v)) 458 } 459 460 func alListenerfv(k int, v []float32) { 461 C.call_alListenerfv(alListenerfvFunc, C.ALenum(k), (*C.ALfloat)(unsafe.Pointer(&v[0]))) 462 } 463 464 func alGenBuffers(n int) []Buffer { 465 s := make([]Buffer, n) 466 C.call_alGenBuffers(alGenBuffersFunc, C.ALsizei(n), (*C.ALuint)(unsafe.Pointer(&s[0]))) 467 return s 468 } 469 470 func alDeleteBuffers(b []Buffer) { 471 C.call_alDeleteBuffers(alDeleteBuffersFunc, C.ALsizei(len(b)), (*C.ALuint)(unsafe.Pointer(&b[0]))) 472 } 473 474 func alGetBufferi(b Buffer, k int) int32 { 475 var v C.ALint 476 C.call_alGetBufferi(alGetBufferiFunc, C.ALuint(b), C.ALenum(k), &v) 477 return int32(v) 478 } 479 480 func alBufferData(b Buffer, format uint32, data []byte, freq int32) { 481 C.call_alBufferData(alBufferDataFunc, C.ALuint(b), C.ALenum(format), unsafe.Pointer(&data[0]), C.ALsizei(len(data)), C.ALsizei(freq)) 482 } 483 484 func alIsBuffer(b Buffer) bool { 485 return C.call_alIsBuffer(alIsBufferFunc, C.ALuint(b)) == C.AL_TRUE 486 }